ちょっと話題の記事

AWS IAM で障害が起こったらどうなるの? AWS IAM のレジリエンス(復元力)に関する記述がドキュメントに追記されていた

AWS ドキュメントの AWS IAM のレジリエンスについての記述が増強されていました。 AWS IAM における障害をどう考えたらいいかの一助になる記述でした。

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

コンバンハ、千葉(幸)です。

AWS サービスで広範囲の障害が起こったときにどう備えるか?は AWS を利用する上では避けて通れない課題です。

例えば Amazon EC2 であれば、アベイラビリティゾーン(AZ)単位での障害に備えてマルチ AZ 構成にしておく、リージョン単位の障害に備えて別リージョンにバックアップを退避させておく、などの構成が思いつきます。

では AWS IAM で障害が起こったときに備えてどうすべきか?改めて問われると難しい問題です。わたしはぼんやりと「そもそも障害が起こることはないんじゃないか?そもそも AWS IAM における障害って何?」という思いを抱いていました。

そんな折、いつものように AWS IAM のドキュメントの更新履歴を眺めていると IAM のレジリエンスに関する更新が行われていることに気がつきました。

Change Description Date
Updates to resilience in IAM Added information about maintaining access to IAM credentials when an event disrupts communication between AWS Regions. May 16, 2022

「AWS リージョン間の接続を阻害する事象があった場合に IAM クレデンシャルへのアクセスがどう維持されるか」について情報が追記されています。

ぼんやりした部分へのアンサーになる内容も含まれていたため、その内容をご紹介します。

変更前のドキュメントの記述をおさえておく

2022/6/5 時点の日本語版のドキュメントでは更新前の内容が確認できます。記念に撮っておきます。

IAM_AWS_Identity_and_Access_Management_-_AWS_Identity_and_Access_Management

見てわかる通り非常にシンプルな記載です。英語版に切り替えると更新後の内容が確認できますので、その差分を楽しんでください。

ドキュメントを読む前に頭の中にイメージを作っておく

いきなりドキュメントを読み解いていく前に、前提となる部分をおさえておきましょう。

これから述べることのイメージは以下です。

AWS IAM はグローバルエンドポイントのみをもつ

AWS サービスにプログラムでアクセスする際には、各サービスで用意されているサービスエンドポイントを宛先にします。ほとんどの AWS サービスではリージョンごとにサービスエンドポイントが用意されており、それらはリージョナルエンドポイントと呼ばれます。

例えば Amazon EC2 の東京リージョンのリージョナルエンドポイントは以下です。

ec2.ap-northeast-1.amazonaws.com

AWS IAM の場合はリージョナルエンドポイントが存在せず、単一のグローバルエンドポイントのみが用意されています。

どのリージョンからアクセスする場合でも、共通してiam.amazonaws.comを指定することになります。

AWS IAM のデータプレーンは各リージョンに存在する

AWS IAM のサービスエンドポイントが単一のグローバルエンドポイントのみで提供されると聞くと AWS IAM というサービスがどこか特定の地域でのみホストされている、と考えてしまうかもしれませんが、そんなことはありません。

AWS IAM は分散コンピューティングモデルが採用されており、各リージョンにホストが存在します。AWS IAM というシステムを構成する要素としてコントロールプレーンデータプレーンを考えたとき、データプレーンは各リージョンに存在することが示されています。

AWS re:Invnet 2021 のキーノートで AWS IAM の裏側に関する説明がなされていましたので、興味がある方は参照してみてください。

45:30 のあたり。

  • ユーザーがコンソールや CLI 等を通じてコントロールプレーンとトークする
  • コントロールプレーンがデータプレーン(各リージョン、デバイスに分散)とトークする

IAM_dataplane_AWS_re_Invent_2021_-_Keynote_with_Dr__Werner_Vogels_-_YouTube

48:00 のあたり。

  • ユーザーから AWS サービスエンドポイントへのリクエストは IAM エンドポイントを通じて AWS IAM にパスされる
    • IAM エンドポイントは数百万のホストからなる
  • 署名検証プロセスにおいて必要となるシークレットキーはコントロールプレーンに存在し、派生キーのみがデータプレーンに提供される

IAM_AWS_re_Invent_2021_-_Keynote_with_Dr__Werner_Vogels_-_YouTube

2022/6/30 追記:ドキュメントに記述されたよ

このブログを書いた後に、AWS ドキュメントにさらなる記述が追加されました。

