【AWS/Terraform】ネットワーク構築

# 概要
この記事では、Terraformを使用して、AWS上でVPCを含む一連のネットワークリソースを構築する方法を記載します。

# 環境
- Terraform v1.0.0以上
- AWSアカウント登録済み
- AWS CLIインストール済み

# 構成図
今後、Webアプリケーションを展開していくため、ALBのサブネット、Webサーバーのサブネット、RDSのサブネットを作成します。
![network.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230985/baaf471d-86b4-57c1-cda0-471f10e26eb8.png)


# ディレクトリ構成
```bash
├── main.tf
├── network.tf
├── terraform.tfstate
```

# Terraformの初期化
最初に、Terraformの初期化を行います。

```bash
terraform init
```

# Terraformファイルの作成
## main.tf
```bash
terraform {
  required_version = ">= 0.13"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0.0"
    }
  }

}

provider "aws" {
  profile = "terraform"
  region  = "ap-northeast-1"
}
```

## network.tf
```tf
resource "aws_vpc" "vpc" {
  cidr_block                       = "10.0.0.0/16"
  instance_tenancy                 = "default"
  enable_dns_hostnames             = true
  enable_dns_support               = true
  assign_generated_ipv6_cidr_block = false
  tags = {
    Name = "vpc"
  }
}

# パブリックサブネット(ELB)
resource "aws_subnet" "public-subnet-elb-1a" {
  vpc_id                  = aws_vpc.vpc.id
  availability_zone       = "ap-northeast-1a"
  cidr_block              = "10.0.12.0/24"
  map_public_ip_on_launch = true
  tags = {
    Name = "public-subnet-elb-1a"
  }
}

# パブリックサブネット(ELB)
resource "aws_subnet" "public-subnet-elb-1c" {
  vpc_id                  = aws_vpc.vpc.id
  availability_zone       = "ap-northeast-1c"
  cidr_block              = "10.0.20.0/24"
  map_public_ip_on_launch = true
  tags = {
    Name = "public-subnet-elb-1c"
  }
}

# パブリックサブネット(開発)
resource "aws_subnet" "public-subnet-dev-1a" {
  vpc_id                  = aws_vpc.vpc.id
  availability_zone       = "ap-northeast-1a"
  cidr_block              = "10.0.21.0/24"
  map_public_ip_on_launch = true
  tags = {
    Name = "public-subnet-dev-1a"
  }
}

# プライベートサブネット(web)
resource "aws_subnet" "private-subnet-web-1a" {
  vpc_id                  = aws_vpc.vpc.id
  availability_zone       = "ap-northeast-1a"
  cidr_block              = "10.0.41.0/24"
  map_public_ip_on_launch = true
  tags = {
    Name = "private-subnet-web-1a"
  }
}

# プライベートサブネット(web)
resource "aws_subnet" "private-subnet-web-1c" {
  vpc_id                  = aws_vpc.vpc.id
  availability_zone       = "ap-northeast-1c"
  cidr_block              = "10.0.51.0/24"
  map_public_ip_on_launch = true
  tags = {
    Name = "private-subnet-web-1c"
  }
}

# プライベートサブネット(db)
resource "aws_subnet" "private-subnet-db-1a" {
  vpc_id                  = aws_vpc.vpc.id
  availability_zone       = "ap-northeast-1a"
  cidr_block              = "10.0.61.0/24"
  map_public_ip_on_launch = true
  tags = {
    Name = "private-subnet-db-1a"
  }
}

# プライベートサブネット(db)
resource "aws_subnet" "private-subnet-db-1c" {
  vpc_id                  = aws_vpc.vpc.id
  availability_zone       = "ap-northeast-1c"
  cidr_block              = "10.0.71.0/24"
  map_public_ip_on_launch = true
  tags = {
    Name = "private-subnet-db-1c"
  }
}

# パブリックルートテーブル
resource "aws_route_table" "public_route" {
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name = "public-rt"
  }
}

resource "aws_route_table_association" "public_route_elb-1a" {
  route_table_id = aws_route_table.public_route.id
  subnet_id      = aws_subnet.public-subnet-elb-1a.id
}

resource "aws_route_table_association" "public_route_elb_1c" {
  route_table_id = aws_route_table.public_route.id
  subnet_id      = aws_subnet.public-subnet-elb-1c.id
}

resource "aws_route_table_association" "public_route_dev" {
  route_table_id = aws_route_table.public_route.id
  subnet_id      = aws_subnet.public-subnet-dev-1a.id
}

# プライベートルートテーブル
resource "aws_route_table" "private_route" {
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name = "private-rt"
  }
}

resource "aws_route_table_association" "private_route_web_1a" {
  route_table_id = aws_route_table.private_route.id
  subnet_id      = aws_subnet.private-subnet-web-1a.id
}

resource "aws_route_table_association" "private_route_web_1c" {
  route_table_id = aws_route_table.private_route.id
  subnet_id      = aws_subnet.private-subnet-web-1c.id
}

resource "aws_route_table_association" "private_route_db_1a" {
  route_table_id = aws_route_table.private_route.id
  subnet_id      = aws_subnet.private-subnet-db-1a.id
}

resource "aws_route_table_association" "private_route_db_1c" {
  route_table_id = aws_route_table.private_route.id
  subnet_id      = aws_subnet.private-subnet-db-1c.id
}

# インターネットゲートウェイ
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name = "igw"
  }
}

resource "aws_route" "public_route_igw" {
  route_table_id         = aws_route_table.public_route.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.igw.id
}
```

# リソースの作成
Terraformを使ってリソースを作成します。terraform applyコマンドを使用すると、Terraformカレントディレクトリ内に存在するtfファイルで定義したリソースを作成します。詳細なプランを見るにはterraform planコマンドを実行します。

```bash
terraform apply
```