diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7e4e7da..5e0e62c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.96.1 + rev: v1.96.2 hooks: - id: terraform_fmt - id: terraform_wrapper_module_for_each diff --git a/README.md b/README.md index eec77d2..1f05853 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ module "cdn" { ## Examples -- [Complete](https://github.com/terraform-aws-modules/terraform-aws-cloudfront/tree/master/examples/complete) - Complete example which creates AWS CloudFront distribution and integrates it with other [terraform-aws-modules](https://github.com/terraform-aws-modules) to create additional resources: S3 buckets, Lambda Functions, CloudFront Functions, ACM Certificate, Route53 Records. +- [Complete](https://github.com/terraform-aws-modules/terraform-aws-cloudfront/tree/master/examples/complete) - Complete example which creates AWS CloudFront distribution and integrates it with other [terraform-aws-modules](https://github.com/terraform-aws-modules) to create additional resources: S3 buckets, Lambda Functions, CloudFront Functions, VPC Origins, ACM Certificate, Route53 Records. ## Notes @@ -107,13 +107,13 @@ ordered_cache_behavior = [{ | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 0.13.1 | -| [aws](#requirement\_aws) | >= 5.12.0 | +| [aws](#requirement\_aws) | >= 5.82 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.12.0 | +| [aws](#provider\_aws) | >= 5.82 | ## Modules @@ -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_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 | | [aws_cloudfront_response_headers_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_response_headers_policy) | data source | @@ -142,6 +143,7 @@ No modules. | [create\_monitoring\_subscription](#input\_create\_monitoring\_subscription) | If enabled, the resource for monitoring subscription will created. | `bool` | `false` | no | | [create\_origin\_access\_control](#input\_create\_origin\_access\_control) | Controls if CloudFront origin access control should be created | `bool` | `false` | no | | [create\_origin\_access\_identity](#input\_create\_origin\_access\_identity) | Controls if CloudFront origin access identity should be created | `bool` | `false` | no | +| [create\_vpc\_origin](#input\_create\_vpc\_origin) | If enabled, the resource for VPC origin will be created. | `bool` | `false` | no | | [custom\_error\_response](#input\_custom\_error\_response) | One or more custom error response elements | `any` | `{}` | no | | [default\_cache\_behavior](#input\_default\_cache\_behavior) | The default cache behavior for this distribution | `any` | `null` | no | | [default\_root\_object](#input\_default\_root\_object) | The object that you want CloudFront to return (for example, index.html) when an end user requests the root URL. | `string` | `null` | no | @@ -161,6 +163,7 @@ No modules. | [staging](#input\_staging) | Whether the distribution is a staging distribution. | `bool` | `false` | no | | [tags](#input\_tags) | A map of tags to assign to the resource. | `map(string)` | `null` | no | | [viewer\_certificate](#input\_viewer\_certificate) | The SSL configuration for this distribution | `any` |
{
"cloudfront_default_certificate": true,
"minimum_protocol_version": "TLSv1"
}
| no | +| [vpc\_origin](#input\_vpc\_origin) | Map of CloudFront VPC origin |
map(object({
name = string
arn = string
http_port = number
https_port = number
origin_protocol_policy = string
origin_ssl_protocols = object({
items = list(string)
quantity = number
})
}))
| `{}` | no | | [wait\_for\_deployment](#input\_wait\_for\_deployment) | If enabled, the resource will wait for the distribution status to change from InProgress to Deployed. Setting this to false will skip the process. | `bool` | `true` | no | | [web\_acl\_id](#input\_web\_acl\_id) | If you're using AWS WAF to filter CloudFront requests, the Id of the AWS WAF web ACL that is associated with the distribution. The WAF Web ACL must exist in the WAF Global (CloudFront) region and the credentials configuring this argument must have waf:GetWebACL permissions assigned. If using WAFv2, provide the ARN of the web ACL. | `string` | `null` | no | @@ -185,6 +188,7 @@ No modules. | [cloudfront\_origin\_access\_identities](#output\_cloudfront\_origin\_access\_identities) | The origin access identities created | | [cloudfront\_origin\_access\_identity\_iam\_arns](#output\_cloudfront\_origin\_access\_identity\_iam\_arns) | The IAM arns of the origin access identities created | | [cloudfront\_origin\_access\_identity\_ids](#output\_cloudfront\_origin\_access\_identity\_ids) | The IDS of the origin access identities created | +| [cloudfront\_vpc\_origin\_ids](#output\_cloudfront\_vpc\_origin\_ids) | The IDS of the VPC origin created | ## Authors diff --git a/examples/complete/README.md b/examples/complete/README.md index 5a12261..ff15316 100644 --- a/examples/complete/README.md +++ b/examples/complete/README.md @@ -8,6 +8,7 @@ Configuration in this directory creates CloudFront distribution which demos such - Lambda@Edge - ACM certificate - Route53 record +- VPC Origins ## Usage @@ -27,7 +28,7 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 4.29 | +| [aws](#requirement\_aws) | >= 5.82 | | [null](#requirement\_null) | >= 2.0 | | [random](#requirement\_random) | >= 2.0 | @@ -35,7 +36,7 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 4.29 | +| [aws](#provider\_aws) | >= 5.82 | | [null](#provider\_null) | >= 2.0 | | [random](#provider\_random) | >= 2.0 | @@ -45,6 +46,7 @@ Note that this example may create resources which cost money. Run `terraform des |------|--------|---------| | [acm](#module\_acm) | terraform-aws-modules/acm/aws | ~> 4.0 | | [cloudfront](#module\_cloudfront) | ../../ | n/a | +| [ec2](#module\_ec2) | terraform-aws-modules/ec2-instance/aws | ~> 5.0 | | [lambda\_function](#module\_lambda\_function) | terraform-aws-modules/lambda/aws | ~> 7.0 | | [log\_bucket](#module\_log\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 4.0 | | [records](#module\_records) | terraform-aws-modules/route53/aws//modules/records | ~> 2.0 | @@ -58,6 +60,7 @@ Note that this example may create resources which cost money. Run `terraform des | [aws_s3_bucket_policy.bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | | [null_resource.download_package](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | +| [aws_ami.al2023](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | | [aws_canonical_user_id.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/canonical_user_id) | data source | | [aws_cloudfront_log_delivery_canonical_user_id.cloudfront](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_log_delivery_canonical_user_id) | data source | | [aws_iam_policy_document.s3_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | @@ -84,4 +87,5 @@ No inputs. | [cloudfront\_origin\_access\_identities](#output\_cloudfront\_origin\_access\_identities) | The origin access identities created | | [cloudfront\_origin\_access\_identity\_iam\_arns](#output\_cloudfront\_origin\_access\_identity\_iam\_arns) | The IAM arns of the origin access identities created | | [cloudfront\_origin\_access\_identity\_ids](#output\_cloudfront\_origin\_access\_identity\_ids) | The IDS of the origin access identities created | +| [cloudfront\_vpc\_origin\_ids](#output\_cloudfront\_vpc\_origin\_ids) | The IDS of the VPC origin created | diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 42b74e6..31bb43c 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -53,6 +53,21 @@ module "cloudfront" { } } + create_vpc_origin = true + vpc_origin = { + ec2_vpc_origin = { + name = random_pet.this.id + arn = module.ec2.arn + http_port = 80 + https_port = 443 + origin_protocol_policy = "http-only" + origin_ssl_protocols = { + items = ["TLSv1.2"] + quantity = 1 + } + } + } + logging_config = { bucket = module.log_bucket.s3_bucket_bucket_domain_name prefix = "cloudfront" @@ -98,6 +113,14 @@ module "cloudfront" { origin_access_control = "s3_oac" # key in `origin_access_control` # origin_access_control_id = "E345SXM82MIOSU" # external OAŠ” resource } + + ec2_vpc_origin = { + domain_name = module.ec2.private_dns + vpc_origin_config = { + vpc_origin = "ec2_vpc_origin" # key in `vpc_origin` + # vpc_origin_id = "vo_Cg6A14otX0DB1yyDQ6Nond" # external VPC Origin resource + } + } } origin_group = { @@ -170,7 +193,16 @@ module "cloudfront" { # Using Cache/ResponseHeaders/OriginRequest policies is not allowed together with `compress` and `query_string` settings compress = true query_string = true + }, + { + path_pattern = "/vpc-origin/*" + target_origin_id = "ec2_vpc_origin" + viewer_protocol_policy = "redirect-to-https" + + allowed_methods = ["GET", "HEAD", "OPTIONS"] + cached_methods = ["GET", "HEAD"] } + ] viewer_certificate = { @@ -316,6 +348,10 @@ module "records" { ] } +######################################### +# S3 bucket policy +######################################### + data "aws_iam_policy_document" "s3_policy" { # Origin Access Identities statement { @@ -351,6 +387,37 @@ resource "aws_s3_bucket_policy" "bucket_policy" { policy = data.aws_iam_policy_document.s3_policy.json } +######################################### +# CloudFront function +######################################### + +resource "aws_cloudfront_function" "example" { + name = "example-${random_pet.this.id}" + runtime = "cloudfront-js-1.0" + code = file("${path.module}/example-function.js") +} + +######################################### +# EC2 instance for CloudFront VPC origin +######################################### + +data "aws_ami" "al2023" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["al2023-ami-2023*-x86_64"] + } +} + +module "ec2" { + source = "terraform-aws-modules/ec2-instance/aws" + version = "~> 5.0" + + ami = data.aws_ami.al2023.id +} + ######## # Extra ######## @@ -358,9 +425,3 @@ resource "aws_s3_bucket_policy" "bucket_policy" { resource "random_pet" "this" { length = 2 } - -resource "aws_cloudfront_function" "example" { - name = "example-${random_pet.this.id}" - runtime = "cloudfront-js-1.0" - code = file("${path.module}/example-function.js") -} diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 3b775e2..fa4f64b 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -62,3 +62,8 @@ output "cloudfront_origin_access_identity_iam_arns" { description = "The IAM arns of the origin access identities created" value = module.cloudfront.cloudfront_origin_access_identity_iam_arns } + +output "cloudfront_vpc_origin_ids" { + description = "The IDS of the VPC origin created" + value = module.cloudfront.cloudfront_vpc_origin_ids +} diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf index e7a0e48..38d6935 100644 --- a/examples/complete/versions.tf +++ b/examples/complete/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 4.29" + version = ">= 5.82" } random = { source = "hashicorp/random" diff --git a/main.tf b/main.tf index b58f5f9..daffdcc 100644 --- a/main.tf +++ b/main.tf @@ -1,6 +1,7 @@ locals { create_origin_access_identity = var.create_origin_access_identity && length(keys(var.origin_access_identities)) > 0 create_origin_access_control = var.create_origin_access_control && length(keys(var.origin_access_control)) > 0 + create_vpc_origin = var.create_vpc_origin && length(keys(var.vpc_origin)) > 0 } resource "aws_cloudfront_origin_access_identity" "this" { @@ -24,6 +25,25 @@ resource "aws_cloudfront_origin_access_control" "this" { signing_protocol = each.value["signing_protocol"] } +resource "aws_cloudfront_vpc_origin" "this" { + for_each = local.create_vpc_origin ? var.vpc_origin : {} + + vpc_origin_endpoint_config { + name = each.value["name"] + arn = each.value["arn"] + http_port = each.value["http_port"] + https_port = each.value["https_port"] + origin_protocol_policy = each.value["origin_protocol_policy"] + + origin_ssl_protocols { + items = each.value.origin_ssl_protocols.items + quantity = each.value.origin_ssl_protocols.quantity + } + } + + tags = var.tags +} + resource "aws_cloudfront_distribution" "this" { count = var.create_distribution ? 1 : 0 @@ -100,6 +120,16 @@ resource "aws_cloudfront_distribution" "this" { origin_shield_region = origin_shield.value.origin_shield_region } } + + dynamic "vpc_origin_config" { + for_each = length(keys(lookup(origin.value, "vpc_origin_config", {}))) == 0 ? [] : [lookup(origin.value, "vpc_origin_config", {})] + + content { + vpc_origin_id = lookup(vpc_origin_config.value, "vpc_origin_id", lookup(lookup(aws_cloudfront_vpc_origin.this, lookup(vpc_origin_config.value, "vpc_origin", ""), {}), "id", null)) + origin_keepalive_timeout = lookup(vpc_origin_config.value, "origin_keepalive_timeout", null) + origin_read_timeout = lookup(vpc_origin_config.value, "origin_read_timeout", null) + } + } } } diff --git a/outputs.tf b/outputs.tf index 0a5f4c2..29e7642 100644 --- a/outputs.tf +++ b/outputs.tf @@ -82,3 +82,8 @@ output "cloudfront_origin_access_controls_ids" { description = "The IDS of the origin access identities created" value = local.create_origin_access_control ? [for v in aws_cloudfront_origin_access_control.this : v.id] : [] } + +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] : [] +} diff --git a/variables.tf b/variables.tf index 4d7e226..13333c3 100644 --- a/variables.tf +++ b/variables.tf @@ -181,3 +181,25 @@ variable "realtime_metrics_subscription_status" { type = string default = "Enabled" } + +variable "create_vpc_origin" { + description = "If enabled, the resource for VPC origin will be created." + type = bool + default = false +} + +variable "vpc_origin" { + description = "Map of CloudFront VPC origin" + type = map(object({ + name = string + arn = string + http_port = number + https_port = number + origin_protocol_policy = string + origin_ssl_protocols = object({ + items = list(string) + quantity = number + }) + })) + default = {} +} diff --git a/versions.tf b/versions.tf index a7b2540..8115b86 100644 --- a/versions.tf +++ b/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.12.0" + version = ">= 5.82" } } } diff --git a/wrappers/main.tf b/wrappers/main.tf index 797019b..a60251c 100644 --- a/wrappers/main.tf +++ b/wrappers/main.tf @@ -10,6 +10,7 @@ module "wrapper" { create_monitoring_subscription = try(each.value.create_monitoring_subscription, var.defaults.create_monitoring_subscription, false) create_origin_access_control = try(each.value.create_origin_access_control, var.defaults.create_origin_access_control, false) create_origin_access_identity = try(each.value.create_origin_access_identity, var.defaults.create_origin_access_identity, false) + create_vpc_origin = try(each.value.create_vpc_origin, var.defaults.create_vpc_origin, false) custom_error_response = try(each.value.custom_error_response, var.defaults.custom_error_response, {}) default_cache_behavior = try(each.value.default_cache_behavior, var.defaults.default_cache_behavior, null) default_root_object = try(each.value.default_root_object, var.defaults.default_root_object, null) @@ -39,6 +40,7 @@ module "wrapper" { cloudfront_default_certificate = true minimum_protocol_version = "TLSv1" }) + vpc_origin = try(each.value.vpc_origin, var.defaults.vpc_origin, {}) wait_for_deployment = try(each.value.wait_for_deployment, var.defaults.wait_for_deployment, true) web_acl_id = try(each.value.web_acl_id, var.defaults.web_acl_id, null) } diff --git a/wrappers/versions.tf b/wrappers/versions.tf index a7b2540..8115b86 100644 --- a/wrappers/versions.tf +++ b/wrappers/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.12.0" + version = ">= 5.82" } } }