Skip to main content

Linode DNS Infrastructure

Automated DNS management for itisajoke.net using Terraform Cloud and GitHub integration.

Overview​

This repository manages Linode DNS records using Infrastructure as Code with Terraform. Changes are automatically deployed through a GitOps workflow:

  • Pull Requests → Terraform runs a plan (preview changes)
  • Merge to main → Terraform automatically applies changes

Repository Structure​

linode_dns_infrastructure/
├── main.tf # Main Terraform configuration
├── variables.tf # Variable definitions
├── outputs.tf # Output definitions
├── terraform.auto.tfvars # DNS records and configuration
└── README.md # This file

Prerequisites​

Initial Setup​

1. Create Terraform Cloud Organization & Workspace​

  1. Go to https://app.terraform.io
  2. Create an organization (or use existing)
  3. Create a new workspace:
    • Choose "Version control workflow"
    • Select GitHub and authorize
    • Select this repository
    • Name: linode_dns_infrastructure
    • Click "Create workspace"

2. Configure Workspace Settings​

Execution Mode:

  1. Go to Settings → General
  2. Set Execution Mode to "Remote"
  3. Save settings

Auto-Apply:

  1. In Settings → General, find "Auto-apply" section
  2. Check: ✅ "Auto-apply API, UI, & VCS runs"
  3. Save settings

This configuration enables:

  • Pull requests run plans automatically (no apply)
  • Merges to main automatically apply changes

3. Add Linode API Token​

  1. Go to workspace Variables tab
  2. Click "Add variable"
  3. Select "Environment variable"
  4. Configure:
    • Key: LINODE_TOKEN
    • Value: Your Linode API token
    • Sensitive: ✅ (check this box)
  5. Click "Add variable"

4. Update Configuration​

Edit terraform.auto.tfvars to match your domain and DNS records:

domain_name  = "itisajoke.net"
soa_email = "vitkovic.tomislav@gmail.com"
default_ttl = 3600

# A Records
a_records = [
{ name = "", target = "198.185.159.144" },
{ name = "gallery", target = "173.230.140.102" },
# Add more records...
]

# CNAME Records
cname_records = [
{ name = "www", target = "ghs.googlehosted.com" },
# Add more records...
]

# MX Records
mx_records = [
{ name = "", target = "aspmx.l.google.com", priority = 1 },
# Add more records...
]

# TXT Records
txt_records = [
{ name = "", target = "v=spf1 include:_spf.google.com ~all" },
# Add more records...
]

5. Push to GitHub​

git add .
git commit -m "Configure Linode DNS infrastructure"
git push origin main

Terraform Cloud will automatically:

  1. Detect the push
  2. Run terraform plan
  3. Apply changes automatically
  4. Create your domain and all DNS records

Monitor the deployment at:

https://app.terraform.io/app/itisajoke-net/workspaces/linode_dns_infrastructure/runs

Daily Workflow​

Making DNS Changes​

Step 1: Create a feature branch

git checkout -b add-new-subdomain

Step 2: Edit DNS records Update terraform.auto.tfvars:

a_records = [
# Existing records...
{
name = "new-service"
target = "192.0.2.1"
}
]

Step 3: Commit and push

git add terraform.auto.tfvars
git commit -m "Add new-service A record"
git push origin add-new-subdomain

Step 4: Create Pull Request

  1. Go to GitHub and create a PR
  2. Review the Terraform plan in the PR comments
  3. The plan shows what will be added/changed/destroyed

Step 5: Merge to deploy

  1. Once approved, merge the PR
  2. Terraform Cloud automatically applies the changes
  3. Your DNS record is live!

Viewing State​

From Local Machine​

# View all resources
terraform state list

# Show specific record details
terraform state show 'linode_domain_record.a_records["gallery"]'

# Export entire state
terraform state pull > state.json

# Verify configuration matches state
terraform plan

In Terraform Cloud UI​

View state versions and outputs:

https://app.terraform.io/app/itisajoke-net/workspaces/linode_dns_infrastructure/states

Outputs​

After applying, Terraform provides these outputs:

  • domain_id - Linode domain ID
  • nameservers - Nameservers for the domain
  • a_records - Map of all A records with FQDNs
  • cname_records - Map of all CNAME records with FQDNs

View outputs:

terraform output
terraform output -json

Configuration Details​

DNS Record Keys​

This configuration uses name-based keys for stable state management:

  • A Records: Keyed by name (e.g., "gallery", "root" for apex)
  • CNAME Records: Keyed by name (e.g., "www")
  • MX Records: Keyed by target-priority (e.g., "aspmx.l.google.com-1")
  • TXT Records: Keyed by name (e.g., "root", "google._domainkey")

This design prevents Terraform from recreating resources when you reorder items in your lists.

TTL Configuration​

Each record can have a custom TTL:

a_records = [
{
name = "cache-long"
target = "192.0.2.1"
ttl = 86400 # 24 hours
},
{
name = "cache-short"
target = "192.0.2.2"
ttl = 300 # 5 minutes
}
]

If ttl is not specified, records use default_ttl (3600 seconds).

Terraform Cloud Organization​

Resources​

Domain Information​

Support​

For issues or questions:

  1. Check the Terraform Cloud run logs
  2. Review this README
  3. Consult the Terraform Linode provider documentation