Instantly share code, notes, and snippets.

Embed
What would you like to do?
Hook for letsencrypt.sh to do DNS challenges
#!/usr/bin/env ruby
require 'aws-sdk'
require 'pry'
require 'awesome_print'
# ------------------------------------------------------------------------------
# Credentials
# ------------------------------------------------------------------------------
# pick up AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY by default from
# environment
Aws.config.update({
region: 'us-west-2',
})
# ------------------------------------------------------------------------------
def setup_dns(domain, txt_challenge)
route53 = Aws::Route53::Client.new()
hosted_zone = route53.list_hosted_zones_by_name(
{dns_name: "#{domain}."}).hosted_zones[0]
changes = []
changes << {
action: "UPSERT",
resource_record_set: {
name: "_acme-challenge.#{domain}.",
type: "TXT",
ttl: 60,
resource_records: [
value: "\"#{txt_challenge}\"",
],
},
}
resp = route53.change_resource_record_sets({
hosted_zone_id: hosted_zone.id,
change_batch: {
changes: changes,
},
})
ap resp
sleep 10
end
def delete_dns(domain, txt_challenge)
route53 = Aws::Route53::Client.new()
hosted_zone = route53.list_hosted_zones_by_name(
{dns_name: "#{domain}."}).hosted_zones[0]
changes = []
changes << {
action: "DELETE",
resource_record_set: {
name: "_acme-challenge.#{domain}.",
type: "TXT",
ttl: 60,
resource_records: [
value: "\"#{txt_challenge}\"",
],
},
}
resp = route53.change_resource_record_sets({
hosted_zone_id: hosted_zone.id,
change_batch: {
changes: changes,
},
})
ap resp
sleep 10
end
if __FILE__ == $0
hook_stage = ARGV[0]
domain = ARGV[1]
txt_challenge = ARGV[3]
puts hook_stage
puts domain
puts txt_challenge
if hook_stage == "deploy_challenge"
setup_dns(domain, txt_challenge)
elsif hook_stage == "clean_challenge"
delete_dns(domain, txt_challenge)
end
end
@spensaurus

This comment has been minimized.

spensaurus commented Feb 19, 2016

This script works great if you are trying to issue a certificate for your hosted zone exactly (e.g. my hosted zone in AWS is example.net and I want a certificate for example.net) but it fails if you want a certificate for a subdomain (e.g. sub.example.net).

The problem is on lines 19 and 45 where it uses the domain name to search for the hosted zone. As a quick patch I just hardcoded the zone I needed and it worked great. Thanks.

@tache

This comment has been minimized.

tache commented Mar 1, 2016

I updated your gist in my fork to allow for subdomains.

@ShruthiPitta

This comment has been minimized.

ShruthiPitta commented Jul 7, 2016

Tried this hook with letsencrypt.sh. Looks like there is an issue when it runs with the latest version of awesome_print(1.7.0).
Throws error: awesome_print-1.7.0/lib/awesome_print/formatter.rb:122:in method': undefined methodto_hash' for class `Seahorse::Client::Response'
It works fine with awesome_print-1.6.1. Thanks.

@bladedoyle

This comment has been minimized.

bladedoyle commented Nov 14, 2018

Seems like 10 seconds is not enough time to propagate DNS txt record.
I increased that and all is well.
Thanks much for this code!

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