terraform の tfstate の管理に GitLab を使ってみた

2022.07.11

背景

terraform の tfstate の管理ですが、基本的には aws では s3 + dynamodb, gcp であれば gcs を採用することが多いです。

ただ、採用するにあたり、下記の問題があります。

  • tfstate の管理に関する情報をどこで管理するか
  • tfstate の管理リソースの作成をどこで管理するか
  • 他のプロジェクトでも相乗りしたいときにどうするか

terraform cloud に任せるとしても、そのアカウント管理を誰が管理するかといった決めるポイントは多いです。

もし、GitLab で project を管理しているのであれば tfstate も GitLab で管理することを検討してはいかがでしょうか。

やってみた

0. terraform の backend の設定を書く

GitLab は http backend で提供しているため、 backend には http を使うことを明示します。

細かいパラメータは GitLab が提供している gitlab-terraform 経由で埋めるため、書く必要はありません。

https://www.terraform.io/language/settings/backends/http

terraform {
  backend "http" {
  }
}

1. .gitlab-ci.yaml を用意する

https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml

公式にサンプルがあるのでこちらをもとに利用します。

terraform のセットアップは公式の template を include して extends するだけで簡単に利用できます。

GitLab Runner にも CircleCI の orbs や GitHub Actions の marketplace のようなものがあったんですね。

variables に TF_STATE_NAME, terraform を実行する directory の場所が違う場合は TF_ROOT を指定します。

---
include:
  - template: Terraform/Base.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml

variables:
  TF_STATE_NAME: development

stages:
  - validate
  - test
  - build
  - deploy

fmt:
  extends: .terraform:fmt
  needs: []

test:
  stage: test
  scripts:
    - gitlab-terraform version

validate:
  extends: .terraform:validate
  needs: []

build:
  extends: .terraform:build

deploy:
  extends: .terraform:deploy
  dependencies:
    - build
  environment:
    name: $TF_STATE_NAME
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

知らなかったのですが、 GitLab Runner は手動で承認して進める manual 機能があります。

デフォルトのテンプレートでは有効になっていますが、今回は外すために rules の設定を上書きしました。

terraform の実行位置を変えたい場合は TF_ROOT の環境変数を設定します。

内部としては gitlab-terraform を使っています。

テンプレートの terraform は 1.1.9 と 2022.07.11 時点では少し古いものを使っていました。

$ gitlab-terraform version
Terraform v1.1.9
on linux_amd64
Your version of Terraform is out of date! The latest version
is 1.2.4. You can update by downloading from https://www.terraform.io/downloads.html

特定のバージョンの terraform を使いたい場合は registry.gitlab.com/gitlab-org/terraform-images/releases/terraform のイメージタグで指定します。

左メニューの インフラ > Terraform から作成されていることが確認できました。

2. ローカルから操作する

CI/CD で完結することが望ましいですが、実際には バージョンアップや設定の齟齬で直接 tfstate を操作する必要が出てくるケースがあります。

その時、GitLab 上の tfstate から接続情報を取得するための方法が確認できます。

実際には下記のようなコマンドで設定できます。

terraform init \
    -backend-config="address=https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/terraform/state/development" \
    -backend-config="lock_address=https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/terraform/state/development/lock" \
    -backend-config="unlock_address=https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/terraform/state/development/lock" \
    -backend-config="username=${GITLAB_USER_NAME}" \
    -backend-config="password=${GITLAB_ACCESS_TOKEN}" \
    -backend-config="lock_method=POST" \
    -backend-config="unlock_method=DELETE" \
    -backend-config="retry_wait_min=5"

参考