はじめに
本記事では、Lambda関数でS3に配置したJSONファイルを、RedshiftにCOPYし、Redshift上でデータ内容を確認するまでの手順を解説します。
記事作成に至る経緯
Lambda 関数を使って S3 から Redshift にデータをコピーする処理を実装する中で、
私は以下の点で大きく躓きました。
- S3 → Redshift の COPY は どこで実行されているのか
- Lambda・Redshift・S3 それぞれに どんな IAM ロールが必要なのか
- COPY 時に指定する IAM ロールは Lambda のものなのか、Redshift のものなのか
- Redshift は どのように S3 にアクセスしているのか
特に、「IAM ロールは設定しているはずなのに COPY が通らない」、「エラーメッセージの意味が分からない」といった状況に何度も遭遇しました。
調べていくうちに、
- COPY の実行主体は Lambda ではなく Redshift
- Lambda は COPY SQL を投げているだけ
- S3 にアクセスする IAM ロールは Redshift クラスターに関連付ける必要がある
といった点が理解できましたが、公式ドキュメントや断片的な記事だけでは全体像を一度に把握するのが難しいと感じました。
そこで本記事では、私自身が躓いたポイントを一つずつ確認しながら、
- S3 → Lambda → Redshift COPY の全体像
- 各サービスの役割と IAM ロールの関係
- よく出るエラーとその原因
を ハンズオン形式で整理することを目的としています。
同じように
「S3 → Redshift COPY がなんとなく分からない」
「IAM 周りで毎回詰まる」
という方の理解の助けになれば幸いです。
全体の流れ
- Lambda 関数で S3 に JSON ファイルをアップロード
- Redshift にテーブルを作成
- Lambda 関数で COPY コマンドを実行
- SELECT 文でデータ内容を確認
Step 1:S3 に JSON ファイルをアップロード
本ステップでは、Lambda 関数を用いて S3 に JSON ファイルをアップロードする方法を説明します。
Lambda関数内に、JSONデータを作成するコードを記載しておりますので、自身でファイルのご用意をしなくともS3にアップロード可能です。
※S3にアップロードする方法は他にもございますので、ご確認ください。
参考資料
S3 バケット情報
- バケット名例:
sample-bucket※個人で設定 - ファイル名:
sample_data.json - 形式:1行1JSON(JSON Lines形式)
Lambda関数に貼る用のPython
import boto3
def lambda_handler(event, context):
s3 = boto3.client("s3")
bucket = "sample-json-bucket" # 個人で設定
key = "sample_data.json"
# アップロード用jsonデータ
data = """
{"id": 1, "name": "Alice", "age": 25}
{"id": 2, "name": "Bob", "age": 30}
{"id": 3, "name": "Charlie", "age": 28}
"""
# S3へアップロード
s3.put_object(
Bucket=bucket,
Key=key,
Body=data.encode("utf-8"),
ContentType="application/json"
)
# Lambda関数内結果確認
return {
"status": "uploaded",
"s3_path": f"s3://{bucket}/{key}"
}
S3の確認画面
ポイント
- S3のオブジェクトの確認(S3 URL, ARN, オブジェクトURL)
参考資料
Step 2:Redshift にテーブルを作成
S3からRedshiftへコピーする際のRedshiftのテーブルを作成する。
Redshiftクラスターの作成方法
IAMロールについて
Redshift から S3 へ COPY を行うためには、
Redshift クラスターにアタッチする IAM ロール が必要になります。
この IAM ロールには、以下 2 種類のポリシーが設定されます。
参考資料
許可ポリシー
「この IAM ロールで 何ができるか」 を定義します。
本記事の構成では、Redshift が S3 上の JSON ファイルを読み込むため、
s3:GetObject 権限のみを付与しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::test-yamaguchi-data/*"
}
]
}
信頼ポリシー
信頼ポリシーは、
「どの AWS サービスがこの IAM ロールを利用できるか」 を定義します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "redshift.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
この設定により、
Redshift サービス自身がこの IAM ロールを引き受け(AssumeRole)できるようになります。
テーブル作成用 CREATE TABLE 文
CREATE TABLE public.users (
id INT,
name VARCHAR(100),
age INT
);
ポイント
- JSON のキー名とカラム名を一致 させる
- COPY 実行時、カラム順は関係ありません(JSON のキーでマッピングされます)
- JSONデータとカラムのデータ型をINT, VARCHAR等に、一致させる
参考資料
Step 3:Lambda 関数で S3 → Redshift COPY を実行
前提条件
- Lambda から Redshift にネットワーク的に接続できること
- Redshift クラスターに S3 読み取り可能な IAM Role がアタッチされていること
Lambda関数コード(Python)
Lambda 関数から Redshift に接続し、S3 上の JSON ファイルを指定した COPY SQL を Redshift に実行させます。
このとき、実際に S3 へアクセスしてデータを読み込むのは Redshift 側 であり、
Lambda は COPY SQL を実行する役割のみを担います。
import psycopg2
import os
def lambda_handler(event, context):
# Redshift 接続情報(環境変数から取得)
host = os.environ['REDSHIFT_HOST']
db = os.environ['REDSHIFT_DB']
user = os.environ['REDSHIFT_USER']
pwd = os.environ['REDSHIFT_PASSWORD']
port = 5439
# COPY 対象の S3 パス ※個人で設定
s3_path = "s3://sample-json-bucket/sample_data.json"
# Redshift に付与している IAM Role ※個人で設定
iam_role = "arn:aws:iam::<account-id>:role/<redshift-iam-role>"
conn = psycopg2.connect(
host=host,
dbname=db,
user=user,
password=pwd,
port=port
)
cur = conn.cursor()
copy_sql = f"""
COPY public.users
FROM '{s3_path}'
IAM_ROLE '{iam_role}'
FORMAT AS JSON 'auto';
"""
cur.execute(copy_sql)
conn.commit()
cur.close()
conn.close()
return {
"status": "success",
"message": "S3 → Redshift COPY completed"
}
ポイント
- Lambda は S3 の中身を処理しません
- Redshift に対して COPY SQL を実行する役割のみ です
- 実際のデータロードは Redshift 側で行われます
参考資料
Redshiftに対して、実行するSQLをLambda関数から投下する
Lambda関数のレイヤーの作成方法
Step 4:Redshift でデータ内容を確認
Step 3にて、以下の出力を必ず確認してからStep4を実行してください。
{
"status": "success",
"message": "S3 → Redshift COPY completed"
}
以下のselect文を実行させ、Redshift内のデータを確認する。
SELECT 文
SELECT *
FROM public.users
ORDER BY id;
実行結果
| id | name | age |
|---|---|---|
| 1 | Alice | 25 |
| 2 | Bob | 30 |
| 3 | Charlie | 28 |
まとめ
本記事では、私自身が Lambda を使った S3 → Redshift 連携で躓いていたポイントを整理するために、
- Lambda 関数から S3 に JSON ファイルを配置
- Redshift にテーブルを作成
- Lambda 関数から Redshift に COPY を実行
- SELECT 文でデータ内容を確認
という S3 → Redshift 連携の最小構成を、実際に手を動かしながら確認しました。
「なんとなく分かっているつもりだった処理」を、
一つずつ分解して実装・確認することで、
全体の流れを自分の中で整理することができました。
同じように、
S3 → Redshift COPY の流れを一度きちんと整理したい方の参考になれば幸いです。
