Open6

Terraform小技集

kaminchukaminchu

Terraformのバージョンを切り替える

プロジェクトごとに別バージョンのterraformを使いたくなるので、ツールで対応する

tfenvの場合

$ tfenv list-remote # 対応してるバージョンを確認
$ tfenv install <version>
$ echo <version> > .terraform-version

.terraform-versionをgit等で共有するとメンバーとバージョンを揃えられる

asdfの場合
asdfはプラグインでterraformを使えるようにする感じなので追加しておく

$ asdf plugin-add terraform https://github.com/asdf-community/asdf-hashicorp.git
$ asdf list all terraform # 対応してるバージョンを確認
$ asdf install terraform <version>
$ asdf local terraform <version> 

.tool-versionsをgit等で共有するとメンバーとバージョンを揃えられる

個人的にはasdfのほうが好きだけど、なんだかんだでtfenvのほうがよく使ってしまっている

kaminchukaminchu

listでfor_eachしたい

for_eachはとても便利だが、実はlistでは回せない。しかし、variableやlocalesでlistを使ってシンプルに表記したい場面はよくある。

その場合は、toset()を使うといい。

resource "aws_s3_bucket" "example" {
  for_each = toset(["bucket1", "bucket2"])
  bucket = each.key
  # ...
}

ちなみに、each.keyeach.valueも同じ値になる

kaminchukaminchu

環境ごとの切り替え

テスト環境と本番環境で値だけ切り替えたいみたいな使い方をしたいことがある。

workspaceという機能があるがどうにも使いにくいので、ディレクトリを分けて作る感じでやってる。

envs/
  testing/
    main.tf
    variables.tf
  production/
    main.tf
    variables.tf
modules/
  server/
    main.tf
    variables.tf

envs/testing/main.tf

module "server" {
  source                  = "../../modules/server"
  # ...
}

この場合、-chdirオプションを使うといい感じに使える

$ terraform -chdir=envs/testing init 
$ terraform -chdir=envs/testing apply
kaminchukaminchu

フォーマッタ

terraformにはフォーマッタが標準であるので、それを使う。そのままだとカレントディレクトリにある*.tfしか対象にしてくれないので、プロジェクトrootで再帰的に実行する-recursiveをつけると楽。

$ terraform fmt -recursive

また、ciなどでフォーマッタをかけてるかだけを調べたい場合はこうするとチェックだけしてくれる。

$ terraform fmt -recursive -check -diff
kaminchukaminchu

構文チェック

terraformの構文が正しいかをおおよそ見てくれる機能もある。

$ terraform  validate

先の環境ごとの切り替えと組み合わせることが多いのでこんな感じにしてる(もっといい方法はありそう)

$ echo "testing production" | xargs -n 1 -I{} terraform -chdir=envs/{} validate

また、validateinit済みでないと実行できないが、ciでのinitはstateとの同期がしんどいので、こうしてる。

$ terraform -chdir=envs/testing init -backend=false
$ terraform -chdir=envs/testing validate
kaminchukaminchu

セキュリティチェック

まずい設定をしてしまっていないかをよしなにチェックしてくれるツールが有るので積極的に使いたい。
https://github.com/aquasecurity/tfsec

環境をきれいに保ちたいと思ってる人間なので、dockerを使ってやっている。

$ docker run --rm -it -v "$(pwd):/src" aquasec/tfsec:latest --force-all-dirs --exclude-downloaded-modules /src

ちなみに、docker hubを見るとtfsec/tfsecというのもあるが、たぶんaquasec/tfsecを使うのが正解