データプレーンに加えコントロールプレーンについても記載されています。以下エントリにてまとめましたので併せてご覧ください。

↓以降の記述は、追記前の内容です。


AWS STS は一時的な認証情報を払い出すサービス

AWS IAM と密接な関係を持つ AWS サービスとして、AWS STS があります。

AWS STS は一時的な認証情報の払い出しを行なってくれるサービスです。「一時的な認証情報」の対となる概念は「永続的(あるいは長期的とも)な認証情報」であり、これは IAM ユーザーから払い出したアクセスキー/シークレットアクセスキーを指します。

例えば AWS CLI の実行を想定した場合、IAM ユーザーの永続的な認証情報を使用する場合と IAM ロールの一時的な認証情報を使用する場合ではプロセスが異なります。

後者の場合は AWS STS のサービスエンドポイントを宛先にsts:AssumeRoleというアクションの実行をリクエストし、一時的な認証情報の払い出しを受けた上で AWS サービスへのリクエストを実行します。

AWS STS はデフォルトでグローバルエンドポイントを向くがリージョナルエンドポイントに切り替えできる

AWS IAM と同様 AWS STS でもグローバルエンドポイントが用意されており、リクエストはデフォルトでグローバルエンドポイントに送信されます。

一方でリージョナルエンドポイントも用意されており、レイテンシーの軽減や冗長性の向上のためにリージョナルエンドポイントの使用が推奨されています。

AWS IAM のレジリエンスに関する記述を確認する

イメージを膨らませたところで、追記された AWS IAM のレジリエンスの記述を確認していきます。

リージョン間の通信を阻害するイベントが発生した場合にどうなるか

リージョン間の通信の中断が発生した場合の影響が記載されています。

Certain events can interrupt communication between AWS Regions over the network. However, even when you can't communicate with the global IAM endpoint, AWS STS can still authenticate IAM principals and IAM can authorize your requests. The specific details of an event that interrupts communication will determine your ability to access AWS services. In most situations, you can continue to use IAM credentials in your AWS environment.

機械翻訳した内容は以下の通りです。

特定のイベントにより、ネットワークを介したAWSリージョン間の通信が中断される場合があります。ただし、グローバルIAMエンドポイントと通信できない場合でも、AWS STSはIAMプリンシパルを認証でき、IAMはリクエストを承認できます。通信を中断するイベントの具体的な詳細によって、AWSサービスにアクセスする能力が決まります。ほとんどの場合、AWS環境でIAMクレデンシャルを引き続き使用できます。

通信を中断するイベントの内訳によるものの、ほとんどの場合 IAM 認証情報を引き続き利用できるとのことです。

「グローバル IAM エンドポイントと通信できない場合」はどことどこの通信を指しているのか理解し切れませんでしたが(おそらくクライアントからiam.amazonaws.comへの通信だろうと想像)、AWS STS によるプリンシパルの認証、IAM によるリクエストの認可は引き続き行われるとのことです。

これは完全に想像ですが、以下のようなことを言っているのかな、というイメージです。

通信を阻害するイベントにおける条件

先ほど「通信を中断するイベントの具体的な詳細によって、AWSサービスにアクセスする能力が決まります。」との記述がありました。事象発生時にどういった影響を受けるのか、条件ごとの記述が続きます。

このあたりのドキュメントの記述の読み取り方に確証が持てなかったので、自分が捉えた内容を記します。正確な内容は原文をご確認ください。

IAM ユーザーの永続的な認証情報を使用する場合

You can authenticate indefinitely in a Region with long-term access keys for IAM users. When you use the AWS Command Line Interface and APIs, you can provide AWS access keys so that AWS can verify your identity in programmatic requests.

永続的な認証情報を使用する場合、リージョン内で無期限に認証できると記載されています。この無期限(indefinitely)は「リージョン間の通信を阻害するイベントがあっても影響を受けずに」の意を含んでいるとわたしは捉えたのですが、いまいち確証が持てていない部分です。

なお、ベストプラクティスとして永続的な認証情報ではなく一時的な認証情報の使用が推奨されています。

一時的な認証情報を使用する場合

You can request new temporary credentials with the AWS STS Regional service endpoint for at least 24 hours. The following API operations generate temporary credentials.

AWS STS のリージョナルエンドポイントを使用して少なくとも 24 時間、新しい一時的な認証情報をリクエストできると記載されています。リージョン間通信の中断によりグローバルエンドポイントとの通信が阻害されるようなイベントがあったとしても、リージョナルエンドポイントを使用すれば引き続き AWS STS を利用できる、という内容であると捉えました。

