-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.tf
137 lines (118 loc) · 4.11 KB
/
main.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
# The following variables should be overriden using a .tfvars file.
# You can just copy the default.tfvars.example file and edit it:
#
# cp default.tfvars.example default.auto.tfvars
#
# Once you edit the file, it will automatically be loaded by terraform
# when you do a `terraform plan` or `terraform apply`
# This creates an IAM policy to allow public-read on all bucket objects.
data "aws_iam_policy_document" "bucket_policy" {
statement {
actions = ["s3:GetObject"]
resources = ["arn:aws:s3:::${var.site_bucket_name}/*"]
principals {
type = "AWS"
identifiers = ["*"]
}
}
}
# This creates the s3 bucket and configures it in a way to host
# a static website.
resource "aws_s3_bucket" "website" {
bucket = "${var.site_bucket_name}"
acl = "public-read"
policy = "${data.aws_iam_policy_document.bucket_policy.json}"
website {
index_document = "index.html"
error_document = "404/index.html"
}
}
# The following resources generate an SSL certificate and
# validate it.
resource "aws_acm_certificate" "cert" {
domain_name = "${var.domain_name}"
validation_method = "DNS"
}
# Assumes that we already have the zone in route53.
data "aws_route53_zone" "zone" {
name = "${var.domain_name}."
private_zone = false
}
resource "aws_route53_record" "cert_validation" {
name = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_name}"
type = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_type}"
zone_id = "${data.aws_route53_zone.zone.id}"
records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
ttl = 60
}
# This isn't a real "thing" in AWS. This is just here to make sure that terraform
# waits for validation to complete.
resource "aws_acm_certificate_validation" "cert" {
certificate_arn = "${aws_acm_certificate.cert.arn}"
validation_record_fqdns = ["${aws_route53_record.cert_validation.fqdn}"]
}
# This creates a CDN in CloudFront that uses our S3 bucket as an origin.
# This provides us with a ton of caching and therefore scale.
resource "aws_cloudfront_distribution" "cdn" {
origin {
domain_name = "${aws_s3_bucket.website.website_endpoint}"
origin_id = "${var.site_bucket_name}"
custom_origin_config {
origin_protocol_policy = "http-only"
http_port = 80
https_port = 443
origin_ssl_protocols = ["TLSv1.2", "TLSv1.1", "TLSv1"]
}
}
enabled = true
is_ipv6_enabled = true
comment = "CDN for ${var.site_bucket_name}"
default_root_object = "index.html"
price_class = "${var.cdn_price_class}"
aliases = ["${var.domain_name}"]
# This can be used to block access to our content by geographic region.
restrictions {
geo_restriction {
restriction_type = "none"
}
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "${var.site_bucket_name}"
# Since this is a static site, no sense to forward
# querystrings and cookies because we will always get the
# same data back.
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
viewer_certificate {
acm_certificate_arn = "${aws_acm_certificate_validation.cert.certificate_arn}"
ssl_support_method = "sni-only"
}
custom_error_response {
error_code = 404
response_code = 404
response_page_path = "/404/index.html"
}
}
# This creates an "alias" record (note: this isn't the same as a CNAME)
# to direct traffic to our CDN.
resource "aws_route53_record" "cdn_alias" {
zone_id = "${data.aws_route53_zone.zone.id}"
name = "${var.domain_name}"
type = "A"
alias {
name = "${aws_cloudfront_distribution.cdn.domain_name}"
zone_id = "${aws_cloudfront_distribution.cdn.hosted_zone_id}"
evaluate_target_health = false
}
}