2

I have a DynamoDB table that is defined in a module. I want to migrate the table away from using this module, and define it in the DynamoDB table declaration that it ultimately expands to. However, when I do this, Terraform plans to destroy and recreate the table, which I'd like to avoid. Does anyone know how I can avoid this?

Here's my module

variable "table_name" {
  type = string
}

variable "sns_topic_arn" {
  type = string
}

variable "stream_enabled" {
  type = bool
  default = false
}

output "table_arn" {
  value = aws_dynamodb_table.table.arn
}

output "stream_arn" {
  value = aws_dynamodb_table.table.stream_arn
}

resource "aws_dynamodb_table" "table" {
  name = var.table_name
  billing_mode = "PAY_PER_REQUEST"
  hash_key = "uuid"
  stream_enabled = var.stream_enabled
  stream_view_type = var.stream_enabled ? "NEW_IMAGE" : null

  attribute {
    name = "uuid"
    type = "S" 
  }
}

resource "null_resource" "enable_point_in_time_recovery" {
  provisioner "local-exec" {
    command = "aws dynamodb update-continuous-backups --table-name ${var.table_name} --point-in-time-recovery-specification PointInTimeRecoveryEnabled=true"
  }
}

And here's where I invoke that module in existing code

    module "tower_table" {
      source = "./modules/kts_dynamodb"
      table_name = "tower"
      sns_topic_arn = aws_sns_topic.sns.arn
      stream_enabled = true
    }

Now this is what I'm replacing it with

    resource "aws_dynamodb_table" "tower" {
      name = "tower"
      billing_mode = "PAY_PER_REQUEST"
      hash_key = "uuid"
      stream_enabled = true
      stream_view_type = "NEW_IMAGE"
    
      attribute {
        name = "uuid"
        type = "S" 
      }
    }

    resource "null_resource" "enable_point_in_time_recovery_on_tower_table" {
      provisioner "local-exec" {
        command = "aws dynamodb update-continuous-backups --table-name tower --point-in-time-recovery-specification PointInTimeRecoveryEnabled=true"
      }
    }

And this is the Terraform plan abridged because there are several uses of the table that are being updated in place or destroyed and readded but I believe those are fine.

  # aws_dynamodb_table.tower will be created
  + resource "aws_dynamodb_table" "tower" {
      + arn              = (known after apply)
      + billing_mode     = "PAY_PER_REQUEST"
      + hash_key         = "uuid"
      + id               = (known after apply)
      + name             = "tower"
      + stream_arn       = (known after apply)
      + stream_enabled   = true
      + stream_label     = (known after apply)
      + stream_view_type = "NEW_IMAGE"

      + attribute {
          + name = "uuid"
          + type = "S"
        }

      + point_in_time_recovery {
          + enabled = (known after apply)
        }

      + server_side_encryption {
          + enabled     = (known after apply)
          + kms_key_arn = (known after apply)
        }
    }

      # null_resource.enable_point_in_time_recovery_on_tower_table will be created
      + resource "null_resource" "enable_point_in_time_recovery_on_tower_table" {
          + id = (known after apply)
        }
    
      # module.tower_table.aws_dynamodb_table.table will be destroyed
      # (because aws_dynamodb_table.table is not in configuration)
      - resource "aws_dynamodb_table" "table" {
          - arn              = "arn:aws:dynamodb:us-east-1:563407091361:table/tower" -> null
          - billing_mode     = "PAY_PER_REQUEST" -> null
          - hash_key         = "uuid" -> null
          - id               = "tower" -> null
          - name             = "tower" -> null
          - read_capacity    = 0 -> null
          - stream_arn       = "arn:aws:dynamodb:us-east-1:563407091361:table/tower/stream/2021-06-05T19:07:29.088" -> null
          - stream_enabled   = true -> null
          - stream_label     = "2021-06-05T19:07:29.088" -> null
          - stream_view_type = "NEW_IMAGE" -> null
          - tags             = {} -> null
          - write_capacity   = 0 -> null
    
          - attribute {
              - name = "uuid" -> null
              - type = "S" -> null
            }
    
          - point_in_time_recovery {
              - enabled = true -> null
            }
    
          - ttl {
              - enabled = false -> null
            }
        }
    
      # module.tower_table.null_resource.enable_point_in_time_recovery will be destroyed
      # (because null_resource.enable_point_in_time_recovery is not in configuration)
      - resource "null_resource" "enable_point_in_time_recovery" {
          - id = "2361959608776928291" -> null
        }
    
    Plan: 3 to add, 2 to change, 3 to destroy.
mmachenry
  • 1,773
  • 3
  • 22
  • 38

0 Answers0