Terraformを使ってAWS基本ネットワークの作成

Terraformを使ってAWS基本ネットワークの作成

以前ブログでAWSの基本ネットワーク構成【ハンズオン版】として挙げたものをTerraformで作成してみました。なるべくわかりやすくモジュール化しました。使用する際は各tfファイルをコピーして作成ください。

https://otomosa.com/aws/aws-network-test-handon/(新しいタブで開く)

作成するネットワーク構成

Terraformの取得+設定方法

https://otomosa.com/terraform/terraform_v1-1-8windows11-ec2/(新しいタブで開く)

構成

00_main.tf
01_vpc.tf
02_subnet_public.tf
03_subnet_private.tf
04_IGW.tf
05_NAtGateway.tf
06_ec2_public.tf
07_ec2_private.tf
60_securitygroup.tf
70_routetable.tf
71_routetable_Natgateway.tf
80_ec2_key_variables.tf
81_ec2_key_public.tf
82_ec2_key_private.tf
90_variables.tf
99_terraform.tfvars
terraform.exe

00_main.tf

TerraformではTerraform本体および各プロバイダーやモジュールの利用バージョンを制限する制約を設定できます。

terraform {
  // Terraform本体に対するバージョン制約
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  #required_version = ">= 0.13.0"
}
// Providerに対するバージョン制約
provider "aws" {
  profile = "default"
  region  = var.aws_region
}

01_vpc.tf

VPCで必要な設定は以下

名前タグ:Tf_network-test-vpc
Ipv4-CIDRブロック:172.16.1.0/24
※CIDRブロックの値は99_terraform.tfvarsに定義しています。

# ---------------------------
# VPC
# ---------------------------

resource "aws_vpc" "Tf_network-test-vpc" {
  cidr_block                       = var.aws_vpc_cidr # VPCに設定したいCIDRを指定
  enable_dns_support               = "true"           # VPC内でDNSによる名前解決を有効化するかを指定
  enable_dns_hostnames             = "true"           # VPC内インスタンスがDNSホスト名を取得するかを指定
  instance_tenancy                 = "default"        # VPC内インスタンスのテナント属性を指定
  assign_generated_ipv6_cidr_block = "false"          # IPv6を有効化するかを指定

  tags = {
    Name = "Tf_network-test-vpc"
  }
}


必須設定はcidr_blockのみです。

必須設定はcidr_blockのみですが、デフォルト値をあえて記載しています。Infrastructure as Codeとしてインフラの設定をコードとして残しておきたい場合は、デフォルトの設定でも必要なものは明記しておいた方が賢明だからです。

なお、instance_tenancyは、VPC内で起動するインスタンスのテナント属性を設定できます。テナント属性の種類は下記のように3種類あります。

default: 共有ハードウェアインスタンスの実行
dedicated: 専用ハードウェアインスタンスの実行(同AWSアカウントでの共有)
host: 専有ホスト上で実行

02_subnet_public.tf

VPC ID :先ほど作成したVPCを選択(Tf_network-test-vpc)
サブネット名:Tf_network-test-public
アベイラビリティゾーン:us-east-1a
IPv4:172.16.1.0/25 #Public subnet側
※CIDRブロックの値は99_terraform.tfvarsに定義しています。

resource "aws_subnet" "Tf_network-test-public" {
  vpc_id                          = aws_vpc.Tf_network-test-vpc.id # VPCのIDを指定
  cidr_block                      = var.aws_subnet_cidr_public                # サブネットに設定したいCIDRを指定
  assign_ipv6_address_on_creation = "false"                        # IPv6を利用するかどうかを指定
  map_public_ip_on_launch         = "true"                         # VPC内インスタンスにパブリックIPアドレスを付与するかを指定
  availability_zone               = var.aws_region_a                   # サブネットが稼働するAZを指定

  tags = {
    Name = "Tf_network-test-public"
  }
}

vpcのidは01_vpc.tfで記述した”aws_vpc”+”Tf_network-test-vpc”+idを記述すること自動で取得することができます。

03_subnet_private.tf

VPC ID :先ほど作成したVPCを選択(Tf_network-test-vpc)
サブネット名:Tf_network-test-public
アベイラビリティゾーン:us-east-1a
IPv4:172.16.1.128/25 #Private subnet側
※CIDRブロックの値は99_terraform.tfvarsに定義しています。

