Skip to content

Instantly share code, notes, and snippets.

@icco
Forked from miketheman/clouddns_to_route53.rb
Created September 13, 2017 15:59
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 icco/9fc761e53571f29598d2d58ae59c8712 to your computer and use it in GitHub Desktop.
Save icco/9fc761e53571f29598d2d58ae59c8712 to your computer and use it in GitHub Desktop.
Tool to migrate DNS records from Rackspace Cloud DNS to AWS Route53
require 'aws-sdk'
require 'fog/aws'
require 'fog/rackspace'
require 'pry'
# The top-level domain name/hosted zone
TOP_DOMAIN = 'example.org'
# A simple Change class, repsenting a single change to end up in Route53
class Change
attr_accessor :name
attr_accessor :type
attr_accessor :value
attr_accessor :ttl
attr_accessor :priority
end
## rackspace methods
def domain_id(domain_list, domain)
domain_list.select { |d| d['name'] == domain }.first['id']
end
def retrieve_rs_records(domain)
rs_dns = Fog::DNS.new({
:provider => 'rackspace',
:rackspace_username => ENV['RACKSPACE_USERNAME'],
:rackspace_api_key => ENV['RACKSPACE_API_KEY'],
})
domains = rs_dns.list_domains.data[:body]['domains']
did = domain_id(domains, domain)
rs_dns.list_domain_details(did).data[:body]['recordsList']['records']
end
## aws methods
def persist_change_batch(change_batch)
# aws-sdk knows how to pick up credentials from environment variables
route53 = Aws::Route53::Client.new(region: 'us-east-1')
r = route53.list_hosted_zones
zone_id = r.hosted_zones.select { |z| z.name == "#{TOP_DOMAIN}." }.first.id
resp = route53.change_resource_record_sets(hosted_zone_id: zone_id, change_batch: { changes: change_batch })
puts resp.inspect
end
## local
def convert_rs_to_changes(records)
records.inject([]) do |accumulator, record|
c = Change.new
c.name = record['name']
c.type = record['type']
c.ttl = record['ttl']
c.value = record['data']
c.priority = record['priority']
accumulator << c
end
end
def convert_mx_to_single_change(mx_changes)
return unless mx_changes.count > 0
c = Change.new
c.name = mx_changes.first.name
c.ttl = mx_changes.first.ttl
c.type = 'MX'
c.value = mx_changes.map do |mx|
"#{mx.priority} #{mx.value}"
end.compact
c
end
def convert_txt_to_single_change(txt_changes)
return unless txt_changes.count > 0
tc = txt_changes[txt_changes.keys.first]
c = Change.new
c.name = tc.first.name
c.ttl = tc.first.ttl
c.type = 'TXT'
# TXT records need to be wrapped in quotes
c.value = tc.map { |t| "\"#{t.value}\"" }
c
end
def create_change_batch(changes)
changes.compact.map do |change|
record_value = determine_record_value(change)
{ action: 'UPSERT', resource_record_set: {
name: change.name,
type: change.type,
ttl: change.ttl,
resource_records: record_value
}
}
end
end
def determine_record_value(change)
if change.value.class == Array
change.value.map { |v| { value: v } }
else
[{ value: change.value }]
end
end
def mx_change?(change)
change.type == 'MX'
end
def ns_change?(change)
change.type == 'NS'
end
def txt_change?(change)
change.type == 'TXT'
end
## main
records = retrieve_rs_records(TOP_DOMAIN)
changes = convert_rs_to_changes(records)
# Route53 doesn't like it when we try to add more NS records for the same level
changes.reject! { |c| ns_change? c }
# MX Records have multiple valuse and need to be submitted as a single record
mx_changes = changes.select { |c| mx_change? c }
mx_change = convert_mx_to_single_change(mx_changes)
# Replace all MX records with the multi-value one
changes.reject! { |c| mx_change? c }
changes.push mx_change
# TXT Records that have the same record need to be consolidated
txt_changes = changes.reject(&:nil?).select { |c| txt_change? c }.group_by(&:name)
txt_changes.select! { |k, v| [k, v] if v.count > 1 }
txt_record = convert_txt_to_single_change(txt_changes)
changes.reject! { |c| txt_change? c }
changes.push txt_record
changes.reject(&:nil?)
puts "We have #{changes.count} records to send to Route53."
change_batch = create_change_batch(changes)
persist_change_batch(change_batch)
puts 'Done!'
source 'https://rubygems.org'
ruby '2.4.0'
gem "fog-aws"
gem "fog-rackspace"
gem "aws-sdk"
gem "pry"
GEM
remote: https://rubygems.org/
specs:
aws-partitions (1.21.0)
aws-sdk (3.0.1)
aws-sdk-resources (~> 3)
aws-sdk-acm (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-apigateway (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-applicationautoscaling (1.2.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-applicationdiscoveryservice (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-appstream (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-athena (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-autoscaling (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-batch (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-budgets (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-clouddirectory (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cloudformation (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cloudfront (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cloudhsm (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cloudhsmv2 (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cloudsearch (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cloudsearchdomain (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cloudtrail (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cloudwatch (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cloudwatchevents (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cloudwatchlogs (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-codebuild (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-codecommit (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-codedeploy (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-codepipeline (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-codestar (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cognitoidentity (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cognitoidentityprovider (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-cognitosync (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-configservice (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-core (3.4.0)
aws-partitions (~> 1.0)
aws-sigv4 (~> 1.0)
jmespath (~> 1.0)
aws-sdk-costandusagereportservice (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-databasemigrationservice (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-datapipeline (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-dax (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-devicefarm (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-directconnect (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-directoryservice (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-dynamodb (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-dynamodbstreams (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-ec2 (1.4.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-ecr (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-ecs (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-efs (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-elasticache (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-elasticbeanstalk (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-elasticloadbalancing (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-elasticloadbalancingv2 (1.2.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-elasticsearchservice (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-elastictranscoder (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-emr (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-firehose (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-gamelift (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-glacier (1.2.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-glue (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-greengrass (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-health (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-iam (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-importexport (1.0.0)
aws-sdk-core (~> 3)
aws-sigv2 (~> 1.0)
aws-sdk-inspector (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-iot (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-iotdataplane (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-kinesis (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-kinesisanalytics (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-kms (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-lambda (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-lambdapreview (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-lex (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-lexmodelbuildingservice (1.2.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-lightsail (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-machinelearning (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-marketplacecommerceanalytics (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-marketplaceentitlementservice (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-marketplacemetering (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-migrationhub (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-mobile (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-mturk (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-opsworks (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-opsworkscm (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-organizations (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-pinpoint (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-polly (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-rds (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-redshift (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-rekognition (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-resourcegroupstaggingapi (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-resources (3.1.0)
aws-sdk-acm (~> 1)
aws-sdk-apigateway (~> 1)
aws-sdk-applicationautoscaling (~> 1)
aws-sdk-applicationdiscoveryservice (~> 1)
aws-sdk-appstream (~> 1)
aws-sdk-athena (~> 1)
aws-sdk-autoscaling (~> 1)
aws-sdk-batch (~> 1)
aws-sdk-budgets (~> 1)
aws-sdk-clouddirectory (~> 1)
aws-sdk-cloudformation (~> 1)
aws-sdk-cloudfront (~> 1)
aws-sdk-cloudhsm (~> 1)
aws-sdk-cloudhsmv2 (~> 1)
aws-sdk-cloudsearch (~> 1)
aws-sdk-cloudsearchdomain (~> 1)
aws-sdk-cloudtrail (~> 1)
aws-sdk-cloudwatch (~> 1)
aws-sdk-cloudwatchevents (~> 1)
aws-sdk-cloudwatchlogs (~> 1)
aws-sdk-codebuild (~> 1)
aws-sdk-codecommit (~> 1)
aws-sdk-codedeploy (~> 1)
aws-sdk-codepipeline (~> 1)
aws-sdk-codestar (~> 1)
aws-sdk-cognitoidentity (~> 1)
aws-sdk-cognitoidentityprovider (~> 1)
aws-sdk-cognitosync (~> 1)
aws-sdk-configservice (~> 1)
aws-sdk-costandusagereportservice (~> 1)
aws-sdk-databasemigrationservice (~> 1)
aws-sdk-datapipeline (~> 1)
aws-sdk-dax (~> 1)
aws-sdk-devicefarm (~> 1)
aws-sdk-directconnect (~> 1)
aws-sdk-directoryservice (~> 1)
aws-sdk-dynamodb (~> 1)
aws-sdk-dynamodbstreams (~> 1)
aws-sdk-ec2 (~> 1)
aws-sdk-ecr (~> 1)
aws-sdk-ecs (~> 1)
aws-sdk-efs (~> 1)
aws-sdk-elasticache (~> 1)
aws-sdk-elasticbeanstalk (~> 1)
aws-sdk-elasticloadbalancing (~> 1)
aws-sdk-elasticloadbalancingv2 (~> 1)
aws-sdk-elasticsearchservice (~> 1)
aws-sdk-elastictranscoder (~> 1)
aws-sdk-emr (~> 1)
aws-sdk-firehose (~> 1)
aws-sdk-gamelift (~> 1)
aws-sdk-glacier (~> 1)
aws-sdk-glue (~> 1)
aws-sdk-greengrass (~> 1)
aws-sdk-health (~> 1)
aws-sdk-iam (~> 1)
aws-sdk-importexport (~> 1)
aws-sdk-inspector (~> 1)
aws-sdk-iot (~> 1)
aws-sdk-iotdataplane (~> 1)
aws-sdk-kinesis (~> 1)
aws-sdk-kinesisanalytics (~> 1)
aws-sdk-kms (~> 1)
aws-sdk-lambda (~> 1)
aws-sdk-lambdapreview (~> 1)
aws-sdk-lex (~> 1)
aws-sdk-lexmodelbuildingservice (~> 1)
aws-sdk-lightsail (~> 1)
aws-sdk-machinelearning (~> 1)
aws-sdk-marketplacecommerceanalytics (~> 1)
aws-sdk-marketplaceentitlementservice (~> 1)
aws-sdk-marketplacemetering (~> 1)
aws-sdk-migrationhub (~> 1)
aws-sdk-mobile (~> 1)
aws-sdk-mturk (~> 1)
aws-sdk-opsworks (~> 1)
aws-sdk-opsworkscm (~> 1)
aws-sdk-organizations (~> 1)
aws-sdk-pinpoint (~> 1)
aws-sdk-polly (~> 1)
aws-sdk-rds (~> 1)
aws-sdk-redshift (~> 1)
aws-sdk-rekognition (~> 1)
aws-sdk-resourcegroupstaggingapi (~> 1)
aws-sdk-route53 (~> 1)
aws-sdk-route53domains (~> 1)
aws-sdk-s3 (~> 1)
aws-sdk-servicecatalog (~> 1)
aws-sdk-ses (~> 1)
aws-sdk-shield (~> 1)
aws-sdk-simpledb (~> 1)
aws-sdk-sms (~> 1)
aws-sdk-snowball (~> 1)
aws-sdk-sns (~> 1)
aws-sdk-sqs (~> 1)
aws-sdk-ssm (~> 1)
aws-sdk-states (~> 1)
aws-sdk-storagegateway (~> 1)
aws-sdk-support (~> 1)
aws-sdk-swf (~> 1)
aws-sdk-waf (~> 1)
aws-sdk-wafregional (~> 1)
aws-sdk-workdocs (~> 1)
aws-sdk-workspaces (~> 1)
aws-sdk-xray (~> 1)
aws-sdk-route53 (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-route53domains (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-s3 (1.2.0)
aws-sdk-core (~> 3)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.0)
aws-sdk-servicecatalog (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-ses (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-shield (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-simpledb (1.0.0)
aws-sdk-core (~> 3)
aws-sigv2 (~> 1.0)
aws-sdk-sms (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-snowball (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-sns (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-sqs (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-ssm (1.1.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-states (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-storagegateway (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-support (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-swf (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-waf (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-wafregional (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-workdocs (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-workspaces (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-xray (1.0.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sigv2 (1.0.1)
aws-sigv4 (1.0.2)
builder (3.2.3)
coderay (1.1.2)
excon (0.59.0)
fog-aws (1.4.1)
fog-core (~> 1.38)
fog-json (~> 1.0)
fog-xml (~> 0.1)
ipaddress (~> 0.8)
fog-core (1.45.0)
builder
excon (~> 0.58)
formatador (~> 0.2)
fog-json (1.0.2)
fog-core (~> 1.0)
multi_json (~> 1.10)
fog-rackspace (0.1.5)
fog-core (>= 1.35)
fog-json (>= 1.0)
fog-xml (>= 0.1)
ipaddress (>= 0.8)
fog-xml (0.1.3)
fog-core
nokogiri (>= 1.5.11, < 2.0.0)
formatador (0.2.5)
ipaddress (0.8.3)
jmespath (1.3.1)
method_source (0.8.2)
mini_portile2 (2.2.0)
multi_json (1.12.2)
nokogiri (1.8.0)
mini_portile2 (~> 2.2.0)
pry (0.10.4)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
slop (3.6.0)
PLATFORMS
ruby
DEPENDENCIES
aws-sdk
fog-aws
fog-rackspace
pry
RUBY VERSION
ruby 2.4.0p0
BUNDLED WITH
1.15.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment