Track route53 records with cloudformation.
Managing route53 records with cloudformation is a good idea for the same reasons that tracking other resources with cloudformation (or terraform or whatever) is better than clicking around in the web console:
- it is less work to manipulate infrastructure by editing json files than clicking through the web console
- a cloudformation template allows us to deploy multiple copies of our architecture (for different products, test environments, etc) in a consistent way
- cloudformation templates capture best practices and institutional conventions, and allow infrastructure to evolve over time
- tracking the cloudformation template and parameters in git gives an audit trail
- cloudformation makes automation easy
We setup the following cloudformation template to start managing our simple route53 zones with cloudformation. The template takes advantage of the nunjucks extensions to cloudformation templates supported by our little stack automation.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"DomainName": {
"Type": "String",
"Description": "the domain name"
}
},
"Resources": {
"HostedZone": {
"Type" : "AWS::Route53::HostedZone",
"Properties" : {
"HostedZoneTags" : [
{{ stackTagsStr }}
],
"Name" : { "Ref": "DomainName" }
}
}
{% if stackVariables.aliasList.length %}
,
{% for item in stackVariables.aliasList %}
"AliasA{{ item.resourceName }}": {
"Type" : "AWS::Route53::RecordSet",
"Properties" : {
"AliasTarget" : {
"DNSName" : "{{ item.target }}",
"HostedZoneId": "{{ item.hostedZoneId }}"
},
"Comment" : "{{ item.comment }}",
"HostedZoneId" : { "Ref": "HostedZone" },
"Name" : "{{ item.domainName }}",
"Type" : "A"
}
},
"AliasAaaa{{ item.resourceName }}": {
"Type" : "AWS::Route53::RecordSet",
"Properties" : {
"AliasTarget" : {
"DNSName" : "{{ item.target }}",
"HostedZoneId": "{{ item.hostedZoneId }}"
},
"Comment" : "{{ item.comment }}",
"HostedZoneId" : { "Ref": "HostedZone" },
"Name" : "{{ item.domainName }}",
"Type" : "AAAA"
}
}
{% if not loop.last %} , {% endif %}
{% endfor %}
{% endif %}
{% if stackVariables.mxConfig %}
,
"MX": {
"Type" : "AWS::Route53::RecordSet",
"Properties" : {
"Comment" : "mx mail config",
"HostedZoneId" : { "Ref": "HostedZone" },
"Name" : { "Ref": "DomainName" },
"ResourceRecords" : {{ stackVariables.mxConfig.resourceRecords | dump }},
"TTL" : "900",
"Type" : "MX"
}
}
{% endif %}
{% if stackVariables.cnameList.length %}
,
{% for item in stackVariables.cnameList %}
"Cname{{item.resourceName}}": {
"Type" : "AWS::Route53::RecordSet",
"Properties" : {
"Comment" : "{{ item.comment }}",
"HostedZoneId" : { "Ref": "HostedZone" },
"Name" : "{{ item.domainName }}",
"ResourceRecords" : [ "{{ item.target }}" ],
"TTL" : "900",
"Type" : "CNAME"
}
}
{% if not loop.last %} , {% endif %}
{% endfor %}
{% endif %}
{% if stackVariables.txtList.length %}
,
{% for item in stackVariables.txtList %}
"Txt{{item.resourceName}}": {
"Type" : "AWS::Route53::RecordSet",
"Properties" : {
"Comment" : "{{ item.comment }}",
"HostedZoneId" : { "Ref": "HostedZone" },
"Name" : { "Ref": "DomainName" },
"ResourceRecords" : [ {{ item.txtValue | dump }} ],
"TTL" : "900",
"Type" : "TXT"
}
}
{% if not loop.last %} , {% endif %}
{% endfor %}
{% endif %}
},
"Outputs": {
"NameServers": {
"Description": "hosted zone nameservers",
"Value": { "Fn::Join": [",", { "Fn::GetAtt": [ "HostedZone", "NameServers" ] }] }
}
}
}
Managing route53 zones with cloudformation is the right thing to do.