hashicorp / terraform-provider-awscc

Terraform AWS Cloud Control provider
https://registry.terraform.io/providers/hashicorp/awscc/latest/docs
Mozilla Public License 2.0
261 stars 120 forks source link

awscc_neptune_db_cluster: state mismatch with defaults based on actual config #1735

Closed quixoticmonk closed 2 months ago

quixoticmonk commented 5 months ago

Community Note

Terraform CLI and Terraform AWS Cloud Control Provider Version

Affected Resource(s)

Terraform Configuration Files

Terraform configuration file below. No subnet specified as there is no awscc resource for the subnet group. Once deployed, a default subnet is created and attached to the cluster.

resource "awscc_neptune_db_cluster" "default" {
  db_cluster_identifier          = "example"
  backup_retention_period        = 5
  preferred_backup_window        = "07:00-09:00"
  iam_auth_enabled               = true
  db_port                        = 8182
  copy_tags_to_snapshot          = true
  deletion_protection            = false
  enable_cloudwatch_logs_exports = ["audit"]
  engine_version                 = "1.3.1.0"
  preferred_maintenance_window   = "sun:10:00-sun:10:30"
  storage_encrypted              = true
  kms_key_id                     = awscc_kms_key.example.key_id

    tags = [{
    key   = "Modified By"
    value = "AWSCC"
  }]
}

resource "awscc_kms_key" "example" {
  description = "KMS Key for root"
  key_policy = jsonencode({
    "Version" : "2012-10-17",
    "Id" : "KMS-Key-Policy-For-Root",
    "Statement" : [
      {
        "Sid" : "Enable IAM User Permissions",
        "Effect" : "Allow",
        "Principal" : {
          "AWS" : "arn:aws:iam::########:root"
        },
        "Action" : "kms:*",
        "Resource" : "*"
      },
    ],
    }
  )
}

Debug Output

Panic Output

Expected Behavior

The DB cluster should be created. On the second run, Terraform identifies a change on the configuration (when there is none) and destroys the existing cluster.

Actual Behavior

  1. Cluster is created.
  2. On second Terraform apply, Terraform identifies the change in the account ( associated subnet, vpc and other configurations) and destroys the existing resource and recreates it.

Logs from the run ..

Terraform will perform the following actions:

  # awscc_neptune_db_cluster.default must be replaced
-/+ resource "awscc_neptune_db_cluster" "default" {
      + associated_roles                 = (known after apply)
      ~ availability_zones               = [
          - "us-east-1f",
          - "us-east-1d",
          - "us-east-1b",
        ] -> (known after apply)
      ~ cluster_resource_id              = "cluster-BIZ5MJGTO7AP3KGJ2XKV6LEDEI" -> (known after apply)
      ~ db_cluster_parameter_group_name  = "default.neptune1.3" -> (known after apply)
      + db_instance_parameter_group_name = (known after apply)
      ~ db_subnet_group_name             = "default" -> (known after apply)
      ~ endpoint                         = "example.cluster-cmphb1zolqxk.us-east-1.neptune.amazonaws.com" -> (known after apply)
      ~ id                               = "example" -> (known after apply)
      ~ kms_key_id                       = "arn:aws:kms:us-east-1:############:key/e9946bf0-54fe-4fe0-aff9-7c5bcea7a009" -> "e9946bf0-54fe-4fe0-aff9-7c5bcea7a009" # forces replacement
      ~ port                             = "8182" -> (known after apply)
      ~ read_endpoint                    = "example.cluster-ro-cmphb1zolqxk.us-east-1.neptune.amazonaws.com" -> (known after apply)
      + restore_to_time                  = (known after apply)
      + serverless_scaling_configuration = (known after apply)
      + snapshot_identifier              = (known after apply)
      + source_db_cluster_identifier     = (known after apply)
        tags                             = [
            {
                key   = "Modified By"
                value = "AWSCC"
            },
        ]
      + use_latest_restorable_time       = (known after apply)
      ~ vpc_security_group_ids           = [
          - "sg-044b064d6706ce34f",
        ] -> (known after apply)
        # (12 unchanged attributes hidden)
    }

Steps to Reproduce

  1. terraform apply
  2. terraform apply

Important Factoids

The Terraform state does include the vpc and az details which are not provided per configuration. The absence of them in the config on a second attempt leads to destroy operation.

            "availability_zones": [
              "us-east-1c",
              "us-east-1a",
              "us-east-1b"
            ],
            "backup_retention_period": 5,
            "cluster_resource_id": "cluster-OFGWFHCRGJDEJ5UMIT36PGGCLU",
            "copy_tags_to_snapshot": true,
            "db_cluster_identifier": "example",
            "db_cluster_parameter_group_name": "default.neptune1.3",

References

quixoticmonk commented 4 months ago

2024-06-29T23:12:04.509-0400 [DEBUG] provider.terraform-provider-awscc_v1.4.0_x5: Detected value change between proposed new state and prior state: tf_rpc=PlanResourceChange @module=sdk.framework tf_attribute_path=kms_key_id tf_provider_addr=registry.terraform.io/hashicorp/awscc tf_req_id=40ac2f17-fe99-7aba-3414-4c32aca60ae0 @caller=github.com/hashicorp/terraform-plugin-framework@v1.9.0/internal/fwserver/server_planresourcechange.go:208 tf_resource_type=awscc_neptune_db_cluster timestamp=2024-06-29T23:12:04.509-0400

