AWS Control Tower有効化時にAWSControlTowerExecutionロールの信頼ポリシーに関するエラーがでたのでトラブルシューティングしてみた
お疲れさまです。とーちです。
先日、既存のアカウントを使ってAWS Control Towerを有効化しようとしたところ、エラーが発生しました。今回はこのトラブルシューティングの過程を共有したいと思います。
発生したエラー
Control Towerを有効化しようとした際に、以下のようなエラーメッセージが表示されました。
AWS Control Tower はランディングゾーンを完全に設定できませんでした。AWS Control Tower failed to deploy one or more stack set instances: StackSet Id: [ID値], Stack instance Id: null, Status: OUTDATED, Status Reason: Account [アカウント番号] should have 'AWSControlTowerExecution' role with trust relationship to Role 'service-role/AWSControlTowerStackSetRole'. 詳細はこちら
英語のエラーメッセージは以下の通りです。
AWS Control Tower failed to set up your landing zone completely: AWS Control Tower failed to deploy one or more stack set instances: StackSet Id: [ID値], Stack instance Id: null, Status: OUTDATED, Status Reason: Account [アカウント番号] should have 'AWSControlTowerExecution' role with trust relationship to Role 'service-role/AWSControlTowerStackSetRole'. Learn more
背景状況
今回のControl Tower有効化は以下のような状況で実施していました。
- 既存のLog ArchiveアカウントとAuditアカウントを使ってControl Towerを有効化しようとしていた
- 半年以上前に、API を使用して AWS Control Tower を有効化を試みたが、エラーにより失敗(エラー内容は失念)
- その状況でAWS マネジメントコンソールから再度有効化を実施(設定内容は以下の通り)
トラブルシューティングの過程
1. エラーメッセージの分析
エラーメッセージを見ると、should have 'AWSControlTowerExecution' role with trust relationship to Role 'service-role/AWSControlTowerStackSetRole'
と書いてあります。まずは対象のアカウントにAWSControlTowerExecution
ロールが存在するかを確認してみました。
2. IAMロールの確認
対象のアカウントを確認したところ、AWSControlTowerExecution
ロールは既に存在していました。
このロールには以下の信頼ポリシーが設定されていました。
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<管理アカウントのID>:root",
"Service": "controltower.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
3. ドキュメントの確認
AWS公式ドキュメントによると、AWSControlTowerExecution
ロールには以下の信頼ポリシーが必要とされています。そのためポリシーも問題なさそうです。
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Principal":{
"AWS": "arn:aws:iam::Management Account ID:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
4. CloudFormation Stack Setsの確認
エラーメッセージにAWS Control Tower failed to deploy one or more stack set instances
とあるので、初期セットアップ時のStack Sets実行に失敗していると推測し、管理アカウントのStack Setsを確認してみました。
3つのStack Setが登録されており、一番上のAWSControlTowerSecurityResources
と二番目のAWSControlTowerLoggingResources
が失敗していることがわかりました。
スタックインスタンスを確認すると、スタックIDが-
になっていることから、スタック自体が作成できていないようです。
5. 既存のStack Setの削除(結論としては不要な作業)
Stack Setsの画面を詳しく見ると、AWSControlTowerExecutionRole
というStack Setが存在していました。これは以前にAPIを使用してControl Towerを有効化しようとした際に作成されたものなのかなと思いました。
このStack Setが問題を引き起こしている可能性を考え、削除することにしました。
対象アカウントに移動すると、上記のStack Setから実行されたスタックが削除され、それに伴いAWSControlTowerExecution
ロールも削除されたことを確認しました。
なお、後から分かったことですが、このStack Setは Control Tower 有効化時に必ず実行されるもので、特に削除する必要はありませんでした。ドキュメントによれば、Security OUのアカウントの場合、AWS Control Towerは初期セットアップ時にAWSControlTowerExecution
ロールを作成するのですが、そのためのStack Setですね。
6. AWS Configの設定確認
他のエラーとなる要因を先につぶしておこうと思ったので、AuditとLog Archiveアカウントに AWS Configが設定されていないかを確認しました。
aws configservice describe-configuration-recorders
aws configservice describe-delivery-channels
設定されている場合は、以下のコマンドを実行して削除しておきます(こちらの記事を参考にさせていただきました)。
for r in `aws ec2 describe-regions --query Regions[*].RegionName --output text`
do
for channel_name in `aws configservice describe-delivery-channels --region $r --query DeliveryChannels[*].name --output text`
do
recorder_name=`aws configservice describe-configuration-recorders --region $r --query ConfigurationRecorders[*].name --output text`
aws configservice delete-configuration-recorder --configuration-recorder-name $recorder_name --region $r
aws configservice delete-delivery-channel --delivery-channel-name $channel_name --region $r
done
done
7. 信頼ポリシーの修正(結論としては不要な作業)
この状態で管理アカウントに移動してControl Tower有効化を再試行しましたが、再びエラーが発生しました。上記のドキュメントを見る限りでは"arn:aws:iam::<管理アカウントのID>:root"
が設定されていれば問題ないですし、こちらのドキュメントにも記載あるようにrootを許可プリンシパルとして追加すればアクセス元のアカウントのすべてのプリンシパルが対象IAMロールを引き受けられるはずですが、念のため、AWSControlTowerStackSetRoleも信頼プリンシパルとして追加してみます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<管理アカウントのID>:root",
"arn:aws:iam::<管理アカウントのID>:role/service-role/AWSControlTowerStackSetRole"
],
"Service": "controltower.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
この修正を行っても問題は解決しませんでした。
原因の特定と解決
しかし、これまでの調査で状況が整理できてきました。
-
Control Tower有効化時に実行される以下2つのStack Setの実行が失敗している
- AWSControlTowerSecurityResources
- AWSControlTowerLoggingResources
-
これらのStack Setはスタックの作成自体ができていない
- Stack Setsのスタックインスタンスの画面でスタックIDが
-
になっている点から推測
- Stack Setsのスタックインスタンスの画面でスタックIDが
-
これらのStack Setは管理アカウント側の
/service-role/AWSControlTowerStackSetRole
が、Audit、Log Archiveアカウント側のAWSControlTowerExecution
のIAMロールにAssumeRoleすることで実行されている -
Audit、Log Archiveアカウント側の
AWSControlTowerExecution
のIAMロールには管理アカウント側の/service-role/AWSControlTowerStackSetRole
を信頼するための信頼ポリシーが間違いなく設定済み
なお、Stack Setsの仕組みを図示すると以下のようになります。
整理した結果、問題は管理アカウント側の/service-role/AWSControlTowerStackSetRole
にあるのではないかと推測しました。
そこで、/service-role/AWSControlTowerStackSetRole
の権限を確認したところ、権限が全くついていませんでした。これが原因だったのです。
解決策
必要な権限はAWS公式ドキュメントに記載されています。
具体的には、AWSControlTowerStackSetRole
には以下のポリシーをアタッチする必要があります
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::*:role/AWSControlTowerExecution"
],
"Effect": "Allow"
}
]
}
このIAMロールに必要な権限を付与した後、再度Control Towerの有効化を試みたところ、ようやく有効化に成功しました。
まとめ
今回のトラブルシューティングから得られた教訓は以下の通りです。
-
Control Towerの有効化は間を空けずにやり切りましょう。特に半年も間が空くと自分が何をしていたか忘れてしまいます。
-
トラブルシューティングをするためには基礎知識が大事です。今回でいうとStack Setsの実行の仕組みなど。わからない場合は調べましょう(ハルシネーションには注意ですが、生成AIに仕組み自体を聞くのもおすすめです)。
-
AWS公式ドキュメントは問題解決の重要な参考資料です。特にIAMロールの権限設定などは公式ドキュメントを確認することが大切です。
以上、とーちでした。