EC2のWindowsにAWS Systems Manager Fleet ManagerのRDP接続できるように設定するTerraformコード

### 1. VPC の作成

EC2 インスタンスが配置されるネットワークを定義します。
CIDR ブロックを設定します (例: 10.0.0.0/16)。
### 2. サブネットの作成

VPC 内に配置するサブネットを定義します。
サブネットに関連付ける CIDR ブロックを設定します。
### 3. インターネットゲートウェイ (IGW) の作成

VPC 内からインターネットアクセスを可能にするゲートウェイを作成します。
### 4. ルートテーブルの作成と関連付け

インターネットゲートウェイへのルートを設定したルートテーブルを作成し、サブネットに関連付けます。
### 5. セキュリティグループ (SG) の作成

RDP (ポート 3389) や必要に応じた他の通信を許可するセキュリティグループを作成します。
### 6. IAM ロールとインスタンスプロファイルの作成

EC2 インスタンスが AWS Systems Manager (SSM) を利用できるようにする IAM ロールとインスタンスプロファイルを作成します。
### 4. EC2 インスタンスの作成

VPC、サブネット、セキュリティグループ、IAM ロールを指定して EC2 インスタンスを作成します。

```
# 1. VPC と関連リソースの定義

resource "aws_vpc" "main_vpc" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "main-vpc"
  }
}

resource "aws_subnet" "main_subnet" {
  vpc_id            = aws_vpc.main_vpc.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "us-east-1a"

  tags = {
    Name = "main-subnet"
  }
}

resource "aws_internet_gateway" "main_igw" {
  vpc_id = aws_vpc.main_vpc.id

  tags = {
    Name = "main-igw"
  }
}

resource "aws_route_table" "main_route_table" {
  vpc_id = aws_vpc.main_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main_igw.id
  }

  tags = {
    Name = "main-route-table"
  }
}

resource "aws_route_table_association" "main_subnet_association" {
  subnet_id      = aws_subnet.main_subnet.id
  route_table_id = aws_route_table.main_route_table.id
}

# 2. セキュリティグループの作成

resource "aws_security_group" "main_sg" {
  name   = "main-sg"
  vpc_id = aws_vpc.main_vpc.id

  ingress {
    from_port   = 3389
    to_port     = 3389
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # 必要に応じて制限
  }

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

  tags = {
    Name = "main-sg"
  }
}

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

data "aws_iam_policy_document" "ec2_ssm_trust" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "ec2_ssm_role" {
  name               = "EC2-SSM-Role"
  assume_role_policy = data.aws_iam_policy_document.ec2_ssm_trust.json
}

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

resource "aws_iam_instance_profile" "ec2_ssm_instance_profile" {
  name = "EC2-SSM-InstanceProfile"
  role = aws_iam_role.ec2_ssm_role.name
}

# 4. EC2 インスタンスの作成

resource "aws_instance" "windows_instance" {
  ami                         = data.aws_ami.windows_server.id
  instance_type               = "t3.medium"
  subnet_id                   = aws_subnet.main_subnet.id
  vpc_security_group_ids      = [aws_security_group.main_sg.id]
  iam_instance_profile        = aws_iam_instance_profile.ec2_ssm_instance_profile.name
    key_name                  = "my-key-pair" # 作成したキーペア名

  # パブリック IP を割り当てる設定 (Elastic IP を使うため不要)
  # associate_public_ip_address = true

  tags = {
    Name = "WindowsServer-for-SSM-Fleet-Manager"
  }
}


data "aws_ami" "windows_server" {
  most_recent = true
  owners      = ["amazon"]

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

# Elastic IP の作成
resource "aws_eip" "main_eip" {
  vpc = true

  tags = {
    Name = "ElasticIP-for-Windows-Instance"
  }
}

# Elastic IP をインスタンスに関連付け
resource "aws_eip_association" "main_eip_association" {
  instance_id   = aws_instance.windows_instance.id
  allocation_id = aws_eip.main_eip.id
}

```
- Windows Server AMI を使用した EC2 インスタンスを起動
<br>

