背景
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"