[アップデート] RDS Data API が PrivateLink に対応しました

Data API のレスポンスは AWS CLI v2 の YAML 形式一択ではなかろうか。
2020.02.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

先日のアップデートで RDS Data API の PrivateLink が利用できるようになりました。

何が嬉しいのか

従来、 RDS Data API を利用する場合はパブリックエンドポイントへアクセスして利用するため、インターネットゲートウェイや NAT ゲートウェイなどパブリックに抜けるためのアクセス経路が必要でした。

これが PrivateLink の対応によってプライベートなネットワークで完結できるようになりましたので、よりセキュアに利用することができますね。

VPC 間もピアリングする必要はなく、PrivateLink だけで接続したり

AWS アカウント間だってもちろん PrivateLink で接続できますね。(アカウント間の場合は、別途、Secrets Manager へのアクセスを許可するなど必要ですが)

やってみる

それでは、今回は上記図のような VPC 間での利用を試してみたいと思います。

Data API の作成

Data API を有効にした、Aurora serverless のインスタンスを作成します。手順は過去の記事などを参照ください。

PrivateLink の作成

VPC 管理コンソールから [Endpoints] を開き、Create Endpoint をクリックします。[AWS service] を選択し、[Service Name] 内にある com.amazonaws.<region>.rds-data を選択します。

あとは PrivateLink を作成したい VPC および、サブネットを指定します。

次に、[Enable DNS name] にチェックを入れます。PrivateLink の ENI にアタッチするセキュリティグループを指定します。基本的には VPC 内から HTTPS が許可されていれば十分です。

ポリシーは [Full Access] を指定し、VPC 内のすべてのユーザーがこのエンドポイントを介して Data API にアクセスできるようにしました。利用可能なユーザー等を制限したい場合は [Custom] を指定し、ポリシーを編集してください。

最後に Create endpoint をクリックして完了です。

名前解決の確認

Data API のエンドポイントへのリクエストが PrivateLink に向いていることを確認します。

通常の場合

自分の PC から標準エンドポイントを名前解決すると、下記のとおりパブリックな IP アドレスが返ります。

$ dig rds-data.ap-northeast-1.amazonaws.com +short
54.65.66.2
18.179.117.220
52.193.89.65

PrivateLink の場合

次に、PrivateLink を作成した VPC 内の EC2 で同様のエンドポイントを名前解決します。下記のようにプライベートな IP アドレスが返ることが確認できましたね。

$ dig rds-data.ap-northeast-1.amazonaws.com +short
10.0.1.232
10.0.0.249

アクセスの確認

EC2 内から Data API に対してアクセスしてみましょう。今回はインスタンスに show databases を発行し、インスタンス作成時に作った apitestdb データベースが表示されることを確認します。

EC2 に IAM ロールをアタッチ

EC2 には AmazonRDSDataFullAccess ポリシーをアタッチした IAM ロールを割り当てています。このポリシーには DataAPI や、Secrets Manager にアクセス可能な権限があたえられています。

ちなみにですが、Secrets Manager には secret:rds-db-credentials/* に合致するような名前をつけて事前に RDS の admin ユーザパスワードを保存しています。secret:rds-db-credentials/* に合致しない場合は、別途、対象の Secrets Manager リソースを指定してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SecretsManagerDbCredentialsAccess",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "secretsmanager:PutResourcePolicy",
                "secretsmanager:PutSecretValue",
                "secretsmanager:DeleteSecret",
                "secretsmanager:DescribeSecret",
                "secretsmanager:TagResource"
            ],
            "Resource": "arn:aws:secretsmanager:*:*:secret:rds-db-credentials/*"
        },
        {
            "Sid": "RDSDataServiceAccess",
            "Effect": "Allow",
            "Action": [
                "dbqms:CreateFavoriteQuery",
                "dbqms:DescribeFavoriteQueries",
                "dbqms:UpdateFavoriteQuery",
                "dbqms:DeleteFavoriteQueries",
                "dbqms:GetQueryString",
                "dbqms:CreateQueryHistory",
                "dbqms:DescribeQueryHistory",
                "dbqms:UpdateQueryHistory",
                "dbqms:DeleteQueryHistory",
                "rds-data:ExecuteSql",
                "rds-data:ExecuteStatement",
                "rds-data:BatchExecuteStatement",
                "rds-data:BeginTransaction",
                "rds-data:CommitTransaction",
                "rds-data:RollbackTransaction",
                "secretsmanager:CreateSecret",
                "secretsmanager:ListSecrets",
                "secretsmanager:GetRandomPassword",
                "tag:GetResources"
            ],
            "Resource": "*"
        }
    ]
}

show databases を実行

以下のように aws rds-data execute-statement で SQL を発行します。

$ aws rds-data execute-statement \
>  --secret-arn "arn:aws:secretsmanager:ap-northeast-1:XXXXXXXXXXXX:secret:rds-db-credentials/dataapi-test-9e9GIt" \
>  --resource-arn "arn:aws:rds:ap-northeast-1:XXXXXXXXXXXX:cluster:dataapi-test" \
>  --sql "show databases"

で、実行結果がこのように返ってきました。apitestdb が表示されており、問題なく接続できることを確認できましたね。

{
    "records": [
        [
            {
                "stringValue": "information_schema"
            }
        ],
        [
            {
                "stringValue": "apitestdb"
            }
        ],
        [
            {
                "stringValue": "mysql"
            }
        ],
        [
            {
                "stringValue": "performance_schema"
            }
        ]
    ],
    "numberOfRecordsUpdated": 0
}

しかし、JSON のレスポンスが見にくいですね、、、。

本日 GA されたばかりの AWS CLI v2 を使って、YAML 形式で出力させてみましょう。

$ aws rds-data execute-statement \
>  --secret-arn "arn:aws:secretsmanager:ap-northeast-1:XXXXXXXXXXXX:secret:rds-db-credentials/dataapi-test-9e9GIt" \
>  --resource-arn "arn:aws:rds:ap-northeast-1:XXXXXXXXXXXX:cluster:dataapi-test" \
>  --sql "show databases" 
numberOfRecordsUpdated: 0
records:
- - stringValue: information_schema
- - stringValue: apitestdb
- - stringValue: mysql
- - stringValue: performance_schema

感動すら覚える見やすさですね。ぜひ、ご利用ください。

さいごに

これまで Data API はパブリックエンドポイントへアクセスする必要がありましたが、PrivateLink の対応によって、よりセキュアなアクセスでの利用が可能となりましたね!

(それよりも、個人的に AWS CLI v2 での YAML 形式のアウトプットに感動しています・・)

以上!大阪オフィスの丸毛(@marumo1981)でした!