Skip to main content
  1. Posts/

Terraform Pihole Records

·713 words·4 mins· loading · loading · ·
Terraform DNS Pihole Gitops Pihole DNS Terraform Gitops
Brock Henrie
Author
Brock Henrie
A little bit about me
pihole - This article is part of a series.
Part 2: This Article

This Guide setups terraform and a CICD pipeline to Control DNS records using Gitlab remote state backend and Gitops

Requirements
#

  • Terraform CLI
  • Gitlab Runner
  • 2 Instances of pihole
  • Runner can talk to Piholes on network


Setup Main
#

Lets configure the main.tf file and add the required providers. We will be using Gitlab for a state backend

main.tf

terraform {
  required_providers {
    pihole = {
      source = "ryanwholey/pihole"
    }
    kubectl = {
      source  = "gavinbunney/kubectl"
      version = ">= 1.7.0"
    }
  }

  backend "http" {
  }
}

Locals
#

The locals.tf file needs to be configured with the following

Change to you pihole ips and correct email and the domain ip is the one you gave traefik. mine is 10.10.1.60

locals {
  pihole_primary_url   = "http://x.x.x.x:8888" # IF you have it on a different port
  pihole_secondary_url = "http://x.x.x.x" # If you didnt change the port setting
  domain_name          = "domain.name"
  domain_ip            = "x.x.x.x"
}
 
Field Description
pihole_primary_url Url to the admin console of your piholes
domain_name The Domain Name to be used for creating the A record
domain_ip The target the A record will point to, example our traefik reverse proxy load balancer ip

Variables
#

add this to variables.tf

variable "PIHOLE_PASSWORD" {
  type      = string
  sensitive = true
}

Providers
#

Create a providers.tf

provider "pihole" {
  url      = local.pihole_primary_url # PIHOLE_URL
  password = var.PIHOLE_PASSWORD      # PIHOLE_PASSWORD
}

provider "pihole" {
  url      = local.pihole_secondary_url # PIHOLE_URL
  password = var.PIHOLE_PASSWORD        # PIHOLE_PASSWORD
  alias    = "secondary"
}

Modules
#

Now lets create a modules reference for our code to run

dns.tf

module "pihole_1_io" {
  source      = "./modules/pihole"
  domain_name = local.domain_name
  domain_ip = local.domain_ip
  providers = {
    pihole = pihole
  }
}

module "pihole_2_io" {
  source      = "./modules/pihole"
  domain_name = local.domain_name
  domain_ip = local.domain_ip
  providers = {
    pihole = pihole.secondary
  }
}

Pihole Module
#

Create Folders modules/pihole/

create files

  • a-records.tf
  • cname.tf
  • main.tf
  • outputs.tf
  • variables.tf

a-recoords.tf
#

point a record to our load balancer

resource "pihole_dns_record" "mantisd-io" {
  domain = var.domain_name
  ip = var.domain_ip
}

cname.tf
#

Create records to both our piholes admin dashboard

resource "pihole_cname_record" "pihole" {
  domain = "pihole.${var.domain_name}"
  target = "${var.domain_name}"
}
resource "pihole_cname_record" "pihole-2" {
  domain = "pihole-2.${var.domain_name}"
  target = "${var.domain_name}"
}

main.tf
#

terraform {
  required_version = ">=1.1.4"
  required_providers {
    pihole = {
      source = "ryanwholey/pihole"
    }
  }
}


data "pihole_cname_records" "cname_records" {
  
}

data "pihole_dns_records" "dns_records" {
  
}

outputs.tf
#

output "dns_records" {
  value = data.pihole_dns_records.dns_records
}

output "cname_record" {
  value = data.pihole_cname_records.cname_records
}

variables.tf
#

variable "domain_name" {
    type = string
}

variable "domain_ip" {
    type = string
}

Add new Records to cname.tf and a-records.tf

CICD
#

Now lets create a pipeline to automatically deploy new routes in the main branch when they are commited to our git repo

gitlab-ci.yml
#


stages:
  - pre
  - build
  - deploy

default:
  tags:
    - your
    - runner
    - tags

variables:
  TF_ROOT: $CI_PROJECT_DIR  # The relative path to the root directory of the Terraform project
  TF_STATE_NAME: pihole-records  # The name of the state file used by the GitLab Managed Terraform state backend
  TF_IMAGE: registry.gitlab.com/gitlab-org/terraform-images/releases/terraform:1.1.9
  ARTIFACT_VERSION: "1.0.0"
  REALEASE_VERSION: $ARTIFACT_VERSION
  TF_ADDRESS: "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}"


tf_init_var_check:
    stage: .pre 
    script:
      - if [ -z "${TF_ADDRESS}"]; then echo "ERROR - TF_ADDRESS does not exist, add to .gitlab-ci.yml"; exit 1; fi
      - if [ -z "${TF_USERNAME}"]; then echo "ERROR - TF_USERNAME does not exist, add to .gitlab-ci.yml"; exit 1; fi
      - if [ -z "${TF_PASSWORD}"]; then echo "ERROR - TF_PASSWORD does not exist, add to .gitlab-ci.yml"; exit 1; fi

.terraform_init:
  script:
  - echo $GITLAB_USER_NAME
  - rm -rf .terraform
  - terraform --version
  - |
      terraform init \
      -backend-config=address=${TF_ADDRESS} \
      -backend-config=lock_address=${TF_ADDRESS}/lock \
      -backend-config=unlock_address=${TF_ADDRESS}/lock \
      -backend-config=username=${TF_USERNAME} \
      -backend-config=password=${TF_PASSWORD} \
      -backend-config=lock_method=POST \
      -backend-config=unlock_method=DELETE \
      -backend-config=retry_wait_min=5      

tf_base_config_var_check:
    stage: .pre 
    script:
      - if [ -z "${TF_IMAGE}"]; then echo "ERROR - TF_IMAGE does not exist, add to .gitlab-ci.yml"; exit 1; fi
      - if [ -z "${TF_ROOT}"]; then echo "ERROR - TF_ROOT does not exist, add to .gitlab-ci.yml"; exit 1; fi

.tf_base_config:
    image: ${TF_IMAGE}
    cache:
      key: "${TF_ROOT}"
      paths:
        - ${TF_ROOT}/.terraform/


plan:
  stage: build
  extends:
      - .tf_base_config
  script:
    - !reference [.terraform_init, script]
    - terraform plan -out "plans"
  artifacts:
    paths:
      - plans
    expire_in: 20m


deploy:
  stage: deploy
  extends:
      - .tf_base_config
  script:
    - !reference [.terraform_init, script]
    - terraform apply -input=false "plans"
  only:
    - master

Now When changes are added to master branch the pipeline will execute and deploy to your piholes

pihole - This article is part of a series.
Part 2: This Article

Related

Pihole Guide
·239 words·2 mins· loading · loading
DNS Linux DNS Linux Pihole