{
  "arn": "arn:aws:kms:us-east-1:############:key/c141edc2-732f-4633-b21d-9b116e206878",
  "bypass_policy_lockout_safety_check": false,
  "description": "KMS Key for root",
  "enable_key_rotation": false,
  "enabled": true,
  "id": "c141edc2-732f-4633-b21d-9b116e206878",
  "key_id": "c141edc2-732f-4633-b21d-9b116e206878",
  "key_policy": "{\"Id\":\"KMS-Key-Policy-For-Root\",\"Statement\":[{\"Action\":\"kms:*\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::############:root\"},\"Resource\":\"*\",\"Sid\":\"Enable IAM User Permissions\"}],\"Version\":\"2012-10-17\"}",
  "key_spec": "SYMMETRIC_DEFAULT",
  "key_usage": "ENCRYPT_DECRYPT",
  "multi_region": false,
  "origin": "AWS_KMS",
  "pending_window_in_days": null,
  "rotation_period_in_days": 365,
  "tags": null
}

{
  "associated_roles": null,
  "availability_zones": null,
  "backup_retention_period": 5,
  "cluster_resource_id": null,
  "copy_tags_to_snapshot": true,
  "db_cluster_identifier": "example",
  "db_cluster_parameter_group_name": null,
  "db_instance_parameter_group_name": null,
  "db_port": 8182,
  "db_subnet_group_name": null,
  "deletion_protection": false,
  "enable_cloudwatch_logs_exports": [
    "audit"
  ],
  "endpoint": null,
  "engine_version": "1.3.1.0",
  "iam_auth_enabled": true,
  "id": null,
  "kms_key_id": "c141edc2-732f-4633-b21d-9b116e206878",
  "port": null,
  "preferred_backup_window": "07:00-09:00",
  "preferred_maintenance_window": "sun:10:00-sun:10:30",
  "read_endpoint": null,
  "restore_to_time": null,
  "restore_type": null,
  "serverless_scaling_configuration": null,
  "snapshot_identifier": null,
  "source_db_cluster_identifier": null,
  "storage_encrypted": true,
  "tags": [
    {
      "key": "Modified By",
      "value": "AWSCC"
    }
  ],
  "use_latest_restorable_time": null,
  "vpc_security_group_ids": null
}
{
  "associated_roles": "\u0000",
  "availability_zones": "\u0000",
  "backup_retention_period": 5,
  "cluster_resource_id": "\u0000",
  "copy_tags_to_snapshot": true,
  "db_cluster_identifier": "example",
  "db_cluster_parameter_group_name": "\u0000",
  "db_instance_parameter_group_name": "\u0000",
  "db_port": 8182,
  "db_subnet_group_name": "\u0000",
  "deletion_protection": false,
  "enable_cloudwatch_logs_exports": [
    "audit"
  ],
  "endpoint": "\u0000",
  "engine_version": "1.3.1.0",
  "iam_auth_enabled": true,
  "id": "\u0000",
  "kms_key_id": "c141edc2-732f-4633-b21d-9b116e206878",
  "port": "\u0000",
  "preferred_backup_window": "07:00-09:00",
  "preferred_maintenance_window": "sun:10:00-sun:10:30",
  "read_endpoint": "\u0000",
  "restore_to_time": "\u0000",
  "restore_type": "full-copy",
  "serverless_scaling_configuration": "\u0000",
  "snapshot_identifier": "\u0000",
  "source_db_cluster_identifier": "\u0000",
  "storage_encrypted": true,
  "tags": [
    {
      "key": "Modified By",
      "value": "AWSCC"
    }
  ],
  "use_latest_restorable_time": "\u0000",
  "vpc_security_group_ids": "\u0000"
}
wellsiau-aws commented 4 months ago

Since awscc_kms_key.example.key_id will return the short ID instead of the full ARN, this causing a drift because the awscc_neptune_db_cluster.kms_key_id will differ from CCAPI GetResource as shown below.

Terraform State (redacted)

    {
      "mode": "managed",
      "type": "awscc_neptune_db_cluster",
      "name": "default",
      "provider": "provider[\"registry.terraform.io/hashicorp/awscc\"]",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            . . .
            "id": "example",
            "kms_key_id": "1d622a64-30db-43a0-9b34-43b76c33ea15",
            . . .
        }
      ]
    }

CCAPI GetResource (redacted)

{
  "KmsKeyId": "arn:aws:kms:us-east-1:204034886740:key/1d622a64-30db-43a0-9b34-43b76c33ea15",
  . . .
  "DBClusterIdentifier": "example",
  . . .
}
wellsiau-aws commented 4 months ago

By changing the kms_key_id reference to use ARN, I was able to avoid the drift:

resource "awscc_neptune_db_cluster" "default" {
  db_cluster_identifier          = "example"
  backup_retention_period        = 5
  preferred_backup_window        = "07:00-09:00"
  iam_auth_enabled               = true
  db_port                        = 8182
  copy_tags_to_snapshot          = true
  deletion_protection            = false
  enable_cloudwatch_logs_exports = ["audit"]
  engine_version                 = "1.3.1.0"
  preferred_maintenance_window   = "sun:10:00-sun:10:30"
  storage_encrypted              = true
  kms_key_id                     = awscc_kms_key.example.arn

    tags = [{
    key   = "Modified By"
    value = "AWSCC"
  }]
}

Plan output:

3c06301d1719:awscc_neptune_db_cluster wellsiau$ terraform plan
awscc_kms_key.example: Refreshing state... [id=1d622a64-30db-43a0-9b34-43b76c33ea15]
awscc_neptune_db_cluster.default: Refreshing state... [id=example]

No changes. Your infrastructure matches the configuration.

This may require another call out in the documentation to recommend using attribute arn instead of key_id

quixoticmonk commented 4 months ago

Updated the examples to use ARN, flipped the PR Ready for review. https://github.com/hashicorp/terraform-provider-awscc/pull/1736

wellsiau-aws commented 2 months ago

with the updated doc as noted in #1736 , I am going to go ahead and close this issue.