一時的な認証情報を生成する API オペレーションとしては以下があります。

  • AssumeRole
  • AssumeRoleWithWebIdentity
  • AssumeRoleWithSAML
  • GetFederationToken
  • GetSessionToken

プリンシパルとパーミッションへの影響

  • You might not be able to add, modify, or remove principals or permissions in IAM.

プリンシパルやパーミッションの追加、変更、削除ができない可能性がある、とされています。

ここでのプリンシパル、パーミッションはそれぞれ以下を指していると捉えましたが、もっと広く含む可能性もあります。

  • プリンシパル
    • IAM ユーザー
    • IAM ロール
    • IAM グループ
  • パーミッション
    • アイデンティティベースポリシー
    • Permissions boundary
    • セッションポリシー

直近で行ったパーミッションの変更が反映されない可能性がある、とされています。

今回想定しているような障害に関係なく、もともと AWS IAM では結果整合性が採用されています。世界中にホストが分散しているため、ノード間、リージョン間の伝達速度やキャッシュにより変更の反映に時間がかかる場合があります。

わたし自身、IAM ポリシーを変更した直後にリクエストを複数回実行した際に「変更前のポリシー基準で認可が行われた結果」と「変更後のポリシー基準で行われた結果」が交互に現れた、という経験があります。

AWS マネジメントコンソールの場合

  • You might be able to use a Regional sign-in endpoint to sign in to the AWS Management Console as an IAM user. Regional sign-in endpoints have the following URL format.

以下のようにリージョンを指定したサインインエンドポイントを使用することで、マネジメントコンソールにサインインできる可能性がある、とされています。

https://111122223333.signin.aws.amazon.com/console?region=us-west-2

ホストは同じでもクエリパラメータを変えることによってサインイン可否が変わるかも、ということですね。

MFA のうち、 Universal 2nd Factor 規格のものは使用できなくなる可能性があるようです。

IAM レジリエンスのベストプラクティス

AWS has built resilience into AWS Regions and Availability Zones. When you observe the following IAM best practices in the systems that interact with your environment, you take advantage of that resilience.

AWS はリージョンとアベイラビリティゾーンにレジリエンスを組み込んでおり、次のベストプラクティスに則ることでそのレジリエンスを利用できる、とされています。

1. Use an AWS STS Regional service endpoint instead of the default global endpoint.

先ほども出てきたように、AWS STS のサービスエンドポイントとしてグローバルエンドポイントでなくリージョナルエンドポイントを使用することが推奨されています。

特定のリージョナルエンドポイントで障害が発生したと想定した時、別のリージョナルエンドポイントへの切り替えによる回避やリージョナルエンドポイント自身のレジリエンスによる復旧が期待できそうです。

2. Review the configuration of your environment for vital resources that routinely create or modify IAM resources, and prepare a fallback solution that uses existing IAM resources.

IAM リソースを定期的に作成・変更する重要なリソースがあった場合はその設定を見直し、既存の IAM リソースを使用するようフォールバックするソリューションの準備をせよ、とされています。

これは「プリンシパルとパーミッションへの影響」で見たような以下のケースを想定し、IAM リソースの変更の即時反映を要求するような構成であれば見直しましょう、ということかと捉えました。

  • プリンシパルやパーミッションの追加、変更、削除ができない
  • パーミッションの変更が結果整合性である

AWS STS のリージョナルエンドポイントを使用する

ベストプラクティスとして AWS STS のリージョナルエンドポイントを使用せよ、という話があったので、どう使えばいいのかを軽く確認しておきます。

AWS STS リージョナルエンドポイントが有効か確認する

前提として、アカウント設定で AWS STS のリージョナルエンドポイントが有効になっている必要があります。香港リージョンなどオプトインが必要なリージョン以外では、デフォルトでリージョナルエンドポイントが有効になっているかと思います。

IAM_Management_Console_AWS_STS_regional_endpoint

AWS CLI で AWS STS リージョナルエンドポイントを指定する

AWS CLI で AWS STS のリージョナルエンドポイントを使用するケースを想定します。

AWS STS サービスエンドポイントへのリクエストが発生するaws sts get-caller-identityを実行し、デバッグログから通信先を確認します。

% aws sts get-caller-identity --debug\
 --region ap-northeast-1
