-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcloudfront.tf
152 lines (126 loc) · 4.13 KB
/
cloudfront.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# ------------------------------------------------------------------------------
# The CloudFront distribution and related S3/Lambda resources that allow us to
# use an HTTPS endpoint, which S3 websites do not support natively.
# ------------------------------------------------------------------------------
locals {
# bucket origin id
s3_origin_id = "S3-${aws_s3_bucket.egress_info.id}"
}
data "aws_acm_certificate" "rules_cert" {
# This certificate must exist prior to applying this Terraform.
# For an example, see cisagov/cool-dns-cyber.dhs.gov/acm_rules_vm.tf
provider = aws.deploy
domain = var.domain
most_recent = true
statuses = ["ISSUED"]
types = ["AMAZON_ISSUED"]
}
# An S3 bucket where artifacts for the Lambda@Edge can be stored
resource "aws_s3_bucket" "lambda_at_edge" {
provider = aws.deploy
bucket_prefix = "publish-egress-ip-lambda-at-edge-"
# TODO: Remove this lifecycle block after we move to version 4.x of the
# Terraform AWS provider.
# https://github.com/hashicorp/terraform-provider-aws/issues/23758
lifecycle {
ignore_changes = [
server_side_encryption_configuration
]
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "lambda_at_edge" {
provider = aws.deploy
bucket = aws_s3_bucket.lambda_at_edge.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_versioning" "lambda_at_edge" {
provider = aws.deploy
bucket = aws_s3_bucket.lambda_at_edge.id
versioning_configuration {
status = "Enabled"
}
}
# This blocks ANY public access to the bucket or the objects it
# contains, even if misconfigured to allow public access.
resource "aws_s3_bucket_public_access_block" "lambda_artifact_bucket" {
provider = aws.deploy
bucket = aws_s3_bucket.lambda_at_edge.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# A Lambda@Edge for injecting security headers
module "security_header_lambda" {
providers = {
aws = aws.deploy
}
source = "transcend-io/lambda-at-edge/aws"
version = "0.5.0"
description = "Adds HSTS and other security headers to the response"
lambda_code_source_dir = "${path.root}/add_security_headers"
name = "add_security_headers"
s3_artifact_bucket = aws_s3_bucket.lambda_at_edge.id
}
resource "aws_cloudfront_distribution" "rules_s3_distribution" {
provider = aws.deploy
origin {
domain_name = aws_s3_bucket.egress_info.bucket_regional_domain_name
origin_id = local.s3_origin_id
}
aliases = [var.domain]
comment = "Created by cisagov/publish-egress-ip-terraform"
default_root_object = var.root_object
enabled = true
is_ipv6_enabled = true
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
lambda_function_association {
# Inject security headers via Lambda@Edge
event_type = "origin-response"
include_body = false
lambda_arn = module.security_header_lambda.arn
}
target_origin_id = local.s3_origin_id
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
compress = true
default_ttl = 30
max_ttl = 30
min_ttl = 0
viewer_protocol_policy = "redirect-to-https"
}
price_class = "PriceClass_100"
restrictions {
geo_restriction {
locations = ["US", "PR", "VI", "AS", "GU", "MP"]
restriction_type = "whitelist"
}
}
custom_error_response {
error_caching_min_ttl = 30
error_code = 403
response_code = 200
response_page_path = "/${var.root_object}"
}
custom_error_response {
error_caching_min_ttl = 30
error_code = 404
response_code = 200
response_page_path = "/${var.root_object}"
}
viewer_certificate {
acm_certificate_arn = data.aws_acm_certificate.rules_cert.arn
minimum_protocol_version = "TLSv1.1_2016"
ssl_support_method = "sni-only"
}
}