aws王道アーキテクチャをterraformで実践する【VPC Subnet編】

想定読者
AWSを触ったことがある
terraformをなんとなく知っている
実践terraformを読んでいる
IaCに興味がある

注意点
terraform初心者である筆者の勉強アウトプットという意味合いが強い記事ですので多分に間違い等あるかと思います。
お気づきになられましたら、ご指摘いただけますと幸いです。
学びがあるたびに修正していくスタイル。

terraformで採用されている言語（HCL）の説明はしていません。
下記の記事がterraform入門のために素晴らしい教材になると思います！
<a href=https://qiita.com/fukubaka0825/items/68506b1e6644404d6cc0>Terraform入門資料(v0.12.0対応) ~基本知識から設計や運用、知っておくべきtipsまで~</a>
### Infrastruscture as Code (IaC) に挑戦したいッッッ！
最近流行りのIaC。最新の技術にキャッチアップしたい意図もありますが、本番環境を万が一吹っ飛ばしたりしたときのために、己の身を守るためにAWSコンソール手動ぽちぽちから卒業するんじゃい!

### 今回のゴール: AWS王道アーキテクチャパーンをコード化する！
アーキテクチャの構成に関しては<a href=https://www.ketancho.net/entry/2018/05/07/080000>こちらの記事</a>を参考にさせていただいております
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366477/7d78a857-d5b6-c9c9-2b25-583c98958a21.png)


### 今回の作業範囲: VPC, Subnet
上の図を一本の記事でするのは大変なので作業を分割します
今回は、VPCの作成とSubnetの作成。そしてそのマルチAZ化まで以下の手順で構築してみたいと思います！
インターネットゲートウェイとかまで書こうと思ってたのですが力尽きました

<table>
<tr><td>手順1</td><td>VPCを作成する</td></tr>
<tr><td>手順2</td><td>public subnetを作成する</td></tr>
<tr><td>手順3</td><td>public subnetをマルチAZ化する</td></tr>
<tr><td>手順4</td><td>private subnetを作成する</td></tr>
<tr><td>手順5</td><td>private subnetをマルチAZ化する</td></tr>
</table>

図にするとこの辺の感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366477/70255ec5-3f89-c6f6-5ff7-0851dae4d5d0.png)


### 手順1 VPCを作成する
VPCの範囲を設定します（10.0.0.0/16）
あと、勝手にパブリックIPを割り当ててくれる `enable_dns_support ` と
名前解決をしてくれる `enable_dns_hostnames `を有効にします
最後に一応 `tag` つけときましょう。

```main.tf
# VPCの作成
resource "aws_vpc" "qiita_vpc" {

  cidr_block           = "10.0.0.0/16"    #required: The CIDR block for the VPC.
  enable_dns_support   = true             #optional: to enable/disable DNS support in the VPC
  enable_dns_hostnames = true             #optional: to enable/disable DNS hostnames in the VPC

  tags = {
    Name = "qiita_vpc"
  }
}

```

### 手順2 private subnetを作成する
それでは、先ほど作成したVPC内にサブネットを割り当てていきます。
まず、`vpc_id` でどのVPCにsubnetを割り当てるか指定してあげます
ちなみに `リソース名.名前.属性`としてあげることで、値を呼び出せます。
今回は、リソース名: aws_vpc 名前: qiita_vpc 属性はidです。
VPCの作成でidなんて指定していないじゃないか！と混乱するところではありますが、勝手に割り振られてるものです。（多分)
terraform公式サイトで `Attirbute Reference`があるのでどんな属性を呼び出せるか確認してみてください。
次に、`cidr_block`を指定します。`10.X.X.X.X/24`とするのが一般的です。Xのところは使用するサブネットの数に合わせて変更してください。今回は `10.0.0.1.0/24`とします。

```main.tf
# public subnetの作成
resource "aws_subnet" "qiita_public" {
  vpc_id                  = aws_vpc.qiita_vpc.id     #required: The VPC ID.
  cidr_block              = "10.0.1.0/24"            #required: the CIDR block for the subnet.
  map_public_ip_on_launch = true                     #optional: to indicate that instances launched into the subnet should be assigned a public IP address. 

  tags = {
    Name = "qiita_public"
  }
}
```


