Last active
August 29, 2015 14:06
-
-
Save IronSavior/49a6971e181a37ffd7a3 to your computer and use it in GitHub Desktop.
Create CNAME records in Route 53 that refer to the running EC2 instance. Can be run at startup or on a cron job.
This file contains hidden or 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
#!/bin/env ruby | |
# Create CNAME records in Route 53 that refer to the running EC2 instance | |
# Unless specified by the first argument, a default TTL of 300 is assumed. | |
# Instance tags specify CNAMES to be set: | |
# 'set_cname:0' => 'name.example.com', 'set_cname:1' => 'name2.example.com', etc | |
# Uses IAM credentials found in the AWS CLI config file: | |
# ~/.aws/config (use `aws configure` to create) | |
# Depends on ec2-metadata command to retrieve the current instance ID | |
# Invoking via rc.local or cron--You may need to set HOME and/or PATH: | |
# HOME=/root PATH=/opt/aws/bin:$PATH /full/path/to/set_ec2_cnames.rb | |
# Author: Erik Elmore <[email protected]> | |
# License: Public Domain | |
require 'aws/ec2' | |
require 'aws/route_53' | |
# Fetch credentials from the AWS CLI config file "~/.aws/config" | |
# You can use the AWS CLI command `aws configure` to create this file. | |
# This requires ENV['HOME'] to be set (which might not be true during boot) | |
def aws_config( opts = {} ) | |
opts = { | |
:profile => :default, | |
:keys => [:aws_access_key_id, :aws_secret_access_key, :region], | |
:file => File.expand_path('~/.aws/config') | |
}.merge opts | |
rx_for = ->(key){ /^\[#{opts[:profile]}\]\n[^\[]+\n#{key}\s*=\s*([^\s]+)$/m } | |
find = ->(key, body){ body.match(rx_for.(key)).captures[0] } | |
body = opts[:body] || File.read(opts[:file]) | |
Hash[ opts[:keys].map{ |key| | |
[key.to_s.gsub('aws_', '').to_sym, find.(key, body)] | |
}] | |
end | |
def instance_id | |
%x{ ec2-metadata -i |cut -f2 -d ' ' }.strip | |
end | |
ttl = (ARGV[0] || 300).to_i | |
AWS.config(aws_config) | |
box = AWS::EC2.new.instances[instance_id] | |
cnames = box.tags.select{ |tag, *| | |
tag =~ /^set_cname\b/ | |
}.map{|*, fqdn| fqdn.end_with?('.')? fqdn : fqdn + '.' } | |
Process.exit 0 if cnames.empty? | |
r53 = AWS::Route53.new | |
cnames.each do |cn| | |
zone = r53.hosted_zones.detect{|z| cn.end_with? z.name } | |
raise 'Cannot set CNAME %s because no matching Route 53 zone was found.' % cn.chop if zone.nil? | |
rs = zone.resource_record_sets[cn, 'CNAME'] | |
if rs.exists? && rs.ttl == ttl && box.dns_name == rs.resource_records[0][:value] | |
puts "No change required for CNAME #{cn}" | |
next | |
end | |
rs.delete if rs.exists? | |
zone.resource_record_sets.create( | |
cn, | |
'CNAME', | |
:ttl => ttl, :resource_records => [{ :value => box.dns_name }] | |
) | |
puts 'Created CNAME %s -> %s with TTL %d' % [cn.chop, box.dns_name, ttl] | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment