メインコンテンツにスキップ

Terraformで構築するWindows EC2へSSM Session Managerで接続する

はじめに

セキュリティの観点から、EC2インスタンスへのリモートアクセスには踏み台サーバーやVPN接続ではなく、AWS Systems Manager (SSM) の Session Manager を利用することが推奨されています。RDPポート(3389)を公開することなく、安全にWindows Serverへリモートデスクトップ接続が可能です。

Terraformを使用してWindows EC2インスタンスを構築し、SSM Session Manager経由で接続するための具体的な設定と手順を残します。

前提条件:SSM Agentのインストール

まず押さえておきたい重要なポイントは、AWSが提供する公式のWindows Server AMIには、SSM Agentがデフォルトでプリインストールされているという点です。

  • 対象AMI: Windows Server 2008 R2 (2016年11月以降) から最新のWindows Server 2022まで
  • 対応: 追加のインストール作業は基本的に不要です。

もしカスタムAMIを使用している場合や、常に最新版のSSM Agentを利用したい場合は、後述するuser_dataを使用してインスタンス起動時に最新版をインストールする方法が有効です。

Terraformによる環境構築

それでは、Terraformを使用して、SSM Session Managerで接続可能なWindows EC2インスタンスを構築します。

1. IAMロールとインスタンスプロファイルの作成

EC2インスタンスがSSM APIと通信するためには、適切な権限を持つIAMロールが必要です。ここでは、AWS管理ポリシーのAmazonSSMManagedInstanceCoreをアタッチします。

########################
# 1) IAM ロール & プロファイル
########################
resource "aws_iam_role" "ec2_ssm" {
  name = "ec2-ssm-role-for-windows"
  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.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

resource "aws_iam_instance_profile" "ec2_ssm_profile" {
  name = "ec2-ssm-profile-for-windows"
  role = aws_iam_role.ec2_ssm.name
}

2. 最新のWindows AMIの取得

aws_amiデータソースを使用して、常に最新の公式Windows Server 2022のAMI IDを取得します。

########################
# 2) 最新 Windows AMI
########################
data "aws_ami" "windows2022" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["Windows_Server-2022-Japanese-Full-Base-*"]
  }
}

3. EC2インスタンスの起動

取得したAMIと作成したIAMインスタンスプロファイルを使用して、EC2インスタンスを起動します。 user_dataでは、念のため最新版のSSM Agentを上書きインストールし、サービスを自動起動に設定するPowerShellスクリプトを記述しています。

########################
# 3) EC2 インスタンス
########################
locals {
  # ap-northeast-1 用 SSM Agent 最新版
  ssm_url = "https://amazon-ssm-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe"
}

resource "aws_instance" "win_server" {
  ami                    = data.aws_ami.windows2022.id
  instance_type          = "t3.medium"
  iam_instance_profile   = aws_iam_instance_profile.ec2_ssm_profile.name
  # subnet_id と vpc_security_group_ids はご自身の環境に合わせて設定してください
  # subnet_id              = aws_subnet.private.id
  # vpc_security_group_ids = [aws_security_group.win_sg.id]

  # プリインストール済みでも最新版で上書きするPowerShellスクリプト
  user_data = base64encode(<<-EOF
    <powershell>
    $ProgressPreference = 'SilentlyContinue'
    $TempDir = "C:\Temp"
    if (-not (Test-Path -Path $TempDir)) {
        New-Item -ItemType Directory -Path $TempDir
    }
    Invoke-WebRequest -Uri "${local.ssm_url}" -OutFile "$TempDir\AmazonSSMAgentSetup.exe"
    Start-Process "$TempDir\AmazonSSMAgentSetup.exe" -ArgumentList "/quiet" -Wait
    Set-Service -Name AmazonSSMAgent -StartupType Automatic
    Start-Service -Name AmazonSSMAgent
    </powershell>
  EOF
  )

  tags = {
    Name = "Windows-Server-for-SSM"
  }
}

4. (任意) SSM Agentの継続的な自動更新

State Managerを利用して、SSM Agentを定期的に(例:30日ごと)自動更新する設定です。これにより、手動でのエージェント管理が不要になります。

########################
# 4) SSM Agent 自動アップデート (任意)
########################
resource "aws_ssm_association" "auto_update_agent" {
  name = "AWS-UpdateSSMAgent"
  targets {
    key    = "InstanceIds"
    values = [aws_instance.win_server.id]
  }
  # 30日ごとにチェック
  schedule_expression = "rate(30 days)"
}

動作確認

Terraformでのデプロイ後、以下のAWS CLIコマンドでSSM Agentが正常にAWSと通信できているか確認できます。

aws ssm describe-instance-information \
  --filters "Key=InstanceIds,Values=<対象のインスタンスID>" \
  --query "InstanceInformationList[].PingStatus"

"Online" というステータスが返ってくれば、Session Managerで接続する準備が整っています。