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について書く。