diff --git a/README.md b/README.md index 0ae2bc0..79e6c3b 100644 --- a/README.md +++ b/README.md @@ -7,22 +7,22 @@ This module will create cdn endpoint with alias and SSL-certificate and optional | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 0.12.26 | -| [aws](#requirement\_aws) | >= 3 | +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 4.29 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 3 | +| [aws](#provider\_aws) | >= 4.29 | | [null](#provider\_null) | n/a | ## Modules | Name | Source | Version | |------|--------|---------| -| [certificate](#module\_certificate) | github.com/terraform-aws-modules/terraform-aws-acm | v3.2.0 | -| [cloudfront](#module\_cloudfront) | github.com/terraform-aws-modules/terraform-aws-cloudfront | v2.7.0 | +| [certificate](#module\_certificate) | github.com/terraform-aws-modules/terraform-aws-acm | v5.0.0 | +| [cloudfront](#module\_cloudfront) | github.com/terraform-aws-modules/terraform-aws-cloudfront | v3.2.1 | ## Resources @@ -33,6 +33,7 @@ This module will create cdn endpoint with alias and SSL-certificate and optional | [aws_s3_bucket_policy.s3_origin_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | | [null_resource.either_s3_origin_hostname_or_s3_origin_name_is_required](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | [null_resource.s3_origin_name_is_required_to_override_the_s3_origin_policy](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | +| [aws_iam_policy_document.oac_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.oai_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_s3_bucket.s3_origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) | data source | @@ -44,6 +45,8 @@ This module will create cdn endpoint with alias and SSL-certificate and optional | [r53\_zone\_id](#input\_r53\_zone\_id) | Route53 zone ID to be used for hostname and certificate validation | `string` | n/a | yes | | [cdn\_logging](#input\_cdn\_logging) | Prefix in s3 bucket for cdn logs | `string` | `""` | no | | [cf\_functions](#input\_cf\_functions) | The Cloud Front function configuration
{type = object{}} ie. {"viewer-request" = object{}}
*type:*
Allowed cf event types are viewer-request and viewer-response
*name:*
Name of the function
*comment:*
Description of the function
*code:*
Source code of the function
*assign:*
true for associating the function with the cf distribution,
false to remove the association. (to remove the cf function firstly set it
to false to dissociate from the cf distribution) |
map(object({
name = string
comment = string
code = string
assign = bool
}))
| `{}` | 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` | `true` | 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 | | [override\_s3\_origin\_policy](#input\_override\_s3\_origin\_policy) | Overrides the S3-bucket policy to set OAI | `bool` | `false` | no | | [s3\_logging\_hostname](#input\_s3\_logging\_hostname) | Hostname of S3-bucket to be used for logging | `string` | `""` | no | diff --git a/main.tf b/main.tf index 77706f4..2ef7f07 100644 --- a/main.tf +++ b/main.tf @@ -8,6 +8,38 @@ locals { override_origin_policy = var.override_s3_origin_policy && var.s3_origin_name != "" function_association = { for type, func in var.cf_functions : type => { function_arn = aws_cloudfront_function.functions[type].arn } if func.assign } + + origin_access_identities = var.create_origin_access_identity ? { + s3_bucket = "Access identity for CDN (${var.r53_hostname})" + } : {} + + oac_key = "${var.r53_hostname}-origin-access-control" + + origin_access_control = var.create_origin_access_control ? { + (local.oac_key) = { + description = "Origin access control for s3 bucket ${data.aws_s3_bucket.s3_origin[0].id}" + origin_type = "s3" + signing_behavior = "always" + signing_protocol = "sigv4" + } + } : {} + + origin_oai = var.create_origin_access_identity ? tomap({ + s3_origin = { + domain_name = local.origin_hostname + s3_origin_config = { + origin_access_identity = "s3_bucket" + } + } + }) : tomap({}) + origin_oac = var.create_origin_access_control ? tomap({ + s3_origin = { + domain_name = data.aws_s3_bucket.s3_origin[0].bucket_domain_name + origin_access_control = local.oac_key + } + }) : tomap({}) + + target_origin_id = var.create_origin_access_control ? "s3_origin_oac" : "s3_origin" } # Workaround for the input variable validation @@ -26,11 +58,12 @@ data "aws_s3_bucket" "s3_origin" { } module "certificate" { - source = "github.com/terraform-aws-modules/terraform-aws-acm?ref=v3.2.0" + source = "github.com/terraform-aws-modules/terraform-aws-acm?ref=v5.0.0" tags = var.tags - domain_name = var.r53_hostname - zone_id = var.r53_zone_id + domain_name = var.r53_hostname + zone_id = var.r53_zone_id + validation_method = "DNS" providers = { aws = aws.us-east-1 @@ -38,7 +71,7 @@ module "certificate" { } module "cloudfront" { - source = "github.com/terraform-aws-modules/terraform-aws-cloudfront?ref=v2.7.0" + source = "github.com/terraform-aws-modules/terraform-aws-cloudfront?ref=v3.2.1" tags = var.tags aliases = [var.r53_hostname] @@ -50,10 +83,11 @@ module "cloudfront" { default_root_object = var.default_root_object - create_origin_access_identity = true - origin_access_identities = { - s3_bucket = "Access identity for CDN (${var.r53_hostname})" - } + create_origin_access_identity = var.create_origin_access_identity + origin_access_identities = local.origin_access_identities + + create_origin_access_control = var.create_origin_access_control + origin_access_control = local.origin_access_control logging_config = var.s3_logging_hostname == "" ? {} : { bucket = var.s3_logging_hostname @@ -61,17 +95,9 @@ module "cloudfront" { prefix = var.cdn_logging } - origin = { - s3_origin = { - domain_name = local.origin_hostname - s3_origin_config = { - origin_access_identity = "s3_bucket" - } - } - } - + origin = merge(local.origin_oai, local.origin_oac) default_cache_behavior = { - target_origin_id = "s3_origin" + target_origin_id = local.target_origin_id viewer_protocol_policy = "redirect-to-https" allowed_methods = ["GET", "HEAD", "OPTIONS"] @@ -89,7 +115,7 @@ module "cloudfront" { } data "aws_iam_policy_document" "oai_policy" { - count = local.override_origin_policy ? 1 : 0 + count = local.override_origin_policy && var.create_origin_access_identity ? 1 : 0 statement { actions = ["s3:GetObject"] @@ -102,11 +128,31 @@ data "aws_iam_policy_document" "oai_policy" { } } +data "aws_iam_policy_document" "oac_policy" { + count = local.override_origin_policy && var.create_origin_access_control ? 1 : 0 + + statement { + actions = ["s3:GetObject"] + resources = ["${data.aws_s3_bucket.s3_origin[0].arn}${var.s3_origin_policy_restrict_access}"] + + principals { + type = "Service" + identifiers = ["cloudfront.amazonaws.com"] + } + + condition { + test = "StringEquals" + values = [module.cloudfront.cloudfront_distribution_arn] + variable = "AWS:SourceArn" + } + } +} + resource "aws_s3_bucket_policy" "s3_origin_policy" { count = local.override_origin_policy ? 1 : 0 bucket = data.aws_s3_bucket.s3_origin[0].id - policy = data.aws_iam_policy_document.oai_policy[0].json + policy = var.create_origin_access_identity ? data.aws_iam_policy_document.oai_policy[0].json : data.aws_iam_policy_document.oac_policy[0].json } resource "aws_route53_record" "this" { diff --git a/variables.tf b/variables.tf index 64aea89..09275e8 100644 --- a/variables.tf +++ b/variables.tf @@ -85,3 +85,15 @@ variable "default_root_object" { type = string default = null } + +variable "create_origin_access_identity" { + description = "Controls if CloudFront origin access identity should be created" + type = bool + default = true +} + +variable "create_origin_access_control" { + description = "Controls if CloudFront origin access control should be created" + type = bool + default = false +} diff --git a/versions.tf b/versions.tf index 0a7e256..890deaf 100644 --- a/versions.tf +++ b/versions.tf @@ -1,7 +1,7 @@ terraform { - required_version = ">= 0.12.26" + required_version = ">= 0.13.1" required_providers { - aws = ">= 3" + aws = ">= 4.29" } }