hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.84k stars 9.19k forks source link

[Bug]: Incorrect order of operations when removing a cloudfront cache behavior and destroying cache policies it is referencing #33047

Closed sidekick-eimantas closed 1 year ago

sidekick-eimantas commented 1 year ago

Terraform Core Version

1.5.2

AWS Provider Version

5.7.0

Affected Resource(s)

Expected Behavior

Distribution ordered_cache_behavior should be removed first, before the destruction of aws_cloudfront_origin_request_policy and aws_cloudfront_cache_policy

Actual Behavior

Terraform tried to destroy aws_cloudfront_cache_policy and aws_cloudfront_origin_request_policy first before removing an ordered_cache_behavior from the distribution, causing the apply to fail, because cache and request policies referenced to by cache behaviors, cannot be deleted.

Relevant Error/Panic Output Snippet

Terraform will perform the following actions:

  # module.sidekick_app_assets.module.cdn.aws_cloudfront_cache_policy.this["publicdocs"] will be destroyed
  # (because key ["publicdocs"] is not in for_each map)
  - resource "aws_cloudfront_cache_policy" "this" {
      - comment     = "Static public document assets" -> null
      - default_ttl = 300 -> null
      - etag        = "E23ZP02F085DFQ" -> null
      - id          = "0bdc9a19-4684-4ebe-b904-124f456fd31a" -> null
      - max_ttl     = 86400 -> null
      - min_ttl     = 300 -> null
      - name        = "sidekick-app-assets-publicdocs" -> null

      - parameters_in_cache_key_and_forwarded_to_origin {
          - enable_accept_encoding_brotli = true -> null
          - enable_accept_encoding_gzip   = true -> null

          - cookies_config {
              - cookie_behavior = "none" -> null
            }

          - headers_config {
              - header_behavior = "none" -> null
            }

          - query_strings_config {
              - query_string_behavior = "none" -> null
            }
        }
    }

  # module.sidekick_app_assets.module.cdn.aws_cloudfront_distribution.this will be updated in-place
  ~ resource "aws_cloudfront_distribution" "this" {
        id                             = "E1QQ1L1SCM5HY7"
        tags                           = {}
        # (19 unchanged attributes hidden)

      - ordered_cache_behavior {
          - allowed_methods          = [
              - "GET",
              - "HEAD",
              - "OPTIONS",
            ] -> null
          - cache_policy_id          = "0bdc9a19-4684-4ebe-b904-124f456fd31a" -> null
          - cached_methods           = [
              - "GET",
              - "HEAD",
              - "OPTIONS",
            ] -> null
          - compress                 = true -> null
          - default_ttl              = 0 -> null
          - max_ttl                  = 0 -> null
          - min_ttl                  = 0 -> null
          - origin_request_policy_id = "c7306944-7cd1-45ec-b65e-84f104854143" -> null
          - path_pattern             = "publicdocs/*" -> null
          - smooth_streaming         = false -> null
          - target_origin_id         = "store" -> null
          - trusted_key_groups       = [] -> null
          - trusted_signers          = [] -> null
          - viewer_protocol_policy   = "redirect-to-https" -> null
        }

        # (8 unchanged blocks hidden)
    }

  # module.sidekick_app_assets.module.cdn.aws_cloudfront_origin_request_policy.this["publicdocs"] will be destroyed
  # (because key ["publicdocs"] is not in for_each map)
  - resource "aws_cloudfront_origin_request_policy" "this" {
      - comment = "Static public document assets" -> null
      - etag    = "E23ZP02F085DFQ" -> null
      - id      = "c7306944-7cd1-45ec-b65e-84f104854143" -> null
      - name    = "sidekick-app-assets-publicdocs" -> null

      - cookies_config {
          - cookie_behavior = "none" -> null
        }

      - headers_config {
          - header_behavior = "none" -> null
        }

      - query_strings_config {
          - query_string_behavior = "none" -> null
        }
    }

Plan: 0 to add, 1 to change, 2 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

module.sidekick_app_assets.module.cdn.aws_cloudfront_origin_request_policy.this["publicdocs"]: Destroying... [id=c7306944-7cd1-45ec-b65e-84f104854143]
module.sidekick_app_assets.module.cdn.aws_cloudfront_cache_policy.this["publicdocs"]: Destroying... [id=0bdc9a19-4684-4ebe-b904-124f456fd31a]
╷
│ Error: deleting CloudFront Cache Policy (0bdc9a19-4684-4ebe-b904-124f456fd31a): CachePolicyInUse: The specified cache policy is currently associated with a cache behavior. Please disassociate the policy before deleting.
│   status code: 409, request id: 0bc999b2-08df-402f-9cfe-1c03037cbe08
│ 
│ 
╵
╷
│ Error: deleting CloudFront Origin Request Policy (c7306944-7cd1-45ec-b65e-84f104854143): OriginRequestPolicyInUse: The specified origin request policy is currently associated with a cache behavior. Please disassociate the policy before deleting.
│   status code: 409, request id: 77020bae-65f3-4bc4-ab80-f2677c19a36f

Terraform Configuration Files

The config files involved are massive. Let me know if they're required to reproduce this and I'll spend some time putting together a minified example.

Steps to Reproduce

terraform apply

Debug Output

No response

Panic Output

No response

Important Factoids

I'm not sure whether this is caused by how the module we're using is written, by this provider or by terraform itself, but it seems that the order of operations is incorrect.

Using -target to try and force terraform to remove the cloudfront cache behavior first had no effect.

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

justinretzolk commented 1 year ago

Hey @sidekick-eimantas 👋 Thank you for taking the time to raise this! Terraform itself is responsible for generating the graph that determines order of operations, and doesn't currently have a way for providers to supply additional information regarding ordering. That said, you can control this to some degree with create_before_destroy (this issue in the Terraform Core repository has quite a bit more information that I found helpful when brushing up on this particular pattern).

Given the info above, I'll close this one out. If you feel I've done this in error, please do let me know.

github-actions[bot] commented 1 year ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.