Terraform テンプレートレシピ

このページのレシピをパイプラインに追加することで、Terraformインテグレーションをカスタマイズできます。

自分のTerraform設定を共有したい場合は、このページにレシピを貢献することを検討してください。

terraform destroy ジョブを有効にします。

以下のスニペットを.gitlab-ci.yml に追加してください:

include:
  - template: Terraform.latest.gitlab-ci.yml

destroy:
  extends: .terraform:destroy

destroy ジョブはcleanup ステージの一部です。deploy ジョブと同様に、destroy ジョブは常にmanual であり、デフォルトブランチには関連付けられません。

destroy ジョブを GitLab 環境に接続するには:

include:
  - template: Terraform.latest.gitlab-ci.yml

deploy:
  environment:
    name: $TF_STATE_NAME
    action: start
    on_stop: destroy

destroy:
  extends: .terraform:destroy
  environment:
    name: $TF_STATE_NAME
    action: stop

この設定では、destroy ジョブは常に作成されます。しかし、特定の条件が満たされたときだけdestroy ジョブを作成したい場合もあるでしょう。

以下の設定は、destroy ジョブを作成し、破壊計画を実行し、TF_DESTROY が真の場合のみdeploy ジョブを省略します:

include:
  - template: Terraform.latest.gitlab-ci.yml

build:
  rules:
    - if: $TF_DESTROY == "true"
      variables:
        TF_CLI_ARGS_plan: "-destroy"
    - when: on_success

deploy:
  environment:
    name: $TF_STATE_NAME
    action: start
    on_stop: destroy
  rules:
    - if: $TF_DESTROY == "true"
      when: never
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $TF_AUTO_DEPLOY == "true"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual

destroy:
  extends: .terraform:destroy
  dependencies:
    - build
  variables:
    TF_CLI_ARGS_destroy: "${TF_PLAN_CACHE}"
  environment:
    name: $TF_STATE_NAME
    action: stop
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $TF_DESTROY == "true"
      when: manual

この設定には既知のイシューがあります。destroy ジョブがdeploy ジョブと同じパイプラインにない場合、on_stop 環境アクションは動作しません。

ジョブ内でカスタムコマンドterraform を実行します。

カスタムterraform コマンドを実行するジョブを定義するには、gitlab-terraform ラッパーをどのジョブでも使用できます:

include:
  - template: Terraform.latest.gitlab-ci.yml

state-list:
  stage: validate # you can use any stage, just make sure to define it
  script: gitlab-terraform state list

gitlab-terraform コマンドはterraform コマンドをセットアップし、与えられた引数で実行します。

Terraformの状態別リソースグループでこのジョブを実行するには、ジョブにresource_group を割り当てます:

include:
  - template: Terraform.latest.gitlab-ci.yml

state-list:
  stage: validate # you can use any stage, just make sure to define it
  resource_group: ${TF_STATE_NAME}
  script: gitlab-terraform state list

ジョブにカスタムデバッグツールを追加

Terraformテンプレートジョブで使われるデフォルトのイメージには、最小限のツールしか含まれていません。しかし、デバッグ用のツールを追加したい場合もあるでしょう。

ツールを追加するには

  1. ジョブまたはパイプラインのbefore_script にツールをインストールします。
  2. script またはafter_script ブロックでツールを使用します。
    • script ブロックを使用する場合は、必ずテンプレート・ジョブ・コマンドを再追加してください。

例えば、以下のスニペットでは、パイプライン内のすべてのジョブに対して、before_scriptbashjq をインストールしています:

include:
  - template: Terraform.latest.gitlab-ci.yml

default:
  before_script: apk add --update bash jq

builddeploy のジョブのみに追加するには、これらのジョブに直接追加してください:

include:
  - template: Terraform.latest.gitlab-ci.yml

build:
  before_script: apk add --update bash jq

deploy:
  before_script: apk add --update bash jq

カスタムコンテナイメージの追加

デバッグツールやシンプルなインストールでは、カスタムのデバッグツールをジョブに追加してください。ツールが複雑であったり、キャッシュが有効であったりする場合は、gitlab-terraform のイメージをベースにカスタムコンテナイメージを作成します。作成したカスタムイメージは、以降のTerraformジョブで使用できます。

