Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.103.0
rev: v1.104.0
hooks:
- id: terraform_fmt
- id: terraform_wrapper_module_for_each
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ ordered_cache_behavior = [{
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.83 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.100 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.83 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.100 |

## Modules

Expand All @@ -127,6 +127,7 @@ No modules.
| [aws_cloudfront_monitoring_subscription.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_monitoring_subscription) | resource |
| [aws_cloudfront_origin_access_control.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_origin_access_control) | resource |
| [aws_cloudfront_origin_access_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_origin_access_identity) | resource |
| [aws_cloudfront_response_headers_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_response_headers_policy) | resource |
| [aws_cloudfront_vpc_origin.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_vpc_origin) | resource |
| [aws_cloudfront_cache_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_cache_policy) | data source |
| [aws_cloudfront_origin_request_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_origin_request_policy) | data source |
Expand All @@ -143,6 +144,7 @@ No modules.
| <a name="input_create_monitoring_subscription"></a> [create\_monitoring\_subscription](#input\_create\_monitoring\_subscription) | If enabled, the resource for monitoring subscription will created. | `bool` | `false` | no |
| <a name="input_create_origin_access_control"></a> [create\_origin\_access\_control](#input\_create\_origin\_access\_control) | Controls if CloudFront origin access control should be created | `bool` | `false` | no |
| <a name="input_create_origin_access_identity"></a> [create\_origin\_access\_identity](#input\_create\_origin\_access\_identity) | Controls if CloudFront origin access identity should be created | `bool` | `false` | no |
| <a name="input_create_response_headers_policy"></a> [create\_response\_headers\_policy](#input\_create\_response\_headers\_policy) | Controls if CloudFront response headers policies should be created | `bool` | `false` | no |
| <a name="input_create_vpc_origin"></a> [create\_vpc\_origin](#input\_create\_vpc\_origin) | If enabled, the resource for VPC origin will be created. | `bool` | `false` | no |
| <a name="input_custom_error_response"></a> [custom\_error\_response](#input\_custom\_error\_response) | One or more custom error response elements | `any` | `{}` | no |
| <a name="input_default_cache_behavior"></a> [default\_cache\_behavior](#input\_default\_cache\_behavior) | The default cache behavior for this distribution | `any` | `null` | no |
Expand All @@ -159,6 +161,7 @@ No modules.
| <a name="input_origin_group"></a> [origin\_group](#input\_origin\_group) | One or more origin\_group for this distribution (multiples allowed). | `any` | `{}` | no |
| <a name="input_price_class"></a> [price\_class](#input\_price\_class) | The price class for this distribution. One of PriceClass\_All, PriceClass\_200, PriceClass\_100 | `string` | `null` | no |
| <a name="input_realtime_metrics_subscription_status"></a> [realtime\_metrics\_subscription\_status](#input\_realtime\_metrics\_subscription\_status) | A flag that indicates whether additional CloudWatch metrics are enabled for a given CloudFront distribution. Valid values are `Enabled` and `Disabled`. | `string` | `"Enabled"` | no |
| <a name="input_response_headers_policies"></a> [response\_headers\_policies](#input\_response\_headers\_policies) | Map of CloudFront response headers policies with their configurations | <pre>map(object({<br/> name = optional(string)<br/> comment = optional(string)<br/> cors_config = optional(object({<br/> access_control_allow_credentials = bool<br/> origin_override = bool<br/> access_control_allow_headers = object({<br/> items = list(string)<br/> })<br/> access_control_allow_methods = object({<br/> items = list(string)<br/> })<br/> access_control_allow_origins = object({<br/> items = list(string)<br/> })<br/> access_control_expose_headers = optional(object({<br/> items = list(string)<br/> }))<br/> access_control_max_age_sec = optional(number)<br/> }))<br/> custom_headers_config = optional(object({<br/> items = list(object({<br/> header = string<br/> override = bool<br/> value = string<br/> }))<br/> }))<br/> remove_headers_config = optional(object({<br/> items = list(object({<br/> header = string<br/> }))<br/> }))<br/> security_headers_config = optional(object({<br/> content_security_policy = optional(object({<br/> content_security_policy = string<br/> override = bool<br/> }))<br/> content_type_options = optional(object({<br/> override = bool<br/> }))<br/> frame_options = optional(object({<br/> frame_option = string<br/> override = bool<br/> }))<br/> referrer_policy = optional(object({<br/> referrer_policy = string<br/> override = bool<br/> }))<br/> strict_transport_security = optional(object({<br/> access_control_max_age_sec = number<br/> override = bool<br/> include_subdomains = optional(bool)<br/> preload = optional(bool)<br/> }))<br/> xss_protection = optional(object({<br/> mode_block = bool<br/> override = bool<br/> protection = bool<br/> report_uri = optional(string)<br/> }))<br/> }))<br/> server_timing_headers_config = optional(object({<br/> enabled = bool<br/> sampling_rate = number<br/> }))<br/> }))</pre> | `null` | no |
| <a name="input_retain_on_delete"></a> [retain\_on\_delete](#input\_retain\_on\_delete) | Disables the distribution instead of deleting it when destroying the resource through Terraform. If this is set, the distribution needs to be deleted manually afterwards. | `bool` | `false` | no |
| <a name="input_staging"></a> [staging](#input\_staging) | Whether the distribution is a staging distribution. | `bool` | `false` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to assign to the resource. | `map(string)` | `null` | no |
Expand Down Expand Up @@ -189,6 +192,7 @@ No modules.
| <a name="output_cloudfront_origin_access_identities"></a> [cloudfront\_origin\_access\_identities](#output\_cloudfront\_origin\_access\_identities) | The origin access identities created |
| <a name="output_cloudfront_origin_access_identity_iam_arns"></a> [cloudfront\_origin\_access\_identity\_iam\_arns](#output\_cloudfront\_origin\_access\_identity\_iam\_arns) | The IAM arns of the origin access identities created |
| <a name="output_cloudfront_origin_access_identity_ids"></a> [cloudfront\_origin\_access\_identity\_ids](#output\_cloudfront\_origin\_access\_identity\_ids) | The IDS of the origin access identities created |
| <a name="output_cloudfront_response_headers_policies"></a> [cloudfront\_response\_headers\_policies](#output\_cloudfront\_response\_headers\_policies) | The response headers policies created |
| <a name="output_cloudfront_vpc_origin_ids"></a> [cloudfront\_vpc\_origin\_ids](#output\_cloudfront\_vpc\_origin\_ids) | The IDS of the VPC origin created |
<!-- END_TF_DOCS -->

Expand Down
4 changes: 2 additions & 2 deletions examples/complete/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.83 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.100 |
| <a name="requirement_null"></a> [null](#requirement\_null) | >= 2.0 |
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 2.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.83 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.100 |
| <a name="provider_null"></a> [null](#provider\_null) | >= 2.0 |
| <a name="provider_random"></a> [random](#provider\_random) | >= 2.0 |

Expand Down
75 changes: 75 additions & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ module "cloudfront" {
cache_policy_name = "Managed-CachingOptimized"
origin_request_policy_name = "Managed-UserAgentRefererHeaders"
response_headers_policy_name = "Managed-SimpleCORS"
# using a response header policy you're dynamically creating below
# response_header_policy: "cors_policy"

function_association = {
# Valid keys: viewer-request, viewer-response
Expand Down Expand Up @@ -231,6 +233,79 @@ module "cloudfront" {
locations = ["NO", "UA", "US", "GB"]
}

create_response_headers_policy = true
response_headers_policies = {
cors_policy = {
name = "CORSPolicy"
comment = "CORS configuration for API"

cors_config = {
access_control_allow_credentials = true
origin_override = true

access_control_allow_headers = {
items = ["*"]
}

access_control_allow_methods = {
items = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
}

access_control_allow_origins = {
items = ["https://example.com", "https://app.example.com"]
}

access_control_expose_headers = {
items = ["X-Custom-Header", "X-Request-Id"]
}

access_control_max_age_sec = 3600
}
}
custom_headers = {
name = "CustomHeadersPolicy"
comment = "Add custom response headers"

custom_headers_config = {
items = [
{
header = "X-Powered-By"
override = true
value = "MyApp/1.0"
},
{
header = "X-API-Version"
override = false
value = "v2"
},
{
header = "Cache-Control"
override = true
value = "public, max-age=3600"
}
]
}
}
remove_headers = {
name = "RemoveHeadersPolicy"
comment = "Remove unwanted headers from origin"

remove_headers_config = {
items = [
{
header = "x-robots-tag"
},
{
header = "server"
},
{
header = "x-powered-by"
}
]
}
}
}

}

######
Expand Down
2 changes: 1 addition & 1 deletion examples/complete/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.83"
version = ">= 5.100"
}
random = {
source = "hashicorp/random"
Expand Down
139 changes: 139 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,145 @@ locals {
create_vpc_origin = var.create_vpc_origin && length(keys(var.vpc_origin)) > 0
}

resource "aws_cloudfront_response_headers_policy" "this" {
for_each = var.create_response_headers_policy && var.response_headers_policies != null ? var.response_headers_policies : {}

name = try(coalesce(each.value.name, each.key))
comment = each.value.comment

dynamic "cors_config" {
for_each = each.value.cors_config != null ? [each.value.cors_config] : []

content {
access_control_allow_credentials = cors_config.value.access_control_allow_credentials
origin_override = cors_config.value.origin_override
access_control_max_age_sec = cors_config.value.access_control_max_age_sec

access_control_allow_headers {
items = cors_config.value.access_control_allow_headers.items
}

access_control_allow_methods {
items = cors_config.value.access_control_allow_methods.items
}

access_control_allow_origins {
items = cors_config.value.access_control_allow_origins.items
}

dynamic "access_control_expose_headers" {
for_each = cors_config.value.access_control_expose_headers != null ? [cors_config.value.access_control_expose_headers] : []

content {
items = access_control_expose_headers.value.items
}
}
}
}

dynamic "custom_headers_config" {
for_each = each.value.custom_headers_config != null ? [each.value.custom_headers_config] : []

content {
dynamic "items" {
for_each = custom_headers_config.value.items

content {
header = items.value.header
override = items.value.override
value = items.value.value
}
}
}
}

dynamic "remove_headers_config" {
for_each = each.value.remove_headers_config != null ? [each.value.remove_headers_config] : []

content {
dynamic "items" {
for_each = remove_headers_config.value.items

content {
header = items.value.header
}
}
}
}

dynamic "security_headers_config" {
for_each = each.value.security_headers_config != null ? [each.value.security_headers_config] : []

content {
dynamic "content_security_policy" {
for_each = security_headers_config.value.content_security_policy != null ? [security_headers_config.value.content_security_policy] : []

content {
content_security_policy = content_security_policy.value.content_security_policy
override = content_security_policy.value.override
}
}

dynamic "content_type_options" {
for_each = security_headers_config.value.content_type_options != null ? [security_headers_config.value.content_type_options] : []

content {
override = content_type_options.value.override
}
}

dynamic "frame_options" {
for_each = security_headers_config.value.frame_options != null ? [security_headers_config.value.frame_options] : []

content {
frame_option = frame_options.value.frame_option
override = frame_options.value.override
}
}

dynamic "referrer_policy" {
for_each = security_headers_config.value.referrer_policy != null ? [security_headers_config.value.referrer_policy] : []

content {
referrer_policy = referrer_policy.value.referrer_policy
override = referrer_policy.value.override
}
}

dynamic "strict_transport_security" {
for_each = security_headers_config.value.strict_transport_security != null ? [security_headers_config.value.strict_transport_security] : []

content {
access_control_max_age_sec = strict_transport_security.value.access_control_max_age_sec
override = strict_transport_security.value.override
include_subdomains = strict_transport_security.value.include_subdomains
preload = strict_transport_security.value.preload
}
}

dynamic "xss_protection" {
for_each = security_headers_config.value.xss_protection != null ? [security_headers_config.value.xss_protection] : []

content {
mode_block = xss_protection.value.mode_block
override = xss_protection.value.override
protection = xss_protection.value.protection
report_uri = xss_protection.value.report_uri
}
}
}
}

dynamic "server_timing_headers_config" {
for_each = each.value.server_timing_headers_config != null ? [each.value.server_timing_headers_config] : []

content {
enabled = server_timing_headers_config.value.enabled
sampling_rate = server_timing_headers_config.value.sampling_rate
}
}
}

resource "aws_cloudfront_origin_access_identity" "this" {
for_each = local.create_origin_access_identity ? var.origin_access_identities : {}

Expand Down
5 changes: 5 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,8 @@ output "cloudfront_vpc_origin_ids" {
description = "The IDS of the VPC origin created"
value = local.create_vpc_origin ? [for v in aws_cloudfront_vpc_origin.this : v.id] : []
}

output "cloudfront_response_headers_policies" {
description = "The response headers policies created"
value = aws_cloudfront_response_headers_policy.this
}
Loading