Skip to content

Instantly share code, notes, and snippets.

@rjz
Created May 30, 2020 00:42
Show Gist options
  • Select an option

  • Save rjz/6332bae1995852643b0905a4f169834a to your computer and use it in GitHub Desktop.

Select an option

Save rjz/6332bae1995852643b0905a4f169834a to your computer and use it in GitHub Desktop.

Revisions

  1. rjz created this gist May 30, 2020.
    111 changes: 111 additions & 0 deletions import_route53_zone_to_terraform.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,111 @@
    #! /bin/bash
    #
    # Translates an existing AWS Route53 zone into Terraform `aws_route53_record` resources.
    #
    # Released under the MIT license; YMMV. Tested on Linux with:
    #
    # - jq-1.6
    # - terraform v0.12.26
    # - aws-cli/1.17.14
    #

    # The base filename for both the TF resources and the import script
    OUTNAME=route53_records

    # Your AWS Zone ID
    ZONE_ID=ABC123

    # The Terraform variable to reference in aws_route53_record entries
    ZONE_VAR=aws_route53_zone.MY_RESOURCE.zone_id


    as_tf_route53_record_dns_name() {
    local name="$1"

    echo $name | sed 's/\\052/*/'
    }

    as_tf_route53_record_resource_name() {
    local name="$1"
    local type=$2

    echo $name | grep -i '^[a-z_]' > /dev/null || {
    # Terraform requires resource names to start with an alpha character or
    # underscore. This one didn'ts, but we can fix that.
    name="_${name}"
    }

    echo "$(echo $name | tr '.' '-' | sed 's/\\052/wildcard/')$(echo $type | tr '[:upper:]' '[:lower:]')"
    }

    as_tf_route53_alias() {
    local alias=$1

    cat <<EOF
    alias {
    zone_id = $(echo "$alias" | jq .HostedZoneId)
    name = $(echo "$alias" | jq .DNSName)
    evaluate_target_health = $(echo "$alias" | jq -r .EvaluateTargetHealth)
    }
    EOF
    }

    as_tf_route53_record() {
    local json="$1"
    local name=$(echo "$json" | jq -r .Name)
    local type=$(echo "$json" | jq -r .Type)
    local alias=$(echo "$json" | jq -r .AliasTarget)

    cat <<EOF
    resource "aws_route53_record" "$(as_tf_route53_record_resource_name $name $type)" {
    zone_id = ${ZONE_VAR}
    name = "$(as_tf_route53_record_dns_name $name)"
    type = "${type}"
    $(
    if [[ "$type" == "A" && "$alias" != "null" ]]; then
    as_tf_route53_alias "$alias"
    else
    echo "ttl = $(echo "$json" | jq -r .TTL)"
    echo "records = $(echo "$json" \
    | jq -r --indent 4 '.ResourceRecords | map(.Value)' \
    | sed 's/\\"//g' | sed 's/",*$/",/')"
    fi
    )
    }
    EOF
    }

    as_tf_route53_record_import() {
    local json="$1"
    local name=$(echo "$json" | jq -r .Name)
    local type=$(echo "$json" | jq -r .Type)

    local import_id=${ZONE_ID}_$(echo "$name" | sed 's/\.$//')_${type}

    echo "terraform import aws_route53_record.$(as_tf_route53_record_resource_name $name $type) $import_id"
    }

    rm ${OUTNAME}.txt
    rm ${OUTNAME}_import.sh

    echo '#!/bin/sh
    ' > ${OUTNAME}_import.sh

    chmod +x ${OUTNAME}_import.sh

    aws route53 list-resource-record-sets \
    --hosted-zone-id=$ZONE_ID \
    | jq -c '.ResourceRecordSets[]' \
    | while IFS= read -r line
    do
    as_tf_route53_record "$line" >> ${OUTNAME}.txt
    as_tf_route53_record_import "$line" >> ${OUTNAME}_import.sh
    done

    echo "Zone retrieved from Route 53!"
    echo
    echo "Copy the resources from ${OUTNAME}.txt into main.tf, then import existing"
    echo "records using:"
    echo
    echo " $ ./${OUTNAME}_import.sh"
    echo