Fiabiliser son Infra as Code avec pre-commits !
🛠️

Fiabiliser son Infra as Code avec pre-commits !

Beaucoup de solutions existent aujourd'hui pour brancher des hooks sur son workflow git local afin d'exécuter du code à chaque commit pour vérifier la qualité du code produit.

Certains sont très liés à un langage comme husky pour NodeJS ou Overcommit pour Ruby. La solution qui nous intéresse dans cet article est simplement nommée pre-commit et développée en Python.

Elle est très intéressante dans le domaine du CloudOps car les nombreux commits développés par la communauté permettent une couverture importante des technologies utilisées, notamment celles liées à l'IaC comme Terraform ou Helm.

L'implémentation la plus basique consiste en un simple fichier de configuration .pre-commit-config.yaml comme celui-ci :

repos:
  - repo: <https://github.com/pre-commit/pre-commit-hooks>
    rev: v4.4.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-added-large-files
      - id: check-yaml
      - id: check-json
      - id: check-toml

Deux difficultés sont soulevées assez rapidement par l'utilisation massive de pre-commit :

  1. L'uniformisation des différents pre-commit utilisés dans des dépôts Git similaires (module terraform, chart helm, cookiecutter, ...).
  2. L'impossibilité de forcer l'installation des pre-commit côté client.

Standardisation des pre-commit

Une des solutions pour contourner ce problème est de prendre exemple sur ce que l'on fait dans une autre technologie, la CICD. Dans Github Actions, il est possible de créer un dépôt de workflow réutilisable. Pour simuler ce comportement avec pre-commit, on peut créer un dépôt avec un ensemble de fichiers de pre-commit correspondants aux différents types de dépôt que l'on a :

  • pre-commit-tf-module.yaml
  • pre-commit-helm-chart.yaml
  • pre-commit-cookiecutter.yaml
  • pre-commit-python-api.yaml

Ensuite, on instancie ce dépôt en tant que submodule du dépôt principal et on créé un lien vers la config voulue :

$ git submodule add MON_DEPOT
$ ln -s pre-commit-XXXXXXXX.yaml .pre-commit-config.yaml

Ainsi si on a une modification à faire sur la configuration des pre-commit, il suffit de faire la modification dans un seul dépôt central et de mettre à jour le submodule dans les dépôts où celui-ci est utilisé.

Un exemple de pre-commit pour un module Terraform

default_install_hook_types:
  - pre-commit
  - commit-msg

repos:
# BASIC CONF FOR ALL PRE-COMMITS REPO TYPE
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: trailing-whitespace
        stages: [commit]
      - id: end-of-file-fixer
        exclude: /secrets
        stages: [commit]
      - id: check-added-large-files
        stages: [commit]
      - id: check-yaml
        args:
        - '--allow-multiple-documents'
        exclude: /templates|/secrets
        stages: [commit]
      - id: check-json
        stages: [commit]
      - id: check-toml
        stages: [commit]
      - id: check-shebang-scripts-are-executable
        stages: [commit]

  - repo: https://github.com/compilerla/conventional-pre-commit
    rev: v2.1.1
    hooks:
      - id: conventional-pre-commit
        stages: [commit-msg]

	- repo: https://github.com/gitleaks/gitleaks
	    rev: v8.16.1
	    hooks:
	      - id: gitleaks

# SPECIFIC CONF FOR TERRAFORM MODULE REPOSITORIES
  - repo: https://github.com/antonbabenko/pre-commit-terraform
    rev: v1.77.1
    hooks:
      - id: terraform_fmt
        args:
        - --args=-diff
        - --args=-write=true
        stages: [commit]
      - id: terraform_docs
        stages: [commit]
      - id: terraform_tflint
        files: \.tf$
        args:
            - --args=--config=__GIT_WORKING_DIR__/.tflint.hcl
        stages: [commit]
      - id: terraform_tfsec
        files: \.tf$
        args:
          - >
            --args=--config-file=__GIT_WORKING_DIR__/.tfsec.yml
            --var-file tests/terraform.tfvars
        stages: [commit]

Forcer l'installation des pre-commit côté client

Actuellement il n'est pas possible de forcer l'installation des pre-commit lors du clonage du dépôt. Une solution bien que contraignante est de répliquer les différents workflows de pre-commit dans la CI en créant un workflow de CI par workflow de pre-commit. Il est également possible de réutiliser les pre-commit dans la CI et de lancer les pre-commit via la commande pre-commit run --all-files.

Référence

Merci pour votre lecture. Cet article vous a plu, partagez sur vos réseaux

Thibault Ayanides - Mai, 2023

image