Open6

Terraform の細かい Tips

snakasnaka

Renovate でバージョン管理できるように terraform ブロックを記述する

terraform {
  required_version = "1.6.1"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.31.0"
    }
  }
}

Renovate がセットアップされたリポジトリにおいて、terraform のコードでこのように記述しておくと、 Terraform のバージョン (required_version = "1.6.1" の箇所) と Provider のバージョン ( version = "5.31.0" の箇所 ) を Renovate で自動的に識別してくれて、新しいバージョンがリリースされたときに、更新の Pull Request を作ってくれる。

Renovateによる更新の例

  required_providers {
    aws = {
      source  = "hashicorp/aws"
-      version = "5.31.0"
+      version = "5.33.0"
    }
  }
  cloud {

https://developer.hashicorp.com/terraform/language/providers/requirements

あと、忘れがちだけど .terraform.hcl.lock はリポジトリで管理すること。

https://developer.hashicorp.com/terraform/language/files/dependency-lock

snakasnaka

Makefile でコマンド実行できるようにしておくと便利

root module を分割すると、provider や module のバージョンアップ後に terraform init を複数箇所で実行するようなケースがあり、地味に面倒です。
そのようなケースでは Makefile を作っておくと便利。

例えば、以下のようなコードで environments/dev, environments/stg, environments/prd の3つの環境で terraform init を実行することができる。

LCYAN=\033[1;36m
NC=\033[0m

.PHONY: init_all

# dev, stg, prd 環境それぞれで terraform init を実行する
init_all:
	@for env in common dev stg prd; do \
		( \
			cd environments/$$env; \
			echo "$(LCYAN)> Run \`terraform init\` in $$(pwd)$(NC)"; \
			terraform init; \
		); \
	done

こうしておくと、以下を実行するだけで済む

make init_all

terraform init 以外にもいろいろ応用できるので、Makefile でインフラ関連のタスクを管理するのは個人的におすすめ。

snakasnaka

リソースの管理元を特定できるように Tag を付与する

Terraform のコードをライフサイクル・コンテキストごとに細分化していると、あるリソースがどこで管理しているものかが分からなくなってくる。それを補うために Tag として管理元の workspace などを識別できるようにしておく。

AWS Provider の場合は以下のように default_tag として root module で設定しておくと、ほぼ全てのリソースにタグが付与される。

provider "aws" {
  region = "ap-northeast-1"

  default_tags {
    tags = {
      Env                = var.env
      TerraformWorkspace = "hoge-${var.env}"
    }
  }
}
snakasnaka

現在の workspace 名は terraform.workspace で参照できる

前述のコードは以下のようにも書ける

provider "aws" {
  region = "ap-northeast-1"

  default_tags {
    tags = {
      Env                = var.env
      TerraformWorkspace = terraform.workspace
    }
  }
}
snakasnaka

asdf を活用したいときは -chdir オプションより cd コマンドを使う

asdf は terraform ブロックに記述されている required_version の内容に応じて適切な terraform のバージョンを利用するようになっているが、 コマンド実行時のディレクトリを起点として認識しているようで、 -chdir オプションを利用した場合、適切なバージョンに切り替わらない。

そのため、前述の Makefile でも

terraform -chdir=environments/$$env init

ではなく、 -chdir は使わずに cd でディレクトリを移動して terraform コマンドを実行している。

cd environments/$$env; \
terraform init