-
-
Notifications
You must be signed in to change notification settings - Fork 278
Open
Description
Description
When defining response_headers_policies inside the module and trying to attach them in the same module invocation, none of the available paths work:
- Attempt 1 (example-style, commented in docs):
# using a response header policy you're dynamically creating below
# response_header_policy = "cors_policy"
response_header_policy = "my-custom-rhp"
No change is applied; the default cache behavior ends up without the policy attached.
- Attempt 2 (lookup by name):
response_headers_policy_name = "my-custom-rhp"
Fails unless the policy already exists (managed or pre-created). If the policy is only defined in response_headers_policies in the same module, the plan fails with:
Error: no matching CloudFront Response Headers Policy (my-custom-rhp)
Result: It is impossible to create and attach a custom response headers policy in a single apply using the module alone.
- ✋ I have searched the open/closed issues and my issue is not listed.
Versions
-
Module version [Required]: 6.0.2
-
Terraform version: Terraform v1.14.0
-
Provider version(s): hashicorp/aws v6.25.0
Reproduction Code [Required]
module "cloudfront_example" {
source = "terraform-aws-modules/cloudfront/aws"
version = "6.0.2"
comment = "Repro response headers policy"
enabled = true
origin = {
s3 = {
domain_name = "example-bucket.s3.amazonaws.com"
origin_access_control = "s3"
origin_id = "s3"
}
}
default_cache_behavior = {
target_origin_id = "s3"
viewer_protocol_policy = "redirect-to-https"
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
default_ttl = 0
max_ttl = 0
min_ttl = 0
# Attempt 1 (from docs example, commented): no attachment happens
# using a response header policy you're dynamically creating below
response_header_policy = "my-custom-rhp"
# Attempt 2 (lookup by name): fails unless policy pre-exists
# response_headers_policy_name = "my-custom-rhp"
}
response_headers_policies = {
my-custom-rhp = {
comment = "My custom RHP"
cors_config = {
access_control_allow_credentials = false
origin_override = true
access_control_allow_headers = { items = ["*"] }
access_control_allow_methods = { items = ["GET", "HEAD"] }
access_control_allow_origins = { items = ["*"] }
access_control_max_age_sec = 600
}
}
}
viewer_certificate = {
cloudfront_default_certificate = true
}
}
Expected behavior
- In a single apply, the module should create the response headers policy defined in
response_headers_policiesand allow attaching it to the cache behavior without a dependency cycle. Either: response_headers_policy_nameshould resolve the newly created policy, orresponse_headers_policy_idshould be usable without creating a cycle when referring to the module’s own created policy.
Steps to reproduce:
terraform init
terraform apply
Actual behavior
- Attempt 1:
response_header_policy = "my-custom-rhp"(as in the commented example) results in no attachment.
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
+ create
Terraform will perform the following actions:
# module.cloudfront_example.aws_cloudfront_distribution.this[0] will be created
+ resource "aws_cloudfront_distribution" "this" {
+ arn = (known after apply)
+ caller_reference = (known after apply)
+ comment = "Repro response headers policy"
+ continuous_deployment_policy_id = (known after apply)
+ domain_name = (known after apply)
+ enabled = true
+ etag = (known after apply)
+ hosted_zone_id = (known after apply)
+ http_version = "http2"
+ id = (known after apply)
+ in_progress_validation_batches = (known after apply)
+ is_ipv6_enabled = true
+ last_modified_time = (known after apply)
+ logging_v1_enabled = (known after apply)
+ price_class = "PriceClass_All"
+ retain_on_delete = false
+ staging = false
+ status = (known after apply)
+ trusted_key_groups = (known after apply)
+ trusted_signers = (known after apply)
+ wait_for_deployment = true
+ default_cache_behavior {
+ allowed_methods = [
+ "GET",
+ "HEAD",
]
+ cached_methods = [
+ "GET",
+ "HEAD",
]
+ compress = true
+ default_ttl = 0
+ max_ttl = 0
+ min_ttl = 0
+ target_origin_id = "s3"
+ trusted_key_groups = (known after apply)
+ trusted_signers = (known after apply)
+ viewer_protocol_policy = "redirect-to-https"
+ forwarded_values {
+ headers = (known after apply)
+ query_string = false
+ query_string_cache_keys = (known after apply)
+ cookies {
+ forward = "none"
+ whitelisted_names = (known after apply)
}
}
+ grpc_config (known after apply)
}
+ origin {
+ connection_attempts = 3
+ connection_timeout = 10
+ domain_name = "example-bucket.s3.amazonaws.com"
+ origin_id = "s3"
+ response_completion_timeout = (known after apply)
# (2 unchanged attributes hidden)
}
+ restrictions {
+ geo_restriction {
+ locations = (known after apply)
+ restriction_type = "none"
}
}
+ viewer_certificate {
+ cloudfront_default_certificate = true
+ minimum_protocol_version = "TLSv1.2_2025"
}
}
# module.cloudfront_example.aws_cloudfront_origin_access_control.this["s3"] will be created
+ resource "aws_cloudfront_origin_access_control" "this" {
+ arn = (known after apply)
+ description = "Origin Access Control for s3"
+ etag = (known after apply)
+ id = (known after apply)
+ name = "s3"
+ origin_access_control_origin_type = "s3"
+ signing_behavior = "always"
+ signing_protocol = "sigv4"
}
# module.cloudfront_example.aws_cloudfront_response_headers_policy.this["my-custom-rhp"] will be created
+ resource "aws_cloudfront_response_headers_policy" "this" {
+ arn = (known after apply)
+ comment = "My custom RHP"
+ etag = (known after apply)
+ id = (known after apply)
+ name = "my-custom-rhp"
+ cors_config {
+ access_control_allow_credentials = false
+ access_control_max_age_sec = 600
+ origin_override = true
+ access_control_allow_headers {
+ items = [
+ "*",
]
}
+ access_control_allow_methods {
+ items = [
+ "GET",
+ "HEAD",
]
}
+ access_control_allow_origins {
+ items = [
+ "*",
]
}
}
}
Plan: 3 to add, 0 to change, 0 to destroy.
- Attempt 2:
response_headers_policy_name "my-custom-rhp"only works if the policy already exists (managed or pre-created).
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
+ create
Terraform planned the following actions, but then encountered a problem:
# module.cloudfront_example.aws_cloudfront_origin_access_control.this["s3"] will be created
+ resource "aws_cloudfront_origin_access_control" "this" {
+ arn = (known after apply)
+ description = "Origin Access Control for s3"
+ etag = (known after apply)
+ id = (known after apply)
+ name = "s3"
+ origin_access_control_origin_type = "s3"
+ signing_behavior = "always"
+ signing_protocol = "sigv4"
}
# module.cloudfront_example.aws_cloudfront_origin_access_control.this["s3"] will be created
+ resource "aws_cloudfront_origin_access_control" "this" {
+ arn = (known after apply)
+ description = "Origin Access Control for s3"
+ etag = (known after apply)
+ id = (known after apply)
+ name = "s3"
+ origin_access_control_origin_type = "s3"
+ signing_behavior = "always"
+ signing_protocol = "sigv4"
}
# module.cloudfront_example.aws_cloudfront_response_headers_policy.this["my-custom-rhp"] will be created
+ resource "aws_cloudfront_response_headers_policy" "this" {
+ arn = (known after apply)
+ comment = "My custom RHP"
+ etag = (known after apply)
+ id = (known after apply)
+ name = "my-custom-rhp"
+ cors_config {
+ access_control_allow_credentials = false
+ access_control_max_age_sec = 600
+ origin_override = true
+ access_control_allow_headers {
+ items = [
+ "*",
]
}
+ access_control_allow_methods {
+ items = [
+ "GET",
+ "HEAD",
]
}
+ access_control_allow_origins {
+ items = [
+ "*",
]
}
}
}
Plan: 3 to add, 0 to change, 0 to destroy.
╷
│ Error: no matching CloudFront Response Headers Policy (my-custom-rhp)
│
│ with module.cloudfront_example.data.aws_cloudfront_response_headers_policy.this["my-custom-rhp"],
│ on .terraform/modules/cloudfront_example/main.tf line 553, in data "aws_cloudfront_response_headers_policy" "this":
│ 553: data "aws_cloudfront_response_headers_policy" "this" {
│
╵
Additional context
- The module code (
main.tf) resolvesresponse_headers_policy_nameviadata.aws_cloudfront_response_headers_policy.this, which presumes the policy exists beforehand, unlike the example suggestion to create it “dynamically below.” - Also, the example comments
response_header_policy = "cors_policy", butmain.tfdoes not reference aresponse_header_policyattribute; onlyresponse_headers_policy_id/response_headers_policy_nameare wired. This adds to the confusion when trying to create-and-attach in a single apply.