【爆速】TerraformでプライベートサブネットのEC2へSession Managerからアクセス可能な環境を構築する: NAT Gateway編
はじめに
こんにちは、Shunです!
EC2を使った検証をする際に、プライベートサブネットにEC2を立てて、NATゲートウェイを作って、ルートテーブルを更新するなど、毎回環境を構築するのは面倒くさいですよね!
そこで、爆速かつセキュアにEC2を検証するTerraformテンプレートをご紹介します!
NATゲートウェイではなく、VPCエンドポイントを使った環境を作りたい方はこちら!
爆速で、CloudFront + S3の静的サイトホスティング環境を作りたい方はこちら!
構築するアーキテクチャ
今回、構築するシステム構成図です。
Session Managerからアクセスするために、Internet Gateway、NAT Gateway等を構築します。

terraformファイル構成
今回使用するtfファイルは以下の構成になっています。
├─ provider.tf ├─ vpc.tf └─ ec2.tf
1.providers.tf
locals内の変数を書き換えるだけで、利用可能です。
locals {
aws_id = "[アカウントID]"
name_prefix = "[名前]"
region = "[リージョン]"
Environment = "[環境名]"
}
terraform {
required_version = "~> 1.7.0"
backend "s3" {
key = "[S3のkey]"
bucket = "[バケット名]"
region = "[リージョン]"
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
variable "vpc" {
description = "Parameter for VPC"
type = string
default = "10.0.0.0/16"
}
variable "public_subnet" {
description = "Parameter for public subnet"
type = string
default = "10.0.0.0/24"
}
variable "private_subnet" {
description = "Parameter for private subnet"
type = string
default = "10.0.128.0/24"
}
variable "default_instance_type" {
default = "t2.micro"
}
2. vpc.tf
vpc.tfでは、3つのことを実施しています。
- VPC、サブネットなどネットワークの構築
- Internet GatewayとNAT Gatewayの作成
- Internet GatewayとNAT Gatewayへ疎通可能なルートテーブルの作成
####################
# vpc
####################
resource "aws_vpc" "main" {
cidr_block = var.vpc
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${local.name_prefix}-${local.Environment}-vpc"
}
}
####################
# subnet
####################
resource "aws_subnet" "public_1a" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet
availability_zone = "ap-northeast-1a"
tags = {
Name = "${local.name_prefix}-${local.Environment}-public-1a"
}
}
# プライベートサブネット作成
resource "aws_subnet" "private_1a" {
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet
availability_zone = "ap-northeast-1a"
tags = {
Name = "${local.name_prefix}-${local.Environment}-private-1a"
}
}
####################
# internet gateway
####################
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.name_prefix}-${local.Environment}-igw"
}
}
####################
# route table
####################
# public_ルートテーブル作成
resource "aws_route_table" "public_1a" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.name_prefix}-${local.Environment}-public-1a"
}
}
# private_ルートテーブル作成
resource "aws_route_table" "private_1a" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.name_prefix}-${local.Environment}-private-1a"
}
}
# public_ルート作成
resource "aws_route" "public_igw_1a" {
destination_cidr_block = "0.0.0.0/0"
route_table_id = aws_route_table.public_1a.id
gateway_id = aws_internet_gateway.main.id
}
# private_ルート作成
resource "aws_route" "nat_1a" {
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat_1a.id
route_table_id = aws_route_table.private_1a.id
}
# public_ルートテーブル紐づけ
resource "aws_route_table_association" "public_1a" {
subnet_id = aws_subnet.public_1a.id
route_table_id = aws_route_table.public_1a.id
}
# private_ルートテーブル紐づけ
resource "aws_route_table_association" "private_1a" {
subnet_id = aws_subnet.private_1a.id
route_table_id = aws_route_table.private_1a.id
}
####################
# nat gateway
####################
# NATゲートウェイ(AZ-1a)に割り当てるEIPを作成
resource "aws_eip" "nat_1a" {
domain = "vpc"
tags = {
Name = "${local.name_prefix}-${local.Environment}-nat-1a"
}
}
# NATゲートウェイ(AZ-1a)作成
resource "aws_nat_gateway" "nat_1a" {
allocation_id = aws_eip.nat_1a.id
subnet_id = aws_subnet.public_1a.id
depends_on = [aws_internet_gateway.main]
tags = {
Name = "${local.name_prefix}-${local.Environment}-ngw-1a"
}
}
3. ec2.tf
ec2.tfでは、3つのことを実施しています。
- 最新のAmazon LinuxのAMIを取得し、EC2を構築
- インバウンドを許可しないセキュリティグループを作成
- Session Managerを使用するためのIAMを作成し、EC2へ付与
####################
# ami
####################
data "aws_ami" "latest_amazon_linux2" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}
####################
# ec2
####################
resource "aws_instance" "main" {
instance_type = var.default_instance_type
ami = data.aws_ami.latest_amazon_linux2.id
subnet_id = aws_subnet.private_1a.id
vpc_security_group_ids = [aws_security_group.main.id]
iam_instance_profile = aws_iam_instance_profile.example_profile.name
root_block_device {
volume_size = 8
volume_type = "gp3"
iops = 3000
throughput = 125
delete_on_termination = true
# EBSのNameタグ
tags = {
Name = "${local.name_prefix}-${local.Environment}"
}
}
lifecycle {
ignore_changes = [
ami,
]
}
tags = {
Name = "${local.name_prefix}-${local.Environment}"
}
}
####################
# security group
####################
resource "aws_security_group" "main" {
name = "${local.name_prefix}-${local.Environment}-sg"
vpc_id = aws_vpc.main.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${local.name_prefix}-${local.Environment}-sg"
}
}
####################
# ec2 iam role
####################
# インスタンスプロファイルを作成
resource "aws_iam_instance_profile" "example_profile" {
name = "${local.name_prefix}-${local.Environment}-ssm"
role = aws_iam_role.ssm_role.name
}
resource "aws_iam_role" "ssm_role" {
name = "${local.name_prefix}-${local.Environment}-ssm"
assume_role_policy = data.aws_iam_policy_document.assume_role.json
}
data "aws_iam_policy_document" "assume_role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy_attachment" "ssm_managed_instance_core" {
role = aws_iam_role.ssm_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
環境構築
今回は、CloudShellを用いて、Terraformを実行します。
CloudShellを開き、以下のコマンドを入力し、Terraformをインストールします。
$ cd ~ $ git clone https://github.com/tfutils/tfenv.git ~/.tfenv $ mkdir -p ~/.local/bin/ $ sudo ln -s ~/.tfenv/bin/* ~/.local/bin/ $ tfenv install 1.7.0 $ tfenv use 1.7.0
続いて、CloudShell内に適当なディレクトリを作成し、今回ご紹介したtfファイルを配置します。
作成したディクトリ配下へ移動し、以下のコマンドを入力します。
$ terraform init $ terraform fmt $ terraform plan
問題なければ、以下のコマンドを実行し、環境へデプロイします。
$ terraform apply
これで環境構築は完了です。
疎通確認
マネジメントコンソールからEC2の画面を開きます。
設定したインスタンスを選択し、セッションマネージャーから接続をします。

以下のように接続ができれば完了です!

さいごに
今回の記事では、プライベートサブネットのEC2へSession Managerからアクセス可能なTerraformテンプレートをご紹介しました!
このテンプレートを使用することで、爆速でセキュアな環境でEC2を利用することができます!
是非、テンプレートを活用し、セキュアなEC2ライフを送ってください!
最後まで読んでいただきありがとうございます!
テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!
Follow @twitterGoogle Cloud Partner Top Engineer 2025、2024 AWS All Cert、ビール検定1冠
Recommends
こちらもおすすめ
-
AWS無料セミナー開催レポート | 大人気のAWS入門セミナー
2018.11.17
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28

AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16


