変数の利用

この講座では、Terraformにおける変数の使い方について学びます。

  • locals(ローカル変数)の定義と参照
  • variable(入力変数)の定義と使用
  • 変数のデフォルト値と型指定
  • terraform.tfvarsによる値の設定
  • output(出力値)の定義と使用

Terraformにおける変数の流れを以下の図に示します。

flowchart LR
    subgraph 入力
        V["variable<br>外部から値を受け取る"]
        TF["terraform.tfvars<br>ファイルで値を設定"]
    end
    subgraph コード内
        L["locals<br>コード内で定義"]
        R["resource ブロック<br>var.xxx / local.xxx で参照"]
    end
    subgraph 出力
        O["output<br>作成結果を表示"]
    end
    V --> R
    TF --> V
    L --> R
    R --> O

1. locals

locals は、Terraformコードの内部だけで使う「変数」を定義するものです。 変数とは、特定の値を入れる「箱」のようなものです。何度も使う値に名前をつけて定義しておくことで、コード内で使い回すことができます。

1.1 記載方法

定義

まずは locals の定義方法です。下記は、stage という locals 変数に、test という値を初期値として設定した場合の例です。

locals {
  stage = "test"
}

このように、locals と書いたブロックの中に、変数を定義します。 また、複数の locals 変数を定義したい場合は、改行して複数定義することもできます。

locals {
  stage = "test"
  app-name = "app1"
}

利用方法

locals を利用する方法を説明します。

例えば下記は、VPCを定義する記載ですが、タグの中にNameタグとして値を設定しています。local.変数名 と記載することで、変数の値を使用できます。この場合、Nameタグに「test」という文字列が設定されます。

resource "aws_vpc" "vpc" {
  tags = {
    Name = local.stage
  }
}

また、文字列と結合する形で利用することもできます。例えば下記は、stage の値と、「-vpc」という文字列を組み合わせています。この場合「test-vpc」という名前が、Nameタグとして利用されます。

resource "aws_vpc" "vpc" {
  tags = {
    Name = "${local.stage}-vpc"
  }
}

1.2 実行してみる

locals を利用したコードを実行してみます。

コードの記載

まずはサンプルコードです。下記は、stage という locals 変数に「test」という値を定義し、それを利用してVPCのNameタグを指定しています。この場合、Nameタグには「test-vpc」という文字列が設定されます。

この内容を、main.tf に記載してください。

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

# Localsの定義
locals {
  stage = "test"
}

# 利用: local.名前 で参照する
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "${local.stage}-vpc"
  }
}

リソースの作成

その後、terraform apply を実行し、結果を反映させます。

terraform apply

実行が完了したら、AWSのリソースを確認します。

VPCのダッシュボードを開き、VPCの一覧から、test-vpc というVPCが作成されていることを確認します。これにより、locals を利用したNameタグの設定が正しく行われていることがわかります。

リソースの削除

確認が終わったら、terraform destroy コマンドで、リソースを削除しておきます。

terraform destroy

2. Variables

variables について解説します。

2.1 記載方法

locals がコード内で計算や再利用をするための「ローカル変数」であるのに対し、variables は外部から値を注入するための「入力変数」です。環境(開発、本番など)ごとに異なる値を設定したい場合などによく利用されます。

基本的な記載方法

まずは最もシンプルな定義方法です。variable ブロックに変数名を記述します。

variable "stage" {}

このように中身を空にして定義した場合、terraform apply などの実行時に「この変数の値は何ですか?」と対話形式で入力を求められます。

variables では、変数の役割や型を明確にするために、以下の属性を付与することが一般的です。

説明(description)

description は変数の説明を記載します。チーム開発などで、何のための変数かを伝えるのに役立ちます。

variable "stage" {
  description = "環境名(例: dev, test, prod)"
}

変数の形(type)

type は、 変数の型(stringnumberboollist など)を指定します。意図しないデータが入るのを防ぎます。

例えば、下記は文字列を表す string を指定した場合です。この場合、"" で囲んだ「文字列」を指定できます。

variable "stage" {
  type        = string
}

typenumber を指定した場合、1や2などの数値のみが指定できます。

variable "stage" {
  type        = number
}

typebool を指定した場合は、true または false の真偽で値を表します。

variable "stage" {
  type        = bool
}

最後に、typelist を指定すると、["開発", "テスト", "本番"] のように、複数の値を結合して利用できます。list(string)list(number) のように、list の中にさらに型を指定します。

variable "stage" {
  type        = list(string)
}

初期値(default)

default は変数の初期値を設定します。これを設定すると、実行時に入力を求められなくなります。

variable "stage" {
  default     = "test"
}

定義した変数は、var.変数名 という形で利用します。 以前のVPCの例で、locals の代わりに variables を使ってみましょう。

💡 ポイント
variables だけで全部できるのでは?」と思われるかもしれません。確かに技術的には variables で全てをカバーすることも可能です。しかし、ファイル内部で完結する定義(プレフィックスや計算結果など)まで variables にしてしまうと、外部から渡す必要のない値まで外部に露出してしまい、コードが冗長になります。

使い分けの基準は外部から値を変えたいかどうかです。
- variables:環境(開発/本番)ごとに変えたい値や、外部から渡したい値に使う
- locals:そのファイル内で完結する固定値や計算結果に使い、コードを簡潔に保つ
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "${var.stage}-vpc"
  }
}

ファイルでの初期値定義

また、専用のファイル(terraform.tfvars)で外から指定することも可能です。 これにより、コード自体(main.tf)を書き換えずに、設定値だけを切り替えることができます。

stage = "prod"
📝 terraform.tfvars の役割
terraform.tfvars は、環境ごとやユーザごとに切り替えたい値をまとめて定義するための専用ファイルです。パスワードなどの機密情報だけでなく、環境名、CIDRブロック、ドメイン名など、環境やユーザによって異なる値全般をここに集約します。terraform.tfvars で値を指定できるのは variables.tf に宣言されている変数だけ で、宣言されていない名前を書いてもエラーになります。つまり、variables.tf が「受け取れる変数の一覧(宣言)」、terraform.tfvars が「実際に渡す値(代入)」という役割分担になっています。

2.2 実際に使ってみる

それでは、実際にコードを書いて挙動を確認してみましょう。

標準的な使い方

まず、main.tf に以下のようなコードを記載します。

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

# default値なしで定義
variable "stage" {
  description = "環境名"
  type        = string
}

resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "${var.stage}-vpc"
  }
}

このコードでは、variables として stage を定義しています。description として「環境名」という説明、type として文字列を表す string を指定しています。default の値は特に指定していません。

この状態で terraform apply を実行してみます。

terraform apply

そうすると、Enter a value という文言により、var.stage の値を入力するように促されます。

$ terraform apply
var.stage
  環境名

  Enter a value:

ここで、今回は開発環境を表す develop を入力してみましょう。

すると、develop-vpc という名前でVPCが作成されます。

⚠️ 変数に日本語を入力するとエラーになる場合
変数の値は半角英数字とハイフン(-)やアンダースコア(_)のみを使用することを推奨します。

defaultを指定

default を指定した場合の挙動を確認します。下記のように、default として "test" という文言を指定してみます。

variable "stage" {
  description = "環境名"
  type        = string
  default     = "test"
}

この状態で、terraform apply を実行します。

terraform apply

すると、VPCの名前が test-vpc として作成されます。

外部ファイルから値の指定

最後に、外部ファイルから値を上書きしてみます。 同じディレクトリに terraform.tfvars というファイルを作成します。Visual Studio Codeのエクスプローラーで作業フォルダを右クリックし、「新しいファイル」を選択してterraform.tfvarsという名前で作成してください。

terraform-basic-handson
├── main.tf
└── terraform.tfvars  ← このファイルを作成

作成したファイルに以下の内容を記述して保存します。

stage = "prod"

画像で表すとこのようになります。

この状態で terraform apply を実行します。

terraform apply
⚠️ terraform.tfvarsの値が反映されない場合
ファイル名が正確にterraform.tfvarsになっているか確認してください(terraform.tfvar(sなし)やvariables.tfvarsなどは自動で読み込まれません)。
また、ファイルがmain.tfと同じディレクトリに存在するか確認してください。

main.tf には default = "test" と書かれていますが、terraform.tfvars の値が優先され、prod-vpc として作成される計画が表示されます。

リソースの削除

確認ができたら、作成されたリソースを削除しておきましょう。

terraform destroy

3. Outputs

outputs について解説します。

3.1 記載方法

variables が「入力」を受け取るためのものであるのに対し、outputs は実行結果を「出力」するためのものです。

標準的な使い方

Terraformでリソースを作成した後、そのリソースのIDやIPアドレスなどの情報をコンソールに表示したり、他のシステムから参照できるようにするために利用します。プログラミングにおける「関数の戻り値(return)」のようなものとイメージすると分かりやすいでしょう。

基本的な定義方法は以下の通りです。output ブロックに名前を付け、value に出力したい値を記述します。

output "vpc_id" {
  value = aws_vpc.vpc.id
}

この例では、作成されたVPCのID(id)を、vpc_id という名前で出力するよう定義しています。

説明(description)

outputs でも、descriptionsensitive といった属性を利用できます。

description には、何を出力しているかの説明を記載します。

output "vpc_id" {
  value       = aws_vpc.vpc.id
  description = "作成されたVPCのID"
}

情報の保護(sensitive)

sensitivetrue に設定すると、パスワードや秘密鍵など、コンソール画面に表示したくない機密情報を隠すことができます(ログには (sensitive value) と表示されます)。ログに出力せず、その後別の機能やアプリケーションに渡したい時に利用できます。

output "db_password" {
  value     = "super_secret_password"
  sensitive = true
}

3.2 実際に使ってみる

それでは、実際にコードを書いて挙動を確認してみましょう。

コードの作成

前回の variables のハンズオンで使用した main.tf に、VPC IDを出力する設定を追加します。

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

resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "${var.stage}-vpc"
  }
}

output "vpc_id" {
  value       = aws_vpc.vpc.id
  description = "The ID of the VPC"
}

値の出力

この状態で、terraform apply を実行してみましょう

terraform apply

実行が完了すると、下記のようにVPCのIDが出力されます。なお、IDの実際の値は環境により異なります。

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

vpc_id = "vpc-076323da6ecf841b7"

実際に作成されたVPCのIDと一致していることを確認してみます。

このように、AWSの管理画面(マネジメントコンソール)にログインして確認しなくても、作成されたリソースのIDなどの重要な情報をすぐに知ることができます。

コマンドによる出力

また、apply の実行直後だけでなく、いつでも以下のコマンドで出力値を確認することができます。

terraform output

そうすると、以下のように output に指定した内容が全て出力されます。

vpc_id = "vpc-076323da6ecf841b7"

特定の値だけ出力

特定の output 値だけを確認したい場合は、名前を指定します。

terraform output vpc_id

実際の値のみが出力されます。

"vpc-076323da6ecf841b7"

リソースの削除

確認ができたら、リソースを削除しておきましょう。

terraform destroy

4. まとめ

この講座では、Terraformの変数について学びました。

  • variable(入力変数)で値を外部から受け取ることができる
  • typeで型を、defaultでデフォルト値を、descriptionで説明を設定できる
  • locals(ローカル変数)でコード内の計算結果や共通値を定義できる
  • outputで作成されたリソースの情報を出力できる
  • sensitive = trueで機密情報をログに表示しないようにできる
  • terraform outputコマンドで出力値を確認できる