【ネットワーク環境構築】terraform AWS環境構築 第1回

AWS

AWSRails + Nginxな環境をTerraformで構築してみようと思います。

はじめに

本連載で一つずつインフラを構築していきます。

ドメインのhttps化したり、ECSを使用したコンテナオーケストレーションを用いてアプリケーションをデプロイします。

この記事ではネットワーク環境の構築を行います。

環境は以下です。

OS Cataline 10.15.6
Terraform 0.14.4

 

 

 

基本構文などこちらにまとめてますので、よかったらみてください!
AWS Terraform 基本コード まとめ

連載一覧

やること

以下の定義と作成をします。

ネットワーク環境構築

基本ファイル作成

インフラを構築する、基本インプット変数を定義しておきます。

./variable.tf

variable "aws_region" {
  type    = string
  default = "ap-northeast-1"
}

variable "aws_profile" {
  type        = string
  default     = "default"
  description = "AWS CLI's profile"
}

variable "app_name" {
  type    = string
  default = "rails_hello"
}

variable "domain" {}

./provider.tf

provider "aws" {
  region  = var.aws_region
  profile = var.aws_profile
}

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }
}

./terraform.tfvars

domain = "<your domain>"

./backend.tf

terraform {
  backend "s3" {}
}

networkモジュールの作成

ネットワーク環境を定義するモジュールを作成します。

terraformフォルダ内にnetworkフォルダを作成しましょう。

networkモジュールを使用できるように./main.tfに以下の記述を追記します。

module "network" {
  source = "./network"

  app_name = var.app_name
}

networkモジュール内でapp_nameを受け取れるように、variable.tfを用意します。

./network/variable.tf

variable "app_name" {}

ディレクトリ構成は以下のようにしています。

[terraform] $ tree 
. 
├── network
│   ├── main.tf
│   └── variable.tf
├── env
│   └── backend.config
├── main.tf
├── backend.tf
├── provider.tf
├── terraform.tfvars
└── variable.tf

用意できたら、terraformの初期化を行いましょう。

[terraform] $ terraform init -backend-config=env/backend.config -upgrade

VPCの作成

まずは、vpcの定義とインプット変数を定義します。

./network/variable.tf に以下を追記します。

variable "app_name" {}

variable "vpc_cidr" {
  default = "135.0.0.0/16"
}

./network/main.tf に以下を追記します。

resource "aws_vpc" "vpc" {
  cidr_block = var.vpc_cidr

  tags = {
    Name = var.app_name
  }
}
  • cidr_blockVPCCIDRブロック
  • tags:タグ

これでvpcの定義は完了です。

terraform plan, apply して作成されるか見てみましょう。

これで、vpcの作成は完了です。

パブリック・プライベートサブネットの作成

次に、パブリック・プライベートサブネットの定義とインプット変数を定義します。

./network/variable.tf に以下を追記します。

variable "public_subnet_cidrs" {
  default = ["135.0.0.0/24", "135.0.1.0/24", "135.0.2.0/24"]
}

variable "private_subnet_cidrs" {
  default = ["135.0.10.0/24", "135.0.11.0/24", "135.0.12.0/24"]
}

variable "azs_name" {
  type    = list(string)
  default = ["1a", "1c", "1d"]
}

./network/main.tf に以下を追記します。

esource "aws_subnet" "public_subnets" {
  # public_subnet_cidrs分、繰り返す
  count = length(var.public_subnet_cidrs)

 # 先程作成したvpc
  vpc_id = aws_vpc.vpc.id

  availability_zone       = var.azs[count.index]
  cidr_block              = var.public_subnet_cidrs[count.index]
  map_public_ip_on_launch = true # パブリックIP割当

  tags = {
    Name = "${var.app_name}-public-${var.azs_name[count.index]}"
  }
}

resource "aws_subnet" "private_subnets" {
  count = length(var.private_subnet_cidrs)

  vpc_id = aws_vpc.vpc.id

  availability_zone = var.azs[count.index]
  cidr_block        = var.private_subnet_cidrs[count.index]

  tags = {
    Name = "${var.app_name}-private-${var.azs_name[count.index]}"
  }
}
  • vpc_id:紐付けるVPCID
  • availability_zone:サブネット配置のアベイラビリティゾーン
  • cidr_block:サブネットのCIDRブロック
  • map_public_ip_on_launch当該サブネットで起動したインスタンスにパブリックIPアドレスを割り当の有無
  • tags:タグ

terraform plan, apply して作成されるか見てみましょう。

これで、パブリック・プライベートサブネットの作成は完了です。

インターネットゲートウェイの作成

vpcがインターネットが接続できるように、インターネットゲートウェイの定義をします。

./terraform/main.tf に以下を追記します。

resource "aws_internet_gateway" "igw" {
  # 先程作成したvpc
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name = var.app_name
  }
}
  • vpc_id:紐付けるVPCID

terraform plan, apply して作成されるか見てみましょう。

これで、「Attached」されていればインターネットゲートウェイの作成は完了です。

ルートテーブルの作成

通信をルートできるように、ルートテーブルの定義をします。

./terraform/main.tf に以下を追記します。

