nginx起動 https化 Terraform AWS VPC

#VPCリソースを構築
- VPC
  - AWS上へ仮想的なネットワークを作成する
- Subnet
  - VPC上へ小規模な仮想的なネットワークを作成する
  - 今回はPublic SubnetとPrivate Subnetの2種類を3個ずつ(AZ分)作成する。
- Internet Gateway
-  VPCはデフォルトだとIN/OUTともにインターネットへの疎通は行えないため、インターネットへの出入り口を作るリソース
- Route Table
  - ネットワークの経路情報を設定するためのサービス
  - Subnetはデフォルトだとインターネットへ疎通できないため、Route Table でSubnetとInternet Gatewayを紐づけて疎通を可能にする必要がある
* NAT Gateway
  - Private Subnetをインターネットへ疎通

#vagrantへログイン

```
$ mkdir　terraform && cd terraform
$ mkdir handson && cd handson
$ touch main.tf
$ vi main.tf
```
main.tfファイルに下記コードを記述

```
provider "aws" {
  region = "us-west-2"
}
```

コンテナ起動コンテナに入る

```
$ docker run \
    -e AWS_ACCESS_KEY_ID=AWS ACCESS KEY \
    -e AWS_SECRET_ACCESS_KEY=AWS SECRET ACCESS KEY \
    -v $(pwd):/terraform \
    -w /terraform \
    -it \
    --entrypoint=ash \
    hashicorp/terraform:0.11.13
```

terraform初期化

```
$ terraform init
$ vi main.tf
```

main.tfファイルに下記コードを記述

```
# VPC
# https://www.terraform.io/docs/providers/aws/r/vpc.html
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "handson"
  }
}
```

terraform planで確認後terraform applyで適用

```
$ terraform plan
& terraform apply
```

awsのコンソールで作成できているか確認


#Subnet作成
Public SubnetとPrivate Subnetの2種類作成
3つのAZへ各種リソース(EC2やECSやRDSなど)を配置したいため、2*3で計6つのサブネットを作成
main.tfファイルに下記コードを記述

```
# Subnet
# https://www.terraform.io/docs/providers/aws/r/subnet.html
resource "aws_subnet" "public_1a" {
  
# 先程作成したVPCを参照し、そのVPC内にSubnetを立てる
  vpc_id = "${aws_vpc.main.id}"
  
# Subnetを作成するAZ
  availability_zone = "us-west-2a"

  cidr_block        = "10.0.1.0/24"

  tags = {
    Name = "handson-public-1a"
  }
}
~    
```

planで確認後apply

```
$ terraform plan
$ terraform apply
```

#残り5つのサブネット作成
下記コード追記

```
resource "aws_subnet" "public_1c" {
  vpc_id = "${aws_vpc.main.id}"

  availability_zone = "us-west-2c"

  cidr_block        = "10.0.2.0/24"

  tags = {
    Name = "handson-public-1c"
  }
}

resource "aws_subnet" "public_1d" {
  vpc_id = "${aws_vpc.main.id}"

  availability_zone = "us-west-2d"

  cidr_block        = "10.0.3.0/24"

  tags = {
    Name = "handson-public-1d"
  }
}

# Private Subnets
resource "aws_subnet" "private_1a" {
  vpc_id = "${aws_vpc.main.id}"

  availability_zone = "us-west-2a"
  cidr_block        = "10.0.10.0/24"

  tags = {
    Name = "handson-private-1a"
  }
}

resource "aws_subnet" "private_1c" {
  vpc_id = "${aws_vpc.main.id}"

  availability_zone = "us-west-2c"
  cidr_block        = "10.0.20.0/24"
  
  tags = {
    Name = "handson-private-1c"
  }
}

resource "aws_subnet" "private_1d" {
  vpc_id = "${aws_vpc.main.id}"

  availability_zone = "us-west-2d"
  cidr_block        = "10.0.30.0/24"

  tags = {
    Name = "handson-private-1d"
  }
}
```

planで確認後apply

```
$ terraform plan
$ terraform apply
```

コンソールで左のVPCでフィルタリングを作成したものに
下のサブネットをクリックして作成できているか確認

#Internet Gateway
VPCからインターネットへの出入り口となるInternet Gatewayを作成

```
# Internet Gateway
# https://www.terraform.io/docs/providers/aws/r/internet_gateway.html
resource "aws_internet_gateway" "main" {
  vpc_id = "${aws_vpc.main.id}"

  tags = {
    Name = "handson"
  }
}
```

planで確認後apply

#NAT Gateway
NAT Gatewayは1つのElastic IPが必要なのでその割り当てと、AZ毎に必要なので3つ作成

```
# Elasti IP
# https://www.terraform.io/docs/providers/aws/r/eip.html
resource "aws_eip" "nat_1a" {
  vpc = true

  tags = {
    Name = "handson-natgw-1a"
  }
}

# NAT Gateway
# https://www.terraform.io/docs/providers/aws/r/nat_gateway.html
resource "aws_nat_gateway" "nat_1a" {
  subnet_id     = "${aws_subnet.public_1a.id}" # NAT Gatewayを配置するSubnetを指定
  allocation_id = "${aws_eip.nat_1a.id}"       # 紐付けるElasti IP

  tags = {
    Name = "handson-1a"
  }
}
```

