Terraformを使ってインフラストラクチャをコード化する際、特定のリソースに対して柔軟に設定を適用したい場合があります。 しかし、全てのインスタンスに同じ設定を適用したいわけではない場合、どのように対処すればよいでしょうか。
課題
例えば、EC2インスタンスのモジュールを作成しているとします。
その中には追加のEBSが必要なインスタンスと、必要無いインスタンスが混在しています。
しかし、モジュールにEBSの設定を含めると全てのインスタンスにEBSが追加されてしまいます。
解決策
これに対する解決策として、Terraformにはdynamicブロックという便利な機能があります。
これを使うと、条件によってリソースのブロックを動的に生成することが可能になります。
TerraformのDynamicブロックとは
dynamicブロックは、Terraformでリソースやモジュールのブロック内にそのブロックのリストを動的に作成するために使用します。 dynamicブロックの内部ではcontentブロックを使用して、ブロックの内容を定義します。
EBSの有無を制御する
EC2インスタンスのモジュールでEBSの追加を制御したい場合、以下のように記述します。
variable "system" {}
variable "env" {}
variable "ami" {}
variable "instance_type" {}
variable "security_group" {}
variable "subnet" {}
variable "key_name" {}
variable "create_ebs" {
default = false
}
variable "ebs_size" {
default = 10
}
resource "aws_instance" "demo" {
ami = var.ami
instance_type = var.instance_type
vpc_security_group_ids = var.security_group
subnet_id = var.subnet
associate_public_ip_address = "true"
key_name = var.key_name
tags = {
Name = "${var.system}-${var.env}"
}
dynamic "ebs_block_device" {
for_each = var.create_ebs ? [1] : []
content {
device_name = "/dev/sdf"
volume_type = "gp2"
volume_size = var.ebs_size
delete_on_termination = true
}
}
}
ここでは、for_each
に条件を指定し、その結果に応じてEBSのブロックを作成するかどうかを制御しています。var.create_ebs
がtrue
の場合、for_each
は[1]
を返し、1つのEBSブロックが作成されます。false
の場合、for_each
は空のリストを返し、EBSブロックは作成されません。
このように、dynamicブロックを利用することで、EBSの有無を柔軟に制御することが可能になります。これにより、同一のモジュールを使用して、EBSの有無が異なるEC2インスタンスを効率的に作成できます。
参考:moduleの呼び出し元
moduleにcreate_ebs = true
を渡すかどうかでEBSの追加を制御していることが分かります。
module "ec2_with_ebs" {
source = "/home/ec2-user/terraform/module/"
system = "demo"
env = "prd"
ami = "ami-xxxx"
instance_type = "t2.micro"
security_group = ["xxxx", "sg-xxxx"]
subnet = "subnet-xxxx"
key_name = "xxxx"
create_ebs = true #ここ!
ebs_size = 20
}
module "ec2_without_ebs" {
source = "/home/ec2-user/terraform/module/"
system = "demo"
env = "stg"
ami = "ami-xxxx"
instance_type = "t2.micro"
security_group = ["sg-xxxx", "sg-xxxx"]
subnet = "subnet-xxxx"
key_name = "xxxx"
}
まとめ
dynamicブロックを利用することで、リソースの設定を動的に制御することが可能なことが分かりました。
これにより同一のモジュールを使用しつつ、インスタンスの特性に応じて設定を変更することが可能になります。
ただし、全てをdynamicで制御するとコードが複雑になってしまうため注意が必要です。
皆様の選択肢の一つとしてお役に立てれば幸いです。