Redshift Serverlessから別アカウントのAuroraMySQLにFederated Queryする

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

はじめに

アプリケーションサービス部 の鎌田(義)です。

Redshiftから直接、AuroraMySQLなどの運用DBにクエリを実行することができるFederatedQueryを クロスアカウントで利用したいケースは多いのではないでしょうか。

本エントリーでは、
VPCピアリングなどのネットワーク周りや権限設定を含めた設定手順を紹介したいと思います。
Redshift Federated Queryにて、別アカウントのAuroraMySQLのテーブルへクエリが実行できるところまで確認します。

構成図

異なるアカウント間でのFederatedQueryを実現する為、
以下の構成を構築します。

事前準備

AuroraMySQL側アカウント

ネットワーク作成

構成図の通り、AuroraMySQL用に以下リソースマップとなるネットワークを構築済のものとします。

サブネットグループ作成

作成済のプライベートサブネットでサブネットグループを作成します。

AuroraMySQL作成

VPC/サブネットグループは上記で作成済のものを選択します。
セキュリティグループは、検証用途の為今回はデフォルトを指定しました。
今回は、ライター/リーダーそれぞれ1台ずつで作成しました。

※この後のテスト用データ投入の為、EC2など任意の環境から接続できるように設定下さい。本エントリーでは、説明を割愛します。

テスト用データ作成

任意の環境からAuroraMySQLへ接続し以下のSQLを実行します。

CREATE DATABASE federatedquery_test_db;
  
use federatedquery_test_db;
  
# DDL
CREATE TABLE users (
    user_id INTEGER PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
  
CREATE TABLE posts (
    post_id INTEGER PRIMARY KEY AUTO_INCREMENT,
    user_id INT NOT NULL,
    title VARCHAR(100) NOT NULL,
    content TEXT NOT NULL,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
);
  
# テスト用データ投入
# users
INSERT INTO users (username, email) VALUES ('test-user01', 'test-user01@example.com');
  
# posts
INSERT INTO posts (user_id, title,  content) VALUES (1, 'title01', 'content01');

Redshift Serverless側アカウント

ネットワーク作成

構成図の通り、Redshift Serverless用に以下リソースマップとなるネットワークを構築済のものとします。

Redshift Serverless ワークグループ/名前空間の作成

今回は以下のような内容で作成しました。 VPC/サブネットグループは上記で作成済のものを選択します。
セキュリティグループは、検証用途の為今回はデフォルトを指定しました。

VPCピアリング作成

Redshift Serverless側アカウント - ピアリングリクエスト作成

今回は、Redshift Serverless側アカウントでピアリングリクエストを作成します。
以下の内容で作成します。
リクエスタには、事前準備で作成したRedshift Serverless側のVPC IDを、
アクセプタには、AuroraMySQL側のアカウントID/VPC IDを指定します。

AuroraMySQL側アカウント - ピアリングリクエスト承認

AuroraMySQL側のコンソールを確認すると以下のように「承認の保留中」ステータスが1件存在しますので承認します。

すると、Redshift Serverless側アカウントの方でもステータスが「アクティブ」に変わります。

両アカウント - ルーティング設定の追加

AuroraMySQL側アカウントでは10.0.0.0/16のターゲットを
Redshift Serverless側アカウントでは、172.30.0.0/16のターゲットを
それぞれ先ほど作成したVPCピアリングに指定します。
※複数ルーティングテーブル(AuroraMySQL側に2つ、Redshift Serverless側に3つ)が存在する為、それぞれのテーブルに上記の設定を追加します。

AuroraMySQL側アカウント - セキュリティグループ修正

AuroraMySQLが使用するセキュリティグループのインバウンドルールに
Redshift Serverless側アカウントのRedshif ServerlessにアタッチしているセキュリティグループIDからのトラフィックを許可します。

Federated Query設定

以下は公式ドキュメントの手順です。
docs.aws.amazon.com クロスアカウントでの接続となる為、
本エントリーで紹介する設定手順は権限周りの設定など上記手順と異なります。

AuroraMySQL側アカウント - KMSキー作成

SecretsManagerが暗号化に使用するKMSキーを先に作成します。
キー管理者/キーユーザーは、空のままでデフォルト設定のまま作成しました。
後ほどポリシーは修正します。

AuroraMySQL側アカウント - SecretsManager作成

Redshift ServerlessがFederated Queryの為に参照するAuroraMySQLへの接続用シークレットを、AuroraMySQL側アカウントに作成します。
暗号化キーには先ほど作成したkmsキーを指定します。

Redshift Serverless側アカウント - IAMポリシー/ロール作成

AuroraMySQL側アカウントで作成したSecretsManagerへのアクセス、
及びkmsキー復号化許可を付与したポリシーをRedshift Serverless側アカウントに作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AccessSecret",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret",
                "secretsmanager:ListSecretVersionIds"
            ],
            "Resource": "arn:aws:secretsmanager:ap-northeast-1:111111111111:secret:/federatedquery/aurora-credentials-xxxxxx"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetRandomPassword",
                "secretsmanager:ListSecrets"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": "arn:aws:kms:ap-northeast-1:111111111111:key/{キーID}"
        }
    ]
}

