Y_Yamashitaのブログ

勉強したことのアウトプット・メモ中心。たまに日記とか。

CloudShellでIAMポリシー/IAMロールを削除しようとして詰まった話

はじめに

先日、以下のハンズオンを実施した。

docs.aws.amazon.com

Lambdaの使い方がよく分かっていないこともあり、関数の作成や呼び出しは手順通りマネジメントコンソールで実行。問題なく関数呼び出しが出来た。

手順の最後にチュートリアル環境の削除手順があり、これもマネコンでの作業手順が記載されているが、せっかく最近CloudShellを触ったので、せめて最後の削除だけはCloudShellで実行してみることにした。そうしたら、IAMポリシー/IAMロールの削除で思うようにいかなかった場面があったので、備忘として記載することにした。

IAMポリシー削除

まずは以下のWEBページでCLIの削除手順を軽く確認。

docs.aws.amazon.com

最初はポリシーのリストを確認するようなので、とりあえずやってみる。

[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam list-policies | grep AWSLambdaS3E*
            "PolicyName": "AWSLambdaS3ExecutionRole-50e074db-f735-45b9-867f-2f1ca04f5ce5",
            "Arn": "arn:aws:iam::xxxxxxxxxxxx:policy/service-role/AWSLambdaS3ExecutionRole-50e074db-f735-45b9-867f-2f1ca04f5ce5",
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ 

表示されたので、消そうとしてみる。

[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam delete-policy \
> --policy-arn arn:aws:iam::xxxxxxxxxxxx:policy/service-role/AWSLambdaS3ExecutionRole-50e074db-f735-45b9-867f-2f1ca04f5ce5

An error occurred (DeleteConflict) when calling the DeletePolicy operation: Cannot delete a policy attached to entities.
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$

「エンティティにアタッチされているポリシーは削除できない」というエラーが出てしまった。

ただ、ハンズオンの手順だと、いきなりポリシーを削除することになっている。マネコンとCLIでは勝手が違うのだろうか。

試しにマネコン上での削除を試みる。

f:id:YuY_83:20210603230939p:plain
マネコンのIAMポリシー削除確認画面

マネコンだとエンティティのデタッチを自動で実施してくれるのか。うーむ、マネコン、侮れん。

再度CloudShellに戻って、ポリシーに割り当たっているエンティティについて確認する。aws iam list-entities-for-policy --policy-arnコマンドで、指定したIAMポリシーにアタッチされているエンティティのリストが表示される模様。想定では、ハンズオンで作成したIAMロールが表示されるはず。

[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam list-entities-for-policy \
> --policy-arn arn:aws:iam::xxxxxxxxxxxx:policy/service-role/AWSLambdaS3ExecutionRole-50e074db-f735-45b9-867f-2f1ca04f5ce5
{
    "PolicyGroups": [],
    "PolicyUsers": [],
    "PolicyRoles": [
        {
            "RoleName": "my-s3-function-role",
            "RoleId": "AROATO53NFKUGNFFORV4I"
        }
    ]
}
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$

想定通り表示された。今度はCLI上でデタッチをやってみる。デタッチについてはaws iam detach-role-policyコマンドで、デタッチしたいロールと、現在アタッチされているポリシーを指定する模様。

[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam detach-role-policy \
> --role-name my-s3-function-role \
> --policy-arn arn:aws:iam::xxxxxxxxxxxx:policy/service-role/AWSLambdaS3ExecutionRole-50e074db-f735-45b9-867f-2f1ca04f5ce5
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ 
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ 

デタッチコマンドが通ったので、改めてエンティティのアタッチ状況を確認する。

[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam list-entities-for-policy --policy-arn arn:aws:iam::xxxxxxxxxxxx:policy/service-role/AWSLambdaS3ExecutionRole-50e074db-f735-45b9-867f-2f1ca04f5ce5
{
    "PolicyGroups": [],
    "PolicyUsers": [],
    "PolicyRoles": []
}
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ 
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ 

デタッチされた模様。では、改めてポリシーを削除する。

[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam delete-policy --policy-arn arn:aws:iam::xxxxxxxxxxxx:policy/service-role/AWSLambdaS3ExecutionRole-50e074db-f735-45b9-867f-2f1ca04f5ce5
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ 

削除成功。

IAMロール削除

続いて、IAMロールを削除する。まずはコマンドを以下のWEBページで確認する。

docs.aws.amazon.com

とりあえず、ページに記載の通りにやってみる。aws iam list-rolesコマンドを実行したら、現在作成されているロールがJSON形式で全て表示された。よくページ見たら、「対象ロール名が分からない場合」と書いてあった。今回は必要なかったな。

気を取り直して、次のコマンドから実行する。

[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam list-instance-profiles-for-role --role-name my-s3-function-role
{
    "InstanceProfiles": []
}
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$  
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam list-role-policies --role-name my-s3-function-role
{
    "PolicyNames": []
}
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ 

特に何も割り当たっていないように見えるので、削除コマンドを実行する。

[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam delete-role --role-name my-s3-function-role

An error occurred (DeleteConflict) when calling the DeleteRole operation: Cannot delete entity, must detach all policies first.
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ 

消せない。「ロールを消したきゃ、まずポリシーからデタッチしろ」とエラーが出た。なんでだ?

他のコマンドで改めてポリシーのアタッチ状況を確認してみる。

[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam list-attached-role-policies --role-name my-s3-function-role
{
    "AttachedPolicies": [
        {
            "PolicyName": "AWSLambdaBasicExecutionRole-b6e2f444-ac64-4852-8685-d03f9e4b131c",
            "PolicyArn": "arn:aws:iam::xxxxxxxxxxxx:policy/service-role/AWSLambdaBasicExecutionRole-b6e2f444-ac64-4852-8685-d03f9e4b131c"
        }
    ]
}
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$

なんか割り当たってる!?状況がよく飲み込めていないが、とりあえずこれをデタッチして、再度削除を試みる。

[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam detach-role-policy \
> --role-name my-s3-function-role \
> --policy-arn arn:aws:iam::xxxxxxxxxxxx:policy/service-role/AWSLambdaBasicExecutionRole-b6e2f444-ac64-4852-8685-d03f9e4b131c
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ 
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam list-attached-role-policies --role-name my-s3-function-role
{
    "AttachedPolicies": []
}
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$ aws iam delete-role --role-name my-s3-function-role
[cloudshell-user@ip-10-xxx-xxx-xxx ~]$

消せた。。いったい全体どういうことなのか。

改めて調べてみた

IAMポリシーには「管理ポリシー」と「インラインポリシー」があり、最初に実行したaws iam list-role-policiesインスタンスポリシーの一覧を、後で実行したaws iam list-attached-role-policiesは管理ポリシーの一覧を表示するものらしい。

管理ポリシーとインラインポリシーの違いについては、ザックリいうと、複数のIAMアイデンティティ(ユーザー、グループ、ロール)に割り当て可能なものが管理ポリシーで、特定のIAMアイデンティティと完全に紐づけされるものがインラインポリシーらしい。IAMにおいては通常は管理ポリシーを利用するのがベストプラクティスな模様。インラインポリシーは、特定のアイデンティティにのみ適用したいポリシーがあり、他とポリシーを共有することによって意図せぬ変更が発生することを避けたいケースで使う。

なお、バケットポリシーのようなリソースベースのポリシーは、必ずインラインポリシーになる模様。

管理ポリシーとインラインポリシーの違いについては、以下のサイトを参考にした。

dev.classmethod.jp

docs.aws.amazon.com

qiita.com

dev.classmethod.jp

おわりに

最初はCloudShellで設定を削除するだけのつもりだったが、思いがけずポリシーの種類の勉強になった。実際に手を動かすと、「なんか上手くいかない → 色々調べる → 知らないまま使っていたものの仕組みが分かる」という学習効果が得られるので、今後も積極的に手を動かしていきたい。