🐥

RDS(postgres)のデータをS3にexportする〜private network編〜

2021/02/13に公開

やりたいこと

VPCのprivate networkの中にあるRDS(postgres)のデータを、
S3に直接exportしたい。

やりかた

export対象のRDSにログインし、以下のSQLを実行すると、
RDSのデータをS3へ直接exportできます。便利。

select * from aws_s3.query_export_to_s3(
  'select * from public.user limit 10',
  aws_commons.create_s3_uri(
    'test', -- bucket名
    'rds_export_test', -- object名
    'ap-northeast-1' -- region名
  )
);

しかし、コマンドを入力するだけではできません。

実現するためには(地味に面倒な)以下の準備が必要です。

  1. RDSからS3へ疎通できるように、ネットワークの設定をする

  2. RDSからS3に書き込みできるように、IAMロールを作成・付与する

  3. RDSにS3へexportする拡張機能を追加する

  4. RDSのユーザが拡張機能を実行できるように、権限を付与する

一つ一つやっていきます。

準備

  1. RDSからS3へ疎通できるように、ネットワークの設定をする

    RDSからS3に書き込みしにいくということで、まずRDSからS3に疎通できるかどうか整理していきます。

    • RDSはVPCの中、S3はVPCの外にある
    • VPCの中にあるインスタンスからVPCの外にあるS3にアクセスするには、インターネットゲートウェイを通る必要がある
    • しかし今回、VPCの中にあるRDSはprivate subnetにあるので、インターネットゲートウェイを通る事ができない

    以上より、このままではRDSからS3へ接続することができません。

    こういうときは、VPCエンドポイントを使います。

    VPCエンドポイントとは

    VPCの中から、VPCの外にあるものにアクセスしたいときに使うものです。

    インスタンスが属しているsubnetのroute tableに紐付けて使います。

    イメージとしてはこんな感じです。

    VPCエンドポイントの具体的な作り方はこちらを参考にしました。

    VPCエンドポイントを作成する際、どのroute tableと紐つけるかを選択する必要があるので、
    今回はRDSが属するsubnetと紐ついているroute tableを選択します。

    これでRDSからS3への疎通を取ることができるようになりました。

  2. RDSからS3に書き込みできるように、IAMロールを作成・付与する

    1. 特定のS3 bucketに対する書き込み権限をもつポリシーを作成
    2. ロールをつくり、1でつくったポリシーを紐つける
    3. ロールを該当RDSに紐つける

    1, 2の手順についてはこちら

    3の手順については、Auroraの場合UI上から設定を行うことができます(接続とセキュリティ > IAM ロールの管理)

    ↑のように設定します。

    Auroraではない場合、UI上からではなくAWS CLIを用いて設定します。

    aws rds add-role-to-db-instance \
    --db-instance-identifier my-db-instance \
    --feature-name s3Export \
    --role-arn your-role-arn   \
    --region your-region
    

    これでRDSがS3に対する書き込み権限を持つようになりました。

  3. RDSにS3へexportする拡張機能を追加する
    今回、aws_s3.query_export_to_s3関数と、aws_commons.create_s3_uriを使用します。
    この関数を使うには、postgresに拡張機能を追加しなければいけません。
    以下のSQLで追加ができます。

    CREATE EXTENSION IF NOT EXISTS aws_s3 CASCADE; -- CASCADEをつけると、依存関係がある拡張機能も一緒に追加できる
    

    \dx で使用できる拡張機能が確認できます。

        Name     | Version |   Schema   |                   Description                   
    -------------+---------+------------+-------------------------------------------------
     aws_commons | 1.1     | public     | Common data types across AWS services
     aws_s3      | 1.1     | public     | AWS S3 extension for importing data from S3
     plpgsql     | 1.0     | pg_catalog | PL/pgSQL procedural language
     uuid-ossp   | 1.1     | public     | generate universally unique identifiers (UUIDs)
    

    ここで、aws_s3のversionが1.0の場合、query_export_to_s3関数は使えません。
    1.1を追加する必要がありますが、

    select * from pg_available_extension_versions where name = 'aws_s3'
    

    ↑の結果に1.1がなければPostgresのエンジンをupdateする必要があります。
    (versionについてはこちら)[https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/postgresql-s3-export.html]

    updateした後、DROP EXTENSIONして再度拡張を追加してください。

    version1.1が追加されていれば成功です。

  4. RDSのユーザが拡張機能を実行できるように、権限を付与する
    この時点で、RDSの管理者はS3のexportが可能です。
    しかし、管理者以外はaws_s3 schemaへの権限とschema配下の関数の実行権限が必要です。
    よって以下のSQLを実行する必要があります。

    GRANT USAGE ON SCHEMA aws_s3 TO user;
    GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA aws_s3 TO user;
    

以上で、RDSからS3への直接exportが可能になります。

参考

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/postgresql-s3-export.html

Discussion