GitOps:Terraform / Terragruntインフラストラクチャのドリフトの検出

みなさん、こんにちは。





免責事項:途中で記事を書いていることをお伝えします。その中の「コード」は機能していますが、ベストプラクティスのふりをしていないので、誤りを見つけないでください:)記事の目的:to関心のあるロシア語を話す人々に一般原則を伝えれば、関心を起こして自分で整理し、より良く、より興味深いことをすることができます。じゃ、行こう!





Terraform / Terragrunt(後者はここでは基本的ではありませんが、まだ使用していない場合はより良い研究)を使用していて、たとえばAWS(必ずしもAWSではない)でインフラストラクチャを自動化するとします。インフラストラクチャはリポジトリのコードにあり、そこからデプロイされます。これはGitOpsの幸福のようです:)





一部のユーザーがコンソール/ UIを介して手で何かを変更し、もちろんそれについて誰かに話すのを忘れるまで、すべてが順調に進んでいます。そして、彼は故意に何か悪いことをしました。そして、ここにあなたのドリフトがあります:コードとインフラストラクチャはもはや一致しません!:(





少なくともタイムリーにこれについて学ぶためには、自動化を少し洗練する必要があります。





いつものように、あなたが望むものを手に入れるための多くの異なる方法があります。たとえば、最近、地平線上に十分に開発されたユーティリティがhttps://github.com/cloudskiff/driftctlに登場しましたこれは、以下で提供する以上のものである可能性がありますが、この記事の執筆時点では、driftctl少なくともawsプロバイダーv2での作業をサポートしておらず、マルチリージョンの方法も知らないため、ほとんどの深刻なプロジェクトで使用できません。しかし、彼らはそれを一ヶ月か二ヶ月で終えることを約束します。





それまでの間、次の非常に単純なスキームの少量のコードの例を説明して示します。





  1. パイプラインを作成します。パイプラインは、スケジュール(Gitlabではパイプラインスケジュールを使用できます)または円のいずれかでテラフォームプランを作成します





  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







PS:私見プロジェクトhttps://github.com/cloudskiff/driftctlは、個人的には本当に便利で正しい問題を解決しているように見えますが、良い類似物がないので、みんなをサポートするようにお願いします。可能であれば、少しやってください。オープンソース用。





みなさん、いい気分です!








All Articles