Skip to content

Commit 1913817

Browse files
authored
Merge pull request #620 from cabinetoffice/EHD-1518-switch-over-live-service
EHD-1518: Switch over Live service
2 parents c61977a + 1de7b6d commit 1913817

5 files changed

+158
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
2+
data "aws_cloudfront_cache_policy" "cache_policy__aws_managed_caching_optimised" {
3+
name = "Managed-CachingOptimized"
4+
}
5+
6+
locals {
7+
distribution_for_www_domain_redirect__origin_id = "${var.service_name_hyphens}--${var.environment_hyphens}--www-Domain-Redirect-origin"
8+
}
9+
10+
resource "aws_cloudfront_distribution" "distribution__www_domain_redirect" {
11+
count = (var.create_redirect_from_www_domain) ? 1 : 0 // Only create this CloudFront Distribution if "var.create_redirect_from_www_domain" is true
12+
13+
// CloudFront distributions have to be created in the us-east-1 region (for some reason!)
14+
provider = aws.us-east-1
15+
16+
comment = "${var.service_name_hyphens}--${var.environment_hyphens}--www-domain-redirect"
17+
18+
origin {
19+
domain_name = "example.com" // The origin domain doesn't matter because we use a CloudFront Function to redirect all traffic.
20+
// We shouldn't use a real domain in case any traffic is forwarded, but example.com is reserved as an unused domain name (https://en.wikipedia.org/wiki/Example.com)
21+
origin_id = local.distribution_for_www_domain_redirect__origin_id
22+
23+
custom_origin_config {
24+
http_port = 80
25+
https_port = 443
26+
origin_protocol_policy = "http-only"
27+
origin_ssl_protocols = ["TLSv1.2"]
28+
}
29+
}
30+
31+
price_class = "PriceClass_100"
32+
33+
aliases = ["${var.dns_record_www_domain_including_dot}${data.aws_route53_zone.route_53_zone_for_our_domain.name}"]
34+
35+
viewer_certificate {
36+
acm_certificate_arn = aws_acm_certificate_validation.certificate_validation_waiter__www_domain_redirect[0].certificate_arn
37+
cloudfront_default_certificate = false
38+
minimum_protocol_version = "TLSv1"
39+
ssl_support_method = "sni-only"
40+
}
41+
42+
enabled = true
43+
is_ipv6_enabled = true
44+
45+
default_cache_behavior {
46+
cache_policy_id = data.aws_cloudfront_cache_policy.cache_policy__aws_managed_caching_optimised.id
47+
allowed_methods = ["GET", "HEAD"]
48+
cached_methods = ["GET", "HEAD"]
49+
target_origin_id = local.distribution_for_www_domain_redirect__origin_id
50+
viewer_protocol_policy = "redirect-to-https"
51+
compress = true
52+
53+
function_association {
54+
event_type = "viewer-request"
55+
function_arn = aws_cloudfront_function.redirect_www_domain_function[0].arn
56+
}
57+
}
58+
59+
restrictions {
60+
geo_restriction {
61+
restriction_type = "none"
62+
locations = []
63+
}
64+
}
65+
}
66+
67+
resource "aws_cloudfront_function" "redirect_www_domain_function" {
68+
count = (var.create_redirect_from_www_domain) ? 1 : 0 // Only create this CloudFront Function if "var.create_redirect_from_www_domain" is true
69+
70+
name = "${var.service_name_hyphens}--${var.environment_hyphens}--redirect-www-domain-function"
71+
runtime = "cloudfront-js-1.0"
72+
publish = true
73+
code = <<EOT
74+
function handler(event) {
75+
var response = {
76+
statusCode: 302,
77+
statusDescription: 'Found',
78+
headers: {
79+
"location": { "value": "https://${var.dns_record_subdomain_including_dot}${data.aws_route53_zone.route_53_zone_for_our_domain.name}" + event.request.uri }
80+
}
81+
};
82+
return response;
83+
}
84+
EOT
85+
}

terraform/dev.tfvars

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ environment_hyphens = "Dev"
55
create_dns_record = true
66
dns_record_subdomain_including_dot = "dev."
77

8+
create_redirect_from_www_domain = false

terraform/https_certificate.tf

+54
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11

