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
- Linode Account with domain configured
- Linode API Token - Create at https://cloud.linode.com/profile/tokens
- Terraform Cloud Account - Sign up at https://app.terraform.io
- GitHub Repository - This repository
Initial Setup
1. Create Terraform Cloud Organization & Workspace
- Go to https://app.terraform.io
- Create an organization (or use existing)
- 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:
- Go to Settings → General
- Set Execution Mode to "Remote"
- Save settings
Auto-Apply:
- In Settings → General, find "Auto-apply" section
- Check: ✅ "Auto-apply API, UI, & VCS runs"
- Save settings
This configuration enables:
- Pull requests run plans automatically (no apply)
- Merges to main automatically apply changes
3. Add Linode API Token
- Go to workspace Variables tab
- Click "Add variable"
- Select "Environment variable"
- Configure:
- Key:
LINODE_TOKEN - Value: Your Linode API token
- Sensitive: ✅ (check this box)
- Key:
- 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:
- Detect the push
- Run
terraform plan - Apply changes automatically
- 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
- Go to GitHub and create a PR
- Review the Terraform plan in the PR comments
- The plan shows what will be added/changed/destroyed
Step 5: Merge to deploy
- Once approved, merge the PR
- Terraform Cloud automatically applies the changes
- 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
- Organization:
itisajoke-net - Workspace:
linode_dns_infrastructure - URL: https://app.terraform.io/app/itisajoke-net/workspaces/linode_dns_infrastructure
Resources
- Linode DNS Manager: https://cloud.linode.com/domains/3266789
- Terraform Provider Docs: https://registry.terraform.io/providers/linode/linode/latest/docs
- Terraform Cloud: https://app.terraform.io
Domain Information
- Domain: itisajoke.net
- Domain ID: 3266789
- SOA Email: vitkovic.tomislav@gmail.com
- Default TTL: 3600 seconds (1 hour)
Support
For issues or questions:
- Check the Terraform Cloud run logs
- Review this README
- Consult the Terraform Linode provider documentation