カスタムコンテナイメージを定義するには:

  1. カスタムツールで新しいDockerfile を定義します。たとえば、.gitlab/ci/Dockerfilebashjq をインストールします:

    FROM registry.gitlab.com/gitlab-org/terraform-images/stable:latest
       
    RUN apk add --update bash jq
    
  2. 新しいジョブで、Dockerfile が変更されるたびにイメージを構築するprepare ステージを定義します。
    • ビルドされたイメージはGitLabコンテナレジストリにプッシュされます。イメージがマージリクエストからビルドされたのか、デフォルトブランチからビルドされたのかを示すタグが適用されます。
  3. builddeploy などの Terraform ジョブでイメージを使用します。
    • Terraform用の入力を生成するようなセットアップコマンドを実行するために、あなたのイメージを特別なbefore_script 設定と組み合わせることができます。

例えば、完全に機能するパイプライン設定は次のようになります:

include:
  - template: Terraform.latest.gitlab-ci.yml

variables:
  IMAGE_TAG: latest

workflow:
  rules:
    - if: $CI_MERGE_REQUEST_IID
      changes:
        - .gitlab/ci/Dockerfile
      variables:
        IMAGE_TAG: ${CI_COMMIT_REF_SLUG}
    - when: always

stages:
  - prepare
  - validate
  - test
  - build
  - deploy
  - cleanup

prepare:image:
  needs: []
  stage: prepare
  image:
    name: gcr.io/kaniko-project/executor:v1.9.0-debug
    entrypoint: [""]
  rules:
    # Tag with the commit SHA if we're in an MR
    - if: $CI_MERGE_REQUEST_IID
      changes:
        - .gitlab/ci/Dockerfile
      variables:
        DOCKER_TAG: $CI_COMMIT_REF_SLUG
    # If we're on our main branch, tag with "latest"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      changes:
        - .gitlab/ci/Dockerfile
      variables:
        DOCKER_TAG: latest
  before_script:
    # Authenticate to the docker registry and dependency proxy
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
  script:
    - /kaniko/executor
      --context "${CI_PROJECT_DIR}/.gitlab/ci"
      --cache=true
      --dockerfile "${CI_PROJECT_DIR}/.gitlab/ci/Dockerfile"
      --destination "${CI_REGISTRY_IMAGE}:${DOCKER_TAG}"

build:
  image: ${CI_REGISTRY_IMAGE}:${IMAGE_TAG}

deploy:
  image: ${CI_REGISTRY_IMAGE}:${IMAGE_TAG}

リポジトリの例については、GitLab Terraformテンプレート利用プロジェクトを参照してください。

デフォルトブランチからの自動デプロイ

TF_AUTO_DEPLOY 変数を"true" に設定すると、デフォルトブランチから自動的にデプロイできます。それ以外の値は"false" として解釈されます。

variables:
  TF_AUTO_DEPLOY: "true"

include:
  - template: Terraform.latest.gitlab-ci.yml

Terraformを複数の環境にデプロイします。

複数の環境でパイプラインを実行することができます。

stages:
  - validate
  - test
  - build
  - deploy

include:
  - template: Terraform/Base.latest.gitlab-ci.yml
  - template: Jobs/SAST-IaC.latest.gitlab-ci.yml

variables:
  # x prevents TF_STATE_NAME from beeing empty for non environment jobs like validate
  # wait for https://gitlab.com/groups/gitlab-org/-/epics/7437 to use variable defaults
  TF_STATE_NAME: x${CI_ENVIRONMENT_NAME}
  TF_CLI_ARGS_plan: "-var-file=vars/${CI_ENVIRONMENT_NAME}.tfvars"

fmt:
  extends: .terraform:fmt
validate:
  extends: .terraform:validate

plan dev:
  extends: .terraform:build
  environment:
    name: dev
plan prod:
  extends: .terraform:build
  environment:
    name: prod

apply dev:
  extends: .terraform:deploy
  environment:
    name: dev

apply prod:
  extends: .terraform:deploy
  environment:
    name: prod

この設定はGitLabの基本テンプレートから変更されています。