AWS IAMリソース パスのススメ

IAMリソースに指定できるパスについて、運用上のメリットと注意点を紹介します。
2022.05.22

こんにちは。サービスグループの武田です。

今回は使いどころがイマイチつかめない(※個人の感想です)IAMリソースの「パス」について紹介します。

IAMがなんなのか、というのは夏目のエントリなどを参照してください。

普段からAWSを使っている方でもIAMの「パス」を意識している人は、あまり多くないのではないでしょうか。というのも、別に意識しなくてもAWSは使えますし、マネジメントコンソールからIAMロールなどを作成する際には設定欄がなかったりします。ぶっちゃけ影が薄いです。

IAMの「パス」を設定する場合は、AWS CLIやSDKを使用することになります。例として、CLIでIAMロールを作成するのであれば次のように作成できます。

$ aws iam create-role --path '/cm-role/' --role-name cm-example --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}'

このエントリでは以下、IAMロールのパスについて言及していますが、ユーザー、グループ、ポリシーなどでも同様のことが言えます。

パスを設定するメリット

さてIAMには影の薄いパスというパラメーターがあるのでした。普段指定しなくても問題ないのですが、設定するメリットはあるのでしょうか?結論を言えば、「将来嬉しいことがあるかもしれない」です。

まず機能としてはパスの有無は関係ありません。指定しなければ、デフォルトの/となるだけです。ではどう変わるかというと、IAMリソースを一覧取得する際に フィルター として使用できる点が異なります。

AWS CLIではlist-rolesを使って、ロールを一覧取得できます。

$ aws iam list-roles

これだとすべてのロールが取得されるわけなのですが、--path-prefixというオプションを指定することで、パスを前方一致でフィルタリングできます。

$ aws iam list-roles --path-prefix '/aws-service-role/'

{
    "Roles": [
        {
            "Path": "/aws-service-role/access-analyzer.amazonaws.com/",
            "RoleName": "AWSServiceRoleForAccessAnalyzer",
...

この--path-prefixは前方一致のため、パスがデフォルトの/だと絞り込むことができません(--path-prefix '/'と指定しても、前方一致のため全取得になる)。とはいえ、じゃあIAMリソースの一覧取得を頻繁にするかといえば運用次第ですし、フィルタリングが必要なほどIAMリソースが増えるのかもケースバイケースです。そのためIAMリソースの設計時にパスも考慮しておくと、将来の自分が助かる かも しれません。というのが私の考えです。

2022-06-22 追記

後述しますがIAMリソースに設定したパスは、ARN上はリソース名のprefixとなります。そのためIAMポリシーなどの条件を指定する際にグループとしての役割を持たせることができるようです。詳細はyhanaのエントリを参照ください。

追記ここまで。

パスを考えるうえでの注意点

IAMリソースのパスを設計・運用していくうえで私が注意すべきだと感じた点は次の3点です。

  1. 階層構造を作る場合は取得したい単位を考える
  2. 後からパスの設定は不可能
  3. どうしてもパスを後から設定したい場合の影響度

階層構造を作る場合は取得したい単位を考える

パスは一覧取得する際に前方一致でフィルタリングできることを前述しました。そのため、何階層かに整理してパスを設定する場合、一覧取得したい単位を意識するとよさそうです。たとえば次のようにシステムレベル、コンポーネントレベルのような階層を設けます。

  • /system-aaa/
  • /system-aaa/component-xxx/

そうすると、aws iam list-roles --path-prefix '/system-aaa/'と指定すれば、下位のcomponent-xxxも含めた一覧が取得できます。またaws iam list-roles --path-prefix '/system-aaa/component-xxx/'と指定すれば、component-xxxに限定して一覧取得できます。逆に包含関係を作りたくないのであれば、フラットな階層にすればよいでしょう。

後からパスの設定は不可能

一度ロールを作成し、運用をしていたとします。そして運用効率化のためにロールのパスを設定(あるいは変更)したくなったとします。設定可能でしょうか?答えは ノー です。ロールのパスは後から設定できません。どうしても設定したいのであればロールを作り直すしかありません。

どうしてもパスを後から設定したい場合の影響度

前述したように後からパスの設定はできません。既存のロールは変更できないため作り直すことになり、その際にロールのARNが変わります。具体的にcm-exampleロールを例にすると、デフォルトではARNはarn:aws:iam::123456789012:role/cm-exampleとなります。/cm-role/パスを設定するとARNはarn:aws:iam::123456789012:role/cm-role/cm-exampleとなります。そのためシステムからロールARNを参照している場合、それらすべてを修正することになります。

変更のインパクトを減らすため、新しいロールを作成し参照箇所をすべて修正してから、古いロールを削除する手順はどうでしょうか。この方法はうまくいきそうですが、ロール名は違うものにする必要があります。既存のcm-exampleロールがあったとして、新しく/cm-role/cm-exampleロールを作成しようとしても EntityAlreadyExists とエラーになり作成できません。どうやらパスはARNに反映されるものの、リソース名の一部とはみなされないようです。そのためロール名はcm-example以外にする必要があります。

どうしても同じ名前のロールを作りたいのであれば、削除して再作成ということになるため、切り替えにかかる時間の一時的なダウンを許容する必要があります。

まとめ

IAMリソースのパスについて現時点での私の理解をまとめてみました。結論としては、後からパスを設定しようとするのは影響が大きすぎて難しい。複数のシステムから参照される、リソース数が多くなる見込みのあるアカウントなどは運用を視野に入れパスを設定しておくよさそう。となります。

もし「こういう目的でパス運用してます」などあればぜひ教えてください。