TerraformでAWSのsubnetを作る
はじめに
TerraformでのAWSのvpcとsubnet部分の作り方をまとめておく。
間違いなどあれば、指摘していただけると幸いだ。
ちなみにIPやcidr_blockなどは実際に作成したものとは違うものを本記事のサンプルコード内で使っている。
ディレクトリ構成
勉強会で作成したインフラ全般のアーキテクチャは下記のようになっていて、
今回はココ、と書いてある所の作り方についてお話しする。
├── terraform │ ├── environment │ │ └── production │ │ ├── locals.tf │ │ └── main.tf │ └── modules │ ├── alb │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf │ ├── alb_listener │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf │ ├── ecs │ │ ├── container_definitions.json │ │ ├── execution-assume-role.json │ │ ├── execution-policy.json │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf │ ├── private_subnet <=======ココ │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf │ ├── public_subnet <=======ココ │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf │ ├── route53 │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf │ ├── security_group │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf │ └── vpc <==============ココ │ ├── main.tf │ ├── output.tf │ └── variables.tf
実装方針
上の構成の通り、 基本的に各機能ごとにmoduleを作り、
main.tf => moduleの機能実装 variables.tf => 外から入れたい変数etc output.tf => 他のmoduleなどから呼び出したい当moduleの変数etc
といった形で定義している。
vpcの実装
- vpc/main.tf
resource "aws_vpc" "main" {
cidr_block = var.cidr_block
tags = {
Name = "hogehoge-${var.env}-main-vpc"
}
}
- vpc/variables.tf
variable "env" {
type = string
description = "Environment"
}
variable "cidr_block" {
type = string
description = "VPCのCIDR Block"
}
- vpc/output.tf
output "id" {
value = aws_vpc.main.id
}
output "cidr_block" {
value = aws_vpc.main.cidr_block
}
public_subnetの実装
- public_subnet/main.tf
resource "aws_subnet" "main" {
vpc_id = var.vpc_id
count = length(var.availability_zones)
cidr_block = element(var.cidr_blocks, count.index)
availability_zone = element(var.availability_zones, count.index)
tags = {
Name = "hogehoge-${var.env}-public-subnet-${element(var.availability_zones, count.index)}"
}
}
resource "aws_route_table" "main" {
vpc_id = var.vpc_id
}
resource "aws_route" "main" {
route_table_id = aws_route_table.main.id
gateway_id = var.internet_gateway_id
destination_cidr_block = "0.0.0.0/0"
}
resource "aws_route_table_association" "main" {
count = length(var.availability_zones)
subnet_id = aws_subnet.main[count.index].id
route_table_id = aws_route_table.main.id
}
resource "aws_eip" "nat_gateway" {
vpc = true
count = length(aws_subnet.main)
}
resource "aws_nat_gateway" "main" {
count = length(aws_subnet.main)
allocation_id = aws_eip.nat_gateway[count.index].id
subnet_id = aws_subnet.main[count.index].id
}
- public_subnet/varaibles.tf
variable "env" {
type = string
}
variable "availability_zones" {
type = list(string)
}
variable "cidr_blocks" {
type = list(string)
}
variable "vpc_id" {
type = string
}
variable "internet_gateway_id" {
type = string
}
- public_subnet/output.tf
output "ids" {
value = aws_subnet.main.*.id
}
output "nat_gateway_ids" {
value = aws_nat_gateway.main.*.id
}
main.tf内で、countを指定することで、指定した数だけsubnetを作ることができる。
element(list, index)を使うことで、arrayのindexに対応するものを参照できる。
[参照元]
www.terraform.io
またnat_gatewayはpublic_subnet内においておく必要があるのここで定義し、また静的なIPを付与するためaws_eipを指定する。
private_subnetの実装
- private_subnet/main.tf
resource "aws_subnet" "main" {
vpc_id = var.vpc_id
count = length(var.availability_zones)
cidr_block = element(var.cidr_blocks, count.index)
availability_zone = element(var.availability_zones, count.index)
}
resource "aws_route_table" "main" {
vpc_id = var.vpc_id
count = length(var.availability_zones)
}
resource "aws_route_table_association" "main" {
count = length(aws_subnet.main)
subnet_id = aws_subnet.main[count.index].id
route_table_id = aws_route_table.main[count.index].id
}
resource "aws_route" "main" {
count = length(var.availability_zones)
route_table_id = aws_route_table.main[count.index].id
nat_gateway_id = element(var.nat_gateway_ids, count.index)
destination_cidr_block = "0.0.0.0/0"
}
- private_subnet/varaibles.tf
variable "env" {
type = string
}
variable "availability_zones" {
type = list(string)
}
variable "cidr_blocks" {
type = list(string)
}
variable "vpc_id" {
type = string
}
variable "nat_gateway_ids" {
type = list(string)
}
- private_subnet/output.tf
output "ids" {
value = aws_subnet.main.*.id
}
public_subnetと違う点は、nat_gateway_idをmain.tf内で指定する所で、
これによって片方向通信をすることができるようになる。
次回
セキュリティグループmoduleについて書く。