marusich pushed a commit to branch master in repository maintenance. commit 5a8cf18447c0e4ee6dbbbe2958fca315dbd86af2 Author: Chris Marusich <cmmarus...@gmail.com> Date: Fri Dec 28 21:15:57 2018 -0800
cdn: Provision a TLS certificate for ci.guix.info. * cdn/README.org: Mention that certificate validation requires manual action outside of Terraform. * cdn/terraform/main.tf (berlin-mirror-certificate): New certificate. (berlin-mirror): Use it with SNI in the CloudFront distribution. --- cdn/README.org | 13 +++++++--- cdn/terraform/main.tf | 68 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/cdn/README.org b/cdn/README.org index 99629d6..3cd4fdb 100644 --- a/cdn/README.org +++ b/cdn/README.org @@ -965,15 +965,15 @@ signatures. * Next steps Currently, we have all the IAM configuration in Terraform config. That's great! -- Integrate the CloudFront distribution with ACM. - Set up locking with the S3 backend. - Package Terraform - Package the AWS Provider plugin for Terraform - Simplify variable definitions by using .tfvars file? -- Use origin failover to server requests via the CDN from berlin - first, and hydra second? +- Use origin failover to serve requests via the CDN from berlin first, + and hydra second? https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/high_availability_origin_failover.html -- Set a billing alarm (or perhaps a "budget"): https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/billing-what-is.html +- Set a billing alarm (or perhaps a "budget"): + https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/billing-what-is.html ** Setting up a budget I haven't actually set up a "budget". But this guide explains how to @@ -1334,3 +1334,8 @@ Rollback as follows: - Send an email to guix-sysad...@gnu.org and info@guix, and notify the #guix chat room on Freenode, to let people know you have rolled back. +* Resources not managed by Terraform +** ACM Certificate Validation +Initial validation of the ACM certificate requires manual creation of +DNS records. See the comment next to berlin-mirror-certificate in the +file "main.tf" for details. diff --git a/cdn/terraform/main.tf b/cdn/terraform/main.tf index c81dc61..00b5f55 100644 --- a/cdn/terraform/main.tf +++ b/cdn/terraform/main.tf @@ -1,11 +1,7 @@ # Backend documentation: # https://www.terraform.io/docs/backends/types/s3.html terraform { - # If you ever want to rebuild everything from scratch, including the - # state bucket and the state it contains, you will need to remove or - # comment out this backend and use the local backend first. After - # creating the bucket, you can then add this backend back and - # migrate the state into it via "terraform init". + # This backend will not work if you delete the corresponding bucket. backend "s3" { # TODO: Add a Dynamo DB table for locking. bucket = "guix-terraform-state" @@ -239,14 +235,19 @@ resource "aws_cloudfront_distribution" "berlin-mirror" { # ordered_cache_behavior {} # TODO: Maybe set a caching behavior for error responses. # custom_error_response {} - # TODO: Integrate with ACM. viewer_certificate { - cloudfront_default_certificate = true - # This is the only option when using the default CloudFront - # certificate. See: - # https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#viewer-certificate-arguments + # Note that "terraform apply" will fail until this certificate is + # valid. See the comment in the definition of + # berlin-mirror-certificate for more information. + acm_certificate_arn = "${aws_acm_certificate.berlin-mirror-certificate.arn}" + # This is the recommended value as of 2018-12-28. See: # https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ViewerCertificate.html - minimum_protocol_version = "TLSv1" + # https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/secure-connections-supported-viewer-protocols-ciphers.html#secure-connections-supported-ciphers + minimum_protocol_version = "TLSv1.1_2016" + # Use SNI. Don't use the "vip" (i.e., dedicated IP address) + # method, since it's expensive and unnecessary. See: + # https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cnames-https-dedicated-ip-or-sni.html + ssl_support_method = "sni-only" } } @@ -262,10 +263,9 @@ output "berlin-mirror-domain-name" { # S3 -# DO NOT DELETE THIS BUCKET! If you think you need to delete this -# bucket, think twice. This bucket contains the Terraform state, -# shared by all Terraform users in the Guix project. Only delete the -# bucket if you're sure it's OK to delete that state! +# DO NOT DELETE THIS BUCKET! This bucket contains the Terraform +# state, shared by all Terraform users in the Guix project. In +# addition, the s3 backend will not function without it. resource "aws_s3_bucket" "guix-terraform-state" { bucket = "guix-terraform-state" # Access should be granted via IAM policies. @@ -318,3 +318,41 @@ resource "aws_s3_bucket" "guix-terraform-state" { prevent_destroy = true } } + +# ACM + +# Terraform will create this certificate automatically. However, to +# validate it requires one-time manual action outside of Terraform. +# This is because there don't seem to be any Terraform providers that +# are compatible with our DNS registrar. To create and validate the +# certificate, you must do the following in order: +# +# - Run "terraform apply" to create the certificate. +# - Run "terraform show" to view the CNAME record ACM needs you to +# create in order to prove domain ownership. +# - Manually create the CNAME record. +# - Run "terraform apply" or "terraform plan" again to ensure the +# resources are in their final, correct state. +# - Run "terraform show" to verify that the certificate is now +# listed as "validated". +# - Repeat the last two steps until the validation succeeds. +# +# This only has to be done once. For more information, see: +# https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-validate-dns.html +# +# Finally, since we intend to use this certificate with our CloudFront +# distribution, we must create it in the us-east-1 region. See: +# https://docs.aws.amazon.com/acm/latest/userguide/acm-services.html +# https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-requirements.html +resource "aws_acm_certificate" "berlin-mirror-certificate" { + domain_name = "ci.guix.info" + validation_method = "DNS" + # The AWS provider documentation recommends setting + # create_before_destroy to true in a lifecycle block. We probably + # won't need this, since we don't currently plan to replace the + # existing certificate using Terraform (ACM will just rotate it for + # us automatically), but it doesn't hurt to include this here. + lifecycle { + create_before_destroy = true + } +}