タグ付けしたRDSにのみ操作可能なIAMポリシーを作りたい

特定のタグをつけたRDSにのみ操作を許可するIAMポリシーを作成する際の注意点をご説明します。
2023.09.27

困っていること

RDSの全ての操作を特定のタグ付けされたリソースにのみ許可したいです。

以下のようなポリシーを作成し、IAMユーザに割り当てました。

 {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "rds:*",
            "Condition": {
                "StringEquals": {
                    "rds:db-tag/Name": [
                        "example-tag"
                    ]
                }
            },
            "Resource": "*"
        }
 }

しかし、名前の変更やスナップショット取得を実行しようとすると以下のエラーが出てしまいます。

※エラー文抜粋

・クラスター名を変更するとき

because no identity-based policy allows the rds:ModifyDBCluster action

・スナップショットを取得するとき

because no identity-based policy allows the rds:CreateDBClusterSnapshot action

また、以下のようにそれぞれアクションを追加してみましたが、やはりエラーになってしまいます。

 {
            "Action": "rds:Describe*",
            "Effect": "Allow",
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "rds:ModifyActivityStream",
                "rds:ModifyCertificates",
                "rds:ModifyDBCluster",
                "rds:ModifyCurrentDBClusterCapacity",
                "rds:ModifyCustomDBEngineVersion",
                "rds:ModifyDBClusterEndpoint",
                "rds:ModifyDBClusterParameterGroup",
                "rds:ModifyDBClusterSnapshotAttribute",
                "rds:ModifyDBInstance",
                "rds:ModifyDBParameterGroup",
                "rds:ModifyDBProxy",
                "rds:ModifyDBProxyEndpoint",
                "rds:ModifyDBProxyTargetGroup",
                "rds:ModifyDBSnapshot",
                "rds:ModifyDBSnapshotAttribute",
                "rds:ModifyDBSubnetGroup",
                "rds:ModifyEventSubscription",
                "rds:ModifyGlobalCluster",
                "rds:ModifyOptionGroup",
                "rds:ModifyRecommendation"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "rds:db-tag/Name": [
                        "example-tag"
                    ]
                }
            }
 }

どのようなポリシーを作成すれば良いでしょうか?

なぜエラーになったのか

[rds:ModifyDBCluster]を例とします。

作成したポリシーは[Condition]ブロックにて、条件キー[rds:db-tag]を使用しようとしています。

公式ドキュメント[1]にて[rds:ModifyDBCluster] アクションの必須リソースを確認すると、[cluster],[cluster-pg],[og]が定義されています。

[1]Amazon RDS のアクション、リソース、および条件キー - Amazon RDS で定義されるアクション

しかし、3つのリソースとも条件キー[rds:db-tag]には対応していないことが公式ドキュメント[2]を参照すると確認できます。

[2]Amazon RDS のアクション、リソース、および条件キー - Amazon RDS で定義されるリソースタイプ

このような場合、公式ドキュメント[3]にあるように、[StringEquals]の条件演算子のチェックが失敗し[ModifyDBCluster]アクションはIAMポリシーに記載されている Effect ( [許可]または[拒否])は適用されなくなってしまいます。

[3] IAM JSON ポリシー要素: 条件演算子 - IfExists 条件演算子

前述のポリシーの目的は、ユーザーが t1、t2および m3 タイプのインスタンスを起動できるようにすることです。ところが、インスタンスを起動する場合には、インスタンス自体に加えて、イメージ、キーペア、セキュリティグループおよびそれ以上のさまざまなリソースにアクセスする必要があります。ステートメント全体が、インスタンスを起動するために必要なすべてのリソースに対して評価されます。これらの追加のリソースには ec2:InstanceType 条件キーがないため、StringLike のチェックは失敗し、ユーザーはいずれのタイプのインスタンスも起動できません。

どう対応すればいいの?

一例として、リソースを分割する方法があります。 [rds:ModifyDBCluster]アクションを例として説明します。

[cluster]リソースにアタッチされるタグは[rds:cluster-tag]となります。 しかし[cluster-pg],[og]には[rds:cluster-tag] が利用できないため、以下のように明確に分けて記載する必要があります。

■サンプルポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "rds:Describe*",
            "Effect": "Allow",
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "rds:ModifyDBCluster",
            "Resource": "arn:aws:rds:::cluster:*",
            "Condition": {
                "StringEquals": {
                    "rds:cluster-tag/Name": [
                        "example-tag"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "rds:ModifyDBCluster",
            "Resource": [
                "arn:aws:rds:::cluster-pg:*",
                "arn:aws:rds:::og:*"
            ]
        }
    ]
}

結果

検証の結果、上記ポリシーをアタッチしたIAMユーザーにて、クラスターの名前を変更することができました。

このようにして、許可したいアクションごとにポリシーを記述する必要があります。

参考

[1]Amazon RDS のアクション、リソース、および条件キー - Amazon RDS で定義されるアクション

[2]Amazon RDS のアクション、リソース、および条件キー - Amazon RDS で定義されるリソースタイプ

[3] IAM JSON ポリシー要素: 条件演算子 - IfExists 条件演算子