Windows で AWS CLI をアップデートしスイッチロールする
コーヒーが好きな emi です。
Windows クライアント端末(Windows 10 や Windows 11 など)内のテキストデータを AWS に連携する方法を検討する中で、手元の Widows 11 端末にインストールした AWS CLI をアップデートする機会がありました。Windows 11 端末で AWS CLI のアップデートを実行し、スイッチロールするまでの手順を記載します。

AWS CLI アップデートの手順と最新バージョンの確認
現在は以下のブログの通り、AWS CLI が手元の Windows 11 端末にインストールされ、IAM ユーザーのアクセスキーは設定済みです。
AWS CLI を最新バージョンに更新する方法は以下ドキュメントに記載されています。「Windows」と書いてある手順を参考にします。
最新バージョンがいつリリースされたかは以下の GitHub ページに記載があります。
最新バージョンは 2.22.28 ですね。(検証日:2025/1/6)

現在 Windows 11 端末にインストールされている AWS CLI のバージョンを確認します。
PowerShell を開き、以下のコマンドを実行します。
aws --version
▼実行結果
C:\Users\kitani.emi>aws --version
aws-cli/2.13.30 Python/3.11.6 Windows/10 exe/AMD64 prompt/off
C:\Users\kitani.emi>
2.13.30 でした。
新しいバージョンの AWS CLI インストール
Windows での AWS CLI の現在のインストールを更新するには、以前のバージョンを上書きするため、更新のたびに新しいインストーラをダウンロードする必要があるとドキュメントに記載されています。インストーラーのダウンロードコマンドは以下です。
実行コマンド
msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi
▼実行結果
PS C:\Users\kitani.emi> msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi
PS C:\Users\kitani.emi>

上記コマンドを実行すると以下のウィザードが立ち上がり、アップデートを進めることができます。Next で進みます。

使用許諾契約の画面で同意にチェックし、Next で進みます。

セットアップでは特にカスタマイズせず、そのまま Next で進めます。

Install します。

数秒待ちます。

完了すると以下の画面になります。Finish をクリックしてウィザードを終了します。

新しいバージョンがインストールできたか確認します。
▼実行結果
PS C:\Users\kitani.emi> aws --version
aws-cli/2.22.28 Python/3.12.6 Windows/11 exe/AMD64
PS C:\Users\kitani.emi>
2.22.28 にアップデートされました。
AWS CLI の設定確認
では、AWS CLI の get-caller-identity コマンドで現在の IAM 権限を確認しましょう。
PS C:\Users\kitani.emi> aws sts get-caller-identity
{
    "UserId": "AIDAXA25AMYQOGCMNXH6A",
    "Account": "111111111111",
    "Arn": "arn:aws:iam::111111111111:user/iam-user-test"
}
PS C:\Users\kitani.emi>
現在は AWS アカウント 111111111111 の IAM ユーザー iam-user-test のアクセスキーが Windows 11 端末に設定されているので、想定通りです。

権限を確認します。
AWS アカウント 111111111111 の IAM ユーザー iam-user-test は、AWS アカウント 111111111111 の EC2 情報を参照する権限がありません。

AWS アカウント `111111111111` の IAM ユーザー `iam-user-test` の IAM ポリシー参考
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateAccessKey",
                "iam:UpdateAccessKey",
                "iam:DeleteAccessKey",
                "iam:CreateVirtualMFADevice"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        }
    ]
}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice"
            ],
            "Resource": "arn:aws:iam::111111111111:mfa/${aws:username}"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:EnableMFADevice",
                "iam:DeactivateMFADevice",
                "iam:ResyncMFADevice"
            ],
            "Resource": "arn:aws:iam::111111111111:user/${aws:username}"
        }
    ]
}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowIndividualUserToManageTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:ChangePassword",
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:DeactivateMFADevice",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice",
                "iam:ListMFADevices"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "BlockMostAccessUnlessSignedInWithMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:ChangePassword",
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:DeactivateMFADevice",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice",
                "iam:ListMFADevices"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}
