☀️ Light Mode

Technitium DNS Management with Gitlab CI/CD

automating dns management with gitlab ci/cd
GitOps DNS Management: From Ansible Automation to CI/CD Pipeline

GitOps DNS Management

From Ansible Automation to Full CI/CD Pipeline

Building on our Technitium DNS automation, we’ll implement GitLab CI/CD for a complete GitOps workflow with automatic deployment triggers, runner configuration, and Infrastructure as Code.

Previously: Manual Ansible

In a previous post, we automated Technitium DNS management using Ansible playbooks: exporting zones for backup, importing zones for deployment, and updating servers for maintenance. Ansible helped us eliminate manual SSH sessions and GUI clicking.

The Gap: You still had to run playbooks manually when DNS changes were needed, and there was no version control integration, no automatic triggers, no audit trail.

Today, we’re evolving to “GitOps DNS management,” where Git commits automatically trigger infrastructure changes via CI/CD pipelines.

GitOps Architecture

🔄 Git Repository

DNS zone files, Ansible playbooks, and CI configuration stored in GitLab. Every change is tracked, reviewed, and versioned.

⚡ GitLab CI/CD

Pipeline automatically triggers on zone file changes. Executes Ansible playbooks against DNS servers with proper authentication and error handling.

🎯 GitLab Runner

Self-hosted runner with Ansible, SSH keys, and network access to DNS servers. Executes jobs in isolated environments with proper secrets management.

GitOps Workflow

Edit Zone FileGit CommitPipeline TriggerAnsible DeployDNS Updated

Repository Structure

Organized for GitOps

Your Ansible repository gets enhanced with CI/CD configuration while maintaining the existing playbook structure.

# GitLab Repository: projects/ansible
ansible/
├── .gitlab-ci.yml                     # CI/CD pipeline definition
├── playbooks/
│   └── dns/
│       ├── dns_deploy.yml              # Import/deploy playbook
│       ├── dns_export.yml              # Export/backup playbook
│       └── records/
│           └── example.zone            # Zone file (triggers CI)
└── inventory/
    └── dns_servers.yml                 # DNS server inventory

GitLab CI Pipeline

Automated DNS Deployment

Pipeline triggers automatically when zone files change, executes your existing Ansible playbook, and deploys DNS updates without manual intervention.

# .gitlab-ci.yml - DNS GitOps Pipeline
stages:
  - dns-deploy