resource "aws_subnet" "Tf_network-test-private" {
  vpc_id                          = aws_vpc.Tf_network-test-vpc.id
  cidr_block                      = var.aws_subnet_cidr_private
  assign_ipv6_address_on_creation = "false"
  map_public_ip_on_launch         = "true"
  availability_zone               = var.aws_region_c

  tags = {
    Name = "Tf_network-test-private"
  }
}

04_IGW.tf

VPC ID :先ほど作成したVPCを選択(Tf_network-test-vpc)
※CIDRブロックの値は99_terraform.tfvarsに定義しています。

resource "aws_internet_gateway" "Tf_igw" {
  vpc_id = aws_vpc.Tf_network-test-vpc.id # VPCのIDを指定

  tags = {
    Name = "Tf_igw"
  }
}

05_NAtGateway.tf

# Elasti IP
resource "aws_eip" "Tf_Elasti_IP" {
  vpc = true

  tags = {
    Name = var.aws_elastic_ip_tags_name
  }
}

# NAT Gateway
resource "aws_nat_gateway" "Tf_nat" {
  subnet_id     = aws_subnet.Tf_network-test-public.id # NAT Gatewayを配置するSubnetを指定
  allocation_id = aws_eip.Tf_Elasti_IP.id      # 紐付けるElasti IP

  tags = {
    Name = var.aws_natgateway_tags_name
  }
}

# Route
# https://www.terraform.io/docs/providers/aws/r/route.html
resource "aws_route" "public" {
  destination_cidr_block = "0.0.0.0/0"
  route_table_id         = aws_route_table.Ft_rt_public.id
  gateway_id             = aws_internet_gateway.Tf_igw.id
}

subnet_idは02_subnet_public.tfの”aws_subnet”+”Tf_network-test-public.id”+idを記述すること自動で取得することができます。

06_ec2_public.tf

resource "aws_instance" "Tf_ec2_public" {
    ami = "ami-05fa00d4c63e32376"                     #amiの最新のものを自動で入れたい
    instance_type = var.aws_ec2_instance_type         # 99_terraform.tfvars
    subnet_id = aws_subnet.Tf_network-test-public.id  # 06_ec2_public.tf
    key_name = aws_key_pair.pub.key_name              # 81_ec2_key_public.tf

    tags = {
        Name = var.aws_ec2_public_tags_name
    }

}

07_ec2_private.tf

resource "aws_instance" "Tf_ec2_private" {
    ami = "ami-05fa00d4c63e32376"                      #amiの最新のものを自動で入れたい
    instance_type = var.aws_ec2_instance_type          # 99_terraform.tfvars
    subnet_id = aws_subnet.Tf_network-test-private.id  # 06_ec2_public.tf
    key_name = aws_key_pair.pri.key_name               # 81_ec2_key_public.tf
    tags = {
        Name = var.aws_ec2_private_tags_name
    }
}

60_securitygroup.tf

