Amazon Redshift でクエリを実行する AWS Lambda 関数を作成したいと考えています。
解決策
前提条件: Lambda 関数を作成する前に、次の Amazon Virtual Private Cloud エンドポイントを設定する必要があります。
- プライベートサブネットを持つ VPC を作成します。
- サブネットグループを作成します。先ほど作成した VPC とサブネットを追加します。
- プライベート Amazon Redshift クラスターを作成します。先ほど作成した VPC とサブネットグループを選択します。
- AWS Secrets Manager で Amazon Redshift 用の新しいシークレットを作成します。シークレットに redshift という名前を付けます。
Lambda 関数を作成する
Amazon Redshift クラスターをクエリする Lambda 関数を作成するには、次の手順を実行します。
-
Lambda コンソールを開きます。
-
[関数の作成] を選択します。
-
[最初から作成] オプションを選択します。
-
次のフィールドを更新します。
関数名: カスタム名を入力します。
ランタイム: コード環境を入力します。(この解像度の例は Python 3.9 と互換性があります。)
アーキテクチャ: システムアーキテクチャを入力します。(この解決策の例は x86_64 と互換性があります。)
アクセス許可: [基本的な Lambda アクセス許可を持つ新しいロールを作成する] を選択します。
-
[関数の作成] を選択します。
Lambda 関数に適切なアクセス許可を設定する
Lambda コンソールで [設定] を選択します。
- [アクセス許可] を選択します。
- Lambda 関数用に作成したロールを選択します。
- アクセス許可を追加] を選択します。
- [ポリシーをアタッチ] を選択します。
- AmazonRedshiftDataFullAccess および SecretsManagerReadWrite ポリシーを Lambda 実行ロールに追加します。
注: タスクの実行に必要なアクセス許可のみに関する最小特権を付与することがベストプラクティスです。詳細については、「最小特権アクセス許可を適用する」を参照してください。
Python コードを Lambda 関数に追加する
- Lambda コンソールで [コード] を選択します。
- 次のコードを [コード] ボックスに貼り付けます。
重要:
- 「dev」をデータベースの名前に置き換えてください。
- 必ず、Lambda 関数の設定セクションに、SecretId キーと secret_name キー用の環境変数を追加してください。
import os
import json
import boto3
import botocore
import botocore.session as bc
from botocore.client import Config
print('Loading function')
secret_name=os.environ['SecretId'] # getting SecretId from Environment varibales
session = boto3.session.Session()
region = session.region_name
# Initializing Secret Manager's client
client = session.client(
service_name='secretsmanager',
region_name=region
)
get_secret_value_response = client.get_secret_value(
SecretId=secret_name
)
secret_arn=get_secret_value_response['ARN']
secret = get_secret_value_response['SecretString']
secret_json = json.loads(secret)
cluster_id=secret_json['dbClusterIdentifier']
# Initializing Botocore client
bc_session = bc.get_session()
session = boto3.Session(
botocore_session=bc_session,
region_name=region
)
# Initializing Redshift's client
config = Config(connect_timeout=5, read_timeout=5)
client_redshift = session.client("redshift-data", config = config)
def lambda_handler(event, context):
print("Entered lambda_handler")
query_str = "create table public.lambda_func (id int);"
try:
result = client_redshift.execute_statement(Database= 'dev', SecretArn= secret_arn, Sql= query_str, ClusterIdentifier= cluster_id)
print("API successfully executed")
except botocore.exceptions.ConnectionError as e:
client_redshift_1 = session.client("redshift-data", config = config)
result = client_redshift_1.execute_statement(Database= 'dev', SecretArn= secret_arn, Sql= query_str, ClusterIdentifier= cluster_id)
print("API executed after reestablishing the connection")
return str(result)
except Exception as e:
raise Exception(e)
return str(result)
この例では、Lambda は Amazon Redshift データベースに接続し、パブリックスキーマに lambda_func テーブルを作成します。