Terraform Route53 And DNS Fun
Table of Contents
Uncover the essentials of a Terraform DNS fix in this article. Earthly ensures your infrastructure builds match the reliability of your application builds. Learn more about Earthly.
In my previous article about terraform I moved my lambda and all related infrastructure to Terraform. I even tested things by destroying everything and then recreating it.
Imagine my surprise then, when several days later I got this.
curl https://earthly-tools.com/text-mode $
curl: (6) Could not resolve host: earthly-tools.com
In this post, I’ll show you how I fixed this and got my DNS records from AWS’s Route53 into terraform.
The Problem
So, I had a working lambda that was getting all requests to earthly-tools.com, but then it stopped working. What was going on?
First, lets check and see what dig says:
dig earthly-tools.com $
;; QUESTION SECTION:
;earthly-tools.com. IN A
Dig is missing the IPs for the A record of my domain name. Here is what a DIG response should look like:
dig google.com $
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 210 IN A 172.217.1.14
I can also use dnschecker.org
to validate that something is wrong:
This is strange, because if I look in AWS, under Route53, I can see the A record is setup to point to my HTTP API.
But here lies the problem. The A value of DNS record points to an API Gateway domain name, but not the one I have setup in AWS.
The problem is when I tore down my API gateway, I left a dangling DNS record pointing to a non-existent API Gateway endpoint. The surprising thing is it kept working for a while. Both the new value and the old must resolve to the same IP, and with all the caching that happens in DNS things just kept working for a while.
So the solution is simple, I need to pull my DNS records into Terraform, so that when I make changes to my HTTP API my DNS records also get updated.
Terraform Import
First thing I do is define my zone resource:
resource "aws_route53_zone" "primary" {
name = "earthly-tools.com"
}
The I import the existing zone:
terraform import aws_route53_zone.primary Z0907636HDO135DJDT7G $
With the zone in place, I can create the resource for my A record:
resource "aws_route53_record" "A" {
name = "earthly-tools.com"
type = "A"
zone_id = aws_route53_zone.primary.id
}
And then I import it.
terraform import aws_route53_record.A Z0907636HDO135DJDT7G_earthly-tools.com_A $
Then, I need to configure it to point to the domain name and zone of my API gateway. To do that I add in an alias property.
resource "aws_route53_record" "A" {
name = "earthly-tools.com"
type = "A"
zone_id = aws_route53_zone.primary.id
+ alias {
+ evaluate_target_health = true
+ name = aws_api_gateway_domain_name.earthly-tools-com.regional_domain_name
+ zone_id = aws_api_gateway_domain_name.earthly-tools-com.regional_zone_id
+ }
}
And with that in place, I can just apply everything.
terraform apply $
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_route53_record.A will be created
+ resource "aws_route53_record" "A" {
+ allow_overwrite = (known after apply)
+ fqdn = (known after apply)
+ id = (known after apply)
+ name = "earthly-tools.com"
+ type = "A"
+ zone_id = "Z0907636HDO135DJDT7G"
+ alias {
+ evaluate_target_health = true
+ name = "d-i2cdn11lkf.execute-api.us-east-1.amazonaws.com"
+ zone_id = "Z1UJRXOUMOOFQ8"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_route53_record.A: Creating...
aws_route53_record.A: Still creating... [10s elapsed]
aws_route53_record.A: Still creating... [20s elapsed]
aws_route53_record.A: Still creating... [30s elapsed]
aws_route53_record.A: Creation complete after 38s [id=Z0907636HDO135DJDT7G_earthly-tools.com_A]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
And now everything is working.
curl https://earthly-tools.com/text-mode $
Earthly.dev Presents:
_____ _
|_ _| ___ __ __ | |_
| | / _ \ \ \/ / | __|
| | | __/ > < | |_
|_| \___| /_/\_\ \__|
__ __ _
| \/ | ___ __| | ___
| |\/| | / _ \ / _` | / _ \
| | | | | (_) | | (_| | | __/
|_| |_| \___/ \__,_| \___|
The code is on GitHub
Earthly Cloud: Consistent, Fast Builds, Any CI
Consistent, repeatable builds across all environments. Advanced caching for faster builds. Easy integration with any CI. 6,000 build minutes per month included.