-
-
Save oveaurs/68c32500c0f5a2a4507f051adf439673 to your computer and use it in GitHub Desktop.
Ruby script to use as a hook for the letsencrypt.sh client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'aws-sdk' | |
# | |
# This script requires you to have the following environment variables set: | |
# AWS_REGION="us-west-2" | |
# AWS_ACCESS_KEY_ID="<YOUR_KEY>" | |
# AWS_SECRET_ACCESS_KEY="<YOUR_SECRET_KEY>" | |
# | |
# Based on https://gist.github.com/asimihsan/d8d8f0f10bdc85fc6f8a | |
# | |
def find_hosted_zone(route53, domain) | |
route53 = Aws::Route53::Client.new | |
hosted_zones = route53.list_hosted_zones_by_name.hosted_zones | |
index = hosted_zones.rindex { |zone| domain.end_with?(zone.name.chop) } | |
if index.nil? | |
puts 'Unable to find matching zone.' | |
exit 1 | |
end | |
hosted_zones[index] | |
end | |
def wait_for_change(route53, change_id) | |
status = '' | |
until status == 'INSYNC' | |
resp = route53.get_change(id: change_id) | |
status = resp.change_info.status | |
if status != 'INSYNC' | |
puts 'Waiting for dns change to complete' | |
sleep 5 | |
end | |
end | |
end | |
def setup_dns(domain, txt_challenge) | |
route53 = Aws::Route53::Client.new | |
hosted_zone = find_hosted_zone(route53, domain) | |
resp = route53.test_dns_answer({ | |
hosted_zone_id: hosted_zone.id, | |
record_name: "_acme-challenge.#{domain}.", | |
record_type: "TXT" | |
}) | |
records = [] | |
resp.record_data.each do |val| | |
records << { | |
value: val | |
} | |
end | |
records << { | |
value: "\"#{txt_challenge}\"" | |
} | |
changes = [] | |
changes << { | |
action: 'UPSERT', | |
resource_record_set: { | |
name: "_acme-challenge.#{domain}.", | |
type: 'TXT', | |
ttl: 60, | |
resource_records: records.uniq | |
} | |
} | |
resp = route53.change_resource_record_sets( | |
hosted_zone_id: hosted_zone.id, | |
change_batch: { | |
changes: changes | |
} | |
) | |
wait_for_change(route53, resp.change_info.id) | |
end | |
def delete_dns(domain, txt_challenge) | |
route53 = Aws::Route53::Client.new | |
hosted_zone = find_hosted_zone(route53, domain) | |
resp = route53.test_dns_answer({ | |
hosted_zone_id: hosted_zone.id, | |
record_name: "_acme-challenge.#{domain}.", | |
record_type: "TXT" | |
}) | |
records = [] | |
method = "DELETE" | |
if resp.record_data.count > 1 | |
method = "UPSERT" | |
resp.record_data.delete("\"#{txt_challenge}\"") | |
resp.record_data.each do |val| | |
records << { | |
value: val | |
} | |
end | |
else | |
records << { | |
value: "\"#{txt_challenge}\"" | |
} | |
end | |
changes = [] | |
changes << { | |
action: method, | |
resource_record_set: { | |
name: "_acme-challenge.#{domain}.", | |
type: 'TXT', | |
ttl: 60, | |
resource_records: records.uniq | |
} | |
} | |
resp = route53.change_resource_record_sets( | |
hosted_zone_id: hosted_zone.id, | |
change_batch: { | |
changes: changes | |
} | |
) | |
wait_for_change(route53, resp.change_info.id) | |
end | |
if __FILE__ == $PROGRAM_NAME | |
hook_stage = ARGV[0] | |
domain = ARGV[1] | |
txt_challenge = ARGV[3] | |
if hook_stage == 'deploy_challenge' | |
puts "stage: #{hook_stage} domain: #{domain} txt_challenge: #{txt_challenge}" | |
setup_dns(domain, txt_challenge) | |
elsif hook_stage == 'clean_challenge' | |
puts "stage: #{hook_stage} domain: #{domain} txt_challenge: #{txt_challenge}" | |
delete_dns(domain, txt_challenge) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment