Skip to content

Commit c76dad4

Browse files
glavkantonbabenko
andauthoredJan 27, 2023
feat: Added Origin Access Control (OAC) (#97)
Co-authored-by: Anton Babenko <anton@antonbabenko.com>
1 parent d24b530 commit c76dad4

File tree

7 files changed

+95
-16
lines changed

7 files changed

+95
-16
lines changed
 

‎README.md

+5
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ No modules.
105105
|------|------|
106106
| [aws_cloudfront_distribution.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution) | resource |
107107
| [aws_cloudfront_monitoring_subscription.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_monitoring_subscription) | resource |
108+
| [aws_cloudfront_origin_access_control.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_origin_access_control) | resource |
108109
| [aws_cloudfront_origin_access_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_origin_access_identity) | resource |
109110

110111
## Inputs
@@ -115,6 +116,7 @@ No modules.
115116
| <a name="input_comment"></a> [comment](#input\_comment) | Any comments you want to include about the distribution. | `string` | `null` | no |
116117
| <a name="input_create_distribution"></a> [create\_distribution](#input\_create\_distribution) | Controls if CloudFront distribution should be created | `bool` | `true` | no |
117118
| <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 |
119+
| <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 |
118120
| <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 |
119121
| <a name="input_custom_error_response"></a> [custom\_error\_response](#input\_custom\_error\_response) | One or more custom error response elements | `any` | `{}` | no |
120122
| <a name="input_default_cache_behavior"></a> [default\_cache\_behavior](#input\_default\_cache\_behavior) | The default cache behavior for this distribution | `any` | `null` | no |
@@ -126,6 +128,7 @@ No modules.
126128
| <a name="input_logging_config"></a> [logging\_config](#input\_logging\_config) | The logging configuration that controls how logs are written to your distribution (maximum one). | `any` | `{}` | no |
127129
| <a name="input_ordered_cache_behavior"></a> [ordered\_cache\_behavior](#input\_ordered\_cache\_behavior) | An ordered list of cache behaviors resource for this distribution. List from top to bottom in order of precedence. The topmost cache behavior will have precedence 0. | `any` | `[]` | no |
128130
| <a name="input_origin"></a> [origin](#input\_origin) | One or more origins for this distribution (multiples allowed). | `any` | `null` | no |
131+
| <a name="input_origin_access_control"></a> [origin\_access\_control](#input\_origin\_access\_control) | Map of CloudFront origin access control | <pre>map(object({<br> description = string<br> origin_type = string<br> signing_behavior = string<br> signing_protocol = string<br> }))</pre> | <pre>{<br> "s3": {<br> "description": "",<br> "origin_type": "s3",<br> "signing_behavior": "always",<br> "signing_protocol": "sigv4"<br> }<br>}</pre> | no |
129132
| <a name="input_origin_access_identities"></a> [origin\_access\_identities](#input\_origin\_access\_identities) | Map of CloudFront origin access identities (value as a comment) | `map(string)` | `{}` | no |
130133
| <a name="input_origin_group"></a> [origin\_group](#input\_origin\_group) | One or more origin\_group for this distribution (multiples allowed). | `any` | `{}` | no |
131134
| <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 |
@@ -152,6 +155,8 @@ No modules.
152155
| <a name="output_cloudfront_distribution_tags"></a> [cloudfront\_distribution\_tags](#output\_cloudfront\_distribution\_tags) | Tags of the distribution's |
153156
| <a name="output_cloudfront_distribution_trusted_signers"></a> [cloudfront\_distribution\_trusted\_signers](#output\_cloudfront\_distribution\_trusted\_signers) | List of nested attributes for active trusted signers, if the distribution is set up to serve private content with signed URLs |
154157
| <a name="output_cloudfront_monitoring_subscription_id"></a> [cloudfront\_monitoring\_subscription\_id](#output\_cloudfront\_monitoring\_subscription\_id) | The ID of the CloudFront monitoring subscription, which corresponds to the `distribution_id`. |
158+
| <a name="output_cloudfront_origin_access_controls"></a> [cloudfront\_origin\_access\_controls](#output\_cloudfront\_origin\_access\_controls) | The origin access controls created |
159+
| <a name="output_cloudfront_origin_access_controls_ids"></a> [cloudfront\_origin\_access\_controls\_ids](#output\_cloudfront\_origin\_access\_controls\_ids) | The IDS of the origin access identities created |
155160
| <a name="output_cloudfront_origin_access_identities"></a> [cloudfront\_origin\_access\_identities](#output\_cloudfront\_origin\_access\_identities) | The origin access identities created |
156161
| <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 |
157162
| <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 |

‎examples/complete/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Note that this example may create resources which cost money. Run `terraform des
6161
| [null_resource.download_package](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
6262
| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |
6363
| [aws_canonical_user_id.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/canonical_user_id) | data source |
64+
| [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 |
6465
| [aws_iam_policy_document.s3_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
6566
| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source |
6667

‎examples/complete/main.tf

+19-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ provider "aws" {
22
region = "us-east-1" # CloudFront expects ACM resources in us-east-1 region only
33

44
# Make it faster by skipping something
5-
skip_get_ec2_platforms = true
65
skip_metadata_api_check = true
76
skip_region_validation = true
87
skip_credentials_validation = true
@@ -37,6 +36,16 @@ module "cloudfront" {
3736
s3_bucket_one = "My awesome CloudFront can access"
3837
}
3938

39+
create_origin_access_control = true
40+
origin_access_control = {
41+
s3_oac = {
42+
description = "CloudFront access to S3"
43+
origin_type = "s3"
44+
signing_behavior = "always"
45+
signing_protocol = "sigv4"
46+
}
47+
}
48+
4049
logging_config = {
4150
bucket = module.log_bucket.s3_bucket_bucket_domain_name
4251
prefix = "cloudfront"
@@ -69,13 +78,19 @@ module "cloudfront" {
6978
}
7079
}
7180

72-
s3_one = {
81+
s3_one = { # with origin access identity (legacy)
7382
domain_name = module.s3_one.s3_bucket_bucket_regional_domain_name
7483
s3_origin_config = {
7584
origin_access_identity = "s3_bucket_one" # key in `origin_access_identities`
7685
# cloudfront_access_identity_path = "origin-access-identity/cloudfront/E5IGQAA1QO48Z" # external OAI resource
7786
}
7887
}
88+
89+
s3_oac = { # with origin access control settings (recommended)
90+
domain_name = module.s3_one.s3_bucket_bucket_regional_domain_name
91+
origin_access_control = "s3_oac" # key in `origin_access_control`
92+
# origin_access_control_id = "E345SXM82MIOSU" # external OAС resource
93+
}
7994
}
8095

8196
origin_group = {
@@ -142,9 +157,11 @@ module "cloudfront" {
142157

143158
custom_error_response = [{
144159
error_code = 404
160+
response_code = 404
145161
response_page_path = "/errors/404.html"
146162
}, {
147163
error_code = 403
164+
response_code = 403
148165
response_page_path = "/errors/403.html"
149166
}]
150167

‎main.tf

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
locals {
22
create_origin_access_identity = var.create_origin_access_identity && length(keys(var.origin_access_identities)) > 0
3+
create_origin_access_control = var.create_origin_access_control && length(keys(var.origin_access_control)) > 0
34
}
45

56
resource "aws_cloudfront_origin_access_identity" "this" {
@@ -12,6 +13,17 @@ resource "aws_cloudfront_origin_access_identity" "this" {
1213
}
1314
}
1415

16+
resource "aws_cloudfront_origin_access_control" "this" {
17+
for_each = local.create_origin_access_control ? var.origin_access_control : {}
18+
19+
name = each.key
20+
21+
description = each.value["description"]
22+
origin_access_control_origin_type = each.value["origin_type"]
23+
signing_behavior = each.value["signing_behavior"]
24+
signing_protocol = each.value["signing_protocol"]
25+
}
26+
1527
resource "aws_cloudfront_distribution" "this" {
1628
count = var.create_distribution ? 1 : 0
1729

@@ -46,7 +58,7 @@ resource "aws_cloudfront_distribution" "this" {
4658
origin_path = lookup(origin.value, "origin_path", "")
4759
connection_attempts = lookup(origin.value, "connection_attempts", null)
4860
connection_timeout = lookup(origin.value, "connection_timeout", null)
49-
origin_access_control_id = lookup(origin.value, "origin_access_control_id", null)
61+
origin_access_control_id = lookup(origin.value, "origin_access_control_id", lookup(lookup(aws_cloudfront_origin_access_control.this, lookup(origin.value, "origin_access_control", ""), {}), "id", null))
5062

5163
dynamic "s3_origin_config" {
5264
for_each = length(keys(lookup(origin.value, "s3_origin_config", {}))) == 0 ? [] : [lookup(origin.value, "s3_origin_config", {})]

‎outputs.tf

+10
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,13 @@ output "cloudfront_distribution_tags" {
7272
description = "Tags of the distribution's"
7373
value = try(aws_cloudfront_distribution.this[0].tags_all, "")
7474
}
75+
76+
output "cloudfront_origin_access_controls" {
77+
description = "The origin access controls created"
78+
value = local.create_origin_access_control ? { for k, v in aws_cloudfront_origin_access_control.this : k => v } : {}
79+
}
80+
81+
output "cloudfront_origin_access_controls_ids" {
82+
description = "The IDS of the origin access identities created"
83+
value = local.create_origin_access_control ? [for v in aws_cloudfront_origin_access_control.this : v.id] : []
84+
}

‎variables.tf

+25
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,31 @@ variable "origin_access_identities" {
1616
default = {}
1717
}
1818

19+
variable "create_origin_access_control" {
20+
description = "Controls if CloudFront origin access control should be created"
21+
type = bool
22+
default = false
23+
}
24+
25+
variable "origin_access_control" {
26+
description = "Map of CloudFront origin access control"
27+
type = map(object({
28+
description = string
29+
origin_type = string
30+
signing_behavior = string
31+
signing_protocol = string
32+
}))
33+
34+
default = {
35+
s3 = {
36+
description = "",
37+
origin_type = "s3",
38+
signing_behavior = "always",
39+
signing_protocol = "sigv4"
40+
}
41+
}
42+
}
43+
1944
variable "aliases" {
2045
description = "Extra CNAMEs (alternate domain names), if any, for this distribution."
2146
type = list(string)

‎wrappers/main.tf

+22-13
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,28 @@ module "wrapper" {
66
create_distribution = try(each.value.create_distribution, var.defaults.create_distribution, true)
77
create_origin_access_identity = try(each.value.create_origin_access_identity, var.defaults.create_origin_access_identity, false)
88
origin_access_identities = try(each.value.origin_access_identities, var.defaults.origin_access_identities, {})
9-
aliases = try(each.value.aliases, var.defaults.aliases, null)
10-
comment = try(each.value.comment, var.defaults.comment, null)
11-
default_root_object = try(each.value.default_root_object, var.defaults.default_root_object, null)
12-
enabled = try(each.value.enabled, var.defaults.enabled, true)
13-
http_version = try(each.value.http_version, var.defaults.http_version, "http2")
14-
is_ipv6_enabled = try(each.value.is_ipv6_enabled, var.defaults.is_ipv6_enabled, null)
15-
price_class = try(each.value.price_class, var.defaults.price_class, null)
16-
retain_on_delete = try(each.value.retain_on_delete, var.defaults.retain_on_delete, false)
17-
wait_for_deployment = try(each.value.wait_for_deployment, var.defaults.wait_for_deployment, true)
18-
web_acl_id = try(each.value.web_acl_id, var.defaults.web_acl_id, null)
19-
tags = try(each.value.tags, var.defaults.tags, null)
20-
origin = try(each.value.origin, var.defaults.origin, null)
21-
origin_group = try(each.value.origin_group, var.defaults.origin_group, {})
9+
create_origin_access_control = try(each.value.create_origin_access_control, var.defaults.create_origin_access_control, false)
10+
origin_access_control = try(each.value.origin_access_control, var.defaults.origin_access_control, {
11+
s3 = {
12+
description = "",
13+
origin_type = "s3",
14+
signing_behavior = "always",
15+
signing_protocol = "sigv4"
16+
}
17+
})
18+
aliases = try(each.value.aliases, var.defaults.aliases, null)
19+
comment = try(each.value.comment, var.defaults.comment, null)
20+
default_root_object = try(each.value.default_root_object, var.defaults.default_root_object, null)
21+
enabled = try(each.value.enabled, var.defaults.enabled, true)
22+
http_version = try(each.value.http_version, var.defaults.http_version, "http2")
23+
is_ipv6_enabled = try(each.value.is_ipv6_enabled, var.defaults.is_ipv6_enabled, null)
24+
price_class = try(each.value.price_class, var.defaults.price_class, null)
25+
retain_on_delete = try(each.value.retain_on_delete, var.defaults.retain_on_delete, false)
26+
wait_for_deployment = try(each.value.wait_for_deployment, var.defaults.wait_for_deployment, true)
27+
web_acl_id = try(each.value.web_acl_id, var.defaults.web_acl_id, null)
28+
tags = try(each.value.tags, var.defaults.tags, null)
29+
origin = try(each.value.origin, var.defaults.origin, null)
30+
origin_group = try(each.value.origin_group, var.defaults.origin_group, {})
2231
viewer_certificate = try(each.value.viewer_certificate, var.defaults.viewer_certificate, {
2332
cloudfront_default_certificate = true
2433
minimum_protocol_version = "TLSv1"

0 commit comments

Comments
 (0)
Please sign in to comment.