Skip to content

Instantly share code, notes, and snippets.

@razbomi
Last active August 25, 2023 01:43
Show Gist options
  • Save razbomi/c38c3adeccd6539746489bdd7c504ac1 to your computer and use it in GitHub Desktop.
Save razbomi/c38c3adeccd6539746489bdd7c504ac1 to your computer and use it in GitHub Desktop.
Export AWS Route53 domain records to Cloudflare as a terraform module
#!/usr/bin/env zx
# npm install -g zx
# ./aws-to-cloudflare-records.mjs my-amazing-zone.com
const domain = process.argv[3]
const recordName = (n) => n.replace("\\052","*").replace(`.${process.argv[3]}.`, "")
const resourceName = (n) => recordName(n).replace(/-/g,"_")
const toString = ({name, type, ttl, value}) => `resource "cloudflare_record" ${JSON.stringify(resourceName(name))} {
name = ${JSON.stringify(recordName(name))}
type = ${JSON.stringify(type)}
ttl = ${JSON.stringify(ttl)}
value = ${JSON.stringify(value)}
zone_id = cloudflare_zone.this.id
}`
const convertAliasTarget = (r) => toString({
name: r.Name,
type: "CNAME",
ttl: 60,
value: r.AliasTarget.DNSName,
})
const convertResourceRecords = (r) => (v) => toString({
name: r.Name,
type: r.Type,
ttl: r.TTL,
value: v.Value
})
const convertRecordSet = (r) => r.AliasTarget
? convertAliasTarget(r)
: r.ResourceRecords.map(convertResourceRecords(r))
const newLine = "\n\n"
const isNotExcluded = (r) => !["NS", "SOA"].includes(r.Type)
const result = (r) => JSON.parse(r.stdout)
.filter(isNotExcluded)
.flatMap(convertRecordSet)
.join(newLine)
const zone = await $`aws route53 list-hosted-zones-by-name --dns-name ${domain} | jq -r '.HostedZones[0] | .Id | sub("/hostedzone/"; "")'`
const recordSets = await $`aws route53 list-resource-record-sets --hosted-zone-id ${zone} --output json | jq '.ResourceRecordSets'`
await fs.outputFile("main.tf", result(recordSets))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment