はじめに
やること
本日もTerraformのお話です。
やることは、Map型の変数でOutputして、別のModuleから参照することです。
前回の記事で、VPCとサブネットを作成しました。
サブネットの情報を別のModuleから参照して、EC2インスタンスを作成してみようと思います。
得られるメリット
モジュールを分けると、どこにどのようなリソースを定義しているかわかりやすくなります。
そしてモジュールで作成したリソースをMap型でOutputできると、別モジュールからKeyで値を取得できます。(あたりまえですが)
また、変数に階層構造をもたせて視覚的にもわかりやすく記述できます。さらに、別モジュールで変数をインポートしてfor_each
などで繰り返し、たとえばマルチAZ構成のEC2をひとつのリソース定義で記述できます。
やってみる
ディレクトリ構成
ディレクトリ構成は以下のようになっています。ハイライトしているところは、今回追加したところです。
{root}/
|
|---[environment]
| |---[dev]
| |---main.tf
| |---provider.tf
|
|---[module]
|---[Computing]
| |---ec2.tf
| |---variable.tf
|
|---[Network]
|---vpc.tf
|---subnet.tf
|---variable.tf
|---output.tf
コード内容
- environment/dev/main.tf
## Networkモジュール
module "network" {
source = "../../module/Network"
sysname = var.param.sysname
env = var.param.env
cidr_block = var.param.cidr_block
zone = var.param.zone
}
## Computingモジュール
module "computing" {
source = "../../module/Computing"
subnets = module.network.subnets
depends_on = [
module.network
]
}
computingモジュールを追加しています。この中にEC2の定義を書いています。
networkモジュールからsubnets
という名前でサブネットの情報をOutputしているので、computingモジュールで使えるように変数に格納しています。(subnets = module.network.subnets
)
- module/Network/output.tf
output "subnets" {
value = (tomap({
"01" = {
"public_subnet" = aws_subnet.public_subnet["01"]
"private_subnet" = aws_subnet.private_subnet["01"]
},
"02" = {
"public_subnet" = aws_subnet.public_subnet["02"]
"private_subnet" = aws_subnet.private_subnet["02"]
}
}))
}
今回のテーマとなるコードです。Map型でOutputするコードとなります。
まず、Output変数(別Moduleから参照されるときに使用する変数)はsubnets
となります。
値(value
)をMap型にするため、Terraformのtomap
関数を使用しています。
Keyは"01"
と"02"
として、それぞれにus-east-1a
とus-east-1c
のパブリックサブネットとプライベートサブネットを変数として組み込んでいます。
- module/Computing/variable.tf
variable "subnets" {}
computingモジュールのvariable.tfでは、networkモジュールがOutputしたsubnets
というMap変数を扱えるようにするため、subnets
変数を宣言しているのみです。
- module/Computing/ec2.tf
resource "aws_instance" "ec2" {
ami = "ami-09d3b3274b6c5d4aa"
subnet_id = var.subnets["02"].public_subnet.id
instance_type = "t2.micro"
}
最低限の設定値のみ記載しています。
注目してほしいところはサブネットの指定です。
Map型であるsubnets
変数のKey"02"
のパブリックサブネットを指定しています。
このように、Keyの指定でどちらのAZに配置するか決めることができます。
実行結果
Map変数のKey"02"
の方である、us-east-1cのパブリックサブネットにEC2がデプロイされました。
番外編(EC2を各AZにfor_eachでデプロイする)
コード内容
- (番外編)module/Computing/ec2.tf (両方のAZに配置する場合)
resource "aws_instance" "ec2_01_and_02" {
for_each = var.subnets
ami = "ami-09d3b3274b6c5d4aa"
subnet_id = each.value.public_subnet.id
instance_type = "t2.micro"
}
Map型の変数がcomputingモジュールで扱えるため、for_each
を使用して両方のAZにEC2をデプロイしてみます。
上のコードの場合、両方のパブリックサブネットに同じEC2がデプロイされます。
実行結果(番外編)
ひとつのresource
ブロックで、2つのEC2が各AZに配置されました。
コメント