- EC2 インスタンスに SSM Agent を使えるようにするための IAM ロール (AmazonSSMManagedInstanceCore) をアタッチ
<br>

- 起動した EC2 インスタンスを AWS Systems Manager Fleet Manager の RDP 接続対象とする

RDP ポート(3389)自体は直接開放しなくても、SSM のポートフォワーディング機能経由で RDP 接続が可能になるため、セキュリティグループで 3389 を開ける必要はありません。

以下は最小構成の例です。必要に応じてインスタンスタイプや AMI 名、サブネット ID、セキュリティグループ ID、キーペアなどを調整してください

## デプロイ後の確認
- Terraform Apply
上記のコードを main.tf などに保存し、terraform init && terraform apply を実行してデプロイします。

- SSM エージェントの稼働確認
AWS の提供する Windows AMI にはあらかじめ SSM エージェントがインストールされています。インスタンス起動後、数分で Systems Manager → Fleet Manager の一覧上に当該インスタンスが表示されるはずです。

- Fleet Manager からの RDP セッション
マネジメントコンソールで Systems Manager → Fleet Manager → 対象インスタンスを選択 → Node actions → Start remote control → RDP を選択し、RDP での接続を開始します。

ユーザー名はデフォルト (Administrator など)
パスワードはインスタンスの Administrator パスワードを取得して入力
これで、SSM を経由した RDP 接続が可能となります。セキュリティグループやパブリック IP を気にせず、プライベートサブネット内でも安全に RDP を行うことができます。

## 手元のRDPクライアントを使いたい場合の方法
もし「Systems Manager (SSM) 経由でポートをフォワードして、手元のPCにインストールされているRDPクライアント(mstsc.exe)を使いたい」場合は、次のような手順で実現できます。

### 1. SSM Session Managerでポート転送を開始

AWS CLI を使って session-manager-plugin 経由でポート転送セッションを開始します。
例として、EC2 インスタンスのプライベート IP アドレスのポート3389を、ローカルの任意のポート (たとえば 13389) にフォワードするイメージです。
```bash
aws ssm start-session \
    --target i-0123456789abcdef0 \
    --document-name AWS-StartPortForwardingSession \
    --parameters '{"portNumber":["3389"],"localPortNumber":["13389"]}'

```
### 2. ローカルの RDPクライアント（mstsc.exe）を起動

- 手元の Windows PC で mstsc.exe を起動し、コンピューター名(接続先)に 127.0.0.1:13389 を指定して RDP 接続します。
- これにより、SSM 経由でトンネリングされた先の EC2 インスタンス(ポート3389)へ接続できます。
- ユーザー名は Administrator、パスワードは EC2 コンソールから取得したものを使います。

これで、インターネット経由で 3389 ポートを直接開放する必要なく、手元のRDPクライアントを使ってプライベートサブネット内のEC2インスタンスへ安全に接続できます。

---
##　追記
### パブリック IP を使いたくないので、Elastic IP をアタッチする方法に修正

### ・EC2 インスタンスの修正
Elastic IP をアタッチする場合、associate_public_ip_address を設定する必要はありません。

### ・Elastic IP の確認
Terraform 適用後、AWS マネジメントコンソールで以下を確認します：

1. EC2 サービス → 対象インスタンスを選択。
2. 「ネットワーク設定」のセクションで Elastic IP が関連付けられていることを確認。

### ・セキュリティの確認
セキュリティグループの設定でポート 3389 (RDP) を適切に制限してください。
例: 自分のグローバル IP アドレスに制限。

### Elastic IP の利点
- パブリック IP を直接利用せず、Elastic IP をインスタンスに固定的に割り当てられるため、IP アドレスが変更される心配がありません。
- インスタンスの再起動や停止・起動時にも IP アドレスを維持できます。