Terraform CLI -vars-fileオプションでファイル指定時もルートディレクトリのterraform.tfvarsは読み込まれる

2024.06.11

Terraform利用時に環境差異をtfvarsで表現するパターンがあると思います。

具体的には、以下のようなものです。

ディレクトリ構成

.
├── envs
│   ├── dev
│   │   └── terraform.tfvars
│   ├── prod
│   │   └── terraform.tfvars
│   └── test
│       └── terraform.tfvars
├── main.tf
└── variables.tf

terraformコマンド実行

terraform plan -var-file="./dev/terraform.tfvars"

環境共通の値をtfvarsで渡したいときがあります。

環境ごとのterraform.tfvars(例: envs/dev/terraform.tfvars)に書けば実現できますが、少し冗長です。

そんなときは、ルートディレクトリに共通の値を記載したterraform.tfvarsを配置すればよいです。

-var-fileオプション使用時でも、ルートディレクトリのterraform.tfvarsは読み込まれます。

.
├── envs
│   ├── dev
│   │   └── terraform.tfvars
│   ├── prod
│   │   └── terraform.tfvars
│   └── test
│       └── terraform.tfvars
├── main.tf
├── terraform.tfvars # 追加
└── variables.tf

実際にやってみます。

やってみた

ディレクトリ構成

.
├── envs
│   ├── dev
│   │   └── terraform.tfvars
│   ├── prod
│   │   └── terraform.tfvars
│   └── test
│       └── terraform.tfvars
├── main.tf
├── terraform.tfvars
└── variables.tf

tfファイル

terraform.tfvarsの動作確認のため、シンプルにvariablesの値を出力するだけです。

main.tf
output "system_name" {
  value = var.system_name
}
output "env" {
  value = var.env
}

variablesは、環境共通値としてsystem_name、環境固有の値としてenvを定義します。

ルートディレクトリのterraform.tfvarsが読み込まれることを確認するために、system_nameにはデフォルト値をあえて指定しないでおきます。

variables.tf
variable "system_name" {
  type = string
}
variable "env" {
  type    = string
  default = "none"
}

ルートディレクトリにある環境共通のterraform.tfvarsは以下のように、system_nameの値をセットします。

terraform.tfvars
system_name = "sato"

環境固有のterraform.tfvarsについてです。

それぞれenvに環境名をセットします。

envs/dev/terraform.tfvars
env = "dev"

Terraform実行

vars-fileを指定して、terraformを実行してみます。

$ terraform plan -var-file="./envs/dev/terraform.tfvars"
Changes to Outputs:
  + system_name = "sato"
  + env         = "dev"

envは、"./envs/dev/terraform.tfvars"system_nameterraform.tfvarsの値が使われていることが確認できました。

おまけ: Terraform Variable読み込みの優先順位

この記事では、terraform.tfvarsファイルを使って、変数を渡す方法使いました。

変数はterraform.tfvarsファイル以外にも、環境変数やファイルterraform.tfvars.json *auto.tfvarsで渡すことができます。

tfvarsの読み込みの優先順位は以下のドキュメントに記載があります。

Input Variables - Configuration Language | Terraform | HashiCorp Developer

-var-fileオプションの優先度が一番高いです。

例えば、今回のコードのルートディレクトリのterraform.tfvarsでVariableenvを設定しても、-var-fileオプションで設定したenvの値が優先されます。

terraform.tfvars
system_name = "sato"
env = "sato" # 追加
$ terraform plan -var-file="./dev/terraform.tfvars"

Changes to Outputs:
  + system_name = "sato"
  + env         = "dev"

おわりに

先日、Best practices for using the Terraform AWS Providerが公開されました。

こちらでは、tfvarsで環境差異をディレクトリ構成が紹介されていて、ルートディレクトリにもterraform.tfvarsと環境ディレクトリそれぞれにterraform.tfvarsがあるパターンでした。

この方法を使ったことが無かったので、気になりブログにしてみました。

以上、AWS事業本部の佐藤(@chari7311)でした。