Terraformで複数環境をデプロイするチュートリアル(tfvarsファイル編)

Terraformで複数環境をデプロイするチュートリアル(tfvarsファイル編)

2025.09.03

前回ローカルモジュールを使った複数環境へのデプロイのチュートリアルを作ってみました。

今回はtfvarsファイルを使ったパターンを作ってみました

https://dev.classmethod.jp/articles/terraform-multi-env-deploy-local-module/

このパターンはAWS公式ドキュメントのTerraform AWS プロバイダーを使用するためのベストプラクティスでも紹介されています。併せて確認するとよいと思います。

tfvarsファイルとは

Terraformではvariableブロックを使って、入力変数を定義できます。

以下では、Variables instance_typeを宣言して、Resourceaws_instanceで利用しています。

main.tf
variable "instance_type" {
  description = "The EC2 instance's type."
  type        = string
  default     = "t2.micro"
}

resource "aws_instance" "app_server" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type

  vpc_security_group_ids = [module.vpc.default_security_group_id]
  subnet_id              = module.vpc.private_subnets[0]
}

Variablesは何も値を指定しないと、defaultで設定した値がセットされます。

tfvarsファイルなし・環境変数なし
terraform plan # instance_typeは"t2.micro"になる

環境変数やオプションでVariablesに値を渡すことができます。

環境変数
export TF_VAR_instance_type=t2.large
terraform plan # instance_typeは"t2.large"になる
コマンドライン
terraform plan -var="instance_type=t2.medium" # instance_typeは"t2.medium"になる

Variablesは変数定義ファイルで渡すこともできます。この変数定義ファイルを、本記事ではtfvarsファイルと呼びます。

env/stg/terraform.tfvars
instance_type=t3.small
tfvarsファイル利用
terraform plan -var-file="envs/stg/terraform.tfvars"

今回紹介するのは、tfvarsファイルを使って環境の差異を表現する方法です。

Variablesの詳細は(優先順位や自動読み込み等)については、以下の公式ドキュメントを確認ください。

https://developer.hashicorp.com/terraform/language/values/variables

前提

冒頭のブログと同様です。

ハンズオン

最終的には以下のディレクトリ構成になります。

.
├── envs
│   ├── prod
│   │   └── terraform.tfvars
│   └── stg
│       └── terraform.tfvars
├── main.tf
├── outputs.tf
├── terraform.tf
└── variables.tf

以降はこの構成になるプロセスを説明します。

ハンズオン用ファイルの用意

冒頭のブログを参考にハンズオン用ファイルを用意します。

tfvarsファイルの作成

環境ごとにtfvarsファイル格納用のディレクトリを作成します。

mkdir -p envs/prod
mkdir -p envs/stg

以下のファイルをそれぞれ作成します。

tfvarsファイルにて環境差異を表現します。

今回はinstance_nameinstance_typeを環境ごとに設定する想定で、ファイルを作成します。

envs/prod/terraform.tfvars
instance_name = "prod-server"
instance_type = "t3.small"
envs/stg/terraform.tfvars
instance_name = "stg-server"
instance_type = "t3.micro"

バックエンド設定ファイルの用意

tfvarsファイルでは、全環境で同じディレクトリでTerraformを実行します。

この場合、デフォルトではステートファイルが同じ場所に同じ名前で作成されてしまいます。

「PROD用のステートファイルをSTG環境の設定で上書きしてしまう」といったことが起きます。

そのため、バックエンド設定を環境ごとに用意する必要があります。

まずは、ルートディレクトリにbackend.tfを作成します。

デフォルトでlocalバックエンドが使用されますが、-backend-configオプションでバックエンドを分けるために明示的に指定する必要があります。

backend.tf
terraform {
  backend "local" {}
}

環境ディレクトリにそれぞれバックエンド設定用ファイルを作成します。

envs/prod/backend.config
path = "prod.tfstate"

envs/stg/backend.config
path = "stg.tfstate"

デフォルトでは、ルートディレクトリにterraform.tfstateという名前でステートファイルが作成されます。

環境ごとに、PRODだったらprod.tfstate STGだったらstg.tfstateという名前でファイルを作成するように指定しました。

https://developer.hashicorp.com/terraform/language/backend/local

動作確認: Terraformの実行

実際に2環境をデプロイしてみます。

以下のコマンドでPROD環境をデプロイします。

PROD環境
terraform init -backend-config="envs/prod/backend.config"
terraform plan -var-file="envs/prod/terraform.tfvars"
terraform apply -var-file="envs/prod/terraform.tfvars"

続いてSTG環境です。terraform initでバックエンド切り替え時に、-reconfigureオプションが必要なことに注意してください。

STG環境
terraform init -reconfigure --backend-config="envs/stg/backend.config"
terraform plan -var-file="envs/stg/terraform.tfvars"
terraform apply -var-file="envs/stg/terraform.tfvars"

2つの環境へのデプロイが成功し、ステートファイルがそれぞれ作成できていることを確認できました。

ls | grep tfstate
出力結果
prod.tfstate
stg.tfstate

クリーンアップ

最後に以下のコマンドで作成したリソースを削除します。

terraform init -reconfigure --backend-config="envs/prod/backend.config"
terraform destroy -var-file="envs/prod/terraform.tfvars"
terraform init -reconfigure --backend-config="envs/stg/backend.config"
terraform destroy -var-file="envs/stg/terraform.tfvars"

おまけ: S3 バックエンドを使っている場合のbackend.config

今回はベースとしたチュートリアルの都合上、localバックエンドを前提にしました。

S3バックエンドを使うパターンも多いかと思うので、軽く触れます。

backend.tfは以下のようにS3に変更します。

backend.tf
terraform {
-  backend "local" {}
+  backend "s3" {}
}

backend.configは、S3バックエンドの引数に置き換えます。

envs/prod/backend.config
- path = "prod.tfstate"
+ bucket = "prod-mybucket"
+ key    = "path/to/my/key"
+ region = "us-east-1"
envs/stg/backend.config
- path = "stg.tfstate"
+ bucket = "stg-mybucket"
+ key    = "path/to/my/key"
+ region = "us-east-1"

https://developer.hashicorp.com/terraform/language/backend/s3

おわりに

tfvarsファイルを使った環境分離についてでした。

ローカルモジュールパターンと比較するとステップ数が少ないです。

モジュール分離について悩まずに済むのも良い点ですね。

一方、環境切り替えやコマンドの実行については、ローカルモジュールパターンの方がシンプルです。

https://dev.classmethod.jp/articles/terraform-multi-env-deploy-local-module/

一長一短ありますが、個人的にはtfvarsファイルを使う方法が好きです。

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.