### 手順3 public subnetをマルチAZ化する
これでpublic subnetができましたが今回はマルチAZ構成にしたいので
さっき作った `qiita_public`をまるっとコピーして resourceの名前を変更します。
そして、新しく作ったsubnetにcidr_blockを割り当てましょう。（図を見ると`10.0.0.3/24`になってますね。）
そして、`availability_zone` でどのAZに配置するか指定してあげます。
`qiita_public_1` は `ap-northeast-1a` に
`qitta_public_2` は `ap-northeast-1c`に配置します。
`tags`の名前も合わせて変更しときましょう。

```main.tf
#元からあったpublic subnet
resource "aws_subnet" "qiita_public_1" {
  vpc_id                  = aws_vpc.qiita_vpc.id     #required: The VPC ID.
  cidr_block              = "10.0.1.0/24"            #required: the CIDR block for the subnet.
  map_public_ip_on_launch = true                     #optional: to indicate that instances launched into the subnet should be assigned a public IP address. 
  #AZを指定
  availability_zone       = "ap-northeast-1a"

  tags = {
    Name = "qiita_public_1"
  }
}

#新しくつくったpublic subnet
resource "aws_subnet" "qiita_public_2" {
  vpc_id                  = aws_vpc.qiita_vpc.id     #required: The VPC ID.
  cidr_block              = "10.0.3.0/24"            #required: the CIDR block for the subnet.
  map_public_ip_on_launch = true                     #optional: to indicate that instances launched into the subnet should be assigned a public IP address. 
  #AZを指定
  availability_zone       = "ap-northeast-1c"

  tags = {
    Name = "qiita_public_2"
  }
}
```
これでprivate subnetをマルチAZ構成にすることができました！

### 手順2 private subnetを作成する
さて、先ほど作成した2つの public subnetをまるっとコピーしてください。
そして先ほどと同じように、resourceの名前を変更して(`qiita_public_1` => `qiita_private_1`)
cidr_blockを指定します。（図を見ると`10.0.0.2/24`とに`10.0.0.4/24`なってますね。）
あ、あと `tag` の名前も忘れずに変更しましよう。

```main.tf
# private subnetの作成
resource "aws_subnet" "qiita_private_1" {
  #required:
  vpc_id = aws_vpc.qiita_vpc.id
  #required:
  cidr_block              = "10.0.2.0/24"
  availability_zone       = "ap-northeast-1a"
  map_public_ip_on_launch = true

  tags = {
    Name = "qiita_private_1"
  }
}

resource "aws_subnet" "qiita_private_2" {
  #required:
  vpc_id = aws_vpc.qiita_vpc.id
  #required:
  cidr_block              = "10.0.4.0/24"
  availability_zone       = "ap-northeast-1c"
  map_public_ip_on_launch = true

  tags = {
    Name = "qiita_private_2"
  }
}
```

最後にproviderを指定しましょう。

```main.tf
provider "aws" {
  region = "ap-northeast-1"
}

```

以下の３コマンドを実行します。
モジュールを読み込むときは必ず↓

```
$ terraform init
```

変更内容の確認

```
$ terraform plan
```
実行！！！

```
$ terraform apply
```

さて、ここまででVPC内にマルチAZ構成で４つのサブネットを作成してきました。
うまくいっていればAWSコンソールにVPCやサブネットができているはずなのでドキドキしながら確認してみてください！
tagを丁寧につけたのでそちらで確認できると思います。

現状では、ただ４つのサブネットがあるだけなので次回の記事では、
*public subnetとインターネットを接続する作業*
*private subnet*をインターネットから隔離する作業
をしていきたいと思います。

参考文献
<a href=https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5Terraform-AWS%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E8%A8%AD%E8%A8%88%E3%81%A8%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9-%E6%8A%80%E8%A1%93%E3%81%AE%E6%B3%89%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%EF%BC%88NextPublishing%EF%BC%89-%E9%87%8E%E6%9D%91-%E5%8F%8B%E8%A6%8F/dp/4844378139>実践Terraform　AWSにおけるシステム設計とベストプラクティス</a>