Amazon Aurora PostgreSQLからLambda関数を呼び出せるようになりました #reinvent
Amazon Aurora MysQLからLambdaを呼べるようになってからはや4年、ようやくAurora PostgreSQLからもLambdaを呼べるようになりました。
さっそく試してみました。
Amazon Aurora PostgreSQL Integrates with AWS Lambda
Amazon Aurora with PostgreSQL compatibility can now make calls to AWS Lambda functions. AWS Lambda lets you run code without provisioning or managing servers, and without worrying about scalability.
Amazon Aurora PostgreSQL からの外部サービスの呼び出しに Lambda が追加
Aurora PostgreSQL 内部からは様々な形で外部サービスを呼び出すことができます。
PostgreSQL に備わっている Foreign Data Wrapper(postgres_fdw) はもちろんのこと、 AWS とのシームレスな連携として S3 や最近では SageMaker や Comprehend といった機械学習系サービスとも連携しています。
今回のアップデートにより、AWS Lambda もその仲間に追加されました。
図は 「re:Invent 2020 : [DAT301]Deep dive on Amazon Aurora with PostgreSQL compatibility」から
手順概要
構成イメージ
- Lambda関数の作成
- IAM ポリシー・ロールの作成
- Aurora PostgreSQL の起動とIAMロールの紐付け
- Lambda用エクステンションの有効化
- Aurora PostgreSQL から Lambda 関数の呼び出し
前提
Aurora PostgreSQL 11.9 以降に対応
Aurora PostgreSQL を起動しようとすると、デフォルトではバージョン 11.7 が選択されます。 このバージョンは Lambda に対応していません。
$ aws rds add-role-to-db-cluster \ --db-cluster-identifier test \ --feature-name Lambda \ --role-arn arn:aws:iam::123:role/rds-aurora-pg-role An error occurred (InvalidParameterValue) when calling the AddRoleToDBCluster operation: The feature name Lambda is not valid for the Aurora PostgreSQL (Compatible with PostgreSQL 11.7) engine.
より新しい 11.9 以降を利用しましょう。
1. Lambda 関数の作成
任意のランタイムで Lambda 関数を作成してください。
2. IAM ポリシー・ロールの作成
PostgreSQL 向け Lambda 関数を呼び出す IAM ポリシーを作成します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAuroraToExampleFunction", "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:<region>:<123456789012>:function:example_function" } ] }
次に、このポリシーを含んだ RDS 向け IAM ロールを作成します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "rds.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
3. Aurora PostgreSQL の起動とIAMロールの紐付け
Aurora PostgreSQL を起動します。
現時点でデフォルトで選択されるバージョン 11.7 は Lambda 連携に対応していません。 11.9 以降を選択してください。
クラスター起動完了後、Feature : Lambda としてIAM ロールを紐付けます。
4. Lambda用エクステンションの有効化
RDS インスタンスに接続し、Lambda 用エクステンションを有効化します。
$ psql -h $HOST -U postgres Password for user postgres: psql (11.5, server 11.9) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=> \dx List of installed extensions Name | Version | Schema | Description ---------+---------+------------+------------------------------ plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (1 row) postgres=> CREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE; NOTICE: installing required extension "aws_commons" CREATE EXTENSION postgres=> \dx List of installed extensions Name | Version | Schema | Description -------------+---------+------------+--------------------------------------- aws_commons | 1.2 | public | Common data types across AWS services aws_lambda | 1.0 | public | AWS Lambda integration plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (3 rows) postgres=> \d aws_commons._lambda_function_arn_1; Composite type "aws_commons._lambda_function_arn_1" Column | Type | Collation | Nullable | Default ---------------+------+-----------+----------+--------- function_name | text | | | region | text | | |
5. Aurora PostgreSQL から Lambda 関数の呼び出し
aws_lambda.invoke
関数 で Lambda 関数を呼び出します。
aws_lambda.invoke関数のfunction_name に aws_commons.create_lambda_function_arn関数の実行結果を利用
postgres=> SELECT * FROM aws_lambda.invoke( aws_commons.create_lambda_function_arn( 'my-function', 'us-west-2'), '{"body": "Hello from Postgres!"}'::json); status_code | payload | executed_version | log_result -------------+----------------------------------------------------+------------------+------------ 200 | {"statusCode":200,"body":"\"Hello from Lambda!\""} | $LATEST | (1 row)
aws_lambda.invoke関数のfunction_name に Lambda 関数の ARN を利用
postgres=> SELECT * FROM aws_lambda.invoke( 'arn:aws:lambda:us-west-2:12345:function:my-function', '{"body": "Hello from Postgres!"}'::json);
非同期
Lambda:Invoke
API と同じく、invocation type
に Event
を指定すると、非同期呼び出しになります。
postgres=> SELECT * FROM aws_lambda.invoke( 'arn:aws:lambda:us-west-2:12345:function:my-function', '{"body": "Hello from Postgres!"}'::json, 'us-west-2', 'Event'); status_code | payload | executed_version | log_result -------------+---------+------------------+------------ 202 | | | (1 row)
権限の付与
非マスターユーザーにはデフォルトでは aws_lambda
の権限が付与されていないため、 ERROR: permission denied for schema aws_lambda エラーが発生します。
マスターユーザで各ユーザーに権限を付与してください。
GRANT USAGE ON SCHEMA aws_lambda TO <ユーザ名>; GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA aws_lambda TO <ユーザ名>;
最後に
Aurora PostgreSQL から Lambda 関数を呼び出す方法を紹介しました。
PostgreSQL からは S3 や Comprehend など、特定の機能に特化したモジュールは提供されてきましたが、Lambda 関数用モジュールも提供されるようになり、より柔軟に外部サービスと連携できるようになりました。
Lambda は自由度が高いため、くれぐれもやりすぎにはご注意ください。
それでは。