AWS CloudFormation で発生する、"Last applied policy cannot be deleted" というエラーを解決したいと考えています。
概略
CloudFormation ポリシー (AWS::SQS::QueuePolicy、AWS::S3::BucketPolicy、AWS::SNS::TopicPolicy、AWS::IAM::Policy など) を削除しようとすると、次のエラーメッセージが発生する場合があります。
"Last applied policy cannot be deleted.Please delete other policies applied to this resource before deleting the last applied policy."
同じリソースにポリシーを適用してから他のポリシーを適用すると、2 番目のポリシーが最後に適用されたポリシーになります。2 番目のポリシーを削除しようとしても、CloudFormation ではポリシーを削除できません。
次のいずれかのシナリオに基づいて、この問題のトラブルシューティングを行います。
- スタックとポリシーの状態が DELETE_FAILED である。
- 同じリソースに適用したポリシーリソースを複数のスタックから削除しようとした。
- スタックとポリシーの状態が UPDATE_FAILED である。
解決策
注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI で発生したエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。
スタックとポリシーの状態が DELETE_FAILED である
スタックを削除しようとしてもポリシーが削除されなかった場合は、CloudFormation コンソールまたは AWS CLI を使用してスタックを再度削除し、リソースをスキップします。
CloudFormation コンソール
「CloudFormation コンソールからスタックを削除する」の手順に従ってスタックを強制削除します。
AWS CLI
次の delete-stack コマンドを実行します。
aws cloudformation delete-stack --stack-name example-stack-name --retain-resources example-policy-resource-id
注: **example-stack-name ** は削除に失敗したスタックに置き換え、example-policy-resource-id は削除に失敗したポリシーリソースの ID に置き換えてください。
スタックを再度削除しても、保持するように選択したリソースは削除されません。スタックのステータスは DELETE_COMPLETE に変わります。
注: 不要な請求を防ぐために、スタックを削除するときに保持されているリソースを手動で削除してください。ターゲットリソースを削除する場合は、ポリシーリソースも削除されるため、リソースを手動で削除する必要はありません。
詳細については、「CloudFormation スタックが DELETE_FAILED ステータスから移行しない場合の削除方法を教えてください」を参照してください。
同じリソースに適用したポリシーリソースを複数のスタックから削除しようとした
同じリソースに対し、複数のスタックから複数のポリシーを適用した場合、適用したポリシーのうち最初のものを削除する必要があります。
たとえば、example-stack-A で ExamplePolicyA を作成し、そのポリシーを exampleQueue1 に適用した後に、example-stack-B で ExamplePolicyB を作成し、そのポリシーを別のアクセス許可を使用して exampleQueue1 に適用した場合は、ExamplePolicyB を削除しようとすると、次のエラーが発生します。
"Last applied policy cannot be deleted.Please delete other policies applied to this resource before deleting the last applied policy."
ExamplePolicyB を削除するには、まず ExamplePolicyA を削除する必要があります。
注: 新しいポリシーを作成する前に、以前のポリシーを削除することをお勧めします。
スタックとポリシーリソースの状態が UPDATE_FAILED である
ポリシーからエンティティを削除した場合、スタックまたはポリシーリソースの状態は UPDATE_FAILED になる可能性があります。このエラーは、ポリシーが別のスタックで定義されている別の AWS::IAM::Policy リソースにアタッチされているか、上書きされているために発生します。
この問題を解決するには、最後に適用したポリシーを削除する前に、同じエンティティに適用した他のスタックから AWS::IAM::Policy リソースを削除してください。
リソースを削除するには、次の手順を実行します。
-
障害が発生したスタックリソースでスタックテンプレートを更新し、DeletionPolicy: Retain がポリシーリソースタイプセクションに含まれるようにします。
ポリシーの例:
yaml
MySharedPolicy:
Type: AWS::IAM::Policy
DeletionPolicy: Retain # Add this line
Properties:
# existing properties remain the same
-
更新したテンプレートと保持ポリシーをデプロイします。
-
CloudFormation テンプレートからポリシーリソースを削除します。
注: 保持ポリシーを追加したので、IAM ポリシーは削除されません。
-
スタックを更新して削除プロセスを完了します。
注: このスタックのポリシーリソースがまだ必要な場合は、ステップ 1 のポリシーに基づいてリソースをテンプレートに戻します。次に、テンプレートを使用してスタックを更新し、リソースを作成します。
AWS::IAM::Policy から AWS::IAM::RolePolicy、AWS::IAM::UserPolicy、AWS::IAM::GroupPolicy のいずれかに移行することをお勧めします。
問題が続く場合や、ポリシーリソースを含む他のスタックを特定できない場合は、リソースを消去して再作成してください。ポリシーリソースを再作成すると、"resource already exists" というエラーが表示される場合があります。この問題を解決するには、PolicyName の名前を変更します。1 つのポリシーリソースを 1 つのスタックのみで管理することをお勧めします。