AWS Systems Managerにオンプレ環境(非EC2)のWindows Serverを追加する

# 概要

AWS Systems Managerのマネージドノードにオンプレミス環境(つまり非EC2)のWindows Serverを追加します。私の環境では公式ドキュメントのコマンドではうまく行かず、結局クラスメソッドさんのDevelopersIOのやり方で追加しましたので備忘録として記録しておきます。何か特別な方法をするというわけではありません(昔のコマンドだとうまくいった、という話)。

私の環境でたまたま発生しただけかもしれませんが、同じような現象の方がいればと思い記録しておきます。なお、2024年10月23日時点での結果です。

ここでは、IAMロールの準備やアクティベーションの準備は説明しないので、公式ドキュメントやDevelopersIOを参照して下さい。

- Systems Managerを利用したハイブリッドおよびマルチクラウド環境でのサーバーの管理
    - https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-hybrid-multicloud.html
- AWS Systems Managerでオンプレ環境のWindowsを管理する
    - https://dev.classmethod.jp/articles/aws-systems-manager-on-premise-windows-2019/

## 確認環境

- Windows Server 2022 Standard 21H2
- PowerShell 7.4.5
- Administrator権限で実行

## ポイント

結局はこういうことでした。

- AWS公式ドキュメントで説明されている `ssm-setup-cli.exe` コマンドでは登録がうまく行かない
    - AmazonSSMAgentサービス起動時に、identity関連(IAM関連?)のエラーが出てエージェントが起動できないようです
- DevelopersIOで説明されている `AmazonSSMAgentSetup.exe` なら問題なく登録できる


# 実際の作業
## うまくいかなかった方法

[AWS公式ドキュメント](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/hybrid-multicloud-ssm-agent-install-windows.html)の通り(2024-10-23時点)だと、以下のコマンドを実行することになります。( `ssm-setup-cli.exe` に `-skip-signature-validation` オプションを追加しています)

```powershell
[System.Net.ServicePointManager]::SecurityProtocol = 'TLS12'
$code   = "<アクティベーションコード>"
$id     = "<アクティベーションID>"
$region = "<リージョン>"
$dir = $env:TEMP + "\ssm"
New-Item -ItemType directory -Path $dir -Force
cd $dir
(New-Object System.Net.WebClient).DownloadFile("https://amazon-ssm-$region.s3.$region.amazonaws.com/latest/windows_amd64/ssm-setup-cli.exe", $dir + "\ssm-setup-cli.exe")
./ssm-setup-cli.exe -skip-signature-validation -register -activation-code="$code" -activation-id="$id" -region="$region"
Get-Content ($env:ProgramData + "\Amazon\SSM\InstanceData\registration")
Get-Service -Name "AmazonSSMAgent"
```

8行目で `ssm-setup-cli.exe` をダウンロードし、9行目で実行しますが、これを実行したときに以下のようなエラーがでます。AmazonSSMAgentサービスがうまく起動できていないようです。WARNは文字化けで見えないので、 `$env:ProgramData + "\Amazon\SSM\Logs"` ディレクトリを確認します。

```powershell
2024-10-23 11:45:32 INFO ssm-setup-cli -version: 3.3.987.0
2024-10-23 11:45:33 INFO Setting proxy config
2024-10-23 11:45:33 DEBUG Current proxy environment variables: https_proxy:;http_proxy:;no_proxy:

...(略)

2024-10-23 11:45:36 INFO Installed agent version - 3.3.987.0
2024-10-23 11:45:36 INFO Version already installed 3.3.987.0:
2024-10-23 11:45:36 INFO Attempting to configure agent
2024-10-23 11:45:36 INFO Verifying agent is installed before attempting to register
2024-10-23 11:45:36 INFO Verified agent is installed
2024-10-23 11:45:36 INFO Agent already registered with instance id: mi-0123456789abcdef0
2024-10-23 11:45:36 INFO skipping registration because override flag is not set, just starting agent back
2024-10-23 11:45:36 INFO Starting agent using windows service manager
2024-10-23 11:45:36 WARN attempt 1/4 failed to start agent: windows: failed to start agent with output '�v������ �t�[�r�x�͊��ɋj�n�����ă��܂��b

net helpmsg 2182 �ɠ��͂����ɓa�����ڂ����������������܂��b' and error: exit status 2
2024-10-23 11:45:37 WARN attempt 2/4 failed to start agent: windows: failed to start agent with output '�v������ �t�[�r�x�͊��ɋj�n�����ă��܂��b

net helpmsg 2182 �ɠ��͂����ɓa�����ڂ����������������܂��b' and error: exit status 2
2024-10-23 11:45:37 WARN attempt 3/4 failed to start agent: windows: failed to start agent with output '�v������ �t�[�r�x�͊��ɋj�n�����ă��܂��b

net helpmsg 2182 �ɠ��͂����ɓa�����ڂ����������������܂��b' and error: exit status 2
2024-10-23 11:45:37 WARN attempt 4/4 failed to start agent: windows: failed to start agent with output '�v������ �t�[�r�x�͊��ɋj�n�����ă��܂��b

net helpmsg 2182 �ɠ��͂����ɓa�����ڂ����������������܂��b' and error: exit status 2
2024-10-23 11:45:37 ERROR Failed to perform Onprem registration: retries exhausted
```

`C:\ProgramData\Amazon\SSM\Logs` ディレクトリに移動し、`errors.log` を確認します。

