前書き
やること
本日はTerraformのお話です。
Map型で宣言した変数を、Moduleに渡してみたいと思います。
得られるメリット
Map型の変数を使用することによって階層構造で定義することができ、視覚的にわかりやすくすることができます。
また、Map型で定義した変数をfor_each
で繰り返して、マルチAZ構成のサブネット等が作れます。
リスト型で定義してしまうと、それぞれのAZの情報の数(サブネットの数など)を合わせる必要が出てきますが、Map型であれば必要なくなります。
リスト型だとインデックスが0から始まり、インクリメントをする必要が出てきますが、Map型の場合はKeyで指定するのでインクリメントのズレによるバグも防げます。
リスト型だとインデックスが0から始まるので、片系を”01″、片系を”02″と呼びたいときにずれが発生しますが、Map型なら自由に決められます。
やってみる
ディレクトリ構成
ディレクトリ構成は以下のようになっています。
{root}/
|
|---[environment]
| |---[dev]
| |---main.tf
| |---provider.tf
| |---variable.tf ←Map型変数を定義する。
|
|---[module]
|---[Network]
|---vpc.tf
|---subnet.tf
|---variable.tf
dev/environment
ディレクトリがTerraform実行ディレクトリです。
ここのvariable.tf
にMap型変数でそれぞれのAZの情報を定義します。
コード内容
コードの内容を記載していきます。
- dev/provider.tf
terraform {
required_version = "~> 1.2.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.38.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
TerraformとAWSレジストリのバージョン、AWSのリージョンを指定しています。
- dev/variable.tf
variable "param" {
default = {
sysname = "demo"
env = "dev"
cidr_block = "10.0.0.0/16"
zone = {
"01" = {
az = "us-east-1a"
public_cidr = "10.0.1.0/24"
private_cidr = "10.0.10.0/24"
},
"02" = {
az = "us-east-1c"
public_cidr = "10.0.2.0/24"
private_cidr = "10.0.20.0/24"
}
}
}
}
今回の肝となるコードです。
Map変数名はparam
として、その中にsysname
(システム名)、env
(環境名)、cidr_block
(VPCのCIDR)、zone
(各AZ固有の情報)を定義しています。zone
はMap変数として、Keyを”01″と”02″で分け、それぞれに各AZの情報を定義しました。
- dev/main.tf
module "network" {
source = "../../module/Network"
sysname = var.param.sysname
env = var.param.env
cidr_block = var.param.cidr_block
zone = var.param.zone
}
Map変数のparam
をnetwork
モジュールに渡しています。
Map型の変数のため、var.[変数名].[変数名]
の形で値にアクセスできます。
- module/Network/variable.tf
### module/Network/variable.tf
variable "sysname" {}
variable "env" {}
variable "zone" {}
variable "cidr_block" {}
main.tf
から渡された変数をnetwork
モジュールで扱えるようにするため、network
モジュール内のvariable.tf
でも変数宣言をします。
- module/Network/vpc.tf
### VPC
resource "aws_vpc" "vpc" {
cidr_block = var.cidr_block
tags = {
"Name" = "${var.env}-${var.sysname}-vpc"
}
}
VPCを作成しています。
main.tfから渡された変数に対して、var.[変数名]
でアクセスしています。
- module/Network/subnet.tf
### パブリックサブネット
resource "aws_subnet" "public_subnet" {
for_each = var.zone
vpc_id = aws_vpc.vpc.id
cidr_block = each.value.public_cidr
availability_zone = var.zone[each.key].az
tags = {
"Name" = "${var.env}-${var.sysname}-public-subnet-${each.key}"
}
}
### プライベートサブネット
resource "aws_subnet" "private_subnet" {
for_each = var.zone
vpc_id = aws_vpc.vpc.id
cidr_block = each.value.private_cidr
availability_zone = var.zone[each.key].az
tags = {
"Name" = "${var.env}-${var.sysname}-private-subnet-${each.key}"
}
}
パブリックサブネット×2とプライベートサブネット×2を作っています。
for_each
をMap型変数のzone
で繰り返して、それぞれのサブネットをus-east-1a
とus-east-1c
に作っています。
AZ(us-east-1a
orus-east-1c
)は、var.zone[each.key].az
で取得しています。
tags
のところを見ていただきたいのですが、${each.key}
でKeyを取得しています。us-east-1a
であれば01
、us-east-1c
であれば02
となります。
実行結果
VPC
サブネット
Nameにて、us-east-1a
のサブネットには01
、us-east-1c
のサブネットには02
の名前が振られています。
参考サイト
https://dev.classmethod.jp/articles/terraform-bset-practice-jp/
コメント