LoginSignup
5
4

More than 3 years have passed since last update.

TerraformでVPC、サブネット、インターネットゲートウェイを作成する

Last updated at Posted at 2020-05-31

はじめに

現在CloudformationとTerraformを学習しています。
先日以下記事を書きました。
CloudFormationでVPC、サブネット、インターネットゲートウェイを作成する

これと同じようなこと(=全く同じではない)をTerraformで作成しました。
まだどちらもそこまで試してないですが、Terraformの方が良い感触です。

環境
% terraform --version
Terraform v0.12.26

ディレクトリ構造

Terraformではディレクトリを役割、環境毎に分けた方が良いとのことです。
今回は役割ごと分割にします。結果以下のようなディレクトリ構造としました。

% tree                                                                                             
.
├── README.md
├── main.tf
├── modules
│   ├── alb
│   │   ├── Create-alb.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── ec2
│   │   ├── Create-ec2.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── rds
│   │   ├── Create-rds.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── security_group
│   │   ├── Create-securitygroup.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── vpc    #本記事で作成
│       ├── Create-vpc.tf
│       ├── outputs.tf
│       └── variables.tf
├── outputs.tf
├── terraform.tfstate
├── terraform.tfstate.backup
└── variables.tf

コード

main.tfの作成

Terraformルートディレクトリに設置したmain.tfには使用するモジュールをメインで書いておきます。
この後作成するvpcモジュールと、プロバイダー情報(今回はAWS)を記載します。(ec2,rds,albなどは別記事で書きます)
vpc_config内は環境に合わせて書いてください。必要に応じて変数の追加も出来ます。

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

module vpc {
  source = "./modules/vpc"

  vpc_config = {
    NameTag              = "Terraform"
    cidr_block           = "10.2.0.0/16"
    enable_dns_support   = true
    enable_dns_hostnames = true
    subnet_count         = 2
  }
}

変数の作成

vpcに関する変数なので、modules/vpcディレクトリ内にvariables.tfを作成し、module vpcで定義した変数をinputします。
stringboolなどの型を定義してますが、分からなければanyでも大丈夫です。

./modules/vpc/variables.tf
variable "vpc_config" {
  type = object({
    NameTag              = string
    cidr_block           = string
    enable_dns_support   = bool
    enable_dns_hostnames = bool
    subnet_count         = number
  })
}

vpcを作成するコード本体の作成

サブネットなど同一構成の場合は作成したい数分count = intを定義する。
ただcountだと一部だけ削除が出来ないのでfor_eachにした方がいいかもしれない。

./modules/vpc/Create-vpc.tf
# アベイラリティゾーンの取得
data "aws_availability_zones" "available" {
  state = "available"
}

# Cretae VPC
resource "aws_vpc" "MyFirstVPC" {
  cidr_block           = var.vpc_config.cidr_block
  enable_dns_hostnames = var.vpc_config.enable_dns_hostnames
  enable_dns_support   = var.vpc_config.enable_dns_support
  tags = {
    Name = "${var.vpc_config.NameTag}-VPC"
  }
}

# Cretae IGW
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.MyFirstVPC.id
  tags = {
    Name = "${var.vpc_config.NameTag}-IGW"
  }
}

# Cretae Subnets
resource "aws_subnet" "public" {
  count                   = var.vpc_config.subnet_count
  vpc_id                  = aws_vpc.MyFirstVPC.id
  cidr_block              = cidrsubnet(aws_vpc.MyFirstVPC.cidr_block, 8, count.index) #10.2.0.0/24,10.2.1.0/24
  map_public_ip_on_launch = true
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  tags = {
    Name = "${var.vpc_config.NameTag}-PublicSubnet${count.index}"
  }
}
resource "aws_subnet" "private" {
  count                   = var.vpc_config.subnet_count
  vpc_id                  = aws_vpc.MyFirstVPC.id
  cidr_block              = cidrsubnet(aws_vpc.MyFirstVPC.cidr_block, 8, count.index + var.vpc_config.subnet_count) #10.2.2.0/24,10.2.3.0/24
  map_public_ip_on_launch = false
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  tags = {
    Name = "${var.vpc_config.NameTag}-PrivateSubnet${count.index}"
  }
}

# Cretae RouteTables
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.MyFirstVPC.id
  tags = {
    Name = "${var.vpc_config.NameTag}-PublicRT"
  }
}
resource "aws_route_table" "private" {
  vpc_id = aws_vpc.MyFirstVPC.id
  tags = {
    Name = "${var.vpc_config.NameTag}-PrivateRT"
  }
}

# Cretae Route
resource "aws_route" "public" {
  route_table_id         = aws_route_table.public.id
  gateway_id             = aws_internet_gateway.igw.id
  destination_cidr_block = "0.0.0.0/0"
}

# Association RouteTables
resource "aws_route_table_association" "public" {
  count          = var.vpc_config.subnet_count
  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}

resource "aws_route_table_association" "private" {
  count          = var.vpc_config.subnet_count
  subnet_id      = aws_subnet.private[count.index].id
  route_table_id = aws_route_table.private.id
}

outputの作成

他のモジュールでIDや値を使うために必要な情報をoutputします。

./modules/vpc/outputs.tf
output "vpc_id" {
  value = aws_vpc.MyFirstVPC.id
}
output "vpc_cidr" {
  value = aws_vpc.MyFirstVPC.cidr_block
}

output "public_subnet_id" {
  value = aws_subnet.public[*].id
}

output "private_subnet_id" {
  value = aws_subnet.private[*].id
}

コードの実行

% terraform plan
% terraform apply

PS:変数やループで固めておくと単純構成なら楽なんですが、一部だけ変えたい時にやりにくいかもですね。。

参考文献

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4