Skip to content

Instantly share code, notes, and snippets.

@vancluever
Last active May 18, 2017 20:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vancluever/07a8169a6701ffdcd43ae34a09f6092b to your computer and use it in GitHub Desktop.
Save vancluever/07a8169a6701ffdcd43ae34a09f6092b to your computer and use it in GitHub Desktop.
Brainstorming config for work to get terraform-provider-acme upstream
variable "cert_domains" {
type = "list"
default = [
"www.example.com",
"www.example.org",
]
}
provider "acme" {
server_url = "https://acme-staging.api.letsencrypt.org/directory"
}
resource "tls_private_key" "reg_key" {
algorithm = "RSA"
}
resource "acme_registration" "reg" {
account_key_pem = "${tls_private_key.reg_key.private_key_pem}"
email_address = "nobody@example.com"
}
resource "acme_authorization" "authorizations" {
count = "${length(var.cert_domains)}"
registration_url = "${acme_registration.reg.id}"
account_key_pem = "${tls_private_key.reg_key.private_key_pem}"
name = "${var.cert_domains[count.index]}"
expect_challenges = [
"dns-01",
]
}
data "aws_route53_zone" "cert_domain_zone_ids" {
count = "${length(var.cert_domains)}"
name = "${join(".", split(".", var.cert_domains[count.index])[1:])}."
}
resource "aws_route53_record" "challenge_record" {
count = "${length(var.cert_domains)}"
zone_id = "${data.aws_route53_zone.cert_domain_zone_ids.*.id[count.index]}"
name = "acme-challenge.${var.cert_domains[count.index]}."
type = "TXT"
ttl = "10"
records = ["${acme_authorization.authorizations.*.dns_01_record[count.index]}"]
}
resource "acme_challenge" "challenge" {
count = "${length(var.cert_domains)}"
registration_url = "${acme_registration.reg.id}"
account_key_pem = "${tls_private_key.reg_key.private_key_pem}"
url = "${acme_authorization.authorizations.*.dns_challenge_url[count.index]}"
}
resource "tls_private_key" "cert_key" {
algorithm = "RSA"
}
resource "tls_cert_request" "cert_req" {
key_algorithm = "RSA"
private_key_pem = "${tls_private_key.cert_key.private_key_pem}"
subject {
common_name = "${var.cert_domains[0]}"
}
dns_names = "${var.cert_domains}"
}
resource "acme_certificate" "certificate" {
registration_url = "${acme_registration.reg.id}"
account_key_pem = "${tls_private_key.reg_key.private_key_pem}"
certificate_request_pem = "${tls_cert_request.cert_req.cert_request_pem}"
authorizations = ["${acme_authorization.authorizations.*.id}"]
}
@vancluever
Copy link
Author

vancluever commented May 18, 2017

Alternate resources for authorization and challenge, using provisioners. Using this method, aws_route53_record would not exist and the provisioning work in satisfying the challenge would be handled out of band. This facilitates cleanup, which is a shortcoming of the current PoC.

Note I don't normally use cli-input-json in the AWS CLI so I don't know if it accepts JSON on stdin 😛

resource "acme_authorization" "authorizations" {                                            
  count            = "${length(var.cert_domains)}"                                          
  registration_url = "${acme_registration.reg.id}"                                          
  account_key_pem  = "${tls_private_key.reg_key.private_key_pem}"                           
  name             = "${var.cert_domains[count.index]}"                                     
                                                                                            
  expect_challenges = [                                                                      
    "dns-01",                                                                               
  ]                                                                                         
                                                                                            
  provisioner "local-exec" {                                                                
    command = <<EOS                                                                         
aws route53 --cli-input-json - <<EOT                                                        
{                                                                                           
  "HostedZoneId": "${data.aws_route53_zone.cert_domain_zone_ids.*.id[count.index]}",        
  "ChangeBatch": {                                                                          
    "Changes": [                                                                            
      {                                                                                     
        "Action": "UPSERT",                                                                 
        "ResourceRecordSet": {                                                              
          "Name": "acme-challenge.${var.cert_domains[count.index]}.",                       
          "Type": "TXT",                                                                    
          "TTL": 10,                                                                        
          "ResourceRecords": [                                                              
            {                                                                               
              "Value": "${acme_authorization.authorizations.*.dns_01_record[count.index]}"  
            }                                                                               
          ]                                                                                 
        }                                                                                   
      }                                                                                     
    ]                                                                                       
  }                                                                                         
}                                                                                           
EOT                                                                                         
EOS                                                                                         
  }                                                                                         
}                                                                                           
                                                                                            
resource "acme_challenge" "challenge" {                                                     
  count            = "${length(var.cert_domains)}"                                          
  registration_url = "${acme_registration.reg.id}"                                          
  account_key_pem  = "${tls_private_key.reg_key.private_key_pem}"                           
  url              = "${acme_authorization.authorizations.*.dns_challenge_url[count.index]}"
                                                                                            
  provisioner "local-exec" {                                                                
    command = <<EOS                                                                         
aws route53 --cli-input-json - <<EOT                                                        
{                                                                                           
  "HostedZoneId": "${data.aws_route53_zone.cert_domain_zone_ids.*.id[count.index]}",        
  "ChangeBatch": {                                                                          
    "Changes": [                                                                            
      {                                                                                     
        "Action": "DELETE",                                                                 
        "ResourceRecordSet": {                                                              
          "Name": "acme-challenge.${var.cert_domains[count.index]}.",                       
          "Type": "TXT",                                                                    
          "TTL": 10,                                                                        
          "ResourceRecords": [                                                              
            {                                                                               
              "Value": "${acme_authorization.authorizations.*.dns_01_record[count.index]}"  
            }                                                                               
          ]                                                                                 
        }                                                                                   
      }                                                                                     
    ]                                                                                       
  }                                                                                         
}                                                                                           
EOT                                                                                         
EOS                                                                                         
  }                                                                                         
}                                                                                           

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment