マージリクエストでのTerraformインテグレーション
Infrastructure as Code (IaC)の変更に関するコラボレーションでは、コードの変更と予想されるインフラの変更の両方をチェックし、承認する必要があります。GitLabはマージリクエストページを使って、Terraformのコード変更とその期待される効果に関するコラボレーションを支援するソリューションを提供します。これにより、ユーザーはカスタムツールを構築したり、IaCワークフローを合理化するためにサードパーティのソリューションに頼る必要がなくなります。
Terraform Plan情報をマージリクエストに出力します。
GitLab Terraform Reportアーティファクトを使うと、terraform plan
の実行の詳細をマージリクエストウィジェットに直接公開することができ、Terraformが作成、変更、破棄したリソースに関する統計を見ることができます。
Terraformレポートアーティファクトの設定
GitLabは、GitLabが管理するTerraformの状態を使用し、マージリクエストにTerraformの変更を表示するCI/CDテンプレートを通してTerraformとインテグレーションします。ビルド済みのイメージをカスタマイズし、gitlab-terraform
ヘルパーを利用して素早くセットアップすることをお勧めします。
GitLab Terraform Reportアーティファクトを手動で設定するには:
-
簡単にするために、これらのファイルを複数回参照できるように再利用可能な変数をいくつか定義しておきましょう:
variables: PLAN: plan.cache PLAN_JSON: plan.json
-
軽量で柔軟なコマンドライン JSON プロセッサーである
jq
をインストールします。 -
terraform plan
出力から抽出したい情報を解析する、特定のjq
コマンドのエイリアスを作成します:before_script: - apk --no-cache add jq - alias convert_report="jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'"
Bashを使用するディストリビューション(Ubuntuなど)では、alias
ステートメントは非対話モードでは展開されません。convert_report: command not found
というエラーでパイプラインが失敗する場合、スクリプトにshopt
コマンドを追加することで、明示的にエイリアス展開を有効にできます:before_script: - shopt -s expand_aliases - alias convert_report="jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'"
-
terraform plan
およびterraform show
を実行するscript
を定義します。これらのコマンドは出力をパイプし、関連するビットをストア変数PLAN_JSON
に変換します。このJSONは、GitLab Terraformレポートのアーティファクトを作成するために使われます。Terraform レポートは Terraformtfplan.json
ファイルを取得します。収集されたTerraformプランレポートはアーティファクトとしてGitLabにアップロードされ、マージリクエストに表示されます。plan: stage: build script: - terraform plan -out=$PLAN - terraform show --json $PLAN | convert_report > $PLAN_JSON artifacts: reports: terraform: $PLAN_JSON
ビルド済みイメージを使った完全な例については、Example
.gitlab-ci.yml
fileを参照してください。複数のレポーターを表示する例については、
.gitlab-ci.yml
複数のレポーター ファイルを参照してください。 -
パイプラインを実行すると、次のようにマージリクエストのウィジェットが表示されます:
-
ウィジェットの [View Full Log] ボタンを選択すると、パイプラインログにあるプラン出力に直接アクセスできます:
.gitlab-ci.yml
ファイルの例
default:
image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
cache:
key: example-production
paths:
- ${TF_ROOT}/.terraform
before_script:
- cd ${TF_ROOT}
variables:
TF_ROOT: ${CI_PROJECT_DIR}/environments/example/production
TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/example-production
stages:
- prepare
- validate
- build
- deploy
init:
stage: prepare
script:
- gitlab-terraform init
validate:
stage: validate
script:
- gitlab-terraform validate
plan:
stage: build
script:
- gitlab-terraform plan
- gitlab-terraform plan-json
artifacts:
name: plan
paths:
- ${TF_ROOT}/plan.cache
reports:
terraform: ${TF_ROOT}/plan.json
apply:
stage: deploy
environment:
name: production
script:
- gitlab-terraform apply
dependencies:
- plan
when: manual
only:
- master
複数のTerraformプランレポーター
GitLab バージョン 13.2 から、マージリクエストページに複数のレポートを表示できるようになりました。レポートにはartifacts: name:
も表示されます。 以下の設定例を参照してください。
default:
image:
name: registry.gitlab.com/gitlab-org/gitlab-build-images:terraform
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
cache:
paths:
- .terraform
stages:
- build
.terraform-plan-generation:
stage: build
variables:
PLAN: plan.tfplan
JSON_PLAN_FILE: tfplan.json
before_script:
- cd ${TERRAFORM_DIRECTORY}
- terraform --version
- terraform init
- apk --no-cache add jq
script:
- terraform validate
- terraform plan -out=${PLAN}
- terraform show --json ${PLAN} | jq -r '([.resource_changes[]?.change.actions?]|flatten)|{"create":(map(select(.=="create"))|length),"update":(map(select(.=="update"))|length),"delete":(map(select(.=="delete"))|length)}' > ${JSON_PLAN_FILE}
artifacts:
reports:
terraform: ${TERRAFORM_DIRECTORY}/${JSON_PLAN_FILE}
review_plan:
extends: .terraform-plan-generation
variables:
TERRAFORM_DIRECTORY: "review/"
# Review will not include an artifact name
staging_plan:
extends: .terraform-plan-generation
variables:
TERRAFORM_DIRECTORY: "staging/"
artifacts:
name: Staging
production_plan:
extends: .terraform-plan-generation
variables:
TERRAFORM_DIRECTORY: "production/"
artifacts:
name: Production