2

I created a documentdb cluster by terraform. When I run terraform plan, it tried to destroy the cluster and rebuild it, but I didn't change the value file.

below is the main content of terraform script,

resource "aws_docdb_subnet_group" "default" {
  name = format("%s-subnet-group", var.env)
  subnet_ids = [
    data.terraform_remote_state.net.outputs.cicd-sub-priv1,
    data.terraform_remote_state.net.outputs.cicd-sub-priv2,
    data.terraform_remote_state.net.outputs.cicd-sub-pub2,
  ]

  tags = {
    Name = format("%s-subnet-group", var.env)
  }
}

resource "aws_docdb_cluster_instance" "docdb" {
  count              = var.docdb_instance_count
  identifier         = "${var.env}-docdb-instance-${count.index}"
  cluster_identifier = aws_docdb_cluster.docdb.id
  instance_class     = var.docdb_instance_class

  tags = {
      Name = format("%s-docdb-cluster-instance", var.env)
  }
}

resource "aws_docdb_cluster" "docdb" {
  cluster_identifier        = format("%s-docdb-cluster", var.env)
  availability_zones        = var.docdb_az
  db_subnet_group_name      = aws_docdb_subnet_group.default.id
  master_username           = var.docdb_master_username
  master_password           = var.docdb_master_password
  storage_encrypted         = "true"
  kms_key_id                = data.aws_kms_alias.rds.arn
  final_snapshot_identifier = format("%s-docdb-final-snapshot", var.env)

  engine         = "docdb"
  engine_version = "4.0.0"
  port           = var.docdb_port

    tags = {
        Name = format("%s-docdb-cluster", var.env)
    }
}

output "docdb_name" {
  value       = aws_docdb_cluster.docdb.id
  description = "The name of docdb cluster"
}

output "docdb_arn" {
  value       = aws_docdb_cluster.docdb.arn
  description = "The arn of docdb cluster"
}

output "docdb_endpoint" {
  value       = aws_docdb_cluster.docdb.endpoint
  description = "The DNS address of the DocDB instance"
}

data_kms_alias_rds.tf

data "aws_kms_alias" "rds" {
  name = "alias/aws/rds"
}

and these are terraform plan out reult

$ terraform plan -out tfplan -var-file test.tfvars
Acquiring state lock. This may take a few moments...
aws_docdb_subnet_group.default: Refreshing state... [id=test-subnet-group]
aws_docdb_cluster.docdb: Refreshing state... [id=test-docdb-cluster]
aws_docdb_cluster_instance.docdb[0]: Refreshing state... [id=test-docdb-instance-0]
aws_docdb_cluster_instance.docdb[1]: Refreshing state... [id=test-docdb-instance-1]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # aws_docdb_cluster.docdb has been changed
  ~ resource "aws_docdb_cluster" "docdb" {
      ~ cluster_members                 = [
          + "test-docdb-instance-0",
          + "test-docdb-instance-1",
        ]
      + enabled_cloudwatch_logs_exports = []
        id                              = "test-docdb-cluster"
      + tags                            = {}
        # (24 unchanged attributes hidden)
    }
  # aws_docdb_cluster_instance.docdb[0] has been changed
  ~ resource "aws_docdb_cluster_instance" "docdb" {
        id                           = "test-docdb-instance-0"
      + tags                         = {}
        # (21 unchanged attributes hidden)
    }
  # aws_docdb_cluster_instance.docdb[1] has been changed
  ~ resource "aws_docdb_cluster_instance" "docdb" {
        id                           = "test-docdb-instance-1"
      + tags                         = {}
        # (21 unchanged attributes hidden)
    }

Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the
following plan may include actions to undo or respond to these changes.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # aws_docdb_cluster.docdb must be replaced
-/+ resource "aws_docdb_cluster" "docdb" {
      + apply_immediately               = (known after apply)
      ~ arn                             = "arn:aws:rds:us-east-1:<hidden>:cluster:test-docdb-cluster" -> (known after apply)
      + cluster_identifier_prefix       = (known after apply)
      ~ cluster_members                 = [
          - "test-docdb-instance-0",
          - "test-docdb-instance-1",
        ] -> (known after apply)
      ~ cluster_resource_id             = "cluster-<hidden>" -> (known after apply)
      ~ db_cluster_parameter_group_name = "default.docdb4.0" -> (known after apply)
      - deletion_protection             = false -> null
      - enabled_cloudwatch_logs_exports = [] -> null
      ~ endpoint                        = "<hidden>" -> (known after apply)
      ~ hosted_zone_id                  = "ZNKXH85TT8WVW" -> (known after apply)
      ~ id                              = "test-docdb-cluster" -> (known after apply)
      ~ kms_key_id                      = "arn:aws:kms:us-east-1:<hidden>:key/<hidden>" -> "arn:aws:kms:us-east-1:<hidden>:alias/aws/rds" # forces replacement
      ~ preferred_backup_window         = "07:55-08:25" -> (known after apply)
      ~ preferred_maintenance_window    = "wed:10:07-wed:10:37" -> (known after apply)
      ~ reader_endpoint                 = "<hidden>" -> (known after apply)
      - tags                            = {} -> null
      ~ tags_all                        = {} -> (known after apply)
      ~ vpc_security_group_ids          = [
          - "sg-066866c3e4988de42",
        ] -> (known after apply)
        # (12 unchanged attributes hidden)
    }

  # aws_docdb_cluster_instance.docdb[0] must be replaced
