0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ap-northeast-1(東京リージョン)におけるセキュアな開発環境のTerraformモジュール完全設計

0
Posted at

ap-northeast-1(東京リージョン)におけるセキュアな開発環境のTerraformモジュール完全設計

Feature(185).png

はじめに

こんにちは、NKKTech Global 技術チームです。

多くの企業で以下のような「開発環境のセキュリティ負債」が見受けられます。

  • SSH接続(ポート22)を開放したパブリック踏み台EC2インスタンスが存在する
  • 開発者ごとに長期有効なIAMアクセスキーを発行し、ローカル端末に平文保存している
  • EBSボリュームやS3バケットが暗号化されていない
  • 開発環境のNAT GatewayがMulti-AZで無駄に起動し、毎月多額の待機コストが発生している

本記事では、AWSのセキュリティベストプラクティス(CIS AWS Foundations Benchmark / Well-Architected Framework)に準拠しつつ、Terraformモジュールとして抽象化・再利用可能な東京リージョン向けセキュア開発基盤の設計を解説します。


1. アーキテクチャ全体設計

設計の4大方針

  1. 踏み台(Bastion)の完全撤廃: AWS Systems Manager(SSM)Session Managerを採用し、インバウンドポート(Port 22)の開放をゼロにします。
  2. IMDSv2の強制: EC2のメタデータ取得におけるSSRF(サーバサイドリクエストフォージェリ)攻撃を防ぐため、IMDSv1を無効化します。
  3. KMS カスタマー管理キー (CMK) による保管時暗号化: EBS、S3、ログのすべてを自社管理のKMSキーで暗号化します。
  4. セキュリティとコストのバランス: 本番ではMulti-AZ必須のNAT Gatewayを、開発環境ではSingle NAT Gatewayに抑え、月額約5,000〜6,000円の固定費を削減します。

2. ディレクトリ構成

Terraformコードは、モジュールとして再利用可能な構造で設計します。

terraform-aws-secure-dev/
├── modules/
│   └── secure_environment/
│       ├── main.tf          # 基本設定・プロバイダー
│       ├── vpc.tf           # ネットワーク・サブネット・NAT GW
│       ├── security.tf      # KMS・IAMロール・セキュリティグループ
│       ├── endpoints.tf     # SSM / S3 VPCエンドポイント
│       ├── compute.tf       # セキュアEC2インスタンス
│       ├── variables.tf     # 入力変数定義
│       └── outputs.tf       # 出力値
└── environments/
    └── dev/
        ├── main.tf          # モジュール呼び出し
        └── backend.tf       # S3 State管理

3. Terraformコード完全実装

① ネットワーク設計 (modules/secure_environment/vpc.tf)

東京リージョンで安定稼働する ap-northeast-1a と ap-northeast-1c を採用し、3層サブネット(Public, Private, Isolated)を構築します。

# VPC作成
resource "aws_vpc" "this" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name        = "${var.environment}-secure-vpc"
    Environment = var.environment
  }
}

# パブリックサブネット (ALB / NAT GW配置用)
resource "aws_subnet" "public" {
  for_each = var.public_subnets

  vpc_id                  = aws_vpc.this.id
  cidr_block              = each.value.cidr
  availability_zone       = each.value.az
  map_public_ip_on_launch = false # デフォルトではパブリックIPを付与しない

  tags = {
    Name = "${var.environment}-public-${each.key}"
  }
}

# プライベートサブネット (アプリケーション・開発インスタンス用)
resource "aws_subnet" "private_app" {
  for_each = var.private_app_subnets

  vpc_id            = aws_vpc.this.id
  cidr_block        = each.value.cidr
  availability_zone = each.value.az

  tags = {
    Name = "${var.environment}-private-app-${each.key}"
  }
}

# アイソレーテッドサブネット (外部通信不要なDB用)
resource "aws_subnet" "isolated_db" {
  for_each = var.isolated_db_subnets

  vpc_id            = aws_vpc.this.id
  cidr_block        = each.value.cidr
  availability_zone = each.value.az

  tags = {
    Name = "${var.environment}-isolated-db-${each.key}"
  }
}

# インターネットゲートウェイ
resource "aws_internet_gateway" "this" {
  vpc_id = aws_vpc.this.id
  tags   = { Name = "${var.environment}-igw" }
}

# 開発環境用 Single NAT Gateway (コスト抑制のため1aのみに配置)
resource "aws_eip" "nat" {
  domain = "vpc"
  tags   = { Name = "${var.environment}-nat-eip" }
}

resource "aws_nat_gateway" "this" {
  allocation_id = aws_eip.nat.id
  subnet_id     = aws_subnet.public["1a"].id
  tags          = { Name = "${var.environment}-single-nat-gw" }

  depends_on = [aws_internet_gateway.this]
}

# ルーティングテーブル定義
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.this.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.this.id
  }
  tags = { Name = "${var.environment}-public-rt" }
}

resource "aws_route_table" "private" {
  vpc_id = aws_vpc.this.id
  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.this.id
  }
  tags = { Name = "${var.environment}-private-rt" }
}

# サブネット関連付け
resource "aws_route_table_association" "public" {
  for_each       = aws_subnet.public
  subnet_id      = each.value.id
  route_table_id = aws_route_table.public.id
}

resource "aws_route_table_association" "private" {
  for_each       = aws_subnet.private_app
  subnet_id      = each.value.id
  route_table_id = aws_route_table.private.id
}

