Skip to content

Instantly share code, notes, and snippets.

@vinicius73
Created March 5, 2022 13:55
Show Gist options
  • Save vinicius73/c69162b5b4e43044c9b75b095111406a to your computer and use it in GitHub Desktop.
Save vinicius73/c69162b5b4e43044c9b75b095111406a to your computer and use it in GitHub Desktop.
Terraform + Cloudfront Static file CDN
# https://docs.aws.amazon.com/pt_br/acm/latest/userguide/acm-regions.html
resource "aws_acm_certificate" "this" {
provider = aws.virginia # need to be created at virginia (cloudfront bizarre)
domain_name = local.host
subject_alternative_names = local.alias
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
resource "aws_route53_record" "validation" {
for_each = {
for dvo in aws_acm_certificate.this.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
allow_overwrite = true
zone_id = data.aws_route53_zone.main.id
name = each.value.name
type = each.value.type
records = [each.value.record]
ttl = 60
}
# this maybe take 30 minutes
resource "aws_acm_certificate_validation" "this" {
provider = aws.virginia # need to be created at virginia
certificate_arn = aws_acm_certificate.this.arn
validation_record_fqdns = [for record in aws_route53_record.validation : record.fqdn]
}
locals {
origin_id = "${local.prefix}-origin-app"
}
resource "aws_cloudfront_distribution" "this" {
enabled = true
is_ipv6_enabled = true
comment = "Mu Project APP"
default_root_object = "index.html"
aliases = local._hosts
origin {
domain_name = aws_s3_bucket.this.bucket_regional_domain_name
origin_id = local.origin_id
}
custom_error_response {
error_caching_min_ttl = 0
error_code = 404
response_code = 200
response_page_path = "/404.html"
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
default_cache_behavior {
target_origin_id = local.origin_id
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
viewer_protocol_policy = "redirect-to-https"
min_ttl = 31536000
default_ttl = 31536000
max_ttl = 31536000
compress = true
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.this.id
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.1_2016"
}
}
resource "aws_route53_record" "this" {
for_each = toset(local._hosts)
zone_id = data.aws_route53_zone.main.zone_id
name = each.value
type = "A"
alias {
name = aws_cloudfront_distribution.this.domain_name
zone_id = aws_cloudfront_distribution.this.hosted_zone_id
evaluate_target_health = false
}
}
output "bucket" {
value = aws_s3_bucket.this.bucket
}
output "hosts" {
value = local._hosts
}
terraform {
required_version = "~> 1.1.7"
backend "s3" {
bucket = "peoplepass-infra-tf-state"
region = "sa-east-1"
key = "---"
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.4.0"
}
}
}
# Providers
provider "aws" {
region = local.region
default_tags {
tags = merge({
repo = "peoplepass-app"
}, local.tags)
}
}
provider "aws" {
alias = "virginia"
region = "us-east-1" // N. Virginia (cloudfront+acm)
default_tags {
tags = local.tags
}
}
resource "aws_s3_bucket" "this" {
bucket_prefix = "${local.prefix}-app-"
}
resource "aws_s3_bucket_cors_configuration" "this" {
bucket = aws_s3_bucket.this.bucket
cors_rule {
allowed_headers = ["*"]
allowed_methods = ["GET", "HEAD"]
expose_headers = ["ETag"]
max_age_seconds = 3000
allowed_origins = local._hosts
}
}
resource "aws_s3_bucket_acl" "this" {
bucket = aws_s3_bucket.this.id
acl = "public-read"
}
resource "aws_s3_bucket_website_configuration" "this" {
bucket = aws_s3_bucket.this.bucket
index_document {
suffix = "index.html"
}
error_document {
key = "index.html"
}
}
resource "aws_s3_bucket_policy" "this" {
bucket = aws_s3_bucket.this.id
policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Sid" : "PublicReadGetObject",
"Effect" : "Allow",
"Principal" : "*",
"Action" : [
"s3:GetObject"
],
"Resource" : [
"arn:aws:s3:::${aws_s3_bucket.this.id}/*"
]
}
]
})
}
data "aws_route53_zone" "main" {
name = local.domain
private_zone = false
}
locals {
domain = "my.site.com"
prefix = "my-project-${terraform.workspace}"
tags = {
Project = "my-project",
ENvironment = terraform.workspace
}
}
locals {
host = local.domain
alias = [
"app.${local.domain}",
"www.${local.domain}",
"www.app.${local.domain}"
]
}
locals {
_hosts = concat([local.host], local.alias)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment