Terraformには、内部で変数を定義し、外部から変数を渡すことが可能です。
変数の定義
input変数の定義は、variable
ブロックで定義します。
書き方:
variable "<変数名>" {
# ...
}
- <変数名>は以下の文字列以外、任意の文字列が使用可能です。
- source
- version
- providers
- count
- for_each
- lifecycle
- depends_on
- locals
input変数使用例
terraform applyを実行するための準備をし、以下の設定ファイルを用意します。
# image_name変数の定義。"image_name"は変数名
# 変数のデータ型はstring
# デフォルト値は"debian-cloud/debian-9"
variable "image_name" {
type = string
default = "debian-cloud/debian-9"
description = "the image name"
}
provider "google" {
project = "test-project"
region = "asia-northeast1"
zone = "asia-northeast1-a"
}
resource "google_compute_instance" "vm_instance" {
name = "terraform-instance"
machine_type = "f1-micro"
boot_disk {
initialize_params {
image = var.image_name # 変数の呼び出し
}
}
network_interface {
network = "default"
access_config {
}
}
}
コマンドで変数を代入して、terraform apply
を実行:
※他に代入する方法もあります、後程ご紹介します。
terraform apply -var="image_name=centos-cloud/centos-7"
これで、centos-7のGCEが作成されます。
変数のデータ型
Terraformは以下のデータ型の変数を定義可能
- 単純なデータ型
string
:文字列number
:数値bool
:True/False
- 複雑なデータ型
list(<TYPE>)
:配列- 例:
list(string)
- 例:
set(<TYPE>)
:map(<TYPE>)
:object({<ATTR NAME> = <TYPE>, ... })
:辞書型(key-value形式のデータ)- 例:
object({foo = "hello", bar = "world"})
- key-valueが改行で記述する場合、
,
は省略可能
- 例:
tuple([<TYPE>, ...])
:
変数の呼び出し
モジュール(tfファイル)内で、変数を定義すると、定義した変数が呼び出し可能です。
使用時はvar.<変数名>
で変数を呼び出します。
例:
resource "google_compute_instance" "vm_instance" {
name = "terraform-instance"
machine_type = "f1-micro"
boot_disk {
initialize_params {
image = var.image_name # 変数の呼び出し
}
}
network_interface {
network = "default"
access_config {
}
}
}
変数のデフォルト値(option)
変数の定義で、変数のデフォルト値を設定することが可能です。
デフォルト値は、変数が外部からinputされなかった場合使用される値です。
例:
variable "image_name" {
type = string
default = "debian-cloud/debian-9" # 変数imange_nameのデフォルト値は"debian-cloud/debian-9"
description = "the image name"
}
変数の注釈(option)
変数の定義で、注釈を入れることが可能です。
variableブロック内に、description
を使って、記述します。また、変数の注釈はなくても問題ありません。
例:
variable "image_name" {
type = string
default = "debian-cloud/debian-9"
description = "the image name" # 注釈
}
変数チェック(option)
変数の定義で、変数値のチェックを定義することも可能です。
variableブロック内に、validation
を使って、記述します。
- 定義内容は以下2つです。
- condition:ルール。
- 条件合致の場合、trueを返します。
- 条件満たさないの場合、falseを返します。同時に、tfチェックがエラーになります。
- error_message:ルールに満たせなかった場合のエラーメッセージ
- conditionがfalseの場合の出力内容
- condition:ルール。
例:
variable "image_name" {
type = string
description = "the image name"
# 変数チェック
validation {
# 条件:image_nameの長さが4桁以上、かつ最初の7桁が"debian-"であること
condition = length(var.image_name) > 7 && substr(var.image_name, 0, 7) == "debian-"
error_message = "The image_name value must be a valid name, starting with \"debian-\"." # ここのエスケープにご注意
}
}
変数チェックの使用条件
This is an experimental language feature that currently requires an explicit opt-in using the experiment keyword variable_validation:
変数チェックはデフォルトでは使用不可です。使用するには、terraformブロックにて、以下の内容を記述する必要があります。
terraform {
experiments = [variable_validation]
}
can()とregex():正規表現の使用
can()
evaluates the given expression and returns a boolean value indicating whether the expression produced a result without any errors.
can()
は、()
内の処理がエラーが返したらfalse、正常終了したらtrueが返すfunctionです。
regex()
は、正規表現を使用ためのfunctionです。
例:
variable "image_name" {
type = string
description = "the image name"
# 変数チェック
validation {
# 正規表現で変数チェックを行う
condition = can(regex("debian-", var.image_name))
error_message = "The image_name value must be a valid name, starting with \"debian-\"." # ここのエスケープにご注意
}
}
変数の代入方法
This section does not apply to child modules, where values for input variables are instead assigned in the configuration of their parent module, as described in Modules.
上記引用の通り、変数のinputはrootモジュールのみに行えるので、注意していください。
- 変数の値をroot モジュールに入れる場合、以下の方法があります
-var
オプションで個別指定.tfvars
ファイルを使って一括導入-var-file
オプションで指定- 固定ファイル名を指定
- 環境変数で導入
- *In a Terraform Cloud workspace
-varオプションで個別指定
terraform plan
やterraform apply
コマンドの実行時に指定します。
例:
# image_nameの値をcentos-cloud/centos-7に指定
terraform apply -var="image_name=centos-cloud/centos-7"
# image_name_listの値を["centos-cloud/centos-7","centos-cloud/centos-8"]に指定
terraform apply -var='image_name_list=["centos-cloud/centos-7","centos-cloud/centos-8"]'
# image_name_mapの値を{"centos7":"centos-cloud/centos-7","centos8":"centos-cloud/centos-8"}に指定
terraform apply -var='image_name_map={"centos7":"centos-cloud/centos-7","centos8":"centos-cloud/centos-8"}'
.tfvarsファイルを使って一括導入
ファイルの拡張子が.tfvars
か.tfvars.json
のファイルが変数定義用ファイルとなります。
基本的に、terraform plan
やterraform apply
コマンドの実行時に-var-file
オプションでファイルを指定します。
例:
terraform apply -var-file="test.tfvars"
test.tfvars
ファイルの中身:
# image_nameの変数値、object型
image_name = {
centos = "centos-cloud/centos-7"
debian = "debian-cloud/debian-9"
}
# availability_zone_namesの変数値、list型
availability_zone_names = [
"asia-northeast1-a",
"asia-northeast1-b",
]
terraformの設定ファイルの中身:
# 変数の定義:object型
variable "image_name" {
type = object({
centos = string
debian = string
})
default = {
centos = "centos-cloud/centos-8"
debian = "debian-cloud/debian-10"
}
description = "the image name"
}
# 変数の定義:list型
variable "availability_zone_names" {
type = list(string)
default = ["asia-northeast1-a"]
description = "description"
}
provider "google" {
project = "test-project"
region = "asia-northeast1"
zone = "asia-northeast1-a"
}
resource "google_compute_instance" "vm_instance" {
name = "terraform-instance"
machine_type = "f1-micro"
zone = var.availability_zone_names[0] # 変数の呼び出し
boot_disk {
initialize_params {
image = var.image_name.centos # 変数の呼び出し
}
}
network_interface {
network = "default"
access_config {
}
}
}
resource "google_compute_instance" "vm_instance_test" {
name = "terraform-instance-test"
machine_type = "f1-micro"
zone = var.availability_zone_names[1] # 変数の呼び出し
boot_disk {
initialize_params {
image = var.image_name.debian # 変数の呼び出し
}
}
network_interface {
network = "default"
access_config {
}
}
}
また、terraformは自動的に以下のファイル名のファイルをロードするようになっています。
terraform.tfvars
またはterraform.tfvars.json
- 任意の拡張子が
.auto.tfvars
または.auto.tfvars.json
のファイル
Files whose names end with .json are parsed instead as JSON objects, with the root object properties corresponding to variable names
拡張子が.jsonで終わるファイルは、json形式で書く必要があります。
環境変数で導入
環境変数で導入する場合、環境変数の変数名はTF_VAR_<Terraform変数名>
の形式になります。
例えば、image_name変数に値を渡す場合、環境変数名はTF_VAR_image_name
にすればいいです。
使用例:
# 環境変数を定義
export TF_VAR_image_name=centos-cloud/centos-7
# terraform planを実行
terraform plan
...
複雑なデータ型の環境変数
上記例の通り、環境変数で定義する場合、string型の値は特に''
や""
なしでも問題ありませんでした。
これはシンプルなデータ型(string
,number
,bool
)は全部同じです。
ただ、複雑なデータ型(list
,set
,map
,object
,tuple
)の場合は''
や""
が必要です。
この場合、値は.tfvars
のファイル内容として解析しますので、エスケープについて注意が必要です。
例:
export TF_VAR_availability_zone_names='["asia-northeast1-a","asia-northeast1-b"]'
For readability, and to avoid the need to worry about shell escaping, we recommend always setting complex variable values via variable definitions files.
エスケープなどで意図しない動作を避けるために、.tfvars
ファイルを使用するのを推奨されています。
コメント