-/+ resource "aws_docdb_cluster_instance" "docdb" {
      + apply_immediately            = (known after apply)
      ~ arn                          = "arn:aws:rds:us-east-1:<hidden>:db:test-docdb-instance-0" -> (known after apply)
      ~ availability_zone            = "us-east-1a" -> (known after apply)
      ~ ca_cert_identifier           = "rds-ca-2019" -> (known after apply)
      ~ cluster_identifier           = "test-docdb-cluster" -> (known after apply) # forces replacement
      ~ db_subnet_group_name         = "test-subnet-group" -> (known after apply)
      ~ dbi_resource_id              = "db-<hidden>" -> (known after apply)
      ~ endpoint                     = "<hidden>" -> (known after apply)
      ~ engine_version               = "4.0.0" -> (known after apply)
      ~ id                           = "test-docdb-instance-0" -> (known after apply)
      + identifier_prefix            = (known after apply)
      ~ kms_key_id                   = "arn:aws:kms:us-east-1:<hidden>:key/<hidden>" -> (known after apply)
      ~ port                         = 37018-> (known after apply)
      ~ preferred_backup_window      = "07:55-08:25" -> (known after apply)
      ~ preferred_maintenance_window = "sat:07:23-sat:07:53" -> (known after apply)
      ~ publicly_accessible          = false -> (known after apply)
      ~ storage_encrypted            = true -> (known after apply)
      - tags                         = {} -> null
      ~ tags_all                     = {} -> (known after apply)
      ~ writer                       = false -> (known after apply)
        # (5 unchanged attributes hidden)
    }

  # aws_docdb_cluster_instance.docdb[1] must be replaced
-/+ resource "aws_docdb_cluster_instance" "docdb" {
      + apply_immediately            = (known after apply)
      ~ arn                          = "arn:aws:rds:us-east-1:<hidden>:db:test-docdb-instance-1" -> (known after apply)
      ~ availability_zone            = "us-east-1c" -> (known after apply)
      ~ ca_cert_identifier           = "rds-ca-2019" -> (known after apply)
      ~ cluster_identifier           = "test-docdb-cluster" -> (known after apply) # forces replacement
      ~ db_subnet_group_name         = "test-subnet-group" -> (known after apply)
      ~ dbi_resource_id              = "db-<hidden>" -> (known after apply)
      ~ endpoint                     = "<hidden>" -> (known after apply)
      ~ engine_version               = "4.0.0" -> (known after apply)
      ~ id                           = "test-docdb-instance-1" -> (known after apply)
      + identifier_prefix            = (known after apply)
      ~ kms_key_id                   = "arn:aws:kms:us-east-1:<hidden>:key/<hidden>" -> (known after apply)
      ~ port                         = 37018 -> (known after apply)
      ~ preferred_backup_window      = "07:55-08:25" -> (known after apply)
      ~ preferred_maintenance_window = "sat:05:13-sat:05:43" -> (known after apply)
      ~ publicly_accessible          = false -> (known after apply)
      ~ storage_encrypted            = true -> (known after apply)
      - tags                         = {} -> null
      ~ tags_all                     = {} -> (known after apply)
      ~ writer                       = true -> (known after apply)
        # (5 unchanged attributes hidden)
    }

Plan: 3 to add, 0 to change, 3 to destroy.

Changes to Outputs:
  ~ docdb_arn      = "arn:aws:rds:us-east-1:<hidden>:cluster:test-docdb-cluster" -> (known after apply)
  ~ docdb_endpoint = "<hidden>" -> (known after apply)
  ~ docdb_name     = "test-docdb-cluster" -> (known after apply)

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "tfplan"
Releasing state lock. This may take a few moments...

How can I keep update the documentdb cluster without rebuilding every time I run my script?

Denis V
  • 78
  • 5
jolla
  • 365
  • 1
  • 2
  • 15
  • Seems KMS key was changed. Who changed it? – Marcin Dec 15 '21 at 04:29
  • I updated kms part, I want to use aws kms key, so I create data_kms_alias_rds.tf, and reference the arn of it in main.tf, is that the correct way to enable kms encrypt, I don't want to use customized kms key – jolla Dec 15 '21 at 04:32
  • Changing kms key for your DocumentDB [requires replacement](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-docdb-dbcluster.html#cfn-docdb-dbcluster-kmskeyid). Did you expect anything else? – Marcin Dec 15 '21 at 04:38
  • thanks @Marchin, you are righ, it is caused by kms key id, If I changed it to the generated value, terraform don't rebuild the cluster, but do you know how to refer the default kms key id , at aws console, it is showing aws/rds – jolla Dec 15 '21 at 04:38
  • I've noticed that all almost your questions got answered yet not a single answer was [accepted](https://meta.stackexchange.com/a/86979). Accepting useful answers is not only a good practice, but reduces duplicates and increases chances of your questions being actually answered. – Marcin Dec 15 '21 at 04:45

2 Answers2

2

Changing kms key for your DocumentDB requires replacement. There is not much you can do about that.

You are correctly referring to default kms (kms_key_id = data.aws_kms_alias.rds.arn). But since you had different kms key before, a replacement is required. If so, make sure you backup your db before that.

Marcin
  • 215,873
  • 14
  • 235
  • 294
2

It seems that AWS replaced the value for kms_key_id property during creation of the cluster. Try to use target_key_arn property instead of arn of the alias in the cluster resource: kms_key_id = data.aws_kms_alias.rds.target_key_arn

That’s the only property which forces replacement of the cluster resource. Cluster instances replacement is a consequence of the cluster replacement.

Denis V
  • 78
  • 5
  • Thanks, this helped me fix my docdb cluster that was getting replaced every time with the use of alias arn, even when no changes were made. I found more info on this issue [here](https://github.com/hashicorp/terraform-provider-aws/issues/3019). – Rohit P Mar 08 '22 at 14:07