プライベートサブネットのWindowsServerにリモートデスクトップ接続

今回は久しぶりにAWSについてのお話です。

# Problem

VPC内でWindowsServerが稼働中。
当該サーバーにリモートデスクトップ接続したいが、プライベートサブネット内にある上、仮にこれをパブリックサブネット内に移したとしてもインターネット経由の接続は組織のポリシーで禁止。
AWSCLIとIAMユーザー・アクセスキーを使用したリモートデスクトップ接続の手法はあるが、アクセスキーの作成も組織のポリシーで禁止。

# Solution

AWS管理コンソールからフリートマネージャー（Fleet Manager）でリモートデスクトップ接続する。

## ポイント

* WindowsServerが起動するEC2インスタンスには `AmazonSSMManagedInstanceCore`許可ポリシーを含むIAMロールをアタッチ
* 3つのVPCエンドポイント `com.amazonaws.[region].ssm`・`com.amazonaws.[region].ssmmessages`・`com.amazonaws.[region].ec2messages` を作成
* EC2インスタンスとVPCエンドポイントの間でHTTPS（ポート443）の通信が可能になるようセキュリティグループを設定
* インスタンスのキーペアを使いAWS管理コンソールからフリートマネージャー（Fleet Manager）で接続

:::note
参考にしたAWS公式の記事： [インターネットにアクセスしなくても、 VPC エンドポイントを作成して、Systems Manager でプライベート EC2 インスタンスを管理するにはどうすればよいですか?](https://repost.aws/ja/knowledge-center/ec2-systems-manager-vpc-endpoints)
:::

:::note warn
今回はEC2インスタンスを起動するにあたってWindowsServer2022のAMIを使用しているのでSSM Agentが初期インストールされていますが、OSバージョン／エディションによってはユーザー開発者自身でインストールしなくてはならないものもあるそうです。ご注意ください。
:::

## 設定の例

まずは手順を説明するための例としてWindowsServerを起動します：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/e88703f2-69b0-e60c-7979-2f193e9a708e.png)

適当なOSバージョン／エディションを選んで・・・：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/75fe9a95-9777-3b12-dc32-f49ffdfe3153.png)

例示用なのでインスタンスタイプは最小で・・・：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/fbae8ee6-51ac-619a-d9bb-370c0a063819.png)

キーペアを作成。リモートデスクトップ接続時に必要になります：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/37692db6-749d-631c-ef13-a500a763a6ff.png)

VPCやサブネットに想定通りのものが選ばれているか確認しつつ（もちろん想定と異なっていたら設定変更）、「からのRDPトラフィックを許可」はOFFに：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/5c4ee487-810e-9fe4-533f-80eec193ff30.png)

ページ最下部右下の「インスタンスを起動」をクリック。

ここからがリモートデスクトップ接続のための設定手順。まずはWindowsServerのEC2インスタンスにアタッチするロールを作成します：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/f9bf4172-9b16-bb05-b26a-5083b98f80a6.png)

ユースケースとして「EC2 Role for AWS Systems Manager」を選択：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/bb5f5c0b-f9fb-f9f7-bdd9-3020de7dd99b.png)

それ以外はデフォルトの内容で、適当な名前をつけて作成：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/181a3270-ddb3-a005-b8ba-d60bb9bb02aa.png)

作成されるロールは `AmazonSSMManagedInstanceCore`許可ポリシーを含み、以下の信頼関係を持つものになります（`ec2.amazonaws.com`サービスによる`AssumeRole`が可能なもの）：

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

作成したIAMロールをEC2インスタンスにアタッチします：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/cea4233f-e27a-a7ad-b2cf-bd9b2900e9d8.png)

続いて、VPCエンドポイントを作成していきます：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/11188eb7-16ce-a4f3-c4cb-275e79538dbc.png)

3つのエンドポイント `ssm`・`ssmmessages`・`ec2messages`を作成します：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/5b22f4f7-6187-82dd-4547-8c8caec328cb.png)

もちろんEC2インスタンスと同じサブネットに作成します：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/b750e227-1a79-6c0d-f2bc-5d647dc99779.png)

セキュリティグループについては今回は設定の手間を少なくするためにEC2インスタンス用に自動で作成されたものを流用することに・・・：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/b1617319-eab3-4e14-3180-816ca14b9834.png)

セキュリティグループのインバウンドルールに同じグループ内のIPアドレスからの接続を許可するルールを追加します。今回はEC2インスタンスとVPCエンドポイントを1つのグループに入れてしまっているのでソースには以下のように同じグループのIDを指定：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/d3c42be0-de51-9793-88b4-55938c826be3.png)

:::note
AWSの記事（前掲）にはEC2インスタンスにアタッチするセキュリティグループの設定に関して「[ソース] で、VPC CIDR を選択します」とありますが、何もそこまで広範囲で通信を許可する必要はないはず・・・ということで上記のような設定にしています。
:::

SystemsManagerのメニューで「フリートマネージャー」をクリック。表示された「マネージドノード」の一覧にはセキュリティグループの設定後しばらく（数十秒から数分）するとEC2インスタンスが表示されるはずです：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/c94c54db-e529-2d4f-c305-fb97232dac1f.png)

フリートマネージャーの「ノードのアクション」→「接続」→「リモートデスクトップで接続」をクリック：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/52ed7e11-7e8f-65f5-ef4b-bd71186770d2.png)

キーペアを指定してログインしてみます：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/6d6454aa-55dc-a886-275e-743594255034.png)

:::note 
ここではキーペアを指定してログインをしていますが、「ユーザー認証情報」（ようするにユーザー名とパスワード）を使用してログインすることもできます。認証情報を使う場合はそれをまず入手してくる必要があり・・・ここではより簡単なキーペアを利用する方法をとりました。
:::

あとは待っているとリモートデスクトップセッションが開始します：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/66ce46fe-cd21-3f72-abd6-031c16d7b184.png)

:::note warn
VPCエンドポイントやセキュリティグループの設定が終わった後、フリートマネージャーから接続が可能になるまでに数十秒から数分の時間差があるようです。少なくとも私の場合はそうでした。
フロートマネージャーの「マネージドノード」一覧にEC2インスタンスが表示されなかったり、「ノードのアクション」からリモートデスクトップ接続を試みてもタイムアウトエラーになったり・・・
そうした時は設定内容はチェックしつつも、あれこれコロコロ設定変更して試すよりも「まずは数分待ってからリトライしてみる」というが良いかもしれません。
:::