この記事にはアフィリエイト広告が含まれています。
冒頭まとめ
AWSのエラーを検索して1件ずつ直しているのに、翌日は別のサービスで同じような壁に当たる。この繰り返しから抜けるには、覚える順序を変える必要があります。
AWSのエラーの多くは、4つの境界のどこかで起きています。誰として呼んでいるかという境界、何を許されているかという境界、自分の権限とサービスへ渡した権限の境界、そしてネットワークの到達性の境界です。エラー文はこの境界のどれで止まったかを示していますが、境界の存在を知らないと文言が読めません。
DockerやTerraformとの違いは、AWSがサービスの集まりであり、覚えるべきサービスの数に終わりがないことです。だからサービスを1つずつ潰す学び方は成立しません。代わりに、どのサービスでも共通して働く仕組みを先に押さえます。認証、認可、リージョン、ネットワーク、制限。この5つはS3でもLambdaでもRDSでも同じ形で現れます。
学ぶ順序は、認証情報とリージョン、IAMの評価順序、サービスへ渡す権限、ネットワークの到達性、制限と再試行、トラブルシューティングの6段階です。各段階には「次へ進む目安」を置きました。飛ばした段階は、後の段階のエラーとして別の顔で現れます。
個別に直すだけでは理解しにくい理由
検索で見つかる対処は、多くの場合その環境で有効だった手順です。なぜ有効だったかは書かれていないことがあります。
たとえば、アクセスが拒否されたときに管理者相当のポリシーを付けたら通った、という手順があります。確かにエラーは消えます。しかし何が足りなかったのかは分からないままです。次に同じ構成を作るとき、同じ広い権限を付けることになります。
同じことがネットワークでも起きます。繋がらないのでセキュリティグループを全開放したら通った、という手順は、どこで止まっていたのかを教えてくれません。セキュリティグループが原因だったのか、ルートテーブルが原因だったのかも区別できていません。
エラー文も同じです。AWSの拒否は、認証に失敗したのか、認証は通ったが許可がないのか、そもそも別のリージョンを見ているのかを示しています。この区別は、次に説明する全体像を知っていれば読み取れます。
最初に理解するべきAWSの全体像
先に、すべてのAWS操作が通る道筋を押さえます。ここを飛ばすと、後のすべての段階で判断がぶれます。
どのサービスへの操作も、同じ形をしています。まず、どの認証情報を使うかが決まります。次に、その認証情報が誰を表すのかが確定します。そのうえで、その相手にその操作が許されているかが判定されます。許されていれば、指定されたリージョンのそのサービスへ要求が届きます。
この道筋のうち、最初の2つと3つ目は別物です。認証情報が正しくても許可がなければ拒否されます。逆に、許可を持つ役割があっても、使っている認証情報が別人のものなら意味がありません。エラーを見るときは、この2つを分けて考えてください。
リージョンも独立した境界です。多くのサービスはリージョンごとに分かれており、東京リージョンで作ったものは大阪リージョンからは見えません。「作ったはずのものが一覧に出てこない」という症状は、リージョンの取り違えであることがよくあります。
まずは手元の環境が誰として動いているかを確認してください。
aws sts get-caller-identity
aws configure list
get-caller-identity は、いま使われている認証情報がどのアカウントの誰を表すかを返します。ここが想定と違えば、この先の調査はすべて無駄になります。
学習ステップ1:認証情報とリージョン
何を理解する段階か:認証情報がどこから読まれるか、そしてその優先順位です。
なぜエラー解決に必要か:手元では通るのに継続的インテグレーションでは拒否される、という症状の大半はここです。環境ごとに使われている認証情報が違います。
最低限覚える概念:公式ドキュメントによれば、AWS CLIはシステムやユーザーの環境変数、ローカルの設定ファイル、コマンドラインのパラメーターなど複数の場所にある認証情報と設定を使い、場所によって優先順位があります。優先順位は上から順に、コマンドラインオプション、環境変数、CLIの認証情報ファイル、CLIの設定ファイル、コンテナの認証情報、そしてEC2インスタンスプロファイルの認証情報です(Configuration settings and precedence)。
この順序が重要です。環境変数に古いキーが残っていると、設定ファイルを正しく直しても環境変数が優先されます。「設定を直したのに変わらない」という状況の典型です。
同じページには、認証情報ファイルと設定ファイルの両方に同じ名前のプロファイルがある場合、認証情報ファイルの値が優先されるという記述もあります。
実際に試すコマンド:
# いま使われている認証情報の持ち主を確認する
aws sts get-caller-identity
# 各設定値がどこから来ているかを確認する(type 列に出所が出る)
aws configure list
# 環境変数に値が残っていないかを確認する
env | grep -i "^AWS_"
# プロファイルを明示して実行する
aws sts get-caller-identity --profile <プロファイル名>
# 現在のリージョンを確認する
aws configure get region
aws configure list の出力は、値そのものではなく出所を示します。env と出ていれば環境変数、shared-credentials-file と出ていればファイルから読まれています。ここを見れば、どこを直せばよいかが決まります。
次の段階へ進む目安:aws configure list の出力から、いま使われている値がどこから来ているかを説明できることです。
関連して発生しやすいエラー:InvalidClientTokenId や SignatureDoesNotMatch は、認証情報そのものが無効か古い状態です。ExpiredToken は一時的な認証情報の期限切れを指します。いずれも許可の問題ではありません。
学習ステップ2:IAMの評価順序
何を理解する段階か:許可がどう決まるか、そして拒否がどう優先されるかです。
なぜエラー解決に必要か:AccessDenied は最も頻繁に見るエラーです。評価順序を知らないと、ポリシーを足しても通らない理由が分かりません。
最低限覚える概念:公式ドキュメントは、単一アカウント内での評価ロジックを次のようにまとめています。既定ではすべての要求が暗黙的に拒否されます。ただしAWSアカウントのルートユーザーは例外で完全なアクセスを持ちます。アイデンティティベースまたはリソースベースのポリシーでの明示的な許可が、この既定を上書きします。アクセス許可の境界、Organizationsのサービスコントロールポリシー、セッションポリシーが存在する場合、それらが許可を暗黙的な拒否で上書きすることがあります。そして、いずれかのポリシーでの明示的な拒否は、あらゆる許可を上書きします(Policy evaluation logic)。
ここから2つのことが言えます。第一に、何も書いていなければ拒否です。だから「許可を消したはずなのに通る」という状況では、別のポリシーが許可を出しています。第二に、明示的な拒否は足し算では消せません。許可をいくら足しても、どこかに拒否があれば通りません。
同じページには、アイデンティティベースのポリシーとリソースベースのポリシーの両方が要求に適用される場合、AWSはすべてのポリシーに少なくとも1つの許可があるかを確認するという記述もあります。片方だけを見て判断すると誤ります。
実際に試すコマンド:
# 自分に紐づくポリシーを一覧する
aws iam list-attached-role-policies --role-name <ロール名>
aws iam list-role-policies --role-name <ロール名>
# ポリシーの中身を確認する
aws iam get-role-policy --role-name <ロール名> --policy-name <ポリシー名>
# 特定の操作が許可されるかを事前に判定する
aws iam simulate-principal-policy \
--policy-source-arn <プリンシパルのARN> \
--action-names s3:GetObject \
--resource-arns <リソースのARN>
simulate-principal-policy は、実際に操作せずに判定結果を返します。許可されない場合、どのポリシーが理由かも示されます。手当たり次第にポリシーを足す前に、これで確認してください。
次の段階へ進む目安:AccessDenied を見たときに、許可が無いのか明示的な拒否があるのかを調べる手順を言えることです。
関連して発生しやすいエラー:AccessDenied の本文には、多くの場合どのプリンシパルがどのアクションをどのリソースに対して拒否されたかが含まれます。この3点をそのまま読んでください。推測で権限を広げるより速く進みます。
学習ステップ3:サービスへ渡す権限
何を理解する段階か:自分の権限と、サービスが使う権限が別物であることです。
なぜエラー解決に必要か:自分は管理者なのに、動かした処理が拒否される。この状況はこの層の理解不足で起きます。
最低限覚える概念:LambdaやECSのようなサービスは、あなたの認証情報では動きません。サービスに与えた役割の権限で動きます。したがって確認すべき対象は2つあります。あなたがその処理を起動できるか、そしてその処理が目的の資源へアクセスできるかです。
役割には2種類のポリシーが付きます。何をしてよいかを定める許可のポリシーと、誰がその役割を引き受けてよいかを定める信頼関係です。どちらが欠けても動きません。信頼関係が誤っていると、権限の中身が正しくても役割そのものを引き受けられません。
前段階で見た評価順序はここでも同じです。役割に許可が無ければ拒否され、どこかに明示的な拒否があれば許可があっても拒否されます。
実際に試すコマンド:
# 役割の信頼関係を確認する(誰が引き受けられるか)
aws iam get-role --role-name <ロール名> --query 'Role.AssumeRolePolicyDocument'
# 役割に付いている許可を一覧する
aws iam list-attached-role-policies --role-name <ロール名>
# その役割として何ができるかを判定する
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::<アカウントID>:role/<ロール名> \
--action-names <アクション名> \
--resource-arns <リソースのARN>
# 役割を引き受けて、その立場で確認する
aws sts assume-role --role-arn <ロールのARN> --role-session-name check
assume-role で得た一時的な認証情報を使えば、その役割の立場で実際に試せます。自分の権限で試して通っても、それは何の証明にもなりません。
次の段階へ進む目安:拒否されたときに、自分の権限の問題かサービスへ渡した権限の問題かを、エラー本文のプリンシパルから判断できることです。
関連して発生しやすいエラー:is not authorized to perform: sts:AssumeRole は信頼関係の問題です。役割の中身ではなく、誰が引き受けられるかの定義を見ます。
学習ステップ4:ネットワークの到達性
何を理解する段階か:通信が止まる場所が複数あることと、それぞれの性質の違いです。
なぜエラー解決に必要か:「繋がらない」という症状は、この段階の理解不足で起きるものが最も多くなります。しかも権限のエラーと違い、明示的なメッセージが出ないまま時間切れになります。
最低限覚える概念:通信の可否は複数の層で決まります。セキュリティグループ、ネットワークACL、ルートテーブル、そして相手側の待ち受けです。どれか1つでも通っていなければ届きません。
このうち性質が大きく違うのがセキュリティグループとネットワークACLです。公式ドキュメントによれば、ネットワークACLは状態を持たず、以前に送受信した通信の情報を保存しません。たとえば特定の受信通信を許可する規則を作っても、それに対する応答は自動的には許可されません。これはセキュリティグループの動きとは対照的です。セキュリティグループは状態を持ち、以前に送受信した通信の情報を保存します。たとえばセキュリティグループがEC2インスタンスへの受信を許可すれば、送信側の規則にかかわらず応答は自動的に許可されます(Control subnet traffic with network access control lists)。
つまりセキュリティグループは受信側だけ書けば往復しますが、ネットワークACLは戻りの通信も明示的に許可する必要があります。応答が戻る側のポート番号は動的に決まるため、範囲で許可することになります。ここを知らずにネットワークACLを絞ると、行きは通るのに戻らない状態になります。
実際に試すコマンド:
# 対象に付いているセキュリティグループを確認する
aws ec2 describe-instances --instance-ids <インスタンスID> \
--query 'Reservations[].Instances[].SecurityGroups'
# セキュリティグループの規則を確認する
aws ec2 describe-security-groups --group-ids <セキュリティグループID>
# サブネットに紐づくネットワークACLを確認する
aws ec2 describe-network-acls --filters Name=association.subnet-id,Values=<サブネットID>
# ルートテーブルを確認する
aws ec2 describe-route-tables --filters Name=association.subnet-id,Values=<サブネットID>
# 到達性を自動で判定する
aws ec2 create-network-insights-path \
--source <送信元ID> --destination <宛先ID> --protocol tcp --destination-port 443
規則を1つずつ目で追うのは間違いやすい作業です。到達性の判定機能を使うと、どの層で止まっているかを機械的に特定できます。全開放して切り分ける方法は避けてください。開けた状態のまま戻し忘れることがあります。
次の段階へ進む目安:応答が返らない場合に、セキュリティグループ、ネットワークACL、ルートテーブルのどれから見るかを決められることです。
関連して発生しやすいエラー:接続が拒否される場合は相手まで届いています。応答が返らないまま時間切れになる場合は、経路のどこかで破棄されています。この2つは調べる場所が違います。
学習ステップ5:制限と再試行
何を理解する段階か:AWS側が意図的に要求を絞る仕組みと、それに対する再試行の扱いです。
なぜエラー解決に必要か:断続的に失敗する、負荷を上げると失敗する、という症状はここです。設定の誤りではないため、設定をいくら見直しても直りません。
最低限覚える概念:公式ドキュメントによれば、AWS CLIはサーバー側の問題や、呼び出そうとしているサービスからの速度制限によって失敗を見ることがあります。この種の失敗は通常、特別な処理を必要とせず、短い待機の後に自動的に再度呼び出されます(AWS CLI retries)。
同じページによれば、従来の再試行方式では最大再試行回数の既定値は4で、合計5回の呼び出しになります。再試行の対象になるのは接続系の失敗と、Throttling や ThrottlingException のようなサービス側の速度制限の例外、そして429、500、502、503、504、509といった状態コードです。再試行には基数2の指数的な待機が含まれます。
ここから読み取れることがあります。速度制限は異常ではなく仕様です。そして、あなたが1回だと思っている呼び出しは、内部で複数回試みられていることがあります。記録を見るときは、この重複を前提に読んでください。
実際に試すコマンド:
# 現在の再試行設定を確認する
aws configure get max_attempts
aws configure get retry_mode
# 再試行の回数と方式を指定して実行する
AWS_MAX_ATTEMPTS=5 AWS_RETRY_MODE=standard aws s3 ls
# サービスごとの上限を確認する
aws service-quotas list-service-quotas --service-code <サービスコード>
# 上限の引き上げ状況を確認する
aws service-quotas list-requested-service-quota-change-history
再試行回数を増やす対処は、一時的な不調には有効です。しかし恒常的に上限へ当たっている場合は、回数を増やしても遅くなるだけです。上限そのものの確認へ進んでください。
次の段階へ進む目安:断続的な失敗を見たときに、設定の誤りではなく制限の可能性を先に疑えることです。
関連して発生しやすいエラー:ThrottlingException や TooManyRequestsException は速度制限です。LimitExceeded の形は数量の上限を指します。前者は待てば通り、後者は待っても通りません。
学習ステップ6:失敗時の確認順序
何を理解する段階か:エラーが出たときに、どの順番で何を見るかです。
なぜエラー解決に必要か:ここまでの5段階は、この順序を実行するための前提知識です。順序が決まっていれば、初めて見るサービスのエラーでも調べる範囲を絞れます。
確認の順序:
第一に、実行したコマンドとプロファイル、リージョンを確認します。別のアカウントや別のリージョンに対して実行していないかを見ます。
aws sts get-caller-identity
aws configure list
第二に、エラー全文を読みます。AWSの拒否メッセージには、どのプリンシパルがどのアクションをどのリソースに対して拒否されたかが含まれることが多くあります。この3点が書かれていれば、次に見る場所はほぼ決まります。
第三に、認証と認可のどちらの問題かを分けます。認証情報が無効なら許可を足しても通りません。逆も同じです。
第四に、認可の問題であれば評価順序に沿って調べます。許可が無いのか、明示的な拒否があるのか、境界やサービスコントロールポリシーで狭められているのかです。
aws iam simulate-principal-policy --policy-source-arn <ARN> --action-names <アクション> --resource-arns <ARN>
第五に、通信が関わる場合はネットワークの到達性を確認します。権限が正しくても届かなければ結果は同じに見えます。
第六に、記録を確認します。誰がいつどの操作を呼んだかはAPIの記録に、処理そのものの出力は各サービスの記録に残ります。
# API 呼び出しの記録を検索する
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=<API名> --max-results 10
# 処理の出力を確認する
aws logs tail <ロググループ名> --since 1h
APIの記録には、拒否された呼び出しも残ります。どのプリンシパルとして呼ばれたかが確認できるため、認証情報の取り違えを裏付けるのに使えます。
より詳しい記録が必要な場合は、CLIの出力を増やせます。
aws s3 ls --debug 2> aws-debug.log
この記録には署名や認証に関わる情報が含まれます。そのまま共有しないでください。
次の段階へ進む目安:初めて見るエラーに対して、この6段階のどこから調べるかを即座に決められることです。
避けるべき対処:管理者相当のポリシーを付けて通す、セキュリティグループを全開放する、バケットやリソースを公開設定にして確認する、長期のアクセスキーを共有する、記録の出力をそのまま貼り付ける、といった手順は、症状を消しても原因を残します。特に権限の拡大と公開設定は、戻し忘れが直接の事故につながります。切り分けのために一時的に緩める場合は、戻す手順を先に決めてから行ってください。
独学と動画講座の使い分け
ここまでの6段階は、公式ドキュメントと手元のアカウントだけでも進められます。実際、この記事で参照した仕様はすべて公式ドキュメントに書かれています。
独学が向いているのは、目的が明確な場合です。特定のエラーを直す、特定のAPIの引数を確認する、といった作業は、公式ドキュメントを直接読むのが最短です。
一方でAWSは、独学の負担が他のツールより大きくなります。サービスの数が多く、どこから読むかを決める段階で止まりやすい構造です。加えて、手を動かして確かめると費用が発生します。消し忘れると課金が続くため、試す回数が減りやすくなります。
動画講座は、学ぶ順序と演習用の構成がまとまっている点が違います。何をどこまで作って確認するかが決まっていれば、消し忘れも減らせます。反面、自分に必要な部分だけを選んで進めるのは難しくなります。
どちらが適しているかは、いま何に時間を取られているかで決まります。仕様が分からなくて止まっているなら公式ドキュメント、何から手を付けるか決められなくて止まっているなら講座、という切り分けが実際的です。
学習後に自力で確認できるようにしたいこと
到達点を具体的に置いておきます。以下を自分の環境で確認できるようになっていれば、この記事の範囲は終わりです。
aws configure list の出力から、いま使われている値がどこから来ているかを説明できる。認証の失敗と認可の失敗を、エラー文から区別できる。既定ではすべての要求が拒否されること、そして明示的な拒否が許可を上書きすることを説明できる。自分の権限とサービスへ渡した権限が別物であることを説明でき、拒否されたときにどちらの問題かを判断できる。セキュリティグループが状態を持ち、ネットワークACLが状態を持たない違いを説明できる。断続的な失敗を見たときに、制限と再試行の可能性を先に疑える。初めて見るエラーに対して、プロファイルとリージョン、エラー全文、認証と認可の切り分け、評価順序、ネットワーク、記録の順で調べられる。
これらは暗記ではなく、手を動かして確認する操作です。費用のかからない範囲から1つずつ試してください。
まとめ
AWSのエラーが繰り返し起きるのは、サービスを知らないからではなく、境界を知らないからです。誰として呼んでいるか、何を許されているか、自分の権限とサービスへ渡した権限、そしてネットワークの到達性。この4つの境界を押さえると、エラー文の読み方が変わります。
学ぶ順序は、認証情報とリージョン、IAMの評価順序、サービスへ渡す権限、ネットワークの到達性、制限と再試行、トラブルシューティングです。それぞれに「次へ進む目安」を置いたのは、飛ばした段階が後から別の顔で現れるからです。
サービスの数に終わりはありませんが、この5つの仕組みはどのサービスでも同じ形で働きます。だから新しいサービスに触れるときも、調べる順序は変わりません。
公式ドキュメントは仕様の確認先として最も確実です。一方で、学ぶ順序や演習用の環境を自分で組み立てる負担が大きいと感じる場合は、順序と演習がまとまった教材を使う選択肢もあります。
内容や価格、対象範囲はリンク先のページで確認してください。自分がいまどの段階で止まっているかを踏まえて、必要な範囲が含まれているかを見るのが選び方の基準になります。
参考資料
- Configuration settings and precedence
- Policy evaluation logic
- Control subnet traffic with network access control lists
- Control traffic to your AWS resources using security groups
- AWS CLI retries
免責事項:本記事の内容は、執筆時点の公開情報をもとに作成したものです。ソフトウェアや講座の内容、価格、提供条件は予告なく変更されることがあります。最新の情報はAWS公式ドキュメントおよびリンク先の講座ページをご確認ください。本記事の情報を利用した結果生じたいかなる損害についても、著者および運営者は責任を負いかねます。