Gestion des DNS OVH via Terraform

Prérequis

  • Terraform
  • Compte OVH
  • Bucket S3

Token

OVH

Pour créer les tokens OVH, il faut d'abord suivre ce tutoriel impérativement.. On aura ainsi par la suite besoin de CONSUMER_KEY, APPLICATION_KEY et APPLICATION_SECRET (pensez à les tocker dans un vault)

CI/CD

Création des secrets

TF_VAR_APPLICATION_KEY
TF_VAR_APPLICATION_SECRET
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
TF_VAR_CONSUMER_KEY

Initialisation Terraform

versions.tf

terraform {
required_version = "~> 1.0"

required_providers { ovh = { source = “ovh/ovh” version = “~> 0.33” } } }

variables.tf

variable "APPLICATION_KEY" {
description = "application key"
type        = string
}

variable "APPLICATION_SECRET" {
description = "application secret"
type        = string
}

variable "CONSUMER_KEY" {
description = "consumer key"
type        = string
}


variable "records" {
description = "records to be created"
type        = map(any)
default     = { 
    record1 = {
        zone      = "incenbie.eu.org"
        subdomain = "blog"
        fieldtype = "A"
        ttl       = "0"
        target    = "192.168.1.1"
    }
}
}

provider.tf

provider "ovh" {
endpoint           = "ovh-eu"
application_key    = var.APPLICATION_KEY
application_secret = var.APPLICATION_SECRET
consumer_key       = var.CONSUMER_KEY
}

Ici, on configure le provider OVH, avec des secrets en variables (étant donné que c'est des variables Terraform, on les précedera de 'TFVAR')

main.tf

resource "ovh_domain_zone_record" "dns_record_terajob" {
for_each  = var.records
zone      = each.value.zone
subdomain = each.value.subdomain
fieldtype = each.value.fieldtype
ttl       = each.value.ttl
target    = each.value.target
}

backend.tf

terraform {
backend "s3" {
    bucket         = "terraform-state"
    region         = "us-east-1"
    key            = "dns/perso.tfstate"
    encrypt        = false
    endpoint =  "s3.pub1.infomaniak.cloud"  
    force_path_style = true
    skip_credentials_validation = true
    skip_region_validation = true    
}
}

Ici, on configure l'emplacement de stockage des states, donc ici le bucket S3, avec l'endpoint et la région cible.

Chaînes CI/CD

Il y a plusieurs étapes :

  • Définition du nom de l'action et de quand elle est déclenchée (push, pull request).

  • Préparation de l'environnement, qui fonctionne sur Ubuntu 20.04 et des variables d'environnement nécessaires à Terraform

  • Déroulement des différentes actions :

    • Linters
    • Formatage et nettoyage des fichiers Terraform
    • Préparer l'environnement d'exécution, en récupérant les dépendances (providers)
    • Revalider la syntaxe et les actions
    • Préparation du plan d'action Terraform
    • On applique si tout est OK.

Github Actions

name: ovh_dns_management
on: [push, pull_request]
jobs:
    build:
        name: OVH DNS
        runs-on: ubuntu-20.04
        env: 
            TF_VAR_CONSUMER_KEY: "${{ secrets.TF_VAR_CONSUMER_KEY }}"
            TF_VAR_APPLICATION_KEY: "${{ secrets.TF_VAR_APPLICATION_KEY }}"
            TF_VAR_APPLICATION_SECRET: "${{ secrets.TF_VAR_APPLICATION_SECRET }}"
            AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}"
            AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}"
        steps:
            - name: Checkout code
                uses: actions/checkout@v3
            - name: Setup Terraform 
                uses: hashicorp/setup-terraform@v2
            - name: Terraform fmt
                id: fmt
                run: terraform fmt -check
                continue-on-error: true
            - name: Terraform Init
                id: init
                run: terraform init
                continue-on-error: false
            - name: Terraform Validate
                id: validate
                run: terraform validate -no-color
                continue-on-error: false
            - name: Terraform Plan
                id: plan
                run: terraform plan -no-color -input=false
                continue-on-error: false
            - name: Terraform Apply
                id: apply
                run: terraform apply -no-color -auto-approve
                continue-on-error: false

Gitea Actions

name: 'Setup Terraform'
on:
    push:
        branches:
            - main
env:
    AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    TF_VAR_APPLICATION_KEY: ${{ secrets.OVH_APPLICATION_KEY }}  
    TF_VAR_APPLICATION_SECRET: ${{ secrets.OVH_APPLICATION_SECRET }}  
    TF_VAR_CONSUMER_KEY: ${{ secrets.OVH_CONSUMER_KEY }}  
jobs:
    terraform-versions:
        name: 'Terraform Versions'
        runs-on: ubuntu-latest
        steps:
        - uses: https://github.com/actions/checkout@v3
        - uses: https://github.com/hashicorp/setup-terraform@v2
        - name: Terraform fmt
        id: fmt
        run: terraform fmt -check
        continue-on-error: true
        - name: Terraform Init
        id: init
        run: terraform init
        - name: Terraform Validate
        id: validate
        run: terraform validate -no-color
        - name: Terraform Plan
        id: validate
        run: terraform plan
        - name: Terraform Apply
        id: apply
        run: terraform apply -auto-approve -input=false

Enjoy !

Chaque fois que vous ajoutez une nouvelle entrée DNS dans variables.tf, la chaîne CI/CD redémarre et ajoute le sous-domaine, avec l'avantage supplémentaire de stocker l'état actuel des enregistrements DNS dans un bucket S3.