deploy_dns_changes:
  stage: dns-deploy
  image: alpine:latest
  before_script:
    # Resolve DNS server hostnames in container
    - echo "$DNS_IP dns1.example.local" >> /etc/hosts
    # Install required tools
    - apk add --no-cache ansible openssh-client
    # Configure SSH agent with private key
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | base64 -d | ssh-add -
    # Add known hosts to prevent SSH prompts
    - mkdir -p ~/.ssh
    - ssh-keyscan -t rsa dns1.example.local >> ~/.ssh/known_hosts
  script:
    - cd playbooks/dns
    # Create temporary vault password file
    - echo "$ANSIBLE_VAULT_PASSWORD" > /tmp/vault_pass
    # Execute DNS deployment playbook
    - ansible-playbook dns_deploy.yml -i ../../inventory/dns_servers.yml --vault-password-file /tmp/vault_pass
    - rm /tmp/vault_pass
  only:
    changes:
      - playbooks/dns/records/*.zone
  after_script:
    - rm -f /tmp/vault_pass

Pipeline Features

  • Smart triggering: Only runs when zone files change
  • DNS resolution: Container can reach your DNS servers
  • Security: SSH keys and vault passwords from GitLab variables
  • Isolation: Each job runs in fresh Alpine container
  • Cleanup: Temporary files removed automatically

GitLab Variables Setup

Configure CI/CD Variables

Store sensitive credentials in GitLab project variables. Navigate to your project’s CI/CD settings to add these required variables.

Step 1: Access GitLab Variables

  1. Go to your GitLab project
  2. Navigate to Settings → CI/CD
  3. Expand the “Variables” section
  4. Click “Add variable” for each required variable

SSH_PRIVATE_KEY

Base64-encoded SSH private key for server access.

Type: Variable • Visible • Expand: ✓ Yes

ANSIBLE_VAULT_PASSWORD

Password for decrypting Ansible Vault encrypted files.

Type: Variable • Visible • Expand: ✓ Yes

DNS_IP

IP address of your primary DNS server for hostname resolution.

Type: Variable • Visibility: Visible

# Step 2: Generate base64 SSH key value
cat ~/.ssh/id_ed25519 | base64 -w 0

# Copy the output and use it as SSH_PRIVATE_KEY value
# Example output: LS0tLS1CRUdJTi0tLS0t...

# Step 3: Variable configuration in GitLab:
SSH_PRIVATE_KEY         = LS0tLS1CRUdJTi...  # Your base64 key
ANSIBLE_VAULT_PASSWORD  = your-vault-password  # Your vault password
DNS_IP                  = 192.168.1.10        # Your DNS server IP

GitLab Runner Setup

Self-Hosted Runner

Install GitLab Runner on a server with network access to your DNS infrastructure. This runner will execute the Ansible playbooks when zone files change.

# Step 1: Install GitLab Runner
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install gitlab-runner

# Step 2: Create runner in GitLab UI first
# Go to: GitLab → Admin → Runners → New instance runner
# Configuration:
# - Description: DNS Automation Runner
# - Tags: (leave empty for untagged jobs)
# - Run untagged jobs: ✓ Enabled
# - Copy the authentication token from the UI

# Step 3: Register runner with authentication token
sudo gitlab-runner register \
  --url https://your-gitlab.example.com \
  --token glrt-your-authentication-token

# When prompted, enter:
# Description: DNS Automation Runner
# Executor: docker
# Default image: alpine:latest

# Step 4: Start runner service
sudo gitlab-runner start
sudo systemctl enable gitlab-runner

Runner Requirements

  • Network access: Runner server must reach your DNS servers
  • Docker executor: Provides clean, isolated environments for each job
  • No tags required: Runner accepts all untagged jobs automatically
  • Authentication token: Generated in GitLab UI, not command line

GitOps Workflow in Action

Complete DNS Change Process

From local zone file edit to live DNS infrastructure – the full GitOps workflow with automatic deployment.

# 1. Clone your GitLab repository
git clone [email protected]:projects/ansible.git
cd ansible

# 2. Edit DNS zone file locally
vim playbooks/dns/records/example.zone

# Add new service:
webapp   3600  IN  A     192.168.1.100
api      3600  IN  CNAME webapp.example.local.

# 3. Commit and push changes
git add playbooks/dns/records/example.zone
git commit -m "DNS: Add webapp and api endpoints"
git push origin main

# 4. GitLab CI automatically:
# - Detects zone file change
# - Triggers dns-deploy pipeline
# - Spins up Alpine container
# - Installs Ansible and SSH
# - Configures authentication
# - Executes dns_deploy.yml playbook
# - Updates Technitium DNS server
# - Zone transfer will replicate to secondary if configured

# 5. Verify deployment
dig @192.168.1.10 webapp.example.local
dig @192.168.1.10 api.example.local

⚡ Automatic Trigger

Git push instantly triggers pipeline

🔐 Secure Deployment

SSH keys and vault passwords from GitLab secrets

📝 Audit Trail

Every change tracked in Git commits and CI logs

🔄 Zone Replication

Primary updates automatically replicate to secondary DNS

GitOps Benefits

Infrastructure as Code

  • DNS configuration in version control
  • Complete change history and rollback capability
  • Peer review via merge requests
  • Branching for experimental changes

Automated Deployment

  • Git push triggers immediate deployment
  • No manual SSH or playbook execution
  • Consistent deployment process
  • Error handling and notifications

Security & Compliance

  • Centralized secrets management
  • Audit trail for all infrastructure changes
  • Access control via GitLab permissions
  • Isolated execution environments

DNS GitOps Complete

We’ve evolved from manual DNS management to Ansible automation to full GitOps deployment with GitLab CI/CD. Your DNS infrastructure now follows modern DevOps practices with automatic deployment, version control, and audit trails. Every DNS change is now a git commit away.

🚀 Ready for Production

Technitium DNS Management with Gitlab CI/CD
Technitium DNS Management with Gitlab CI/CD
NAXS Labs
Logo