TL;DR
variableブロックにはdefault、type、description、validation、sensitive、nullableを指定できる。typeとvalidationを組み合わせると、期待しない値の代入を防ぐ堅牢な変数を定義できる。
内容
variable ブロックのパラメータ
Terraform の variable ブロックでは、次のパラメータを指定できる。どれも省略できる。
default: 値が渡されなかったときのデフォルト値type: 型description: 説明文validation: 値のルールsensitive: パスワードや API キーのような秘匿性の高い値かどうかnullable:nullを許すかどうか
type による制御
type を指定すると、期待と異なる型の値が代入されるのを防げる。
variable "ebs_storage_size" {
description = "EBS storage size indicated by number."
type = number
}validation による制御
validation ブロックでは、condition に書いた式で値を評価し、結果が false ならエラーにする。エラーメッセージは error_message で指定する。
variable "s3_arn" {
description = "ARN of the S3 bucket to output logs."
type = string
validation {
condition = can(regex("^arn:aws:s3:::", var.s3_arn))
error_message = "s3_arn should start with arn:aws:s3:::"
}
}v1.9 からは、validation の式から他の変数、データリソース、ローカル変数を参照できるようになった。これにより、ある変数の値に応じて別の変数の値を検査できる。
variable "create_fargate_cluster" {
description = "Whether to create a new cluster."
type = bool
default = false
}
variable "fargate_cluster_endpoint" {
description = "Endpoint of the existing cluster to use."
type = string
default = ""
validation {
condition = var.create_fargate_cluster == false ? length(var.fargate_cluster_endpoint) > 0 : true
error_message = "You must specify a value for fargate_cluster_endpoint if create_fargate_cluster is false."
}
}より厳格な制御
object 型の変数では、フィールドごとに validation で値を検査できる。次の例では、インスタンスタイプが t で始まり、プライベート IP が 10.0.10. で始まることを求めている。
variable "sample_ec2_setting" {
type = object({
instance_type = string
private_ip = string
})
validation {
condition = can(regex("^t", var.sample_ec2_setting.instance_type)) && can(regex("^10.0.10.", var.sample_ec2_setting.private_ip))
error_message = "The instance_type must be t type and private_ip must be 10.0.10.x."
}
}object のリストを for_each で回せば、型で決めたパラメータをループの中で使える。
resource "aws_security_group_rule" "sample" {
for_each = { for setting in var.sample_rule_setting : setting.description => setting }
security_group_id = "sg-xxxxxx"
type = each.value.type
from_port = each.value.from_port
to_port = each.value.to_port
protocol = each.value.protocol
cidr_blocks = each.value.cidr_blocks
description = each.value.description
}
variable "sample_rule_setting" {
type = list(object({
type = string
from_port = string
to_port = string
protocol = string
cidr_blocks = list(string)
description = string
}))
}