Terraformには変数の条件によって使い分けをする場合はmapを使用するとめちゃくちゃ便利だということをブログしてなかったので今回お話をしましょう。
他にも関数によるインスタンス台数が増える場合もcount.indexを使ってインスタンス数を指定するだけや、Nameタグの値にインデックスを含めるにはformat関数など併用して、${}の中では算術演算子が使えるなど、さらにコードを短くすることも可能です。
今回はせっかくなのでそれらを応用して構築してみました。
■Map/Function
https://www.terraform.io/docs/configuration/variables.html
https://www.terraform.io/docs/configuration/interpolation.html
■かつてのaws_ec2.tf
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | ##EC2(adachin-web01) resource "aws_instance" "adachin-web01" {   ami                     = "${var.ami}"   instance_type           = "${var.instance_type}"   disable_api_termination = false   key_name                = "adachi_aws"   vpc_security_group_ids  = ["${aws_security_group.adachin-web.id}"]   subnet_id               = "${aws_subnet.public-a.id}"   root_block_device = {     device_name = "/dev/sdf"     volume_type = "gp2"     volume_size = "${var.volume_size}"   }   tags {     Name = "adachin-web01"   } } ##EIP(adachin-web01) resource "aws_eip" "adachin-web01" {   instance = "${aws_instance.adachin-web01.id}"   vpc      = true } ##EC2(adachin-web02) resource "aws_instance" "adachin-web02" {   ami                     = "${var.ami}"   instance_type           = "${var.instance_type}"   disable_api_termination = false   key_name                = "adachi_aws"   vpc_security_group_ids  = ["${aws_security_group.adachin-web.id}"]   subnet_id               = "${aws_subnet.public-a.id}"   root_block_device = {     device_name = "/dev/sdf"     volume_type = "gp2"     volume_size = "${var.volume_size}"   }   tags {     Name = "adachin-web02"   } } ##EIP(adachin-web02) resource "aws_eip" "adachin-web02" {   instance = "${aws_instance.adachin-web02.id}"   vpc      = true } | 
このようにインスタンス数が増えるとじゃんじゃんコードも増えるわけです。
■aws_ec2.tf
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | resource "aws_instance" "adachin-web" {   count                   = 2   ami                     = "${var.ami}"   instance_type           = "${var.instance_type}"   disable_api_termination = false   key_name                = "${aws_key_pair.adachin.id}"   vpc_security_group_ids  = ["${aws_security_group.adachin.id}"]   subnet_id               = "${lookup(var.subnets_id, count.index%3)}"   root_block_device = {     volume_type = "gp2"     volume_size = "${var.volume_size}"   }   tags {     Name = "${format("adachin-webn%02d", count.index + 1)}"   } } resource "aws_eip" "adachin-web" {   count    = 1   instance = "${element(aws_instance.adachin-web.*.id, count.index)}"   vpc      = true   tags {     Name = "${format("adachin-web%02d", count.index + 1)}"   } } resource "aws_key_pair" "adachin" {   key_name   = "adachin"   public_key = "ssh-rsa xxx" } | 
■ aws_variables.tf
| 1 2 3 4 5 6 7 | variable "subnets_id" {   default = {     "0" = "subnet-xxxxx"     "1" = "subnet-xxxxx"     "2" = "subnet-xxxxx"   } } | 
・Nameタグの数値をインスタンス毎に変更する
(例)adachin-web01,adachin-web02
まず上記に書きましたcount.indexを使うことで、リソースのインデックスを取得することができます。インデックスは0から始まるので今回2台構築となると+1で値を指定しましょう。さらにタグの値にインデックスを含めるにはformat関数を利用して文字列を整形します。
・毎回異なるAZ(サブネット)に配置する
(例)subent_id
ここでmapを使い、サブネットIDを変数化します。aws_variables.tfではa,c,dとサブネットが3つ指定しています。これをlookup関数によりmapの値を取得します。ちなみにmapではなく、element関数とsplit関数を使って取得する方法もあるそうです。(めんどくさい)
| 1 | subnet_id = "${element(split(",", var.subnets_id), count.index%length(split(",", var.subnets_id)))}" | 
・インスタンス毎にEIPを設定する
こちらもcount.indexを使ってインスタンスIDを一つずつ取り出しています。
■まとめ
便利か!!コードは短いほうがメンテしやすいのでぜひ使いこなしましょう!!!ただmapに依存してしまうとメンテしづらいのと、可読性が下がるというデメリットを感じましたね。使う用途によって利用するのがベストだと感じました。

 
													 
													 
													
0件のコメント