resource "aws_security_group" "allow_all" {
  name        = "allow_all"
  description = "Allow all inbound traffic"
  vpc_id      = aws_vpc.Tf_network-test-vpc.id   # 01_vpc.tf
  ingress {
    from_port   = 0
    to_port     = 65535
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

##Security groupを紐づける
resource "aws_network_interface_sg_attachment" "sg_attachment" {
  security_group_id    = aws_security_group.allow_all.id
  network_interface_id = aws_instance.Tf_ec2_public.primary_network_interface_id
}

70_routetable.tf

resource "aws_route_table" "Ft_rt_public" {
  vpc_id = aws_vpc.Tf_network-test-vpc.id # VPCのIDを指定

  # 外部向け通信を可能にするためのルート設定
  route {
    cidr_block = var.aws_igw_cidr
    gateway_id = aws_internet_gateway.Tf_igw.id  # 04_IGW.tf
  }

  tags = {
    Name  = "Ft_rt_public"
  }
}

#ルートテーブルをpublic subnet側にアタッチ
resource "aws_route_table_association" "public_route_table_1a" {
  route_table_id = aws_route_table.Ft_rt_public.id 
  subnet_id = aws_subnet.Tf_network-test-public.id # 02_subnet_public.tf
}


resource "aws_route_table" "Ft_rt_private" {
  vpc_id = aws_vpc.Tf_network-test-vpc.id # VPCのIDを指定 01_vpc,tf

  # 外部向け通信を可能にするためのルート設定
  route {
    cidr_block = var.aws_igw_cidr
    nat_gateway_id = aws_nat_gateway.Tf_nat.id # 05_NAtGateway.tf
  }

  tags = {
    Name  = "Ft_rt_private"
  }
}

#ルートテーブルをprivate subnet側にアタッチ
resource "aws_route_table_association" "Tf_private_route_table" {
  route_table_id = aws_route_table.Ft_rt_private.id
  subnet_id = aws_subnet.Tf_network-test-private.id # 03_subnet_private.tf
}

71_routetable_Natgateway.tf

resource "aws_route_table" "Ft_rt_natgateway" {
  vpc_id = aws_vpc.Tf_network-test-vpc.id # VPCのIDを指定

  # 外部向け通信を可能にするためのルート設定
  route {
    cidr_block = var.aws_igw_cidr
    nat_gateway_id = aws_nat_gateway.Tf_nat.id # 05_NAtGateway.tf
    
  }

  tags = {
    Name  = "aws-network-test-private"
  }
}

80_ec2_key_variables.tf

###########################################
#キーペア
###########################################
resource "tls_private_key" "main" {
    algorithm = "RSA"
    rsa_bits = 4096
}

81_ec2_key_public.tf

# 公開鍵(OPENSSHフォーマット)
#tls_private_key.pub.public_key_openssh

resource "aws_key_pair" "pub" {
    key_name = var.aws_ec2_public_key
    public_key = tls_private_key.main.public_key_openssh

    tags = {
        Name = var.aws_ec2_public_key
    }
}

resource "local_file" "keypair_pub_pem" {
    filename = "${path.module}/keypair_pub.pem"
    sensitive_content = tls_private_key.main.private_key_pem
    file_permission = "0600" # 秘密鍵は権限を0600に変更する。
}
resource "local_file" "keypair_pub" {
    filename = "${path.module}/keypair_pub.pub"
    sensitive_content = tls_private_key.main.public_key_openssh
    file_permission = "0600" # 公開鍵も権限を0600に変更する。(必須ではない。)
}

82_ec2_key_private.tf

# 公開鍵(OPENSSHフォーマット)
#tls_private_key.pri.private_key_openssh

resource "aws_key_pair" "pri" {
    key_name = var.aws_ec2_private_key
    public_key = tls_private_key.main.public_key_openssh

    tags = {
        Name = var.aws_ec2_private_key
    }
}

resource "local_file" "keypair_pri_pem" {
    filename = "${path.module}/keypair_pri.pem"
    sensitive_content = tls_private_key.main.private_key_pem
    file_permission = "0600" # 秘密鍵は権限を0600に変更する。
}

resource "local_file" "keypair_pri" {
    filename = "${path.module}/keypair_pri.pub"
    sensitive_content = tls_private_key.main.public_key_openssh
    file_permission = "0600" # 公開鍵も権限を0600に変更する。(必須ではない。)
}

90_variables.tf

variable aws_region {}
variable aws_region_a {}
variable aws_region_c {}
variable aws_vpc_cidr {}
variable aws_subnet_cidr_public {}
variable aws_subnet_cidr_private {}

variable aws_igw_cidr  {}
variable aws_ec2_public_key  {}
variable aws_ec2_private_key {}

variable aws_ec2_instance_type {}
variable aws_ec2_public_tags_name {}
variable aws_ec2_private_tags_name {}

variable aws_elastic_ip_tags_name {}
variable aws_natgateway_tags_name {}

99_terraform.tfvars

aws_region              = "us-east-1"
aws_region_a            = "us-east-1a"
aws_region_c            = "us-east-1c"
aws_vpc_cidr            = "172.16.1.0/24"
aws_subnet_cidr_public  = "172.16.1.0/25"
aws_subnet_cidr_private = "172.16.1.128/25"
aws_igw_cidr            = "0.0.0.0/0"

aws_ec2_public_key      = "ec2_public_keypair"
aws_ec2_private_key     = "ec2_private_keypair"

aws_ec2_instance_type   = "t2.micro"
aws_ec2_public_tags_name   = "Tf_ec2_public"
aws_ec2_private_tags_name   = "Tf_ec2_pravite"

aws_elastic_ip_tags_name   = "Tf_Elastic_IP"
aws_natgateway_tags_name   = "Tf_natgateway"

Terraformの実行

terraform init
terraform plan -var-file .\99_terraform.tfvars
terraform apply -var-file .\99_terraform.tfvars