Skip to content

Instantly share code, notes, and snippets.

@staticaland
Last active May 28, 2024 11:34
Show Gist options
  • Save staticaland/c5827456da01160b55238c4d973d007b to your computer and use it in GitHub Desktop.
Save staticaland/c5827456da01160b55238c4d973d007b to your computer and use it in GitHub Desktop.

Managing state discrepancies: No-op vs. active changes during Terraform import for AWS Resources

TL;DR

For the enable_global_write_forwarding attribute in Terraform-managed AWS RDS clusters, setting it to false results in a state-only update with no AWS API call, effectively a no-op. Setting it to true triggers an actual API call to AWS to enable the feature.

Hypothesis

  1. State Tracking:

    • Terraform tracks the state of resources both in its state file and in AWS.
    • The attribute enable_global_write_forwarding is part of the Terraform configuration for an RDS cluster.
  2. Behavior of enable_global_write_forwarding:

    • When enable_global_write_forwarding is set to false in Terraform, it appears to be a state-only attribute. This means that Terraform will track this setting in its state file but it does not result in an API call to AWS to modify the resource.
    • When importing the RDS cluster with terraform import, if the state file has enable_global_write_forwarding = false, Terraform detects this as a planned change but it is essentially a no-op, resulting in no actual change to the AWS resource.
  3. Potential for API Calls:

    • If enable_global_write_forwarding is set to true in the Terraform configuration, Terraform may attempt to apply this change to the AWS resource, resulting in an API call to enable global write forwarding on the RDS cluster.
    • Therefore, setting enable_global_write_forwarding to true is not a no-op and will lead to changes in AWS.

Key Points

  • No-op with false: When enable_global_write_forwarding is false, Terraform updates the state file without making an API call to AWS. This means the planned change is purely for state synchronization.
  • Active Change with true: When enable_global_write_forwarding is set to true, Terraform will make an API call to AWS to enable this feature on the RDS cluster.

Steps to Confirm Behavior

  1. Check Plan Output: Running terraform plan will show if Terraform plans to "add" or "modify" the attribute.

    • If the plan indicates changes with false but does not specify an API action, it confirms a state-only update.
    • If the plan indicates changes with true, it should specify the corresponding API call.
  2. Debug Logging: Using debug logging with terraform apply (TF_LOG=DEBUG terraform apply) will provide detailed information on whether Terraform makes an API call when enable_global_write_forwarding is set to true.

  3. AWS Console Verification: Post-apply, you can verify in the AWS Management Console whether the RDS cluster settings reflect the changes, specifically for enabling global write forwarding.

CLI verification:

aws rds describe-db-clusters --query '*[].{DBClusterIdentifier:DBClusterIdentifier,GlobalWriteForwardingStatus:GlobalWriteForwardingStatus}'

This command fetches details about your RDS DB clusters, specifically:

  • DBClusterIdentifier: The unique identifier of the DB cluster.
  • GlobalWriteForwardingStatus: The status of global write forwarding for the DB cluster.

Conclusion

  • No-op Change: enable_global_write_forwarding = false results in no actual change to the AWS resource, only an update to the Terraform state.
  • Operational Change: enable_global_write_forwarding = true triggers an API call to AWS to enable the feature on the RDS cluster.

Understanding this behavior helps ensure that Terraform manages state accurately without making unnecessary changes to your infrastructure.

Other

This is probably related to ImportStateVerifyIgnore.

Some resource attributes only exist within the context of the Terraform resource or are only used to modify an API request during resource Create, Update, and Delete functions. In these cases, if implementation of the resource cannot obtain the value for the attribute in the Read function or its not determined/defaulted to the correct value during the Importer State function, the acceptance testing may return an error

https://github.com/hashicorp/terraform-provider-google/wiki/Developer-Best-Practices#importstateverifyignore

Not all attributes on a resource are returned from a resource's GET call, and thus can't be imported. For example, secrets are often returned as empty, and we sometimes add virtual fields to a resource that are not part of its API to control behavior. In these circumstances, the field can be ignored in the test using ImportStateVerifyIgnore. This is also useful for fields that have DiffSuppressFuncs that can't be worked around by providing a different value in the test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment