Amazon RDS が使用する IAM ロールをうっかり絵を描いて整理してみた

AWS サービスロール と AWS サービスにリンクされたロール の違いを説明できますか?

コンバンハ、千葉(幸)です。

突然ですが問題です。

Amazon RDS では、データベースのログファイルを CloudWatch Logs に出力することができます。RDS のセットアップ時にログ出力を有効にすれば、CloudWatch Logs ロググループの作成や、ログストリームへのログのプッシュが行われます。

(エンジンにより出力できるログの種類や必要な設定に細かい違いがありますがここではあまり気にしない方向で……。)

上記で太字にしたようなアクションは、次のうちのどのロールに割り当てられた権限によって実現されているでしょうか。最も適切なものを選択してください。(10点)

  • a. RDS が使用する AWS サービスにリンクされたロール
  • b. RDS が使用する AWS サービスロール
  • c. RDS の DB インスタンスもしくはクラスターに関連づけられたロール
  • d. 上記のうちどれでもない

なお、それぞれの選択肢が表すのは以下のイメージの通りとします。

……。(シンキングタイム)

…………。(シンキングタイム)

………………。(シンキングタイム)

はい、そうですね。

正解は a. です。

なんのこっちゃという感じですよね。

しかも私は c. の存在をごく最近になって知りました。(エンジンによっては)個々の DB インスタンスやクラスターにロールを関連づけられるなんて知らずに生きてきました。

いったんここらで整理しましょう。

目次

AWS サービスにリンクされたロール とは

以下の★を付与している箇所にあたるものです。

ロールに付与されている権限を引き受けることができるエンティティにはいくつかの種類があります。

ロールに関する用語と概念 - AWS Identity and Access Management

IAM ロールをマネジメントコンソールを作成したことがある方は以下のような画面がピンとくるかも知れません。

AWS サービスが引き受ける場合、それは AWS サービスロールと呼ばれます。 AWS サービスロールはさらに分類され、その中で特定のものが AWS サービスにリンクされたロール (AWS service-linked role)と呼ばれます。

(以降、AWS service-linked role と EC2 用ロール 以外の AWS サービスロールを「狭義の AWS サービスロール」とします。)

AWS service-linked role はすべての AWS サービスで用意されているわけではありません。その有無は、以下ページの 「サービスにリンクされたロール」列から確認することができます。もちろん RDS は AWS service-linked role に対応しています。

IAM と連携する AWS のサービス - AWS Identity and Access Management

サービスにリンクされたロールは、(対応しているサービスにおいては)必ず一意で定義されます。つまり、RDS 用の AWS service-linked role は複数個作成することはできません。(RDS 用の狭義の AWS サービスロールは複数個作成することができます。)

AWS service-linked role と 狭義の AWS サービスロールの違いについてバチっと定義された記述は見つけられなかったのですが、前者は「 AWS サービスと直接リンク」されていると表現されています。ざっくり、 サービス全体として必要なものが AWS service-linked role であり、サービス内の個々のリソースが必要に応じて使用するものが狭義の AWS サービスロールであるのかと理解しています。

RDS 用の AWS service-linked role

多くの AWS service-linked role は、サービスの使用時に自動的に作成されます。 RDS で DB インスタンスを作成されたことがある方は、 自動的に AWSServiceRoleForRDS が作成されているはずです。明示的に作成する必要がないため、あまり意識する機会がないかも知れません。

RDS 用の AWS service-linked role については以下のページで確認できます。

Amazon RDS のサービスにリンクされたロールの使用 - Amazon Relational Database Service

ロールに付与されている権限は以下の通りです。 CloudWatch Logs 関連の権限もここで定義されていますし、 ENI の作成、削除を始めとした各種必要な権限が含まれています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:CreateNetworkInterface",
                "ec2:CreateSecurityGroup",
                "ec2:DeleteNetworkInterface",
                "ec2:DeleteSecurityGroup",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcAttribute",
                "ec2:DescribeVpcs",
                "ec2:ModifyNetworkInterfaceAttribute",
                "ec2:ModifyVpcEndpoint",
                "ec2:RevokeSecurityGroupIngress",
                "ec2:CreateVpcEndpoint",
                "ec2:DescribeVpcEndpoints",
                "ec2:DeleteVpcEndpoints",
                "ec2:AssignPrivateIpAddresses",
                "ec2:UnassignPrivateIpAddresses"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:Publish"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:/aws/rds/*",
                "arn:aws:logs:*:*:log-group:/aws/docdb/*",
                "arn:aws:logs:*:*:log-group:/aws/neptune/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:DescribeLogStreams"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:/aws/rds/*:log-stream:*",
                "arn:aws:logs:*:*:log-group:/aws/docdb/*:log-stream:*",
                "arn:aws:logs:*:*:log-group:/aws/neptune/*:log-stream:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "kinesis:CreateStream",
                "kinesis:PutRecord",
                "kinesis:PutRecords",
                "kinesis:DescribeStream",
                "kinesis:SplitShard",
                "kinesis:MergeShards",
                "kinesis:DeleteStream",
                "kinesis:UpdateShardCount"
            ],
            "Resource": [
                "arn:aws:kinesis:*:*:stream/aws-rds-das-*"
            ]
        }
    ]
}   

冒頭の問題で「a. RDS が使用する AWS サービスにリンクされたロール」を正解としたのはこういった理由です。

RDS が使用する AWS サービスロールを全部作ってみた

先ほどチラッと IAM ロール作成時のマネジメントコンソールの画面を載せました。

ここで AWS サービスの中から RDS を選択すると、いくつかの候補が出てきます。

それぞれユースケースを選択すると、広義の AWS サービスロールの作成画面に遷移します。適用する IAM ポリシーやロールの名称を自動的に設定してくれるものもあります。

ひとまず全部作ってみた結果以下のようになりました。パスが設定されているものは、そのサービスの AWS service-linked role です。

# ユースケース パス ロール名 適用ポリシー 信頼されたエンティティ
1 RDS /aws-service-role/rds.amazonaws.com/ AWSServiceRoleForRDS AmazonRDSServiceRolePolicy rds.amazonaws.com
2 RDS - Add Role to Database /(なし) 任意 任意 rds.amazonaws.com
3 RDS - Beta /aws-service-role/beta.rds.amazonaws.com/ AWSServiceRoleForRDSBeta AmazonRDSBetaServiceRolePolicy beta.rds.amazonaws.com、rds.amazonaws.com
4 RDS - CloudHSM /(なし) 任意 RDSCloudHsmAuthorizationRole rds.amazonaws.com
5 RDS - Directory Service /(なし) 任意 AmazonRDSDirectoryServiceAccess directoryservice.rds.amazonaws.com、rds.amazonaws.com
6 RDS - Enhanced Monitoring /(なし) 任意 AmazonRDSEnhancedMonitoringRole monitoring.rds.amazonaws.com
7 RDS - Preview /aws-service-role/rds-preview.amazonaws.com/ AWSServiceRoleForRDSPreview AmazonRDSPreviewServiceRolePolicy rds-preview.amazonaws.com

Beta や Preview という括りがあるのを初めて知りました。通常 RDS を利用する分には特に考慮は不要でしょう。

#5 RDS - Directory Service は SQL Server で Windows 認証を使用したり、一部のエンジンで Kerberos 認証を使用する際に必要になるロールですね。

接続方式の一つとして IAM DB 認証 も一部のエンジンでサポートされていますが、ここでは RDS が使用するロールはありません。関係するとしたら、接続元の EC2 インスタンスや Lambda 関数にアタッチされているロールになります。

#4 RDS - CloudHSM はどの場面で使用するものなのか調べきれませんでした。( KMS のカスタムキーストアとして CloudHSM クラスターを使用し、そこで生成したキーを用いて RDS を暗号化する際に必要……などでしょうか。)

よくある質問 - AWS CloudHSM | AWS

その他のロールは後で出てくるので次に行きます。

RDS インスタンスローンチ時に設定できるロールを確認してみる

上記の #5 RDS - Directory Service は DB インスタンスローンチ時に自動で作成されるロールではありますが、特にユーザー側で指定できるものではないことや、一部のエンジン限定であることから、少し毛色が異なるものとして扱います。

すべてのエンジンで共通する項目であり、ユーザー側で参照できるものとして以下を確認します。

  • #1 RDS
  • #6 RDS - Enhanced Monitoring

今回は PostgreSQL のエンジンの作成画面で確認します。

[ 追加設定 ] を展開します。

拡張モニタリング を有効化すると、使用するロールを選択できるようになります。デフォルトを選択すると、 rds-monitoring-role という名称のロールが設定されます。(初回であれば自動的に作成。)

また、ログのエクスポートにおいては、 AWS service-linked role が使用される旨が確認できます。「CloudWatch Logs にログを発行するために使用されます。」の文言がありますね。また、 RDS Service Linked Role と呼称されることをここで初めて知りました。

自分の中で一時期こんがらがっていたのですが、 Performance Insights を有効化する際には特に IAM ロールの設定は不要です。

なんとなくこれで RDS が使用するロールを網羅できた気になりました。

CloudFormation における AssociatedRoles って何だ

マネジメントコンソールから RDS を 作成するイメージもついたし、 CloudFormation でも作ってみるかと思い構文を調べると、プロパティの中でイメージがつかないものがあります。

AssociatedRoles です。

AWS::RDS::DBInstance - AWS CloudFormation

Type: AWS::RDS::DBInstance
Properties: 
  AllocatedStorage: String
  AllowMajorVersionUpgrade: Boolean
  AssociatedRoles: 
    - DBInstanceRole
  AutoMinorVersionUpgrade: Boolean
  AvailabilityZone: String
  BackupRetentionPeriod: Integer

    --- 中略 ---

  MasterUsername: String
  MasterUserPassword: String
  MaxAllocatedStorage: Integer
  MonitoringInterval: Integer
  MonitoringRoleArn: String
  MultiAZ: Boolean
  OptionGroupName: String
  PerformanceInsightsKMSKeyId: String
  PerformanceInsightsRetentionPeriod: Integer
  Port: String
    
    --- 後略 ---

拡張モニタリングに使用するロールは 17行目の MonitoringRoleArn で定義しているし、 AWS service-linked role はわざわざテンプレート内で定義する必要ないだろうし、これは何なんだ……?という疑問が生じました。

同様のプロパティはサービスタイプが DB クラスターの場合にも存在しています。

AWS::RDS::DBCluster - AWS CloudFormation

DB インスタンスに IAM ロールを関連づける

結果から言うと、一部の DB エンジンではDB インスタンスないしクラスターに IAM ロールを関連づけることができます。

例えば RDS における Oracle では、オプショングループで Amazon S3 の統合 を有効化することで、DB インスタンスと S3 バケット間でファイルを転送できるようになります。

Amazon S3 の統合 - Amazon Relational Database Service

そこで S3 バケットへのアクセス権限を定義するために、DB インスタンスに IAM ロールを関連づける必要があります。

RDS AWS service Role S3

(ちなみに、ここで DB インスタンスから S3 バケットへの VPC エンドポイントは用意する必要がないそうです。不思議ですね。)

マネジメントコンソールから DB インスタンスにロールを関連づけるにはどういった操作になるか確認しておきましょう。

Oracle の DB インスタンスを作成しました。関連づける操作は「追加する」と表現されますが、追加するためにはステータスが 利用可能 である必要があります。

[ 接続とセキュリティ ] タブを選択します。

下にスクロールしていくと、 [ IAM ロールの管理 ] という項目が確認できます。IAM ロールの追加に対応していない DB エンジンでは、この項目は表示されていませんでした。

RDS 用の 狭義の AWS サービスロールがドロップダウンで選択できるため、使用する機能として S3_INTEGRATION を選択した上で [ ロールの追加 ] を押下すれば、ロールが追加できます。

CloudFormation テンプレートで確認したプロパティ AssociatedRoles は、この操作を代替するものであると理解できました。

Aurora では、MySQL の DB クラスターで IAM ロールの関連付けが行えるようです。

AWS のサービスにアクセスするための IAM ロールの設定 - Amazon Aurora

結論

  • IAM ロールを引き受けるエンティティが AWS サービスの場合、そのロールは AWS サービスロールと呼ばれる
  • AWS サービスロールのうち、サービスと直接リンクされたものを サービスにリンクされたロールと呼ぶ
  • RDS の AWS サービスロールは複数の種類がある
  • RDS の拡張モニタリングには AWS サービスロールが使用される
  • RDS による CloudWatch Logs へのログ出力は AWS サービスにリンクされたロールによって行われる
  • 一部の DB エンジンでは 他の AWS サービスとの連携する機能のために インスタンスないしクラスターに RDS 用の AWS サービスロールを関連づけることができる

終わりに

10 点 獲得された方はおめでとうございます。特に意味はありませんが、ぜひ強く生きてください。

以上、そんなつもりなかったのにうっかり絵を描いた千葉(幸)がお送りました。