1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Claude Code + Terraform】Session Managerを利用したEC2環境を構築してみた

1
Posted at

概要

この記事Claude Code + Terraformを活用してSession Managerを利用したEC2環境を構築内容を簡潔に説明します。

ClaudeCodeで開発するにあたって、CLAUDE.mdとMCPサーバーを使用する前提で進めたいと思います。
開発環境を用意したい方は下記記事を参考に進めて頂けたらと思います。

Claude Codeを使ってみた

目次

やったこと

  1. 構成図の作成
  2. Terraformで開発
  3. 動作検証

手順

具体的な手順をステップバイステップで説明します。

ステップ1: 構成図の作成

Claudeに構成図を作ってもらいます。
構成図についてはアイコンなど用意せずに最低限内容が理解できるもので良いかと思われます。

image.png

ステップ2: Terraformで開発

構成図を使ってClaude Codeに開発してもらいましょう。

image.png

CLAUDE.mdで開発フローは定義しているので対象サービスの調査から開発まで基本一通り作業を実施してくれます。
作業を終えた後、以下のようにterraformディレクトリ内にファイルが作成されているはずです。

├── main.tf               # AWSインフラ全体のエントリーポイント
├── output.tf             # Terraform実行後に出力される値を定義
├── variables.tf          # モジュールが受け取る変数の型・説明・デフォルト値を定義
├── terraform.tfvars      # 変数の実際の値を定義
|
└── modules/              # AWSインフラの各コンポーネントを定義するモジュール
    ├── ec2/              # EC2インスタンスの定義
    ├── iam/              # IAMロールとポリシーの定義
    ├── ssm/              # SSMパラメータストアの定義
    ├── vpc/              # VPCとサブネットの定義
    └── vpc_endpoints/    # VPCエンドポイントの定義

一通り作成された成果物の中身を一部抜粋して見ていきましょう。

main.tf

各モジュールの変数に対して値が定義されています。
また、EC2モジュールについてはdepends_onを定義して明示的な依存関係が設定されています。

  • vpc_endpoints: VPCエンドポイントが存在しないとSSMエージェントが起動直後に通信できない
  • ssm: Session Managerのドキュメント・ログ設定が整ってからEC2を起動する

Terraformは通常、参照関係から依存を自動解決しますが、ssm モジュールは直接の出力参照がないため depends_onで明示的に指定しています。

module "vpc" {
  source = "./modules/vpc"

  project             = var.project
  environment         = var.environment
  vpc_cidr            = var.vpc_cidr
  private_subnet_cidr = var.private_subnet_cidr
  availability_zone   = var.availability_zone
}

module "vpc_endpoints" {
  source = "./modules/vpc_endpoints"

  project           = var.project
  environment       = var.environment
  vpc_id            = module.vpc.vpc_id
  vpc_cidr_block    = module.vpc.vpc_cidr_block
  private_subnet_id = module.vpc.private_subnet_id
  region            = var.region
}

module "iam" {
  source = "./modules/iam"

  project     = var.project
  environment = var.environment
}

module "ssm" {
  source = "./modules/ssm"

  project            = var.project
  environment        = var.environment
  log_retention_days = var.log_retention_days
}

module "ec2" {
  source = "./modules/ec2"

  project                   = var.project
  environment               = var.environment
  instance_type             = var.instance_type
  subnet_id                 = module.vpc.private_subnet_id
  security_group_id         = module.vpc_endpoints.ec2_security_group_id
  iam_instance_profile_name = module.iam.instance_profile_name

  depends_on = [module.vpc_endpoints, module.ssm]
}

vpc_endpoints/main.tf

SessionManagerをプライベートサブネットで使うために必要なセキュリティグループとVPCエンドポイントが定義されています。

セキュリティグループ
名前 説明
vpce-sg ・インバウンド: VPC内からHTTPS(443)を許可
・EC2からのリクエストを受け付けるためのルール
ec2-sg ・アウトバウンド: VPC内へHTTPS(443)を許可
・EC2からVPCエンドポイントへ通信するためのルール
VPCエンドポイント
名前 説明 説明
ssm *.ssm SSMエージェント ↔ SSMサービス間の通信
ssmmessages *.ssmmessages Session Managerのセッション制御
ec2messages *.ec2messages SSMエージェント ↔ EC2サービス間の通信
通信フロー

  EC2 (ec2-sg)                                                                         
    │ HTTPS(443) アウトバウンド
    ▼ 
 VPCエンドポイント (vpce-sg)
    │ HTTPS(443) インバウンド
    ▼ 
 AWS SSMサービス(インターネット不要)
    

