概要
ELBとS3ログの作成をCFで実施したら以下エラー。
Resource handler returned message: "Access Denied for bucket: xxx. Please check S3bucket permission
原因はバケットポリシーやIAMロール権限などではなく、意外なところでしたので紹介します。
原因
エラーメッセージは「ELBがS3バケットにアクセスできません」と言っています。
xxx
という名前のS3バケットに対するアクセスが拒否されています。
原因としてよくあるのは以下だと思います。
・ELBがS3バケットにアクセスするためのIAMロールが適切な権限を持っていない
・S3バケットのポリシーがELBからのアクセスを拒否している
しかし、今回はどちらも問題ありませんでした。
原因は、CloudFormationでの実施順序にありました。
イベントの履歴を確認すると、BucketPolicyLog
がまだ完全に適用されていない状態でPublicLoadBalancer
が更新されており、そのせいでアクセス権限が不足してしまっていたのです。
解決策
BucketPolicyLog
が適用されるのを待ってからPublicLoadBalancer
を更新するように、依存関係を明示的に定義してあげればOKです。
以下のようにDependsOn
属性を追加します。
PublicLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
DependsOn: BucketPolicyLog # 追加
Properties:
# ...
これにより、CloudFormationはBucketPolicyLog
が完全に作成または更新されるのを待ってからPublicLoadBalancer
を更新してくれるようになり、エラーがなくなりました。
実施順序(依存関係)によるエラーは、それが「実施順序の問題だよ」と教えてくれないので、ハマると大変です。なるべくエラーイベントにある箇所から「どうしてここでエラーが起きているのか?」を考えるのがベストかなと思います。
以前にも似たことがあったのでご参考までに。