はじめに
Terraformでインフラ構成管理をしていると同じtfファイルを使いながらも、特定の環境だけに作りたいリソースが出てくることがあります。
例えば開発環境には社内からのアクセスのみ許可する、といった具合にです。
Terraformにはif
のような条件分岐がないものの、count
を使うことで上記のことを実現できます。
ベースとなるtfファイル
以下の3つのtfファイルをベースにして説明します。なお利用したTerraformのバージョンはv0.8.4です。
provider "aws" {}
variable "is_dev" {
default = "0"
}
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"]
}
resource "aws_security_group" "test-sg-for-all" {
name = "test-sg-for-all"
vpc_id = "vpc-xxxxxxxx"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [
"xxx.xxx.xxx.xxx/32"
]
}
tags {
Name = "test-sg-for-all"
}
}
resource "aws_instance" "test-instance" {
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.micro"
subnet_id = "subnet-xxxxxxxx"
security_groups = ["${aws_security_group.test-sg-for-all.id}"]
tags {
Name = "test-instance"
}
}
variables.tf
に定義したis_dev
変数は、開発環境のときは1
で、それ以外のときは0
が指定されているものとします。
開発環境のみに作成するリソースを作る
is_dev
変数をcount
に指定(count = "${var.is_dev}"
)することで、開発環境のみに作成するリソースを作ることができます。
resource "aws_security_group" "test-sg-for-dev" {
count = "${var.is_dev}"
name = "test-sg-for-dev"
vpc_id = "vpc-xxxxxxxx"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [
"xxx.xxx.xxx.xxx/32"
]
}
}
開発環境のみに作成するリソースと通常のリソースを混ぜて他のリソースで使う
上記で作成した開発環境用のtest-sg-for-dev
と全環境で作成されるtest-sg-for-all
を使ったEC2インスタンスを作成するサンプルが以下になります。
resource "aws_instance" "test-instance" {
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.micro"
subnet_id = "subnet-xxxxxxxx"
security_groups = ["${
compact(
concat(
aws_security_group.test-sg-for-dev.*.id,
list(aws_security_group.test-sg-for-all.id)
)
)
}"]
tags {
Name = "test-instance"
}
}
ポイントは以下の点です。
-
count
を使って作成したリソースをaws_security_group.test-sg-for-dev.*.id
のようにListで取得する。 - 全環境用のリソースは
list()
を使い、Listにする。 - それら2つのListを
concat
を使い結合する。 -
is_dev=0
のときaws_security_group.test-sg-for-dev.*.id
が空文字になるのをcompact
で取り除く。
まとめ
Terraformのcount
を使ってif
のような条件分岐を実装することができました。
TerraformのInterpolation SyntaxにはListを扱う様々なSyntaxが用意されているので、これらを利用してある程度は条件分岐を作ることができます。