VPCエンドポイントとSGを別モジュールで管理した場合は修正案を投げちゃいましょう。


resource "aws_security_group" "vpc_endpoint" {
  name        = "${var.environment}-${var.project}-vpce-sg"
  description = "Security group for VPC endpoints"
  vpc_id      = var.vpc_id

  tags = {
    Name        = "${var.environment}-${var.project}-vpce-sg"
    Environment = var.environment
    Project     = var.project
    ManagedBy   = "Terraform"
  }
}

resource "aws_vpc_security_group_ingress_rule" "vpc_endpoint_https" {
  security_group_id = aws_security_group.vpc_endpoint.id
  description       = "Allow HTTPS from VPC"
  from_port         = 443
  to_port           = 443
  ip_protocol       = "tcp"
  cidr_ipv4         = var.vpc_cidr_block
}

resource "aws_security_group" "ec2" {
  name        = "${var.environment}-${var.project}-ec2-sg"
  description = "Security group for EC2 instances"
  vpc_id      = var.vpc_id

  tags = {
    Name        = "${var.environment}-${var.project}-ec2-sg"
    Environment = var.environment
    Project     = var.project
    ManagedBy   = "Terraform"
  }
}

resource "aws_vpc_security_group_egress_rule" "ec2_https" {
  security_group_id = aws_security_group.ec2.id
  description       = "Allow HTTPS to VPC endpoints"
  from_port         = 443
  to_port           = 443
  ip_protocol       = "tcp"
  cidr_ipv4         = var.vpc_cidr_block
}

resource "aws_vpc_endpoint" "ssm" {
  vpc_id              = var.vpc_id
  service_name        = "com.amazonaws.${var.region}.ssm"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = [var.private_subnet_id]
  security_group_ids  = [aws_security_group.vpc_endpoint.id]
  private_dns_enabled = true

  tags = {
    Name        = "${var.environment}-${var.project}-vpce-ssm"
    Environment = var.environment
    Project     = var.project
    ManagedBy   = "Terraform"
  }
}

resource "aws_vpc_endpoint" "ssmmessages" {
  vpc_id              = var.vpc_id
  service_name        = "com.amazonaws.${var.region}.ssmmessages"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = [var.private_subnet_id]
  security_group_ids  = [aws_security_group.vpc_endpoint.id]
  private_dns_enabled = true

  tags = {
    Name        = "${var.environment}-${var.project}-vpce-ssmmessages"
    Environment = var.environment
    Project     = var.project
    ManagedBy   = "Terraform"
  }
}

resource "aws_vpc_endpoint" "ec2messages" {
  vpc_id              = var.vpc_id
  service_name        = "com.amazonaws.${var.region}.ec2messages"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = [var.private_subnet_id]
  security_group_ids  = [aws_security_group.vpc_endpoint.id]
  private_dns_enabled = true

  tags = {
    Name        = "${var.environment}-${var.project}-vpce-ec2messages"
    Environment = var.environment
    Project     = var.project
    ManagedBy   = "Terraform"
  }
}

resource "aws_vpc_endpoint" "logs" {
  vpc_id              = var.vpc_id
  service_name        = "com.amazonaws.${var.region}.logs"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = [var.private_subnet_id]
  security_group_ids  = [aws_security_group.vpc_endpoint.id]
  private_dns_enabled = true

  tags = {
    Name        = "${var.environment}-${var.project}-vpce-logs"
    Environment = var.environment
    Project     = var.project
    ManagedBy   = "Terraform"
  }
}

その他成果物については特筆すべきことがなく仕様通り構築されていたので割愛します。

動作検証

では実際に構築してもらいましょう。
applyを実行してマネコン上で検証したいと思います。

image.png

インスタンスが出来ていることを確認できました。

image.png

SSMエージェントのステータスも「オンライン」であることを確認し、「接続」ボタンを押下することでコンソール画面が開くこと(接続成功)が確認できました。

image.png

image.png

まとめ

今回はClaude Code + Terraformを活用してSession Managerを利用したEC2環境を構築しました。
構成図の準備(インプット材料)から開発までClaude Codeを主軸に進めることでAI駆動開発のメリットを感じました。

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?