はじめに
- Terraformの勉強記録です
- 本稿ではTerraformで複数azに跨るサブネットを一気に作る手順を記します
- 複数リソースのループはfor_eachを使用しています
- 誤りの訂正・より良い方法のご助言、どしどしコメント頂ければ幸いです
Terraform 実行環境
- AWS Cloud9
- Amazon Linux2
- t2.micro
- Cloud9を使う理由
- 標準でTerraformが備わっているため
作成環境の構成
アウトライン
- プロバイダー・locals変数
- VPC
- サブネット
- インターネットゲートウェイ
- ルートテーブル
- NATゲートウェイ
1. プロバイダー・locals変数
- 東京リージョンを指定
variables.tf
locals {
name = "terraform"
region = "ap-northeast-1"
}
- Nameタグに使う文字列など、複数のresourceで共通して使う値をlocals変数に格納
variables.tf
provider "aws" {
region = local.region
}
2. VPC
-
vpc_cidr
の値にしたがってVPCを構築
variables.tf
variable "vpc_cidr" {
type = string
default = "10.1.0.0/16"
}
vpc.tf
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
instance_tenancy = "default"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${local.name}-vpc"
}
}
3. サブネット
- 3つのAvailability Zoneそれぞれにパブリック・プライベートサブネットを作成
- プライベート・パブリックサブネットそれぞれの設定情報を持つ変数を宣言
- for_eachで呼び出すため、map(any)型で情報を格納
variables.tf
variable "subnets" {
type = map(any)
default = {
private_subnets = {
private-1a = {
name = "private-1a",
cidr = "10.1.10.0/24",
az = "ap-northeast-1a"
},
private-1c = {
name = "private-1c",
cidr = "10.1.11.0/24",
az = "ap-northeast-1c"
},
private-1d = {
name = "private-1d",
cidr = "10.1.12.0/24",
az = "ap-northeast-1d"
},
},
public_subnets = {
public-1a = {
name = "public-1a"
cidr = "10.1.100.0/24"
az = "ap-northeast-1a"
},
public-1c = {
name = "public-1c"
cidr = "10.1.101.0/24"
az = "ap-northeast-1c"
},
public-1d = {
name = "public-1d"
cidr = "10.1.102.0/24"
az = "ap-northeast-1d"
}
}
}
}
- サブネットの作成
- for_eachで回す
-
each.value.hoge
で欲しい情報にアクセス
subnet.tf
resource "aws_subnet" "private" {
for_each = var.subnets.private_subnets
vpc_id = aws_vpc.main.id
cidr_block = each.value.cidr
availability_zone = each.value.az
tags = {
Name = "${local.name}-${each.value.name}"
}
}
resource "aws_subnet" "public" {
for_each = var.subnets.public_subnets
vpc_id = aws_vpc.main.id
cidr_block = each.value.cidr
availability_zone = each.value.az
tags = {
Name = "${local.name}-${each.value.name}"
}
}
4. インターネットゲートウェイ
- VPCのidと関連付け
gateway.tf
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.name}-igw"
}
}
5. ルートテーブル
- 各サブネット分作成
route_table.tf
# create
resource "aws_route_table" "private" {
for_each = var.subnets.private_subnets
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.name}-${each.value.name}-rt"
}
}
resource "aws_route_table" "public" {
for_each = var.subnets.public_subnets
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.name}-${each.value.name}-rt"
}
}
- サブネットと関連付ける
- サブネットもルートテーブルも同一のキーで生成されているため、同じように書ける
route_table.tf
# association
resource "aws_route_table_association" "private" {
for_each = var.subnets.private_subnets
subnet_id = aws_subnet.private[each.key].id
route_table_id = aws_route_table.private[each.key].id
}
resource "aws_route_table_association" "public" {
for_each = var.subnets.public_subnets
subnet_id = aws_subnet.public[each.key].id
route_table_id = aws_route_table.public[each.key].id
}
- パブリックサブネットはインターネットゲートウェイとも関連付ける
route_table.tf
# associate with gateway
resource "aws_route" "igw" {
for_each = var.subnets.public_subnets
route_table_id = aws_route_table.public[each.key].id
gateway_id = aws_internet_gateway.main.id
destination_cidr_block = "0.0.0.0/0"
}
6. NATゲートウェイ
- 一工夫必要
-
Elastic IPの作成
- NATゲートウェイに割り当てるもの
- パブリックサブネット分、作成
resource "aws_eip" "nat_gateway" { for_each = var.subnets.public_subnets vpc = true tags = { Name = "${local.name}-${each.value.name}-ngw-eip" } }
-
NATゲートウェイの作成
- 関連付けるサブネット・EIPを指定
- (publicサブネットに配置するが、関連付ける対象的に
private
と命名)
resource "aws_nat_gateway" "private" { for_each = var.subnets.public_subnets allocation_id = aws_eip.nat_gateway[each.key].id subnet_id = aws_subnet.public[each.key].id tags = { Name = "${local.name}-${each.value.name}-ngw" } depends_on = [aws_internet_gateway.main] # internet_gateway作成後に作成 }
-
Route Tableの関連付け
- private subnetのルートテーブルにNATゲートウェイへのルートを追加したい
- route_tableは
var.private_subnets
のkey、nat_gatewayはvar.public_subnets
のkeyで生成されている(ややこしい) -
zipmap
をうまく使って一気に作る
resource "aws_route" "ngw" { for_each = zipmap(keys(var.subnets.public_subnets), keys(var.subnets.private_subnets)) route_table_id = aws_route_table.private[each.value].id nat_gateway_id = aws_nat_gateway.private[each.key].id destination_cidr_block = "0.0.0.0/0" }
-
完成
おわりに
- 無事、複数azに跨るサブネットを一気に作ることができました
- ネタがあれば引き続きTerraformの検証記事を書いていく予定です