# インターネットへのルート
resource "aws_route" "public" {
  route_table_id         = aws_vpc.vpc.default_route_table_id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.igw.id
}

# パブリック用のルートテーブルとパブリックサブネットの関連付け
resource "aws_route_table_association" "public" {
  count = length(var.public_subnet_cidrs)

  # *.idでサブネットIdを配列を取得
  # element()で、配列のindexのIdを取得
  subnet_id      = element(aws_subnet.public_subnets.*.id, count.index)
  route_table_id = aws_vpc.vpc.default_route_table_id
}

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

  tags = {
    Name = "${var.app_name}-private-rtb"
  }
}

# プライベート用のルートテーブルとプライベートサブネットの関連付け
resource "aws_route_table_association" "private" {
  count = length(var.private_subnet_cidrs)

  # *.idでプライベートIdを配列を取得
  # element()で、配列のindexのIdを取得
  subnet_id      = element(aws_subnet.private_subnets.*.id, count.index)
  route_table_id = aws_route_table.private.id
}
  • aws_route
    • route_table_id:ルート設定するルートテーブルID
    • destination_cidr_block:ルートの送信先
    • gateway_id:インターネットゲートウェイのID
  • aws_route_table_association
    • subnet_id:紐付けるサブネットID
    • route_table_id:紐付け対象のルートテーブルID
  • aws_route_table
    • vpc_idVPCID

terraform plan, apply して作成されるか見てみましょう。

パブリック用ルートテーブル

プライベート用ルートテーブル

これで、ルートテーブルの定義と作成は完了です。

まとめ

vpc・サブネットのidはロードバランサー構築等で使用するので、アウトプット変数を定義しておきましょう。

./network/output.tf

output "vpc_id" {
  value = aws_vpc.vpc.id
}

output "public_subnet_ids" {
  value = aws_subnet.public_subnets.*.id
}

output "private_subnet_ids" {
  value = aws_subnet.private_subnets.*.id
}

./output.tf

output "vpc_id" {
  value = module.network.vpc_id
}

output "public_subnet_ids" {
  value = module.network.public_subnet_ids
}

output "private_subnet_ids" {
  value = module.network.private_subnet_ids
}

今回、作成したコードとディレクトリ構成は以下になります。

[terraform] $ tree 
. 
├── network 
│   ├── main.tf 
│   ├── output.tf 
│   └── variable.tf
├── env
│   └── backend.config
├── main.tf
├── output.tf
├── backend.tf
├── provider.tf
├── terraform.tfvars
└── variable.tf

.network/main.tf

resource "aws_vpc" "vpc" {
  cidr_block = var.vpc_cidr

  tags = {
    Name = var.app_name
  }
}

resource "aws_subnet" "public_subnets" {
  count = length(var.public_subnet_cidrs)

  vpc_id = aws_vpc.vpc.id

  availability_zone       = var.azs[count.index]
  cidr_block              = var.public_subnet_cidrs[count.index]
  map_public_ip_on_launch = true

  tags = {
    Name = "${var.app_name}-public-${var.azs_name[count.index]}"
  }
}

resource "aws_subnet" "private_subnets" {
  count = length(var.private_subnet_cidrs)

  vpc_id = aws_vpc.vpc.id

  availability_zone = var.azs[count.index]
  cidr_block        = var.private_subnet_cidrs[count.index]

  tags = {
    Name = "${var.app_name}-private-${var.azs_name[count.index]}"
  }
}

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.vpc.id

  tags = {
    Name = var.app_name
  }
}

resource "aws_route" "public" {
  route_table_id         = aws_vpc.vpc.default_route_table_id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.igw.id
}

resource "aws_route_table_association" "public" {
  count = length(var.public_subnet_cidrs)

  subnet_id      = element(aws_subnet.public_subnets.*.id, count.index)
  route_table_id = aws_vpc.vpc.default_route_table_id
}

resource "aws_route_table" "private" {
  vpc_id = aws_vpc.vpc.id

  tags = {
    Name = "${var.app_name}-private-rtb"
  }
}

resource "aws_route_table_association" "private" {
  count = length(var.private_subnet_cidrs)

  subnet_id      = element(aws_subnet.private_subnets.*.id, count.index)
  route_table_id = aws_route_table.private.id
}

./network/variable.tf

variable "app_name" {}

variable "azs" {
  type    = list(string)
  default = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
}

variable "azs_name" {
  type    = list(string)
  default = ["1a", "1c", "1d"]
}
variable "vpc_cidr" {
  default = "135.0.0.0/16"
}
variable "public_subnet_cidrs" {
  default = ["135.0.0.0/24", "135.0.1.0/24", "135.0.2.0/24"]
}
variable "private_subnet_cidrs" {
  default = ["135.0.10.0/24", "135.0.11.0/24", "135.0.12.0/24"]
}

おわり

これで、ネットワーク環境の構築は完了しました。お疲れさまでした!

何か疑問に思うことがあれば、何でもコメントしてください!

次回は、ドメインのhttps化・ACM(SSL)証明書のリクエストを行います。

参考サイト

VPC - Terraformで構築するAWS

コメント

タイトルとURLをコピーしました