IAMReadOnlyAccessIAMSelfManageServiceSpecificCredentials
AWS アカウント 222222222222 の IAM ロール kitani.emi は AWS アカウント 222222222222 の EC2 情報を参照する権限があります。

AWS アカウント `222222222222` の IAM ロール `kitani.emi` の IAM ポリシー参考
AmazonEC2FullAccessなど
まずは AWS アカウント 111111111111 の IAM ユーザー iam-user-test のアクセスキーが default で設定された Windows 11 端末で PowerShell を開き、以下の EC2 の詳細情報を取得するコマンドを実行してみます。
aws ec2 describe-instances
▼実行結果
PS C:\Users\kitani.emi> aws ec2 describe-instances
An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation. User: arn:aws:iam::111111111111:user/iam-user-test is not authorized to perform: ec2:DescribeInstances with an explicit deny in an identity-based policy
PS C:\Users\kitani.emi>
想定通り、EC2 へのアクセス権限がない、というエラーになりました。
スイッチロールする
では、AWS アカウント 111111111111 から AWS アカウント 222222222222 へ AWS CLI にスイッチしてみます。
--profile オプションで config で設定した AWS アカウント 222222222222 の IAM ロールのプロファイルを指定して実行します。
aws ec2 describe-instances --profile kitani.emi
▼実行結果
PS C:\Users\kitani.emi> aws ec2 describe-instances --profile kitani.emi
You must specify a region. You can also configure your region by running "aws configure".
PS C:\Users\kitani.emi>
リージョンを指定せよと言われました。私の個人的な好みで、「スイッチしてリソース見たいときに東京リージョンのリソースを見るとは限らないんだから、config には書かずに都度指定すれば良いや」と思って設定していなかったのが原因です。
config の中でリージョンを設定しても良いですし、都度リージョンを --region オプションで設定しても構いません。詳細は以下のブログも参照ください。
「よく考えたらほとんど東京リージョンのリソースしか見ないな」と思い、今回は config を編集することにしました。
Windows 11 では config ファイルはエクスプローラーの C:\Users\<Windows 11 端末のローカルユーザー名>\.aws に存在します。

私は設定ファイル関連を編集する際にバックアップとしてコピーを作成しているためたくさんコピーファイルが見えていますが、気にしないでください。
余談:C:\Users\<Windows 11 端末のローカルユーザー名>\.aws\cli 配下のキャッシュについて
ちなみに、C:\Users\<Windows 11 端末のローカルユーザー名>\.aws\cli 配下に「cache」というフォルダがあり以下のような JSON が格納されている場合があります。これは AWS CLI のスイッチロールで MFA 認証を行う際、一時的な認証情報がここにキャッシュされるためです。

