はじめに
複数環境のリモートバックエンドにTerraform Cloudを使う場合、
下図のように環境ごとのbackend.tf
へOrganization名とWorkspace名(もしくは変数参照)を書くと以下図のように環境の数だけbackend.tf
ができる場合があるかと思います。
.
├── env
│ ├── dev
│ │ └── backend.tf ← 開発環境のOrganization名とWorkspace名
│ ├── prod
│ │ └── backend.tf ← 本番環境のOrganization名とWorkspace名
│ └── stg
│ └── backend.tf ← ステージング環境のOrganization名とWorkspace名
└── main.tf
今回はGitHub Actionsでのデプロイ時に環境変数からデプロイ先環境のOrganizationとWorkspaceを注入し、backend.tf
が1枚で済むCI/CDをGitHub Actionsで構成する方法の1つをご紹介します。(他にも方法はいろいろあると思います)
前提
- CI/CD:GitHub Actions
- Terraform CloudのExecutionMode:Remote
ざっくりやり方
以下2つの環境変数を使います。
TF_WORKSPACE
TF_CLOUD_ORGANIZATION: Specifies the name of the organization. Terraform reads this variable when organization is omitted from the cloud block`. If both are specified, the configuration takes precedence.
出典:https://developer.hashicorp.com/terraform/cli/cloud/settings
TF_CLOUD_ORGANIZATION
TF_WORKSPACE: Specifies the name of a single HCP Terraform workspace. Terraform reads this when workspaces is omitted from the cloud block. HCP Terraform does not create a new workspace from this variable. The workspace must already exist in the specified organization. You can set TF_WORKSPACE if the cloud block uses tags. However, you must include the value of TF_WORKSPACE in the set of tags. This variable also selects the workspace in your local environment. Refer to TF_WORKSPACE for details.
出典:https://developer.hashicorp.com/terraform/cli/cloud/settings
それぞれ、Cloud
ブロックのorganization
とworkspaces.name
にて指定が無い場合にTF_CLOUD_ORGANIZATION
、TF_WORKSPACE
から値を取得する挙動をします。今回はこれを利用します。
以下のようなイメージです。
terraform {
cloud {
organization = "<organizationの名前>" # → 指定が無い場合、TF_CLOUD_ORGANIZATIONを使用
workspaces {
name = "<workspaceの名前>" # → 指定が無い場合、TF_WORKSPACEを使用
}
}
}
※なお、環境変数とCloud
ブロック両方に指定がある場合はCloud
ブロックを優先する動きをします。
構成例
元々のファイル構成から以下図のように変更しました。
.
├── env
│ ├── dev
- │ │ └── backend.tf
│ ├── prod
- │ │ └── backend.tf
│ └── stg
- │ └── backend.tf
├── main.tf
+ └── backend.tf
新規作成したbackend.tf
は以下内容だけにします。
terraform {
cloud {
hostname = "app.terraform.io"
}
}
あとは、ワークフローのYAML内にて以下順で処理をさせるだけ!
- 環境変数を設定
-
terraform init
(環境変数で指定したOrganizationとWorkspaceを認識する) -
terraform apply
(2で認識したバックエンドを対象にApplyを行う)
name: Deploy Terraform
on:
push:
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
env:
TF_CLOUD_ORGANIZATION: <デプロイしたい環境のOrganization名>
TF_WORKSPACE: <デプロイしたい環境のWorkspace名>
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Terraform CLI
uses: hashicorp/setup-terraform@v3
with:
cli_config_credentials_token: <Terraform CloudのAPIトークン>
- name: Terraform Init (Terraform Cloud backend)
run: terraform init # ここで環境変数に設定したOrganizationとWorkspaceを認識してくれる
- name: Terraform Apply
run: terraform apply -auto-approve -no-color
後は
- <デプロイしたい環境のOrganization名>
- <デプロイしたい環境のWorkspace名>
- <Terraform CloudのAPIトークン
このあたりにGitHub ActionsのSecretsやVariablesから取得した値を動的に代入するようするようワークフローを組めば、デプロイ用YAMLも1枚で済みますね!
参考
↑公式ドキュメントでは本記事で扱った環境変数以外にも利用可能な環境変数がリストアップされています。