planで確認後apply

#残り2つのNAT Gatewayも作成

```
resource "aws_eip" "nat_1c" {
  vpc = true

  tags = {
    Name = "handson-natgw-1c"
  }
}

resource "aws_nat_gateway" "nat_1c" {
  subnet_id     = "${aws_subnet.public_1c.id}"
  allocation_id = "${aws_eip.nat_1c.id}"

  tags = {
    Name = "handson-1c"
  }
}

resource "aws_eip" "nat_1d" {
  vpc = true

  tags = {
    Name = "handson-natgw-1d"
  }
}

resource "aws_nat_gateway" "nat_1d" {
  subnet_id     = "${aws_subnet.public_1d.id}"
  allocation_id = "${aws_eip.nat_1d.id}"

  tags = {
    Name = "handson-1d"
  }
}
```

planで確認後apply

#Route Table
トラフィックを疎通させるための経路設定
Internet Gatewayを使用してインターネットへ疎通するためのRoute Table/Routes と NAT Gatewayを経由してインターネットへ疎通するためのRoute Table/Routes を設定

#Internet GatewayとSubnetの経路を作成
- “aws_route_table”
  - 経路情報の格納
- “aws_route”
  - Route Tableへ経路情報を追加
  - インターネット(0.0.0.0/0)へ接続する際はInternet Gatewayを使用するように設定する
- “aws_route_table_association”
  - Route TableとSubnetの紐づけ

```
# Route Table
# https://www.terraform.io/docs/providers/aws/r/route_table.html
resource "aws_route_table" "public" {
  vpc_id = "${aws_vpc.main.id}"

  tags = {
    Name = "handson-public"
  }
}

# Route
# https://www.terraform.io/docs/providers/aws/r/route.html
resource "aws_route" "public" {
  destination_cidr_block = "0.0.0.0/0"
  route_table_id         = "${aws_route_table.public.id}"
  gateway_id             = "${aws_internet_gateway.main.id}"
}

# Association
# https://www.terraform.io/docs/providers/aws/r/route_table_association.html
resource "aws_route_table_association" "public_1a" {
  subnet_id      = "${aws_subnet.public_1a.id}"
  route_table_id = "${aws_route_table.public.id}"
}

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

resource "aws_route_table_association" "public_1d" {
  subnet_id      = "${aws_subnet.public_1d.id}"
  route_table_id = "${aws_route_table.public.id}"
}
```

planで確認後apply

#NAT GatewayとSubnetの経路作成
各AZにNAT Gateway が必要

```
# Route Table (Private)
# https://www.terraform.io/docs/providers/aws/r/route_table.html
resource "aws_route_table" "private_1a" {
  vpc_id = "${aws_vpc.main.id}"

  tags = {
    Name = "handson-private-1a"
  }
}

resource "aws_route_table" "private_1c" {
  vpc_id = "${aws_vpc.main.id}"

  tags = {
    Name = "handson-private-1c"
  }
}

resource "aws_route_table" "private_1d" {
  vpc_id = "${aws_vpc.main.id}"

  tags = {
    Name = "handson-private-1d"
  }
}

# Route (Private)
# https://www.terraform.io/docs/providers/aws/r/route.html
resource "aws_route" "private_1a" {
  destination_cidr_block = "0.0.0.0/0"
  route_table_id         = "${aws_route_table.private_1a.id}"
  nat_gateway_id         = "${aws_nat_gateway.nat_1a.id}"
}

resource "aws_route" "private_1c" {
  destination_cidr_block = "0.0.0.0/0"
  route_table_id         = "${aws_route_table.private_1c.id}"
  nat_gateway_id         = "${aws_nat_gateway.nat_1c.id}"
}

resource "aws_route" "private_1d" {
  destination_cidr_block = "0.0.0.0/0"
  route_table_id         = "${aws_route_table.private_1d.id}"
  nat_gateway_id         = "${aws_nat_gateway.nat_1d.id}"
}

# Association (Private)
# https://www.terraform.io/docs/providers/aws/r/route_table_association.html
resource "aws_route_table_association" "private_1a" {
  subnet_id      = "${aws_subnet.private_1a.id}"
  route_table_id = "${aws_route_table.private_1a.id}"
}

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

resource "aws_route_table_association" "private_1d" {
  subnet_id      = "${aws_subnet.private_1d.id}"
  route_table_id = "${aws_route_table.private_1d.id}"
}
```

planで確認後apply

#経路設定が行えているかWebコンソール上から確認
“handson-” という名前からはじまるRoute Tableが4つあるか


“handson-public” に3つSubnetが登録されているか


“handson-public” に登録されている3つのSubnetはPublic Subnetの命名になっているか


“handson-public” の0.0.0.0への経路はInternet Gatewayを使用しているか


“handson-private-*” は3つ存在し、それぞれ1つずつSubnetを持っているか


“handson-private-*” は0.0.0.0への経路はNAT Gatewayを使用しているか