Skip to content

Instantly share code, notes, and snippets.

@mmalone

mmalone/acme.tf Secret

Created September 17, 2019 16:55
Show Gist options
  • Save mmalone/881b638fa0d71b03e9e082b05f0f5b38 to your computer and use it in GitHub Desktop.
Save mmalone/881b638fa0d71b03e9e082b05f0f5b38 to your computer and use it in GitHub Desktop.
ACME Terraform Example
# Define the provider that we are going to use
provider "aws" {
profile = "default"
region = "us-west-1"
}
# Create an SSH key pair to connect to our instances.
#
# If the key-pair is already created you will get an error, to get rid of it
# just comment this section.
resource "aws_key_pair" "terraform" {
key_name = "terraform-key"
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC7YNXWbeBVIkF8jtgtyg9UZPVYYXUTiFvfvk/q8GSroV3ITesNi0s7Hpq/GDuudNlGMZ2YruLG1pw8yJ+uBAd36W1EWJgd2FP1f0tMoqALiTC2pMvxbs2F/7Q3XxPOAS2RjndZvkemiTIl5g1qn0LdI2LO1kEPJAcUxNX3mwLMB06Ja5vg43qXaSc6xfYIeqFJhWYLaVTKOECUydK2WHVfwn5cBJU2bhu5ACUGoXSM+DWqFiM1BndrBG+7+5KxfLKFDG079dOOCvE6wsyJ7Gik46dcn8BzV1Ar356Pf9MtrfNl9y9B6xfr+404h0dG5ek5DbhiMzwW9rQ+VXHr3oqtJPVhK2p+5U9kedoaAxO4gVnjkfyStAlI/VKCcxmRffjli0ddOyabSoXLnVThc7MKBbYZG9ndUwml6m+RTDw7g5UZljQiF+iGcc65UmdhZt88ixZa83DslmRksoPxcltNFSh+VvrOJYOK5rjY015SSUzHBIadnM76lwlbyx32QxJDpzGQNqwQ/dSGtLEsSwXFGMwn+LpcWhx79AOfcRePyg8dl9NrAs5HbFI3ujSf5rZGnzsEh9lYk5E3OCNqrXA29RJ3hmwJijSTtP3JT6gNXkLjvGcFvswJp8B0eF58hf+9KlinmZ8pXLZGBYOj0JiEYeux+PVjwLUQz6/EDr9edQ== mariano@smallstep.com"
}
variable "key_name" {
type = string
default = "terraform-key"
}
variable "ami" {
type = string
default = "ami-068670db424b01e9a"
}
variable "instance_type" {
type = string
default = "t2.micro"
}
resource "aws_instance" "nginx" {
ami = var.ami
instance_type = var.instance_type
key_name = var.key_name
tags = {
Name = "nginx-acme-demo"
}
# Required to use remote-exec
associate_public_ip_address = true
# Install nginx
provisioner "remote-exec" {
connection {
type = "ssh"
user = "ubuntu"
host = aws_instance.nginx.public_ip
private_key = "${file("~/.ssh/terraform")}"
}
inline = [
"set -x",
# apt-get update fails often, sometimes writing the cache
"sudo apt-get update || sudo apt-get update", "sudo apt-get update",
"sudo apt-get -y install nginx",
"sudo systemctl start nginx",
]
}
}
# Define DNS entries with Route53
data "aws_route53_zone" "main" {
name = "lpbck.io."
private_zone = false
}
# If we configure the nginx instance with HTTPS and copy the certificate and
# private key to it we would be able to just do this, but we're going to use ELB
# instead.
# resource "aws_route53_record" "nginx" {
# zone_id = "${data.aws_route53_zone.main.zone_id}"
# name = "acme.${data.aws_route53_zone.main.name}"
# type = "A"
# ttl = "300"
# records = ["${aws_instance.nginx.public_ip}"]
# }
# Create entry with let's encrypt certificate. We need the certificate before
# creating the ELB, and we need the ELB DNS name, to avoid a loop we will create
# a tmp record that will have the ELB DNS name.
resource "aws_route53_record" "nginx" {
zone_id = "${data.aws_route53_zone.main.zone_id}"
name = "acme.${data.aws_route53_zone.main.name}"
type = "CNAME"
ttl = "300"
records = ["tmp-acme.${data.aws_route53_zone.main.name}"]
}
resource "aws_route53_record" "tmp-nginx" {
zone_id = "${data.aws_route53_zone.main.zone_id}"
name = "tmp-acme.${data.aws_route53_zone.main.name}"
type = "CNAME"
ttl = "300"
records = ["${aws_elb.nginx.dns_name}"]
}
# Use terraform ACME provider to create a certificate
provider "acme" {
server_url = "https://acme-staging-v02.api.letsencrypt.org/directory"
}
resource "tls_private_key" "private_key" {
algorithm = "RSA"
}
resource "acme_registration" "nginx" {
account_key_pem = "${tls_private_key.private_key.private_key_pem}"
email_address = "nobody@smallstep.com"
}
resource "acme_certificate" "nginx" {
account_key_pem = "${acme_registration.nginx.account_key_pem}"
common_name = "acme.lpbck.io"
subject_alternative_names = ["lpbck.io"]
dns_challenge {
provider = "route53"
}
}
# Configure ELB with ACME certificates
resource "aws_iam_server_certificate" "elb_cert" {
name_prefix = "letfdemo-cert-"
certificate_body = "${acme_certificate.nginx.certificate_pem}"
certificate_chain = "${acme_certificate.nginx.issuer_pem}"
private_key = "${acme_certificate.nginx.private_key_pem}"
lifecycle {
create_before_destroy = true
}
}
resource "aws_elb" "nginx" {
name = "nginx-acme-demo"
instances = ["${aws_instance.nginx.id}"]
availability_zones = ["us-west-1a", "us-west-1b"]
tags = {
Name = "nginx-acme-demo"
}
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 443
lb_protocol = "https"
ssl_certificate_id = "${aws_iam_server_certificate.elb_cert.arn}"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment