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