2+
////////////////////////////////////////////////
3+
// The HTTPS certificate for the main website
4+
25
resource "aws_acm_certificate" "https_certificate_for_our_domain" {
36
// This certificate is for use by CloudFront, so it has to be created in the us-east-1 region (for some reason!)
47
provider = aws.us-east-1
@@ -31,3 +34,54 @@ resource "aws_acm_certificate_validation" "certificate_validation_waiter" {
3134
certificate_arn = aws_acm_certificate.https_certificate_for_our_domain.arn
3235
validation_record_fqdns = [for record in aws_route53_record.example : record.fqdn]
3336
}
37+
38+
39+
///////////////////////////////////////////////////////
40+
// The HTTPS certificate for the www domain redirect
41+
42+
resource "aws_acm_certificate" "https_certificate__www_domain_redirect" {
43+
count = (var.create_redirect_from_www_domain) ? 1 : 0 // Only create this HTTPS Certificate if "var.create_redirect_from_www_domain" is true
44+
45+
// This certificate is for use by CloudFront, so it has to be created in the us-east-1 region (for some reason!)
46+
provider = aws.us-east-1
47+
48+
domain_name = "${var.dns_record_www_domain_including_dot}${data.aws_route53_zone.route_53_zone_for_our_domain.name}"
49+
validation_method = "DNS"
50+
}
51+
52+
locals {
53+
dns_records_we_need_to_verify_www_domain__list = flatten([
54+
for https_certificate in aws_acm_certificate.https_certificate__www_domain_redirect : [
55+
for dvo in https_certificate.domain_validation_options : {
56+
domain_name = dvo.domain_name
57+
name = dvo.resource_record_name
58+
record = dvo.resource_record_value
59+
type = dvo.resource_record_type
60+
}
61+
]
62+
])
63+
dns_records_we_need_to_verify_www_domain__map = {
64+
for i, record in local.dns_records_we_need_to_verify_www_domain__list: record.domain_name => record
65+
}
66+
}
67+
68+
resource "aws_route53_record" "dns_records_for_https_certificate_verification__www_domain_redirect" {
69+
for_each = local.dns_records_we_need_to_verify_www_domain__map
70+
71+
allow_overwrite = true
72+
name = each.value.name
73+
records = [each.value.record]
74+
ttl = 60
75+
type = each.value.type
76+
zone_id = data.aws_route53_zone.route_53_zone_for_our_domain.zone_id
77+
}
78+
79+
resource "aws_acm_certificate_validation" "certificate_validation_waiter__www_domain_redirect" {
80+
count = (var.create_redirect_from_www_domain) ? 1 : 0 // Only create this HTTPS Certificate if "var.create_redirect_from_www_domain" is true
81+
82+
// This certificate is for use by CloudFront, so it has to be created in the us-east-1 region (for some reason!)
83+
provider = aws.us-east-1
84+
85+
certificate_arn = aws_acm_certificate.https_certificate__www_domain_redirect[0].arn
86+
validation_record_fqdns = [for record in aws_route53_record.dns_records_for_https_certificate_verification__www_domain_redirect : record.fqdn]
87+
}

terraform/prod.tfvars

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
environment = "Prod"
3+
environment_hyphens = "Prod"
4+
5+
create_dns_record = true
6+
dns_record_subdomain_including_dot = ""
7+
8+
create_redirect_from_www_domain = true
9+
dns_record_www_domain_including_dot = "www."

terraform/variables.tf

+9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ variable "dns_record_subdomain_including_dot" {
3333
description = "The subdomain (including dot - e.g. 'dev.' or just '' for production) for the Route53 alias record"
3434
}
3535

36+
variable "create_redirect_from_www_domain" {
37+
type = bool
38+
description = "Should terraform create a CloudFront distribution to redirect the www. domain to the root domain"
39+
}
40+
variable "dns_record_www_domain_including_dot" {
41+
type = string
42+
description = "The www. domain (including dot - e.g. 'www.dev.' or just 'www.' for production) for the www domain redirect"
43+
}
44+
3645
// SECRETS
3746
// These variables are set in GitHub Actions environment-specific secrets
3847
// Most of these are passed to the application via Elastic Beanstalk environment variables

0 commit comments

Comments
 (0)