4
0

More than 3 years have passed since last update.

Terraformで複数azに跨るサブネットを一気に作る

Last updated at Posted at 2021-08-09

はじめに

  • Terraformの勉強記録です
  • 本稿ではTerraformで複数azに跨るサブネットを一気に作る手順を記します
    • 複数リソースのループはfor_eachを使用しています
  • 誤りの訂正・より良い方法のご助言、どしどしコメント頂ければ幸いです

Terraform 実行環境

  • AWS Cloud9
    • Amazon Linux2
    • t2.micro
  • Cloud9を使う理由
    • 標準でTerraformが備わっているため

作成環境の構成

vpc.png


アウトライン

  1. プロバイダー・locals変数
  2. VPC
  3. サブネット
  4. インターネットゲートウェイ
  5. ルートテーブル
  6. NATゲートウェイ

1. プロバイダー・locals変数

  • 東京リージョンを指定
variables.tf
locals {
  name = "terraform"
  region   = "ap-northeast-1"
}
  • Nameタグに使う文字列など、複数のresourceで共通して使う値をlocals変数に格納
variables.tf
provider "aws" {
  region = local.region
}

2. VPC

  • vpc_cidrの値にしたがってVPCを構築
variables.tf
variable "vpc_cidr" {
  type    = string
  default = "10.1.0.0/16"
}
vpc.tf
resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr

  instance_tenancy     = "default"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "${local.name}-vpc"
  }
}

3. サブネット

  • 3つのAvailability Zoneそれぞれにパブリック・プライベートサブネットを作成
  • プライベート・パブリックサブネットそれぞれの設定情報を持つ変数を宣言
    • for_eachで呼び出すため、map(any)型で情報を格納
variables.tf
variable "subnets" {
  type = map(any)
  default = {
    private_subnets = {
      private-1a = {
        name = "private-1a",
        cidr = "10.1.10.0/24",
        az   = "ap-northeast-1a"
      },
      private-1c = {
        name = "private-1c",
        cidr = "10.1.11.0/24",
        az = "ap-northeast-1c"  
      },
      private-1d = {
        name = "private-1d",
        cidr = "10.1.12.0/24",
        az = "ap-northeast-1d"  
      },
    },
    public_subnets = {
      public-1a = {
        name = "public-1a"
        cidr = "10.1.100.0/24"
        az   = "ap-northeast-1a"
      },
      public-1c = {
        name = "public-1c"
        cidr = "10.1.101.0/24"
        az = "ap-northeast-1c"
      },
      public-1d = {
        name = "public-1d"
        cidr = "10.1.102.0/24"
        az = "ap-northeast-1d"
      }
    }
  }
}
  • サブネットの作成
    • for_eachで回す
    • each.value.hoge で欲しい情報にアクセス
subnet.tf
resource "aws_subnet" "private" {
  for_each = var.subnets.private_subnets

  vpc_id = aws_vpc.main.id

  cidr_block        = each.value.cidr
  availability_zone = each.value.az

  tags = {
    Name = "${local.name}-${each.value.name}"
  }
}

resource "aws_subnet" "public" {
  for_each = var.subnets.public_subnets

  vpc_id = aws_vpc.main.id

  cidr_block        = each.value.cidr
  availability_zone = each.value.az

  tags = {
    Name = "${local.name}-${each.value.name}"
  }
}

4. インターネットゲートウェイ

  • VPCのidと関連付け
gateway.tf
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "${local.name}-igw"
  }
}

5. ルートテーブル

  • 各サブネット分作成
route_table.tf
# create
resource "aws_route_table" "private" {
  for_each = var.subnets.private_subnets
  vpc_id   = aws_vpc.main.id

  tags = {
    Name = "${local.name}-${each.value.name}-rt"
  }
}

resource "aws_route_table" "public" {
  for_each = var.subnets.public_subnets
  vpc_id   = aws_vpc.main.id

  tags = {
    Name = "${local.name}-${each.value.name}-rt"
  }
}
  • サブネットと関連付ける
    • サブネットもルートテーブルも同一のキーで生成されているため、同じように書ける
route_table.tf
# association
resource "aws_route_table_association" "private" {
  for_each = var.subnets.private_subnets

  subnet_id      = aws_subnet.private[each.key].id
  route_table_id = aws_route_table.private[each.key].id
}

resource "aws_route_table_association" "public" {
  for_each = var.subnets.public_subnets

  subnet_id      = aws_subnet.public[each.key].id
  route_table_id = aws_route_table.public[each.key].id
}
  • パブリックサブネットはインターネットゲートウェイとも関連付ける
route_table.tf
# associate with gateway
resource "aws_route" "igw" {
  for_each               = var.subnets.public_subnets
  route_table_id         = aws_route_table.public[each.key].id
  gateway_id             = aws_internet_gateway.main.id
  destination_cidr_block = "0.0.0.0/0"
}

6. NATゲートウェイ

  • 一工夫必要

  • Elastic IPの作成

    • NATゲートウェイに割り当てるもの
    • パブリックサブネット分、作成
    resource "aws_eip" "nat_gateway" {
      for_each = var.subnets.public_subnets
    
      vpc = true
      tags = {
        Name = "${local.name}-${each.value.name}-ngw-eip"
      }
    }
    
  • NATゲートウェイの作成

    • 関連付けるサブネット・EIPを指定
    • (publicサブネットに配置するが、関連付ける対象的にprivateと命名)
    resource "aws_nat_gateway" "private" {
      for_each = var.subnets.public_subnets
    
      allocation_id = aws_eip.nat_gateway[each.key].id
      subnet_id     = aws_subnet.public[each.key].id
    
      tags = {
        Name = "${local.name}-${each.value.name}-ngw"
      }
    
      depends_on = [aws_internet_gateway.main] # internet_gateway作成後に作成
    }
    
  • Route Tableの関連付け

    • private subnetのルートテーブルにNATゲートウェイへのルートを追加したい
    • route_tableはvar.private_subnetsのkey、nat_gatewayはvar.public_subnetsのkeyで生成されている(ややこしい)
    • zipmapをうまく使って一気に作る
    resource "aws_route" "ngw" {
      for_each               = zipmap(keys(var.subnets.public_subnets), keys(var.subnets.private_subnets))
      route_table_id         = aws_route_table.private[each.value].id
      nat_gateway_id         = aws_nat_gateway.private[each.key].id
      destination_cidr_block = "0.0.0.0/0"
    }
    
  • 完成

おわりに

  • 無事、複数azに跨るサブネットを一気に作ることができました
  • ネタがあれば引き続きTerraformの検証記事を書いていく予定です
4
0
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
4
0