StackSetが存在するのにDescribeStackSetでnot foundエラーになる原因と解決方法
事象
StackSets を特定のメンバーアカウントへ委任している環境で、委任されたアカウント上で DescribeStackSet
の API を実行しました。その結果対象の StackSet がないというエラーになりました。以下は CLI から実行した際の結果です。
$ aws cloudformation describe-stack-set --stack-set-name aws-execution-role
An error occurred (StackSetNotFoundException) when calling the DescribeStackSet operation: StackSet aws-execution-role not found
コンソールを確認すると、該当する StackSet は確かに存在します。
なぜエラーになったのでしょうか?
原因
原因は--call-as
オプションが不足していたことでした。このオプションは管理アカウント、委任された管理者どちらで操作しているかを指定するものです。
組織の管理アカウントでアカウント管理者として行動しているか、メンバー アカウントで委任された管理者として行動しているかを指定します。
引用:describe-stack-set — AWS CLI 1.38.22 Command Reference
解決方法
デフォルトでは管理アカウントを示す SELF
が設定されるため、オプションを指定していない場合は管理アカウントでの実行と判断されます。
今回 CLI を実行したのは、管理アカウントではなく StackSets を委任していたアカウントでした。
そのため、オプションとして --call-as DELEGATED_ADMIN
を追加する必要がありました。
$ aws cloudformation describe-stack-set --stack-set-name aws-execution-role --call-as DELEGATED_ADMIN
SERVICE_MANAGEDで展開したStackSetはどちらからも参照できる
よく考えれば当然のことですが、委任された管理者側で SERVICE_MANAGED
を使って展開した StackSet は管理アカウントでも委任先のアカウントでも確認できます。
そのため、コンソール側では全く同じ StackSet が確認できます。
管理アカウントから見た StackSet
委任された管理者アカウントから見た StackSet
どちらも StackSet の ID が一致しており、参照している実態は同じリソースであることがわかります。
この前提があるため、DescribeStackSet
を実行しているのが管理アカウントなのかを判別するオプションが必要だということです。
エラーメッセージから推測すると、DELEGATED_ADMIN
オプションがある場合のみ、SERVICE_MANAGED
で展開されている StackSet まで取得する動作をしているように見えます。
SERVICE_MANAGEDとSELF_MANAGED
StackSets には、「SERVICE_MANAGED」と「SELF_MANAGED」という 2 つの管理モードがあります。
SELF_MANAGED
SELF_MANAGED は手動でターゲットアカウントとリージョンを指定してスタックインスタンスをデプロイします。この場合、デプロイ先のアカウントには適切な IAM ロールを作成する必要があります。
セルフマネージド許可を持つ CloudFormation StackSets を作成する - AWS CloudFormation
SERVICE_MANAGED
SERVICE_MANAGED は Organizations と統合して利用でき、組織内のアカウントに対してスタックをデプロイできます。このモードでは、Organizations の組織単位(OU)やアカウントを指定するだけで、簡単にスタックをデプロイできます。
サービスマネージド許可を持つ CloudFormation StackSets を作成する - AWS CloudFormation
今回のケースでは、SERVICE_MANAGED モードで展開された StackSet を操作しています。
そのため管理アカウントと委任された管理者アカウントの両方から同じ StackSet を参照できますが、API の実行時には--call-as オプションで操作の主体を明示する必要があります。
SERVICE_MANAGED とは違い、委任されたアカウント上で SELF_MANAGED で展開した StackSet は、管理アカウント上で確認できないことに注意しましょう。
管理アカウントでStackSetを確認
管理アカウントでは--call-as
のオプションがデフォルトで SELF
となるため、追加しなくても成功しました。
$ aws cloudformation describe-stack-set --stack-set-name aws-execution-role
{
"StackSet": {
"StackSetName": "aws-execution-role",
"StackSetId": "aws-execution-role:54c14cd9-f2d9-43d9-a21c-80f15af68ecc",
"Status": "ACTIVE",
...省略
}
}
もちろん--call-as
でSELF
を追加しても成功します。
$ aws cloudformation describe-stack-set --stack-set-name aws-execution-role --call-as SELF
{
"StackSet": {
"StackSetName": "aws-execution-role",
"StackSetId": "aws-execution-role:54c14cd9-f2d9-43d9-a21c-80f15af68ecc",
"Status": "ACTIVE",
...省略
}
}
DELEGATED_ADMIN
で実行すると not a delegated administrator
とエラーを出してくれました。こちらはオプションが間違っていることが分かりやすいですね。
$ aws cloudformation describe-stack-set --stack-set-name aws-execution-role --call-as DELEGATED_ADMIN
An error occurred (ValidationError) when calling the DescribeStackSet operation: Account used is not a delegated administrator
委任されたアカウントでStackSetを確認
委任されたアカウント側でも同様に確認します。冒頭のオプションなしで失敗するケースです。
$ aws cloudformation describe-stack-set --stack-set-name aws-execution-role
An error occurred (StackSetNotFoundException) when calling the DescribeStackSet operation: StackSet aws-execution-role not found
委任されたアカウント上の StackSets には該当の StackSet がない旨のメッセージが出力されました。
オプションに DELEGATED_ADMIN
を追加して SERVICE_MANAGED
で展開されている StackSet まで確認します。
$ aws cloudformation describe-stack-set --stack-set-name aws-execution-role --call-as DELEGATED_ADMIN
{
"StackSet": {
"StackSetName": "aws-execution-role",
"StackSetId": "aws-execution-role:54c14cd9-f2d9-43d9-a21c-80f15af68ecc",
"Status": "ACTIVE",
...省略
}
}
無事対象の StackSet が取得できました。
まとめ
DescribeStackSet
が "not found" エラーになる原因について調査してみました。
StackSets を委任している環境では他の API でも同様のエラーになる可能性があります。StackSet が存在しているのにエラーとなる場合は、 CallAs
のオプションが付いていることを確認しましょう。