② セキュリティ・KMS・IAM設計 (modules/secure_environment/security.tf)

# 1. 開発環境専用 KMS キー (EBS/ログ暗号化用)
resource "aws_kms_key" "dev_key" {
  description             = "KMS Key for ${var.environment} secure resources"
  deletion_window_in_days = 7
  enable_key_rotation     = true

  tags = { Name = "${var.environment}-kms-key" }
}

# 2. リージョン全体でEBS暗号化をデフォルト有効化
resource "aws_ebs_encryption_by_default" "enabled" {
  enabled = true
}

resource "aws_ebs_default_kms_key" "current" {
  key_arn = aws_kms_key.dev_key.arn
}

# 3. 開発インスタンス用最小権限 IAM ロール (SSM専用)
resource "aws_iam_role" "ec2_ssm_role" {
  name = "${var.environment}-ec2-ssm-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action    = "sts:AssumeRole"
      Effect    = "Allow"
      Principal = { Service = "ec2.amazonaws.com" }
    }]
  })
}

resource "aws_iam_role_policy_attachment" "ssm_core" {
  role       = aws_iam_role.ec2_ssm_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

resource "aws_iam_instance_profile" "ec2_profile" {
  name = "${var.environment}-ec2-instance-profile"
  role = aws_iam_role.ec2_ssm_role.name
}

# 4. セキュリティグループ (インバウンド完全遮断)
resource "aws_security_group" "private_app_sg" {
  name        = "${var.environment}-private-app-sg"
  description = "Security group for private app instances (No Inbound)"
  vpc_id      = aws_vpc.this.id

  # インバウンドルールなし (SSMはアウトバウンドHTTPSのみで接続可能)

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = { Name = "${var.environment}-private-app-sg" }
}

③ コンピュート設計 (modules/secure_environment/compute.tf)

IMDSv2を強制し、暗号化EBSをアタッチした開発用EC2インスタンスです。

resource "aws_instance" "dev_instance" {
  ami                  = var.ami_id # Amazon Linux 2023 (ap-northeast-1)
  instance_type        = var.instance_type
  subnet_id            = aws_subnet.private_app["1a"].id
  iam_instance_profile = aws_iam_instance_profile.ec2_profile.name
  vpc_security_group_ids = [
    aws_security_group.private_app_sg.id
  ]

  # IMDSv2の強制 (必須セキュリティ設定)
  metadata_options {
    http_endpoint               = "enabled"
    http_tokens                 = "required" # IMDSv1を無効化
    http_put_response_hop_limit = 1
  }

  # ルートボリュームの暗号化 (KMS CMK)
  root_block_device {
    volume_size           = 30
    volume_type           = "gp3"
    encrypted             = true
    kms_key_id            = aws_kms_key.dev_key.arn
    delete_on_termination = true
  }

  tags = {
    Name        = "${var.environment}-dev-app-server"
    AutoStop    = "true" # 夜間停止スクリプト用タグ
    Environment = var.environment
  }
}

4. 開発者の接続方法:SSHキー不要のセキュア接続

開発者は公開鍵(.pem / .pub)を持つ必要はありません。AWS CLIがインストールされた端末から、IAM権限に基づいてワンコマンドでログインします。

# 1. インスタンスIDの確認
aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=dev-dev-app-server" \
    --query "Reservations[].Instances[].InstanceId" --output text

# 2. SSM セッションマネージャーで直接シェル起動 (ポート22開放不要)
aws ssm start-session --target i-0123456789abcdef0

# 3. ローカルからのポートフォワード (例: リモートのDBやWebポートを手元に転送)
aws ssm start-session \
    --target i-0123456789abcdef0 \
    --document-name AWS-StartPortForwardingSession \
    --parameters '{"portNumber":["8080"],"localPortNumber":["8080"]}'

5. 運用コストをさらに下げる自動化(FinOps)

開発環境のクラウド破産を防ぐため、以下の自動化を推奨します。

  1. 夜間・休日のEC2自動停止:
    AutoStop = "true" タグが付与されたインスタンスを、Amazon EventBridge + AWS Systems Manager Automation で平日19:00に自動停止し、月額コストを約60%カットします。
  2. gp3ボリュームの採用:
    旧来のgp2からgp3に切り替えるだけで、ストレージコストを最大20%削減しつつベーススループットを向上させます。
  3. Single NAT Gatewayの維持:
    本番昇格時はMulti-AZ NATに変更しますが、開発環境では1つに絞ることで、月額約45ドル(約7,000円)のNAT待機コストを削減します。

まとめ:セキュリティと開発体験(DX)は両立できる

「厳格なセキュリティ」と「使いやすい開発環境」は決して相反しません。

  • VPCの3層分離とSingle NATで、安全かつ低コストな基盤を構築する。
  • SSM Session Managerで、秘密鍵管理の煩わしさとポート開放リスクを同時に排除する。
  • IMDSv2 & KMS暗号化をTerraformでコード化し、人手による設定漏れをゼロにする。

NKKTech Globalでは、このような「セキュア・バイ・デザイン」を徹底したクラウドインフラ構築を、日本およびグローバル企業のプロジェクトで標準採用しています。


お問い合わせ先

セキュアなAWS基盤の構築、TerraformによるIaC導入、クラウドコスト削減(FinOps)のご相談は、下記よりお気軽にお問い合わせください。

著者:NKKTech Global 技術チーム
私たちは、強固なクラウドセキュリティとIaC自動化技術で、企業の安全かつ迅速なDXを支援します。

0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?