Skip to content

Commit

Permalink
PLT-0 - Allow to set origin access controls
Browse files Browse the repository at this point in the history
* update modules
* allow to create origin access controls
  • Loading branch information
Engerim committed Dec 22, 2023
1 parent 0c844a6 commit 22c08e1
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 26 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ This module will create cdn endpoint with alias and SSL-certificate and optional

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12.26 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.29 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.29 |
| <a name="provider_null"></a> [null](#provider\_null) | n/a |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_certificate"></a> [certificate](#module\_certificate) | github.com/terraform-aws-modules/terraform-aws-acm | v3.2.0 |
| <a name="module_cloudfront"></a> [cloudfront](#module\_cloudfront) | github.com/terraform-aws-modules/terraform-aws-cloudfront | v2.7.0 |
| <a name="module_certificate"></a> [certificate](#module\_certificate) | github.com/terraform-aws-modules/terraform-aws-acm | v5.0.0 |
| <a name="module_cloudfront"></a> [cloudfront](#module\_cloudfront) | github.com/terraform-aws-modules/terraform-aws-cloudfront | v3.2.1 |

## Resources

Expand All @@ -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 |

Expand All @@ -44,6 +45,8 @@ This module will create cdn endpoint with alias and SSL-certificate and optional
| <a name="input_r53_zone_id"></a> [r53\_zone\_id](#input\_r53\_zone\_id) | Route53 zone ID to be used for hostname and certificate validation | `string` | n/a | yes |
| <a name="input_cdn_logging"></a> [cdn\_logging](#input\_cdn\_logging) | Prefix in s3 bucket for cdn logs | `string` | `""` | no |
| <a name="input_cf_functions"></a> [cf\_functions](#input\_cf\_functions) | The Cloud Front function configuration<br> {type = object{}} ie. {"viewer-request" = object{}}<br> *type:*<br> Allowed cf event types are viewer-request and viewer-response<br> *name:*<br> Name of the function<br> *comment:*<br> Description of the function<br> *code:*<br> Source code of the function<br> *assign:*<br> true for associating the function with the cf distribution,<br> false to remove the association. (to remove the cf function firstly set it<br> to false to dissociate from the cf distribution) | <pre>map(object({<br> name = string<br> comment = string<br> code = string<br> assign = bool<br> }))</pre> | `{}` | 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` | `true` | no |
| <a name="input_default_root_object"></a> [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 |
| <a name="input_override_s3_origin_policy"></a> [override\_s3\_origin\_policy](#input\_override\_s3\_origin\_policy) | Overrides the S3-bucket policy to set OAI | `bool` | `false` | no |
| <a name="input_s3_logging_hostname"></a> [s3\_logging\_hostname](#input\_s3\_logging\_hostname) | Hostname of S3-bucket to be used for logging | `string` | `""` | no |
Expand Down
83 changes: 64 additions & 19 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,37 @@ 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({})

}

# Workaround for the input variable validation
Expand All @@ -26,19 +57,20 @@ 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
}
}

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]

Expand All @@ -50,26 +82,19 @@ 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
include_cookies = false
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"
viewer_protocol_policy = "redirect-to-https"
Expand All @@ -89,7 +114,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"]
Expand All @@ -102,11 +127,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" {
Expand Down
12 changes: 12 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
4 changes: 2 additions & 2 deletions versions.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
terraform {
required_version = ">= 0.12.26"
required_version = ">= 0.13.1"

required_providers {
aws = ">= 3"
aws = ">= 4.29"
}
}

0 comments on commit 22c08e1

Please sign in to comment.