詳細は以下ブログも参照ください。
# Core AWS account
[default] 
region = ap-northeast-1
output = json
# Personal verification account IAM role : kitani.emi 
[profile kitani.emi]
output = json
role_arn = arn:aws:iam::222222222222:role/kitani.emi
source_profile = default 
mfa_serial = arn:aws:iam::111111111111:mfa/iam-user-test
## MFA device of the account from which the switch source is being made.
↓
編集
↓
# Core AWS account
[default] 
region = ap-northeast-1
output = json
# Personal verification account IAM role : kitani.emi 
[profile kitani.emi]
region = ap-northeast-1
output = json
role_arn = arn:aws:iam::222222222222:role/kitani.emi
source_profile = default 
mfa_serial = arn:aws:iam::111111111111:mfa/iam-user-test
## MFA device of the account from which the switch source is being made.
ちなみに、スイッチロールする際に MFA code を求めるように config を設定しています。
コメントは日本語で入力してうまく動くこともあるのですが、たまに Unable to parse config file: エラーで失敗することがあるので私は英語にしています。
では再度スイッチロールして EC2 の情報を取得してみます。
PS C:\Users\kitani.emi> aws ec2 describe-instances --profile kitani.emi
Enter MFA code for arn:aws:iam::111111111111:mfa/iam-user-test:
MFA code を入力します。
PS C:\Users\kitani.emi> aws ec2 describe-instances --profile kitani.emi
Enter MFA code for arn:aws:iam::111111111111:mfa/iam-user-test:
{
    "Reservations": [
        {
            "ReservationId": "r-07e9441e07f6769c7",
            "OwnerId": "222222222222",
            "RequesterId": "331753876576",
            "Groups": [],
            "Instances": [
                {
                    "Architecture": "x86_64",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/xvda",
                            "Ebs": {
                                "AttachTime": "2024-01-17T09:47:30+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-0fd1e050be08806f6"
                            }
                        }
                    ],
                    :
                    :
                }
            ]
        },
        :
        :
    ]
}
PS C:\Users\kitani.emi>
情報を取得できました。
ここで、再度スイッチロールして EC2 の情報を取得しようとすると、以下のようにもう MFA code の入力を求められなくなります。
PS C:\Users\kitani.emi> aws ec2 describe-instances --profile kitani.emi
{
    "Reservations": [
        {
            "ReservationId": "r-07e9441e07f6769c7",
            "OwnerId": "222222222222",
            "RequesterId": "331753876576",
            "Groups": [],
            "Instances": [
                {
                    "Architecture": "x86_64",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/xvda",
                            "Ebs": {
                                "AttachTime": "2024-01-17T09:47:30+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-0fd1e050be08806f6"
                            }
                        }
                    ],
                    :
                    :
                }
            ]
        },
        :
        :
    ]
}
PS C:\Users\kitani.emi>
2 回目以降のコマンド実行では MFAコードの入力を求められないのは、一度 MFA 認証を完了すると一時的な認証情報がキャッシュされ、一時的な認証情報の有効期限が切れるまでキャッシュされた一時的な認証情報を使用するからです。
キャッシュの保存場所が気になる方は「余談:C:\Users\<Windows 11 端末のローカルユーザー名>\.aws\cli 配下のキャッシュについて」のトグルに戻ってみてください。
では、AWS CLI での IAM ロールの使用 - AWS Command Line Interface に記載されているキャッシュのクリアコマンドを実行してキャッシュを削除してみましょう。
PS C:\Users\kitani.emi> del /s /q %UserProfile%\.aws\cli\cache
Remove-Item : 引数 '/q' を受け入れる位置指定パラメーターが見つかりません。
発生場所 行:1 文字:1
+ del /s /q %UserProfile%\.aws\cli\cache
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Remove-Item]、ParameterBindingExcept
    ion
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands
   .RemoveItemCommand
PS C:\Users\kitani.emi>
エラーになってしまいました。
このエラーは、PowerShell とコマンドプロンプト (cmd) のコマンド構文の違いによるものです。
del /s /q は cmd のコマンドであるため、PowerShell では動作しません。ドキュメントに記載されているコマンドはコマンドプロンプトが前提だったのですね。
PowerShell で同様の操作を行うには、以下のコマンドを実行します。
Remove-Item -Path "$env:UserProfile\.aws\cli\cache" -Recurse -Force
▼実行結果
PS C:\Users\kitani.emi> Remove-Item -Path "$env:UserProfile\.aws\cli\cache" -Recurse -Force
PS C:\Users\kitani.emi>
以下のようにキャッシュがクリアされ消えました。

この状態で aws ec2 describe-instances --profile kitani.emi などのコマンドを実行すると、MFA code の入力が再度求められるようになります。
以上です。
質問やご要望については画面下部のお問い合わせ「DevelopersIO について」からご連絡ください。記事に関してお問い合わせいただけます。
参考
機能の追加履歴はこちらから






