Terraform小技集
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のほうがよく使ってしまっている
listでfor_eachしたい
for_eachはとても便利だが、実はlistでは回せない。しかし、variableやlocalesでlistを使ってシンプルに表記したい場面はよくある。
その場合は、toset()
を使うといい。
resource "aws_s3_bucket" "example" {
for_each = toset(["bucket1", "bucket2"])
bucket = each.key
# ...
}
ちなみに、each.key
もeach.value
も同じ値になる
環境ごとの切り替え
テスト環境と本番環境で値だけ切り替えたいみたいな使い方をしたいことがある。
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
フォーマッタ
terraformにはフォーマッタが標準であるので、それを使う。そのままだとカレントディレクトリにある*.tf
しか対象にしてくれないので、プロジェクトrootで再帰的に実行する-recursive
をつけると楽。
$ terraform fmt -recursive
また、ciなどでフォーマッタをかけてるかだけを調べたい場合はこうするとチェックだけしてくれる。
$ terraform fmt -recursive -check -diff
構文チェック
terraformの構文が正しいかをおおよそ見てくれる機能もある。
$ terraform validate
先の環境ごとの切り替えと組み合わせることが多いのでこんな感じにしてる(もっといい方法はありそう)
$ echo "testing production" | xargs -n 1 -I{} terraform -chdir=envs/{} validate
また、validate
はinit
済みでないと実行できないが、ciでのinit
はstateとの同期がしんどいので、こうしてる。
$ terraform -chdir=envs/testing init -backend=false
$ terraform -chdir=envs/testing validate
セキュリティチェック
まずい設定をしてしまっていないかをよしなにチェックしてくれるツールが有るので積極的に使いたい。
環境をきれいに保ちたいと思ってる人間なので、dockerを使ってやっている。
$ docker run --rm -it -v "$(pwd):/src" aquasec/tfsec:latest --force-all-dirs --exclude-downloaded-modules /src
ちなみに、docker hubを見るとtfsec/tfsec
というのもあるが、たぶんaquasec/tfsec
を使うのが正解