...
2022-06-05 21:43:29,392 - MainThread - botocore.httpsession - DEBUG - Certificate path: /usr/local/aws-cli/awscli/botocore/cacert.pem
2022-06-05 21:43:29,392 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): sts.ap-northeast-1.amazonaws.com:443
2022-06-05 21:43:29,513 - MainThread - urllib3.connectionpool - DEBUG - https://sts.ap-northeast-1.amazonaws.com:443 "POST / HTTP/1.1" 200 406
...

指定したリージョンのリージョナルエンドポイントsts.ap-northeast-1.amazonaws.comに通信が行われています。

リージョンを変えて実行してみます。

% aws sts get-caller-identity --debug\
 --region us-east-1
...
2022-06-05 21:47:41,278 - MainThread - botocore.httpsession - DEBUG - Certificate path: /usr/local/aws-cli/awscli/botocore/cacert.pem
2022-06-05 21:47:41,278 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): sts.us-east-1.amazonaws.com:443
2022-06-05 21:47:42,080 - MainThread - urllib3.connectionpool - DEBUG - https://sts.us-east-1.amazonaws.com:443 "POST / HTTP/1.1" 200 406
...

指定したリージョンのリージョナルエンドポイントsts.us-east-1.amazonaws.comに通信先が変わっています。

ここのコントロールは AWS CLI コンフィグのsts_regional_endpointsによって実現できます。

sts_regional_endpointsの値として以下のいずれかを指定できます。

  • legacy
    • 特定のリージョンではグローバルエンドポイントを使用し、それ以外ではリージョナルエンドポイントを使用する
    • AWS CLI v1のデフォルト
  • regional
    • 使用するリージョンのリージョナルエンドポイントを使用する
    • AWS CLI v2のデフォルト

わたしが使用しているのは AWS CLI v2 であるため、特に意識することなく AWS STS のリージョナルエンドポイントを使用するようになっていました。

明示的に指定したい場合や AWS CLI v1 で使用したい場合には、以下のように指定してあげればOKです。

~/.aws/config

[profile Sample]
region = ap-northeast-1
output = json
sts_regional_endpoints = regional

AWS SDK で AWS STS リージョナルエンドポイントを指定する

AWS SDK を使用する場合は以下のようにコード内で記述することでリージョナルエンドポイントを指定できそうです。

使用する言語によって指定の仕方やデフォルト値が異なることもあるかと思いますので、詳細は各リファレンスをご参照ください。

直近で発生した AWS IAM の障害は?

以下の記事を参考に、Service Health Dashboard(現在は AWS Health Dashboard に統合)の履歴を確認してみました。

サービス区分が IAM のものでフィルタリングしてみると、1件だけ該当するものがありました。2021/8/27(JST)のものです。

% curl https://status.aws.amazon.com/data.json | jq '.archive | sort_by(.date) | .[] | select(.service == "iam")'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  212k  100  212k    0     0  55903      0  0:00:03  0:00:03 --:--:-- 55941
{
  "service_name": "AWS Identity and Access Management",
  "summary": "[RESOLVED] IAM errors and propagation latency",
  "date": "1629996723",
  "status": "1",
  "details": "",
  "description": "<div><span class=\"yellowfg\"> 9:52 AM PDT</span>&nbsp;We are investigating elevated latencies and errors on the IAM APIs. In addition, we are investigating propagation delays for recently created or recently updated IAM users, credentials, roles, policies. Authentication and authorization of existing users, credentials, roles, policies are not impacted. Other AWS services like AWS CloudFormation that use IAM roles were also impacted.</div><div><span class=\"yellowfg\">10:39 AM PDT</span>&nbsp;Between 6:44 AM and 9:12 AM PDT, customers experienced elevated latency and error rates in response to IAM API requests, as well as delays in describing recently created or modified IAM resources. In addition, between 6:44 AM and 10:02 AM, propagation of IAM API updates was delayed in the ME-SOUTH-1, EU-SOUTH-1, AP-EAST-1, and AF-SOUTH-1 regions, and newly created or recently updated IAM users, credentials, roles, and policies may not have been available for authentication and authorization in those regions. Other AWS Services that rely on IAM changes to provision resources, such as CloudFormation, were also impacted. Authentication and authorization for existing users, credentials, roles, policies were not impacted. The issue has been resolved and the service is operating normally.</div>",
  "service": "iam"
}

第一報がこちら。

9:52 AM PDT We are investigating elevated latencies and errors on the IAM APIs. In addition, we are investigating propagation delays for recently created or recently updated IAM users, credentials, roles, policies. Authentication and authorization of existing users, credentials, roles, policies are not impacted. Other AWS services like AWS CloudFormation that use IAM roles were also impacted.

