香港などのオプトインリージョンにスイッチロールしてCLIコマンドを実行したらAuthFailureになった件について

2019.11.22

こんにちは、カトアキです。

タイトルの通りうまくいかなくて色々と調査しました。 原因と対応方法が分かったので、自分への備忘録&同じ用に悩むだれか向けに記事を書くことにしました。

なにが起こったの?

以下の流れでアカウントBの香港リージョンに ec2 describe-regionsを実行したところエラーが返ってきました。

前提

  • アカウントAIAMユーザがスイッチロールするためのロールがアカウントBに用意されている

流れ

アカウントBのロールにスイッチロール

sts assume-roleでセッショントークンを取得

aws sts assume-role \
--role-arn "arn:aws:iam::{BのアカウントID}:role/katoaki” \
--role-session-name katoaki@{BのアカウントID}
{
    "Credentials": {
        "AccessKeyId": “{xxx}“,
        "SecretAccessKey": “{yyy}”,
        "SessionToken": “{zzz}”,
        "Expiration": "2019-11-22T14:04:11Z"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": “aaa”,
        "Arn": "arn:aws:sts::{AのアカウントID}:assumed-role/katoaki/katoaki@{BのアカウントID}”
    }
}

セッション情報を環境変数にセット

export AWS_ACCESS_KEY_ID={xxx}
export AWS_SECRET_ACCESS_KEY={yyy}
export AWS_SESSION_TOKEN={zzz}

香港リージョンのインスタンス情報の参照

describe-regionsを実行

aws ec2 describe-instances --region ap-east-1
An error occurred (AuthFailure) when calling the DescribeInstances operation: AWS was not able to validate the provided access credentials

ちなみにこの時、ap-northeast-1を指定した場合にはエラーは返ってきません。

aws ec2 describe-instances --region ap-northeast-1
{
    "Reservations": []
}

なぜエラーになったの?

理由は、実は上記の操作を行った際に、セッションの取得をグローバルのSTSエンドポイントから取得しており、かつ「デフォルトで有効になっている AWS リージョンでのみ有効」の設定になっていたためです。(sts assume-roleを実行したときにリージョンを指定しない場合、デフォルトのグローバルSTSエンドポイントが利用されます。また、グローバルSTSエンドポイントのデフォルト設定が「デフォルトで有効になっている AWS リージョンでのみ有効」です。)

こちらのページ*1 に書いてあるとおり、オプトインリージョン(香港やバーレーンのリージョンなど、デフォルトで有効になっていないリージョン*2 )にアクセスするためには、グローバルのSTSエンドポイントのリージョン互換性の設定を「すべての AWS リージョンで有効」にする必要があります。

~バージョン 1 トークンは、デフォルトで利用できる AWS リージョンでのみ有効です。これらのトークンは、アジアパシフィック (香港) など手動で有効になっているリージョンでは動作しません。バージョン 2 のトークンはすべてのリージョンで有効です。~

*1 AWS リージョンでの AWS STS の管理 - AWS Identity and Access Management https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html

*2 AWS リージョンの管理 - AWS 全般のリファレンス https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande-manage.html

対応方法

アカウントASTSの設定変更を行い、グローバルSTSエンドポイントでバージョン2トークンを使う設定(「すべてのAWSリージョンで有効」を設定)に変更する

 

もしくは、リージョンのSTSエンドポイントを使って sts assumeroleを実行します。これならグローバルのSTSエンドポイントの設定は不要です。

aws sts assume-role \
--role-arn "arn:aws:iam::{BのアカウントID}:role/katoaki” \
--role-session-name katoaki@{BのアカウントID}
--endpoint https://sts.ap-northeast-1.amazonaws.com

結果

グローバルのSTSエンドポイントの設定を変更してv2トークンを使うようにした結果、このようになります。エラーが出なくなりました!

おわりに

これ、AuthErrorって出ても直感的にどうしたらいいのかわかりにくいですよね。アカウントBSTSの設定を変更してみたりと当初は迷走していました。

実はしばらく前にこの機能のアップデートの情報が出てたので知っていればあー、あれかってなるんですけど(それでもこの件すぐに理解しづらい気がしますけど!)

> AWS Security Token Service (STS) で、すべての AWS リージョンと互換性のあるセッショントークンがグローバル STS エンドポイントにより発行されるようになりました https://aws.amazon.com/jp/about-aws/whats-new/2019/04/aws-security-token-service-sts-now-supports-enabling-the-global-sts-endpoint-to-issue-session-tokens-compatible-with-all-aws-regions/

自分への備忘録として書いてますが、だれかの助けになれば幸いです。