クロスアカウントでS3からAuroraに直接データをロードする


LOAD DATA FROM S3

AWSのMySQL互換DBであるところのAuroraにはデータをS3から直接ロードする構文が用意されている。

これの使用例はクラスメソッドさんなどもブログにしているのでそこまで話題にしない。

SQLの構文

詳しい設定方法は上の公式ドキュメントを見てほしい。結構大変で、DB側に専用のIAMロールと、DBのパラメーターグループ、そしてアクセスするユーザにパーミッションを設定する必要がある。

そしてなんやかんやで 'S3-URI' にファイルパスを指定すれば読み込める

便利なもんですなあ

LOAD DATA FROM S3 [FILE | PREFIX | MANIFEST] 'S3-URI'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [PARTITION (partition_name,...)]
    [CHARACTER SET charset_name]
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number {LINES | ROWS}]
    [(col_name_or_user_var,...)]
    [SET col_name = expr,...]

サンプルDDL

  • カンマ区切りのダブルクォート、ヘッダあり仕様のCSVをロードする
sample.sql
LOAD DATA FROM S3 's3://your.name.of.bucket/normal.csv' 
INTO TABLE `schema_name`.`table_name` 
FIELDS TERMINATED BY ',' 
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;

S3が同じアカウント内であるか、パブリックになっていればこれで設定は終わると思う。

クロスアカウントでの操作とエラー

たとえ正しくIAMを設定したとしてもAuroraDBの対向になるS3を保持するAWSアカウントが自分のものと異なる場合以下のようなエラーが出る

error: Unable to initialize S3Stream

参考

クロスアカウントでの操作のためにS3を設定する

例 2: バケット所有者がクロスアカウントのバケットのアクセス許可を付与

  • AccountBのところにAurora側のAWSのアカウントIDを設定
  • "Resource"のところは "arn:aws:s3:::your.name.of.bucket/*" とかで設定できるはず
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Sid": "Example permissions",
         "Effect": "Allow",
         "Principal": {
            "AWS": "arn:aws:iam::AccountB-ID:root"
         },
         "Action": [
            "s3:GetBucketLocation",
            "s3:ListBucket"
         ],
         "Resource": [
            "arn:aws:s3:::examplebucket"
         ]
      }
   ]
}

これをS3のバケットに設定すると、Aurora内で LOAD FROM S3 が実行できるようになる。