AWS CDKデプロイで"Assuming role failed: Signature expired"にハマった話

この記事では、CDKデプロイ時の`Assuming role failed: Signature expired`に対処する方法を説明します。また、ふりかえりとして、原因の追跡に時間を要した理由とそこから得たトラブルシュートのヒントを共有します。

# 環境
Ubuntu 22.04.1 LTS on WSL2 (WSL バージョン: 1.2.5.0)

# 発生した事象
`cdk deploy`コマンドの応答がない。`cdk diff`でも同様。ターミナルには`current credentials could not be used to assume`の警告が出力される。

```bash
$ cdk diff
Stack BackupCfnRdsStack
current credentials could not be used to assume 'arn:aws:iam::xxxxxxxxxxxx:role/cdk-hnb659fds-lookup-role-xxxxxxxxxxxx-ap-northeast-1', but are for the right account. Proceeding anyway.
(To get rid of this warning, please upgrade to bootstrap version >= 8)
current credentials could not be used to assume 'arn:aws:iam::xxxxxxxxxxxx:role/cdk-hnb659fds-deploy-role-xxxxxxxxxxxx-ap-northeast-1', but are for the right account. Proceeding anyway.
```

# エラーの原因

Stack Overflowで同様の事象をみつけました。

https://stackoverflow.com/a/72049399/10893959

回答に従い`--verbose`を付けて実行すると、クロックの問題で資格情報の期限が切れたことがわかりました。

```bash
$ cdk diff --verbose
...（省略）
[07:52:39] Assuming role failed: Signature expired: 20230423T225239Z is now earlier than 20230423T233502Z (20230423T235002Z - 15 min.)
[07:52:39] Could not assume role in target account using current credentials Signature expired: 20230423T225239Z is now earlier than 20230423T233502Z (20230423T235002Z - 15 min.) . Please make sure that this role exists in the account. If it doesn't exist, (re)-bootstrap the environment with the right '--trust', using the latest version of the CDK CLI.
```

確かに、Ubuntuの日時が実際の日時から１時間ほどずれていました。

```bash
$ date
Mon Apr 24 08:04:18 AM JST 2023
```

# トラブルシュートのふりかえり

ここで、もう一度`--verbose`なしでのターミナル出力を見てほしいのですが、「現在の資格情報ではAssumeできない」と出力されているものの、時刻のずれとは関係の薄い警告も出ているため、原因にたどり着くまでに時間を要しました。

IAMユーザーの永続的な認証情報で試したり、Identity Centerから認証情報を取得し直したり、といった解決にたどり着けない試行を繰り返してしまいました。

まずは`--verbose`で情報を収集し、何が起こっているかを正確に掴むのが先決でした。

# WSL2の時刻がずれた原因

時刻のずれが原因であることはわかりましたが、そもそも、なぜずれてしまったのでしょうか。

Qiitaの記事で、その原因がわかりました。

https://qiita.com/moriai/items/f633e01728d8d062adb1

記事によると、ホストマシンのスリープなどでWSL2の時刻がずれるとのことでした。確かにその日はスリープを何度か行っていました。

# WindowsとLinux環境の時刻ずれを修正する

先述の記事を参考に、NTPで修正します。

https://qiita.com/moriai/items/f633e01728d8d062adb1#ntp-%E3%81%A7%E4%BF%AE%E6%AD%A3%E3%81%99%E3%82%8B

以降のコマンドはPowerShellで実行します。

まず、Windowsで利用しているNTPサーバーを確認すると、`time.windows.com`でした。

```powershell
> Get-WinEvent -ProviderName Microsoft-Windows-Time-Service | Where-Object {$_.Id -eq 35 } | Format-List -Property TimeCreated,Message


TimeCreated : 2023/04/24 9:10:41
Message     : タイム サービスはシステム時刻とタイム ソース time.windows.com,0x9 (ntp.m|0x9|0.0.0.0:123->20.43.94.199:123) (参照 ID 3344837396) の同期をとっています。現在のローカル階層番号は 4 です。
```

次に、Linux環境に`ntpdate`をインストールします。Ubuntuにログインして`sudo apt install ntpdate`でインストールできました。

最後に、Linux環境をNTPサーバー`time.windows.com`と同期します。

```powershell
> wsl -u root ntpdate time.windows.com
24 Apr 10:06:59 ntpdate[15493]: step time server 20.43.94.199 offset +3058.078917 sec
```

時刻が同期されたか確認します。

```powershell
> $rfc3339 =  "yyyy-MM-dd HH:mm:ss.fffffff00zzz"
> Get-Date -Format $rfc3339; wsl date --rfc-3339=ns; Get-Date -Format $rfc3339
2023-04-24 10:12:19.865452600+09:00
2023-04-24 10:12:19.967213840+09:00
2023-04-24 10:12:20.022133400+09:00
```

期待通りに、Windows環境とLinux環境の時刻が同期されました。

Ubuntuに戻って`cdk diff`を実行すると、問題が解消されたことがわかります。

```bash
$ cdk diff
Stack BackupCfnRdsStack
Resources
[+] AWS::RDS::DBSubnetGroup BackupTest/SubnetGroup BackupTestSubnetGroup1133FFD2 
[+] AWS::SecretsManager::Secret BackupTest/Secret BackupTestSecretF7CC8F2C 
[+] AWS::SecretsManager::SecretTargetAttachment BackupTest/Secret/Attachment BackupTestSecretAttachmentABA01CC7 
[+] AWS::RDS::DBInstance BackupTest BackupTestDD32FE24 
```

この後、`cdk deploy`も無事通りました。

# まとめ
CDKデプロイに応答がなく`current credentials could not be used to assume`が出力される場合は、時刻のずれを疑います。

本事象に限らず、まずは`--verbose`で情報収集することが有効です。

WSL2であれば、Windows環境と時刻同期することで、問題を解消できます。