GitOps: detección de deriva en su infraestructura Terraform / Terragrunt

Hola a todos.





Descargo de responsabilidad : le diré que estoy escribiendo un artículo en el camino, el "código" en él está funcionando, pero no pretende ser ninguna de las mejores prácticas, así que no encuentre fallas :) El propósito del artículo: para Transmitir principios generales a la parte interesada de la población de habla rusa, es posible despertar el interés para resolverlo usted mismo y hacer algo mucho mejor y más interesante. ¡Entonces vamos!





Digamos que está trabajando con Terraform / Terragrunt (este último no es fundamental aquí, pero es mejor estudiarlo si aún no lo está usando) y automatizar la infraestructura, por ejemplo, en AWS (pero no necesariamente en AWS). La infraestructura está en el código del repositorio, se implementa desde él, parecería que esto es la felicidad de GitOps :)





Todo va bien hasta que algún usuario cambia algo con sus manos a través de la consola / UI y por supuesto se olvidó de decírselo a alguien. Y luego hizo algo malo a propósito. Y aquí está su deriva: ¡el código y la infraestructura ya no coinciden! :(





Para al menos aprender a tiempo sobre esto, es necesario refinar ligeramente la automatización.





Como de costumbre, hay muchas formas diferentes de conseguir lo que desea. Por ejemplo, recientemente apareció en el horizonte una utilidad en buen desarrollo https://github.com/cloudskiff/driftctl , que incluso puede ser más de lo que le ofreceré a continuación, pero en el momento de escribir este artículo, driftctl al menos no admite trabajar con el proveedor de AWS v2, y tampoco sabe cómo realizar múltiples regiones, lo que imposibilita su uso en la mayoría de los proyectos serios. Pero los chicos prometen terminarlo en uno o dos meses.





Mientras tanto, describiré y daré un ejemplo de una pequeña cantidad de código para el siguiente esquema muy simple:





  1. Creamos un pipeline, que en un horario (en Gitlab puedes usar los horarios del Pipeline) o en un círculo hará un plan de terraform





  2. (diff ) pipeline , , Slack.





, , issue , api , apply, . - state, .





live , .. , :





account_1/
├── eu-central-1
│   ├── dev
│   │   ├── eks
│   │   │   ├── terragrunt.hcl
│   │   │   └── values.yaml
│   │   └── s3-bucket
│   │       ├── terragrunt.hcl
│   │       └── values.yaml
│   ├── prod
│   │   ├── eks
│   │   │   ├── terragrunt.hcl
│   │   │   └── values.yaml
│   │   └── s3-bucket
│   │       ├── terragrunt.hcl
│   │       └── values.yaml
│   └── staging
│       ├── eks
│       │   ├── terragrunt.hcl
│       │   └── values.yaml
│       └── s3-bucket
│           ├── terragrunt.hcl
│           └── values.yaml
├── us-east-1
│   ├── dev
│   │   ├── eks
│   │   │   ├── terragrunt.hcl
│   │   │   └── values.yaml
│   │   └── s3-bucket
│   │       ├── terragrunt.hcl
│   │       └── values.yaml
│   ├── prod
│   │   ├── eks
│   │   │   ├── terragrunt.hcl
│   │   │   └── values.yaml
│   │   └── s3-bucket
│   │       ├── terragrunt.hcl
│   │       └── values.yaml
│   └── staging
│       ├── eks
│       │   ├── terragrunt.hcl
│       │   └── values.yaml
│       └── s3-bucket
│           ├── terragrunt.hcl
│           └── values.yaml
└── terragrunt.hcl
      
      



account_1



2 : us-east-1



eu-central-1



, AWS. Terragrunt /, , "${basename(get_terragrunt_dir())}"







, 2: eks



s3-bucket







,





<account_name>/<region>/<environment>/<component>/*







.. " " */*/*/<component>/*







, , s3-bucket ( , ).





Incoming WebHooks Slack Webhook URL. : https://api.slack.com/messaging/webhooks





pipeline Slack diff' :





#!/bin/bash

ROOT_DIR=$(pwd)

plan () {
  echo -e "$(date +'%H-%M-%S %d-%m-%Y') $F"

  CURRENT_DIR=$(pwd)
  PLAN=$CURRENT_DIR/plan.tfplan

  terragrunt run-all plan --terragrunt-non-interactive -lock=false -detailed-exitcode -out=$PLAN 2>/dev/null || ec=$?
  
  case $ec in
    0) echo "No Changes Found"; exit 0;;
    1) printf '%s\n' "Command exited with non-zero"; exit 1;;
    2) echo "Changes Found! Reporting!"; 
  
       MESSAGE=$(terragrunt show -no-color ${PLAN} | sed "s/\"/'/g");    # let's replace the double quotes from the diff with single as double quotes "break" the payload
       curl -X POST --data-urlencode "payload={\"channel\": \"#your-slack-channel-here\", \"username\": \"webhookbot\", \"text\": \"DRIFT DETECTED!!!\n ${MESSAGE}\", \"icon_emoji\": \":ghost:\"}" https://hooks.slack.com/services/YOUR/WEBHOOK/URL_HERE;;
  esac
}

N="$(($(grep -c ^processor /proc/cpuinfo)*4))"    # any number suitable for your situation goes here

for F in */*/*/s3-bucket/*; do
  ((i=i%N)); ((i++==0)) && wait    # let's run only N jobs in parallel to speed up the process
  cd $ROOT_DIR
  cd $F
  plan &    # send the job to background to start the new one
done
      
      



- , pipeline :)





!





, /, - , , , , , , @vainkop







PD: En mi humilde opinión, el proyecto https://github.com/cloudskiff/driftctl me parece personalmente realmente útil y resuelve el problema correcto y no tiene buenos análogos, así que les pido que apoyen a los chicos, y si es posible, hagan su granito de arena. para código abierto.





¡Buen humor a todos!








All Articles