Terraform CloudのWorkspaceにtfvarsファイルの内容を渡す

2023.02.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

「Terraform Cloudでtfvarsファイルの値を渡すには、どうすればいいんだろう」

terraform apply -vars-file terraform.tfvarsの様にtfvarsファイルを指定して、Terraformコマンドを実行している場合があります。

Terraform Cloudに移行しようとしたときに、このvars-fileどうやって渡せばいいんだろうと思いました。

結論

結論から書くと、Terraform CloudのWorkspaceの変数で渡します。

Terraform CloudではWorkspaceに対して、変数を設定することができます。

この変数にtfvarsの内容を記載することで、terraform apply -vars-file terraform.tfvars相当の操作ができます。

変数にはカテゴリ(Terraform VarialbesEnvironment Variables)がありますが、以下の様に使い分けると良いと思います。

  • 基本的にはTerraform Variablesを使う
  • stateファイルに残したくない情報は、Environment Varialbesを使う。変数名のKeyはTF_VAR_nameとする

また、複数のWorkspaceで使い回す変数に関しては、Variables Setを使用すると楽です。

Manage Variable Sets in Terraform Cloud | Terraform | HashiCorp Developer

やってみた

サンプルコード

以下のディレクトリ構成でTerraformを運用しているとします。 環境差異の表現は、tfvarsにて行なっています。 (この構成が推奨ということではなく、一例として。)

├── ./envs
│   ├── ./envs/prod.tfvars
│   ├── ./envs/stg.tfvars
│   └── ./envs/test.tfvars
└── ./main.tf

main.tf

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

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 4.49.0"
    }
  }
}

variable "instance_type" {
  description = "Type of EC2 instance to use"
  default     = "t2.micro"
  type        = string
}

data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = var.instance_type
}

./envs/stg.tfvars

instance_type      = "t3.micro"

コマンド実行する際は以下のように、tfvarsを渡すものとします。

$ terraform plan -var-file stg.tfvars

Terraform CloudのWorkspaceに変数をセット

環境ごと(prod/stg/test)にTerraform CloudのWorkspaceを作っているとします。

Terraform Cloudを使って複数環境(本番/STG)にAWSリソースをデプロイしてみる | DevelopersIO

サンプルコードの状態で、Planを実行してみます。

デフォルト値として、設定しているt2.microが設定されています。

tfvarsの内容であるt3.microに変更します。

tfvarsファイルをTerraform Cloud側で指定することはできないため、変数にtfvarsファイルの内容を設定します。

Variables -> Workspace variables -> Add variableの順に選択して、以下のように変数を設定します。

設定ができたところで、再度Runを実行して結果を見てみましょう。

t2.microだった箇所がWorkspaceの変数で設定したt3.microに変わっていることが確認できました。

Terraform CloudをTerraformで管理する

「Terraform CloudのWorkspaceに環境変数をGUIで一つ一つ設定するのは辛い」と思った方もいるかもしれません。

その場合は、Terraform Cloud自体をTerraformで管理するのがお勧めです。 tfvarsファイルの内容をこれまで通り、コードで管理できます。

例えば以下のように定義することで、Terraform CloudのWorkspacetest-workspaceに対して変数key:instance_type value:t3.microを設定できます。

tfc/main.tf

provider "tfe" {
  hostname = "app.terraform.io"
}

resource "tfe_organization" "main" {
  name  = "my-org-name"
  email = "admin@company.com"
}

resource "tfe_workspace" "test" {
  name         = "test-workspace"
  organization = tfe_organization.main.name
}

resource "tfe_variable" "aws_instance_type" {
  key          = "instance_type"
  value        = "t3.micro"
  category     = "terraform"
  workspace_id = tfe_workspace.test.id
}

Docs overview | hashicorp/tfe | Terraform Registry

おわりに

tfvarsで環境差異を表現している場合の、Terraform Cloudでの実現方法でした。

Googleが公開しているTerraform使用するためのベストプラクティス環境のようなディレクトリ構成にして、そもそもtfvarsに書く必要があるのかを精査するのも良いかと思います。

  • 環境ごとにディレクトリを作成
  • 環境ごとに共通する部分はmodule化、環境差異の部分だけ変数化
  • 環境ディレクトリ配下のmain.tfで環境差異を表現
    • 今回例に挙げた、instance_typeなど

それでもtfvarsで書く必要があるものは、Terraform Cloudの変数にtfc providerを使って設定するのが運用負荷が低そうです。

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

あわせて読みたい記事

参考