(機械翻訳) 9:52 AM PDT IAM APIの遅延とエラーの上昇を調査しています。さらに、最近作成または更新された IAM ユーザー、資格情報、ロール、ポリシーの伝搬遅延を調査しています。既存のユーザー、資格情報、ロール、ポリシーの認証と承認には影響がありません。IAMロールを使用するAWS CloudFormationのような他のAWSサービスにも影響がありました。

50 分程度後の最終報がこちらです。

10:39 AM PDT Between 6:44 AM and 9:12 AM PDT, customers experienced elevated latency and error rates in response to IAM API requests, as well as delays in describing recently created or modified IAM resources. In addition, between 6:44 AM and 10:02 AM, propagation of IAM API updates was delayed in the ME-SOUTH-1, EU-SOUTH-1, AP-EAST-1, and AF-SOUTH-1 regions, and newly created or recently updated IAM users, credentials, roles, and policies may not have been available for authentication and authorization in those regions. Other AWS Services that rely on IAM changes to provision resources, such as CloudFormation, were also impacted. Authentication and authorization for existing users, credentials, roles, policies were not impacted. The issue has been resolved and the service is operating normally

(機械翻訳) 10:39 AM PDT 午前 6:44 AM から午前 9:12 AM PDT の間に、顧客は IAM API 要求に対する遅延とエラー率の上昇、および最近作成または修正された IAM リソースの説明の遅延を経験しました。さらに、午前6時44分から午前10時2分の間に、ME-SOUTH-1, EU-SOUTH-1, AP-EAST-1, AF-SOUTH-1 地域で IAM API 更新の伝播が遅れ、新しく作成または最近更新した IAM ユーザー、資格情報、役割、ポリシーはこれらの地域で認証と承認に利用できなかったかもしれません。CloudFormationなど、リソースのプロビジョニングにIAMの変更に依存している他のAWSサービスも影響を受けました。既存のユーザー、クレデンシャル、ロール、ポリシーの認証と承認には影響がありませんでした。この問題は解決され、サービスは正常に動作しています。

大まかに以下の内容です。

  • IAM API リクエストの遅延とエラー率の上昇が見られた
  • 直近で作成・更新された IAM リソースの記述の遅延が見られた
  • いくつかのリージョンで、新規に作成・更新された IAM ユーザー、クレデンシャル、ロール、ポリシーの認証・認可が失敗した可能性がある
  • CloudFormation など、リソースのプロビジョニングに IAM の変更に依存する AWS サービスも影響を受けた
  • 既存のユーザー、クレデンシャル、ロール、ポリシーの認証・認可は影響を受けなかった

少なくともこのイベントでは、既存の IAM リソースは影響を受けなかったようです。ここまで見てきた内容とも矛盾していません。こういった障害が起こりうる、と覚えておくとよさそうですね。

遡って履歴を確認できるのは 1 年程度

今回イベント履歴を確認したのは 2022/6/6 ですが、取得できたイベントの最古と最新は以下の通りでした。

OLDEST=$(curl https://status.aws.amazon.com/data.json | jq -r '.archive | sort_by(.date) | .[0].date')
LATEST=$(curl https://status.aws.amazon.com/data.json | jq -r '.archive | sort_by(.date) | reverse | .[0].date')
date -r $OLDEST
date -r $LATEST
...
2021年 6月10日 木曜日 03時41分51秒 JST
2022年 5月27日 金曜日 11時21分35秒 JST

およそ 1 年程度の情報を取得できるようです。

終わりに

AWS IAM のレジリエンスについて AWS ドキュメントに追記された内容を確認してみました。

ぼんやりと「AWS IAM の障害起こったらどうしよう」と考えていましたが、エンドポイントのホストでの障害、リージョン間通信の障害など、障害発生時のイメージがより具体的につきました。

これだけ読めばOK、というほど網羅的で詳細な記述はされていませんが、今回の記述追加により以下を読み取りました。

  • ほとんどの場合で AWS IAM は引き続き使用できる
  • 利用者側で対策を取れるとしたら以下の通り
    • AWS STS のリージョナルエンドポイントを使用する
    • AWS IAM の結果整合性を踏まえた構成にしておく

同じようなことが気になった方の参考になれば幸いです。興味があれば読んでみてください。

以上、 チバユキ (@batchicchi) がお送りしました。