Auroraリードレプリカをスケジュールベースで増減させるための最小権限について考えてみた

記事タイトルとURLをコピーする

技術4課の前田です。 前回の記事で解説させていただいた用語、コマンド等が出てくるため、まだ読んでない方は目を通してくださると幸いです。 blog.serverworks.co.jp

今回は下記のような課題に直面し考えたことを書いていきます。

課題

  • お客様のユーザ部門は、AWS CLIを使用してAuroraリードレプリカをスケジュールベースで増減させたい

  • お客様の管理部門は、セキュリティ統制のために上記操作を実施するためのIAMユーザを最小権限で運用したい。

  • 2部門の希望を両立させるようなIAMポリシー設定を考える必要がある。

結論

下記のIAMポリシーなら2部門の希望を両立させられそうです。

  • <スケーラブルターゲットID>の箇所はスケーラブルターゲット登録時に発行されるIDに置換してください。
  • <アカウントID>の箇所はお使いのAWSアカウントIDに置換してください。
  • 【重要】スケーラブルターゲットの登録は管理部門などが行う前提です。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "application-autoscaling:PutScheduledAction",
                "application-autoscaling:DescribeScalingActivities",
                "application-autoscaling:DeleteScheduledAction"
            ],
            "Resource": "arn:aws:application-autoscaling:ap-northeast-1:<アカウントID>:scalable-target/<スケーラブルターゲットID>"
        },
        {
            "Effect": "Allow",
            "Action": [
                "application-autoscaling:DescribeScalableTargets",
                "application-autoscaling:DescribeScheduledActions"
            ],
            "Resource": "arn:aws:application-autoscaling:ap-northeast-1:<アカウントID>:scalable-target/*"
        }
    ]
}

最小権限への道①~公式ドキュメントに記載されているポリシーをそのまま利用~

公式ドキュメントの情報から下記の権限が必要になります。

上記をそのまま反映した場合、IAMポリシーは下記のようになります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
              "application-autoscaling:RegisterScalableTarget",
              "application-autoscaling:DescribeScalableTargets",
              "application-autoscaling:DeregisterScalableTarget",
              "application-autoscaling:PutScheduledAction",
              "application-autoscaling:DescribeScheduledActions",
              "application-autoscaling:DescribeScalingActivities",
              "application-autoscaling:DeleteScheduledAction"
            ],
            "Resource": "arn:aws:application-autoscaling:ap-northeast-1:<アカウントID>:scalable-target/*"
        },
        {
            "Effect": "Allow",
            "Action": [
              "rds:AddTagsToResource",
              "rds:CreateDBInstance",
              "rds:DeleteDBInstance",
              "rds:DescribeDBClusters",
              "rds:DescribeDBInstances",              
              "cloudwatch:DescribeAlarms",
              "cloudwatch:PutMetricAlarm",
              "cloudwatch:DeleteAlarms"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "arn:aws:iam::<アカウントID>:role/aws-service-role/rds.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_RDSCluster",
            "Condition": {
                "StringLike": {
                    "iam:AWSServiceName":"rds.application-autoscaling.amazonaws.com"
                }
            }
        }
    ]
}

問題点

上記のポリシーには下記の問題点が挙げられます。

  • 「Auto Scaling APIアクションに必要な許可」の対象リソースが「scalable-target/*」となっていることで、想定と異なるスケーラブルターゲットにAuto Scaling設定が実行出来てしまうリスクがある

  • 「ターゲットサービスとCloudWatchでのAPIアクションに必要な許可」の対象リソースが「*」となっていることでDBインスタンスを無制限に作成・削除出来てしまったりタグ付与できてしまったり、CloudWatchアラームを無制限に作成・削除出来てしまうリスクがある


最小権限への道②~アクションが削減できないか検討する~

実際にはDeleteDBInstance等の操作はユーザではなくApplication AutoScalingが行うため、IAMポリシーで上記アクションへの許可が必要になる理由が分かりませんでした。

公式ドキュメント精査やCloudTrailログ調査を行った結果(※補足で説明)、下記のようなポリシーに落ち着きました。

  • CloudWatchアラームを作成する「PutMetricAlarm」と削除する「DeleteAlarms」を削除する。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
              "application-autoscaling:RegisterScalableTarget",
              "application-autoscaling:DescribeScalableTargets",
              "application-autoscaling:DeregisterScalableTarget",
              "application-autoscaling:PutScheduledAction",
              "application-autoscaling:DescribeScheduledActions",
              "application-autoscaling:DescribeScalingActivities",
              "application-autoscaling:DeleteScheduledAction"
            ],
            "Resource": "arn:aws:application-autoscaling:ap-northeast-1:<アカウントID>:scalable-target/*"
        },
        {
            "Effect": "Allow",
            "Action": [
              "rds:AddTagsToResource",
              "rds:CreateDBInstance",
              "rds:DeleteDBInstance",
              "rds:DescribeDBClusters",
              "rds:DescribeDBInstances",              
              "cloudwatch:DescribeAlarms"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "arn:aws:iam::<アカウントID>:role/aws-service-role/rds.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_RDSCluster",
            "Condition": {
                "StringLike": {
                    "iam:AWSServiceName":"rds.application-autoscaling.amazonaws.com"
                }
            }
        }
    ]
}




問題点

しかし、上記ポリシーには依然として下記の問題点が残っています。

  • 「Auto Scaling APIアクションに必要な許可」の対象リソースが「scalable-target/*」となっていることで、想定と異なるスケーラブルターゲットにAuto Scaling設定が実行出来てしまうリスクがある。

  • 「ターゲットサービスとCloudWatchでのAPIアクションに必要な許可」の対象リソースが「*」となっていることでDBインスタンスを無制限に作成・削除出来てしまったりタグ付与できてしまうリスクがある。


最小権限への道③~Resourceを絞れないか検討する~

次に検討したのは、各アクションの対象リソースを絞れないかということでした。 こちらも実際に動かして試行錯誤し、とりあえず下記のようなポリシーに落ち着きました。

  • スケジュールドアクションの作成・変更をする「PutScheduledAction」や削除する「DeleteScheduledAction」などには、ResourceにスケーラブルターゲットIDを指定する。
  • RDSインスタンスを削除する「DeleteDBInstance」やタグ付与する「AddTagsToResource」には、出来る限り限定したARNを指定する。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
              "application-autoscaling:DeregisterScalableTarget",
              "application-autoscaling:PutScheduledAction",
              "application-autoscaling:DescribeScalingActivities",
              "application-autoscaling:DeleteScheduledAction"
            ],
            "Resource": "arn:aws:application-autoscaling:ap-northeast-1:<アカウントID>:scalable-target/<スケーラブルターゲットID>"
        },
        {
            "Effect": "Allow",
            "Action": [
                "application-autoscaling:RegisterScalableTarget",
                "application-autoscaling:DescribeScalableTargets",
                "application-autoscaling:DescribeScheduledActions"
            ],
            "Resource": "arn:aws:application-autoscaling:ap-northeast-1:<アカウントID>:scalable-target/*"
        },
        {
            "Effect": "Allow",
            "Action": [
              "rds:AddTagsToResource",
              "rds:DeleteDBInstance"
            ],
            "Resource": "arn:aws:rds:ap-northeast-1:<アカウントID>:db:application-autoscaling*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "rds:DescribeDBClusters",
                "rds:DescribeDBInstances",
                "rds:CreateDBInstance",
                "cloudwatch:DescribeAlarms"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "arn:aws:iam::<アカウントID>:role/aws-service-role/rds.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_RDSCluster",
            "Condition": {
                "StringLike": {
                    "iam:AWSServiceName":"rds.application-autoscaling.amazonaws.com"
                }
            }
        }
    ]
}

問題点

しかし、上記ポリシーには依然として下記の問題点が残っています。

  • 「ターゲットサービスとCloudWatchでのAPIアクションに必要な許可」の対象リソースが「*」となっていることでDBインスタンスを無制限に作成できてしまうリスクがある。

上記の問題についてはARNで制限することも出来ず、またAmazon RDSのポリシーリソースにも下記のような記載があるため、Resourceを制限するのは無理そうです。 (Condition句を上手く使えば制限できるかもしれませんが、そこまで検証する前に力尽きました…。)

リソースの作成など、一部の RDS API オペレーションは、特定のリソースで実行できません。このような場合は、ワイルドカード (*) を使用します。


最小権限への道④~スケーラブルターゲット関連の操作をなくす~

CreateDBInstance等のアクションはスケーラブルターゲット登録時しか必要にならないため、スケーラブルターゲット登録だけは情シス部門や構築ベンダーが行い、ユーザ部門は左記以外のAuto Scaling設定を実施する方針として考えれば問題を解決できるのではないかと考えました。

  • スケーラブルターゲットを登録する「RegisterScalableTarget」を削除する。

  • スケーラブルターゲットを解除する「DeregisterScalableTarget」も削除する。(登録できないのに解除だけできても良くないため)

  • CreateDBInstance等の「ターゲットサービスとCloudWatchでのAPIアクションに必要な許可」を削除する。(スケーラブルターゲット登録がなければ不要であるため)

  • 「サービスリンクロールの作成に必要な許可」を削除する。(スケーラブルターゲット登録がなければ不要であるため)

上記を反映したIAMポリシーが下記になります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "application-autoscaling:PutScheduledAction",
                "application-autoscaling:DescribeScalingActivities",
                "application-autoscaling:DeleteScheduledAction"
            ],
            "Resource": "arn:aws:application-autoscaling:ap-northeast-1:<アカウントID>:scalable-target/<スケーラブルターゲットID>"
        },
        {
            "Effect": "Allow",
            "Action": [
                "application-autoscaling:DescribeScalableTargets",
                "application-autoscaling:DescribeScheduledActions"
            ],
            "Resource": "arn:aws:application-autoscaling:ap-northeast-1:<アカウントID>:scalable-target/*"
        }
    ]
}

動作検証

「最小権限への道④」のIAMポリシーに記載されている下記の5つのアクションが正常に動作するのかを確認していきます。

  • スケーラブルターゲットの確認(DescribeScalableTargets)

  • スケジュールドアクションの登録(PutScheduledAction)

  • スケジュールドアクションの確認(DescribeScheduledActions)

  • スケジュールドアクションの削除(DeleteScheduledAction)

  • スケーリング結果の確認(DescribeScalingActivities)


対象DBは、Aurora PostgreSQL「kengen-test」になります。デフォルトでライターインスタンス1台とリードレプリカ1台が存在します。

事前作業1_スケーラブルターゲット登録

この操作は管理部門・構築ベンダー等が実施する想定で、今回はAdministratorAccess権限を持つIAMユーザを使用してCloudShellから実行しました。

aws application-autoscaling register-scalable-target \
    --service-namespace rds \
    --resource-id cluster:kengen-test \
    --scalable-dimension rds:cluster:ReadReplicaCount \
    --min-capacity 1 --max-capacity 5


スケーラブルターゲット登録を行うとスケーラブルターゲットIDが返されるのでメモしておきます。次のIAMポリシー作成で使用します。


事前作業2_Auto Scaling設定用IAMポリシー作成

Auto Scaling設定用IAMポリシーを作成します。 「最小権限への道④」で記載したIAMポリシーに、アカウントIDと事前作業1でメモしておいたスケーラブルターゲットIDを反映します。


IAMポリシーをユーザ部門用IAMユーザにアタッチします。今回は「maeda_cli2」というIAMユーザにアタッチしています。


検証1_スケーラブルターゲットの確認

下記コマンドを実行します。

aws application-autoscaling describe-scalable-targets \
    --service-namespace rds \
    --profile maeda_cli2


エラーなく実行でき、結果が表示されました。


検証2_スケジュールドアクションの登録

下記コマンドを実行します。

aws application-autoscaling put-scheduled-action \
    --service-namespace rds \
    --scalable-dimension rds:cluster:ReadReplicaCount \
    --resource-id cluster:kengen-test \
    --scheduled-action-name scaleout \
    --schedule "cron(13 9 * * ? *)" \
    --scalable-target-action MinCapacity=5,MaxCapacity=5 \
    --profile maeda_cli2


エラーなく実行出来ました。


スケジュールで指定した時間以降、実際にリードレプリカ台数も増加しています。


検証3_スケジュールドアクションの確認

下記コマンドを実行します。

aws application-autoscaling describe-scheduled-actions \
    --service-namespace rds \
    --resource-id cluster:kengen-test \
    --profile maeda_cli2


エラーなく実行でき、スケジュールドアクションが表示されました。


検証4_スケーリング結果の確認

下記コマンドを実行します。

aws application-autoscaling describe-scaling-activities \
    --service-namespace rds \
    --scalable-dimension rds:cluster:ReadReplicaCount \
    --resource-id cluster:kengen-test \
    --profile maeda_cli2


エラーなく実行でき、スケーリングアクティビティが表示されました。


検証5_スケジュールドアクションの削除

下記コマンドを実行します。

aws application-autoscaling delete-scheduled-action \
    --service-namespace rds \
    --scalable-dimension rds:cluster:ReadReplicaCount \
    --resource-id cluster:kengen-test \
    --scheduled-action-name scaleout \
    --profile maeda_cli2


エラーなく実行出来ました。


確認コマンドを打ってみると、削除されていることが分かります。

補足_スケジュールベースのApplication Auto Scaling設定でCreateDBInstance等への権限が必要となる操作について

スケーラブルターゲット登録時のみ必要になります。
公式ドキュメント「ターゲットリソースでの API コールに対する許可の検証」には下記のように記載されています。

ユーザーが Aurora DB クラスターに対して RegisterScalableTarget API を呼び出すと、Application Auto Scaling は 以下のすべてのチェックを実行してユーザーに必要なアクセス許可 (太字) があることを確認します。
▪ rds:CreateDBInstance:(中略)
▪ rds:DeleteDBInstance:(中略)
▪ rds:AddTagsToResource:(中略)
▪ rds:DescribeDBCluster:(中略)
▪ rds:DescribeDBInstance:(中略)
▪ cloudwatch:PutMetricAlarm:(中略)
▪ cloudwatch:DescribeAlarms:(中略)
▪ cloudwatch:DeleteAlarms:(中略)

実際にスケーラブルターゲット登録実行時のCloudTrailログを見てみると、上記ドキュメント記載のイベントが1秒間のうちに発生していることが分かります。
ただしドキュメントの内容と反し、「PutMetricAlarm」と「DeleteAlarms」は発生していませんでした。



「スケーラブルターゲット登録」以外の設定操作にCreateDBInstance等への権限が不要であることは、動作検証の章の内容が証明になるかと思います。

感想

残念ながらIAMポリシー内だけで最小権限を実現することは出来ませんでしたが、「枠にとらわれず解決策を考える」経験になったので良かったと思います。
非常にニッチなテーマになってしまいましたが、どなたかの一助になれば幸いです。

前田 青秀(執筆記事の一覧)

2023年2月入社 技術4課

AWS資格12冠

ジムに通い始めましたが、なるべく楽してマッチョになりたい…