AWS CodeCommit + AWS CodePipeline + AWS CodeBuild 環境でのTerraformドリフト検出

AWS

2024.3.30

Topics

こんにちは、tkgです。
IaC(Infrastructure as Code)ツールを活用するとテキストベースで簡単にインフラやコンポーネントの展開が可能となりますが、その運用上で避けることができないのが実際のインフラ環境とコードとの差分、「ドリフト」と呼ばれる状況です。
運用プロセスの問題や緊急対応に伴う変更など、ドリフトが起きる状況は多々ありますが、IaC運用を続けるためにもこのドリフトを検知し、解消することが重要になります。

GitHub Actionsを利用する手段もありますが、今回はAWS環境のみでドリフト検出する構成として、AWS Codeシリーズを活用した構成を考えてみました。

構成

今回は CodeCommit + CodePipeline + CodeBuildを利用して ドリフト状態を確認するパイプラインを作成、EventBridgeで定期実行、ドリフト状態を検出した場合 Code BuildからSNS経由のChatBot、最終的にslackへの通知を行う仕組みとしています。

ファイル構成は下記の通りを想定しています。

.
├── buildspec.yml
└── terraform
    ├── main.tf
    └── hogehoge.tf

Codeシリーズで実行パイプラインを作成する

CodeCommitでリポジトリを作成、上記構成のようにTerraformのコードを配置後、Code Pipelineを作成します。

Step 1

今回は1日1回の動作を想定しているパイプラインのため、V2を選択してみます。
ドリフト検知のみの場合は V1でもよいですが、他のCICDと組み合わせる場合 V2のほうがユースケースに合っているかなと感じます。
参考: AWS CodePipeline の料金

Step 2

ソースプロバイダでは 作成した CodeCommitを設定します。
今回は検出オプションとして Amazon CloudWatch Events (現EventBridge) を選択します。

Step 3

ここではAWS CodeBuildを選択します。
このページから CodeBuildの作成画面も呼び出して設定が可能です。

CodeBuildの設定では、実行コマンドを buildspec.ymlとして配置しますのでそちらの設定をいれておきます。
また、環境変数には TF_DIR:./terraform/ を設定してください。
他のCI/CDの設定と同居させる場合は、任意の名前を設定して、後述のbuildspec.yml配置時のファイル名を任意の名前としてください。


buildspec.ymlを定義する

次のようなコードを作成し、CodeCommitに配置します。
CodeBuilc上で設定した環境変数を terraformコマンドの -chdir で利用し、対象のディレクトリ指定としています。
複数CodeBuildを並べることで、階層が複数あるterraformの環境にも対応できますね。

また、今回は tfenv をinstallフェーズで導入する形としていますが、Terraform自体をインストールしても問題はありません。

version: 0.2

phases:
  install:
    commands:
      - git clone https://github.com/tfutils/tfenv.git ~/.tfenv
      - echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
      - source ~/.bash_profile
      - tfenv install
      - tfenv use

  pre_build:
    commands:
      - terraform -chdir=$TF_DIR init

  build:
    commands:

      - terraform -chdir=$TF_DIR plan -detailed-exitcode

通知設定を行う

Chatbotの設定

予め、SNSトピックを作成しておきます。

Chatbot側では特に変わった設定はなく、ドキュメント記載の通りにSlackと連携できればOKです。
参考: 通知と AWS Chatbot との統合の設定

通知チャンネル設定作成画面の通知オプションにて、作成しておいたSNSトピックを設定します。

CodeBuild失敗時の通知設定

CodePipeline作成時に作成したCodebuildの画面から、アクション > 通知を作成を選択し、通知設定を行います。
今回は Build phase の Failureの通知を有効にしてみます。

EventBridgeの実行タイミングの修正

CodePipelineの作成時に自動作成されたEventBridgeを修正します。
指定branchの変更タイミングでのイベントパターンが設定されていますが、今回は定期的な実行を行いたいので、Cron式での実行に修正します。

上部編集からルールを編集します。スケジュールを選択し、Cron式を設定します。
今回は日本時間16時に実行されるようにしてみます。

その他設定については修正せずそのままとします。

動作を確認する

指定した時間に動作が始まり、通知が行われることが確認できたら設定完了です。

今回は予め terraform planコマンドで差分が出る状態にしておいたので、-detailed-exitcodeオプションで status が2となりFailure、通知が行われるという状況となりました。

まとめ

各サービスへの理解と連携手法などを理解しておく必要はありますが、通知周りの設定をAWSのマネージドサービスを利用することができ、最小のコード記述だけで実装可能な点が良いところだなと感じました。
基本的にはCI/CDの手法と変わらないので、CI/CDパイプラインを設定するついでに設定しておくと記憶が新しい間にコードの追従が可能かもしれません。
すべての操作はコードで行う、といった覚悟も大事ではありますが、臨機応変にIaCと向き合っていけるとよいですね。

テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!

tkg

2016年入社のインフラエンジニアです。 写真が趣味。防湿庫からはレンズが生え、押入れには機材が生えます。 2D/3DCG方面に触れていた時期もありました。

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら