構成図を書きながらterraformの勉強

# はじめに
[Pragmatic Terraform on AWS](https://booth.pm/ja/items/1318735) の写経をするにあたって、ただ写経するのではなく作った構成を図に起こしながら写経した方が理解が深まると思い、やってみる。

# VPC AZが一つ
`Pragmatic Terraform on AWS` の7章で紹介されている構成

![Untitled Diagram (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/e694b6ff-4361-c33c-1e3f-9ba117e50d1a.png)

```tf
resource "aws_vpc" "example" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "example"
  }
}

resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.example.id
  cidr_block              = "10.0.0.0/24"
  map_public_ip_on_launch = true
  availability_zone       = "ap-northeast-1a"
}

resource "aws_internet_gateway" "example" {
  vpc_id = aws_vpc.example.id
}

# パブリックルートテーブル
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.example.id
}

# パブリック用のルートテーブルのルート
# デフォルトルート(0.0.0.0/0)はインターネットゲートウェイにつなぐ
resource "aws_route" "public" {
  route_table_id         = aws_route_table.public.id
  gateway_id             = aws_internet_gateway.example.id
  destination_cidr_block = "0.0.0.0/0"
}

# パブリックサブネットとパブリックルートテーブルを紐付ける
resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

# プライベートのサブネット
resource "aws_subnet" "private" {
  vpc_id                  = aws_vpc.example.id
  cidr_block              = "10.0.64.0/24"
  availability_zone       = "ap-northeast-1a"
  map_public_ip_on_launch = false
}

# プライベート用のルートテーブル
resource "aws_route_table" "private" {
  vpc_id = aws_vpc.example.id
}

# プライベート用のルートテーブルのルート。下で作成するNATゲートウェイにつなぐ
resource "aws_route" "private" {
  route_table_id         = aws_route_table.private.id
  nat_gateway_id         = aws_nat_gateway.example.id
  destination_cidr_block = "0.0.0.0/0"
}

# 「プライベート用」サブネットとルートテーブルを紐付ける
resource "aws_route_table_association" "private" {
  subnet_id      = aws_subnet.private.id
  route_table_id = aws_route_table.private.id
}

# NATゲートウェイが使うEIPの生成
resource "aws_eip" "nat_gateway" {
  vpc        = true
  depends_on = [aws_internet_gateway.example]
}

# NATゲートウェイの作成。(NATゲートウェイの作成する場所はパブリックサブネット内)
resource "aws_nat_gateway" "example" {
  allocation_id = aws_eip.nat_gateway.id
  subnet_id     = aws_subnet.public.id
  depends_on    = [aws_internet_gateway.example]
}
```

# VPC マルチAZ
`Pragmatic Terraform on AWS` の7章で紹介されている構成

![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/e163fd78-d3ef-7d96-338a-a11707430b86.png)
プライベートサブネットごとにnatゲートウェイを用意し、冗長化している。
ルートテーブルのデフォルトルートは一つのルートテーブルにつき一つしか指定できない。そのため、プライベートサブネットごとにプライベートルートテーブルを用意し、デフォルトルートには冗長化した各natゲートウェイを指定している。

```tf
resource "aws_vpc" "example" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "example"
  }
}

resource "aws_internet_gateway" "example" {
  vpc_id = aws_vpc.example.id
}

# パブリックサブネット
resource "aws_subnet" "public_0" {
  vpc_id                  = aws_vpc.example.id
  cidr_block              = "10.0.1.0/24"
  map_public_ip_on_launch = true
  availability_zone       = "ap-northeast-1a"
}

resource "aws_subnet" "public_1" {
  vpc_id                  = aws_vpc.example.id
  cidr_block              = "10.0.2.0/24"
  map_public_ip_on_launch = true
  availability_zone       = "ap-northeast-1c"
}

# パブリックルートテーブル
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.example.id
}

# パブリック用のルートテーブルのルート
# デフォルトルート(0.0.0.0/0)はインターネットゲートウェイにつなぐ
resource "aws_route" "public" {
  route_table_id         = aws_route_table.public.id
  gateway_id             = aws_internet_gateway.example.id
  destination_cidr_block = "0.0.0.0/0"
}

# パブリックサブネットとパブリックルートテーブル(igwのルーティングを含むもの)の紐付け。
# ルートテーブルは同じものを紐付ける
resource "aws_route_table_association" "public_0" {
  subnet_id      = aws_subnet.public_0.id
  route_table_id = aws_route_table.public.id
}

resource "aws_route_table_association" "public_1" {
  subnet_id      = aws_subnet.public_1.id
  route_table_id = aws_route_table.public.id
}

# プライベートのサブネット
resource "aws_subnet" "private_0" {
  vpc_id                  = aws_vpc.example.id
  cidr_block              = "10.0.65.0/24"
  availability_zone       = "ap-northeast-1a"
  map_public_ip_on_launch = false
}

resource "aws_subnet" "private_1" {
  vpc_id                  = aws_vpc.example.id
  cidr_block              = "10.0.66.0/24"
  availability_zone       = "ap-northeast-1c"
  map_public_ip_on_launch = false
}

# プライベート用のルートテーブル
resource "aws_route_table" "private_0" {
  vpc_id = aws_vpc.example.id
}

resource "aws_route_table" "private_1" {
  vpc_id = aws_vpc.example.id
}

# プライベート用のルートテーブルのルート。下で作成するNATゲートウェイにつなぐ
resource "aws_route" "private_0" {
  route_table_id         = aws_route_table.private_0.id
  nat_gateway_id         = aws_nat_gateway.nat_gateway_0.id
  destination_cidr_block = "0.0.0.0/0"
}

resource "aws_route" "private_1" {
  route_table_id         = aws_route_table.private_1.id
  nat_gateway_id         = aws_nat_gateway.nat_gateway_1.id
  destination_cidr_block = "0.0.0.0/0"
}

# 「プライベート用」サブネットとルートテーブルを紐付ける
resource "aws_route_table_association" "private_0" {
  subnet_id      = aws_subnet.private_0.id
  route_table_id = aws_route_table.private_0.id
}

resource "aws_route_table_association" "private_1" {
  subnet_id      = aws_subnet.private_1.id
  route_table_id = aws_route_table.private_1.id
}

# NATゲートウェイが使うEIPの生成
resource "aws_eip" "nat_gateway_0" {
  vpc        = true
  depends_on = [aws_internet_gateway.example]
}

resource "aws_eip" "nat_gateway_1" {
  vpc        = true
  depends_on = [aws_internet_gateway.example]
}

# NATゲートウェイの作成。(NATゲートウェイの作成する場所はパブリックサブネット内)
resource "aws_nat_gateway" "nat_gateway_0" {
  allocation_id = aws_eip.nat_gateway_0.id
  subnet_id     = aws_subnet.public_0.id
  depends_on    = [aws_internet_gateway.example]
}

resource "aws_nat_gateway" "nat_gateway_1" {
  allocation_id = aws_eip.nat_gateway_1.id
  subnet_id     = aws_subnet.public_1.id
  depends_on    = [aws_internet_gateway.example]
}

```

# VPC、ALB、ECS
`Pragmatic Terraform on AWS` の7章、8章、9章の構成

![ecs_nginx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/ae80b71b-2e1e-768a-906a-bdf277ed5c23.png)

コード
https://github.com/pokotyan/terraform-ecs-practice/tree/4c7cdf6b948314f572014069544a13a80a8ce204

# VPC、ALB、ECS、RDS
`Pragmatic Terraform on AWS` の13章あたりまで写経した構成

![ecs-rds.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/9ea84fb6-613e-3ea5-93d5-8d85f692b1fd.png)

コード
https://github.com/pokotyan/terraform-ecs-practice/tree/34bff76b05ea9ff28e22622bcbd391251a1a9e1d