次に、IAMロールを作成します。
上記で作成したポリシーをアタッチします。

最後に、作成したIAMロールをRedshift Serverlessに関連付けます。
名前空間の設定 > セキュリティと暗号化から先ほど作成したIAMロールを関連付けます。
以下のような状態となっていればOKです。

AuroraMySQL側アカウント - SecretsManagerリソースポリシー修正

先ほど作成したシークレットのリソースポリシーを編集し
Redshift Serverless側アカウントのIAMロールからのアクセス許可ポリシーを追加します。

{
  "Version" : "2012-10-17",
  "Statement" : [
    {
      "Effect" : "Allow",
      "Principal" : {
        "AWS" : "arn:aws:iam::222222222222:role/FederatedQueryRedshiftSecretsAccessRole"
      },
      "Action" : "secretsmanager:GetSecretValue",
      "Resource" : "*"
    }
  ]
}

AuroraMySQL側アカウント - KMSキーポリシー修正

先ほど作成したkmsキーのポリシーを編集し
Redshift Serverless側アカウントのIAMロールからのアクセス許可設定を追加します。

        {
            "Sid": "AllowUseOfTheKey",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::222222222222:role/FederatedQueryRedshiftSecretsAccessRole"
            },
            "Action": "kms:Decrypt",
            "Resource": "arn:aws:kms:ap-northeast-1:111111111111:key/{キーID}"
        }

Redshift Serverless側アカウント - VPCエンドポイント作成

拡張VPCルーティングをオンにしたプライベートサブネットのRedshift ServerlessからSecretsManagerへ接続する為、VPCエンドポイントを作成します。

Redshift Serverless側アカウント - 外部スキーマ作成

Redshift Serverlessでのクエリ実行には、今回はコンソールのクエリエディタを使用します。
以下クエリで外部スキーマを作成します。

CREATE EXTERNAL SCHEMA IF NOT EXISTS aurora_federated
FROM MYSQL
DATABASE 'federatedquery_test_db'
URI '{AuroraMySQLリーダーエンドポイント}'
PORT 3306
IAM_ROLE 'arn:aws:iam::222222222222:role/FederatedQueryRedshiftSecretsAccessRole'
SECRET_ARN 'arn:aws:secretsmanager:ap-northeast-1:111111111111:secret:/federatedquery/aurora-credentials-xxxxxx'

Redshift Serverless側アカウント - クエリ実行

上記で作成したスキーマに対してクエリを実行します。

無事に結果を取得することができました!

おわりに

同一VPC内にAuroraMySQL/Redshiftが存在する場合はドキュメント通り4ステップ程で可能ですが、
異なるアカウントとなると、
VPCピアリングの設定や、クロスアカウントでのSecretsManager/kmsキーへの権限が必要だったり考慮すべき点も多いかと思います。
本エントリーがどなたかの参考になれば幸いです。

参考

鎌田 義章 (執筆記事一覧)

2023年4月入社 AS部DS3課