```text:C:\ProgramData\Amazon\SSM\Logs\errors.log
2024-10-23 11:57:54 ERROR [newAgentIdentityInner @ identity_selector.go.99] Agent failed to assume any identity
2024-10-23 11:57:54 ERROR [NewAgentIdentity @ identity_selector.go.112] failed to find identity, retrying: failed to find agent identity
2024-10-23 11:57:55 ERROR [newAgentIdentityInner @ identity_selector.go.99] Agent failed to assume any identity
2024-10-23 11:57:55 ERROR [NewAgentIdentity @ identity_selector.go.112] failed to find identity, retrying: failed to find agent identity
2024-10-23 11:57:55 ERROR [newAgentIdentityInner @ identity_selector.go.99] Agent failed to assume any identity
2024-10-23 11:57:55 ERROR [Init @ bootstrap.go.75] failed to get identity: failed to find agent identity
2024-10-23 11:57:55 ERROR [Execute @ agent_windows.go.194] Failed to start agent. failed to get identity: failed to find agent identity
```

アイデンティティが取得できないというエラーが出てうまく起動していないようです。AWSCLIをインストールして `aws configre` で管理権限のあるアクセスキーを設定したりしても改善しませんでした。

## うまくいった方法

いろいろやってもうまく行かなかった(2-3時間ハマった)のですが、たまたま見つけたDevelopersIOの記事を見てみるとコマンドの内容が違うことに気がつきました。で、それを試したらあっさりと登録できました。

以下がうまく行ったコマンドです。`ssm-setup-cli.exe` が `AmazonSSMAgentSetup.exe` に変わっています。というか、いつからか `ssm-setup-cli.exe` に変わったのだと思われます。

```powershell
[System.Net.ServicePointManager]::SecurityProtocol = 'TLS12'
$code   = "<アクティベーションコード>"
$id     = "<アクティベーションID>"
$region = "<リージョン>"
$dir = $env:TEMP + "\ssm"
New-Item -ItemType directory -Path $dir -Force
cd $dir
(New-Object System.Net.WebClient).DownloadFile("https://amazon-ssm-$region.s3.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe", $dir + "\AmazonSSMAgentSetup.exe")
Start-Process .\AmazonSSMAgentSetup.exe -ArgumentList @("/q", "/log", "install.log", "CODE=$code", "ID=$id", "REGION=$region") -Wait
Get-Content ($env:ProgramData + "\Amazon\SSM\InstanceData\registration")
Get-Service -Name "AmazonSSMAgent"
```

以下のようにあっさり登録されました。あの苦労は何だったのか。

```powershell
PowerShell 7.4.5
PS C:\Users\Administrator> [System.Net.ServicePointManager]::SecurityProtocol = 'TLS12'
PS C:\Users\Administrator> $code   = "<アクティベーションコード>"
PS C:\Users\Administrator> $id     = "<アクティベーションID>"
PS C:\Users\Administrator> $region = "<リージョン>"
PS C:\Users\Administrator> $dir = $env:TEMP + "\ssm"
PS C:\Users\Administrator> New-Item -ItemType directory -Path $dir -Force

    Directory: C:\Users\ADMINI~1\AppData\Local\Temp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2024/10/23    11:57                ssm

PS C:\Users\Administrator> cd $dir
PS C:\Users\Administrator\AppData\Local\Temp\ssm> (New-Object System.Net.WebClient).DownloadFile("https://amazon-ssm-$region.s3.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe", $dir + "\AmazonSSMAgentSetup.exe")
PS C:\Users\Administrator\AppData\Local\Temp\ssm> Start-Process .\AmazonSSMAgentSetup.exe -ArgumentList @("/q", "/log", "install.log", "CODE=$code", "ID=$id", "REGION=$region") -Wait
PS C:\Users\Administrator\AppData\Local\Temp\ssm> Get-Content ($env:ProgramData + "\Amazon\SSM\InstanceData\registration")
{"ManagedInstanceID":"mi-0123456789abcdef0","Region":"ap-northeast-1"}
PS C:\Users\Administrator\AppData\Local\Temp\ssm> Get-Service -Name "AmazonSSMAgent"

Status   Name               DisplayName
------   ----               -----------
Running  AmazonSSMAgent     Amazon SSM Agent

PS C:\Users\Administrator\AppData\Local\Temp\ssm>
```


# リモートデスクトップへの接続

ブラウザ経由でマネージメントコンソールからも接続できますが、 `aws ssm` コマンドでポートフォワードしてRDPで接続するコマンドをメモしておきます。AWSCLIとSession Manager Pluginをインストールし、適切な認証情報が必要です。

```powershell
aws ssm start-session --target mi-0123456789abcdef0 --document-name AWS-StartPortForwardingSession --parameters "portNumber=3389,localPortNumber=13389"
```

これで `localhost:13389` をリモートの `3389` に転送します。Windowsのリモートデスクトップ接続で `localhost:13389` に接続することでRDP接続されます。便利！

# 参考

- Systems Managerを利用したハイブリッドおよびマルチクラウド環境でのサーバーの管理
    - https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-hybrid-multicloud.html
- ハイブリッドWindows ServerノードにSSM Agentをインストールする
    - https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/hybrid-multicloud-ssm-agent-install-windows.html
- AWS Systems Managerでオンプレ環境のWindowsを管理する
    - https://dev.classmethod.jp/articles/aws-systems-manager-on-premise-windows-2019/
- 【AWS】「AWS Systems Manager」経由でWindowsサーバーにリモートデスクトップ接続する方法
    - https://business.ntt-east.co.jp/content/cloudsolution/column-try-27.html