【爆速】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
こちらもおすすめ
-
Terraform AWS Moduleのすすめ
2022.5.25
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28
AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16