Calling AWS from Inside Aurora and RDS - aws_lambda, Aurora MySQL's S3 and Lambda Statements, and Which IAM Role Each Uses

First Published:
Last Updated:

Amazon Aurora PostgreSQL-Compatible Edition (hereafter Aurora PostgreSQL) and Amazon RDS for PostgreSQL can invoke AWS Lambda functions from SQL using the aws_lambda.invoke function provided by the aws_lambda extension. Amazon Aurora MySQL-Compatible Edition (hereafter Aurora MySQL) invokes Lambda functions using the native functions lambda_sync and lambda_async, and can read and write files from Amazon S3 using statements such as LOAD DATA FROM S3, LOAD XML FROM S3, and SELECT INTO OUTFILE S3. In all cases, an IAM role must be associated with the DB cluster or DB instance. However, the method of association, the permissions required on the database side, the default waits, and how failures show up differ depending on the route.

This article presents these three routes side by side. For each route, it details what users need to write, the available values, what happens if something is omitted, what happens at the boundaries, where this information is visible, and what the sources do not state. In particular, it addresses the difference between Aurora PostgreSQL and RDS for PostgreSQL, which associate roles using --feature-name Lambda, and Aurora MySQL, which requires both role association and cluster parameter configuration.

This article does not cover how to write Lambda functions, ETL design, or pricing. It also does not say which route is better. The information presented is based on documentation verified on October 25, 2026. The results presented in Section 8 were obtained using a small configuration created in the US East (Northern Virginia) Region specifically for this article.

Related articles on this site:

Table of Contents

  1. 1. Scope and Assumptions
  2. 2. How to Read the Tables
  3. 3. The Three Routes Side by Side
  4. 4. The aws_lambda Extension in Aurora PostgreSQL and RDS for PostgreSQL
  5. 5. Lambda in Aurora MySQL - Two Steps and a Database Role
  6. 6. The S3 Statements in Aurora MySQL
  7. 7. Network Paths
  8. 8. What This Configuration Returned
  9. 9. What the Sources Do Not State, and Variations Within the Sources
  10. 10. Failure Modes
  11. 11. Frequently Asked Questions About Calling AWS from Inside Aurora and RDS
  12. 12. Summary
  13. 13. References

1. Scope and Assumptions

This section first defines the intended audience, the scope of this article, the sources read, the names, and how versions are written. The conclusions come first, as the following seven points.

  • The aws_lambda pages for Aurora PostgreSQL and RDS for PostgreSQL associate IAM roles with the --feature-name Lambda parameter. Aurora PostgreSQL associates with the DB cluster, while RDS for PostgreSQL associates with the DB instance.
  • The Aurora MySQL pages require two steps: associating an IAM role and configuring the ARN for cluster parameters (Lambda uses aws_default_lambda_role, and S3 uses aws_default_s3_role). The CLI examples on the association page do not include the --feature-name parameter. Both steps are required, and neither takes precedence over the other.
  • Simply associating a role is not sufficient to allow database users to call AWS. In PostgreSQL, after installing the extension, GRANT permissions are required for users other than rds_superuser. For Aurora MySQL version 3 and version 8.4, grant the database roles AWS_LAMBDA_ACCESS, AWS_LOAD_S3_ACCESS, and AWS_SELECT_S3_ACCESS, and activate them in the session. The LOAD and SAVE pages state that the administrative user of the DB cluster is granted the S3 role or privilege by default.
  • The default wait for the response from aws_lambda.invoke is 3000 milliseconds on the reference page. The default connection timeout is 1000 milliseconds. No statement was found that aws_lambda.invoke waits until the Lambda function's timeout.
  • For public databases, the aws_lambda pages give an outbound rule for port 443. For private databases, the pages give either NAT or a VPC endpoint. Only the aws_lambda page for RDS for PostgreSQL specifies that setting rds.custom_dns_resolution to 1 is required to use a Lambda VPC endpoint.
  • No statement was found that describes how RDS signs requests, the relationship with statement_timeout, or whether RDS for MySQL and RDS for MariaDB allow SQL to call Lambda or S3.
  • In this article's configuration (October 24, 2026), calls did not succeed until 59 to about 100 seconds after the Aurora PostgreSQL association status reached ACTIVE. In Aurora MySQL 3.10.3, the API rejected the --feature-name Lambda parameter, and aws_default_lambda_role worked before a reboot (Section 8).

1.1 Who This Article Is For

This article is intended for developers and operations personnel who are considering designs that invoke Lambda functions from Aurora or RDS triggers or stored procedures, or designs that move data between SQL and S3. Specifically, this article assumes readers who hold one of the following assumptions:

  • Attaching an IAM role to a database allows consistent invocation across different database engines.
  • Aurora MySQL also associates a role using --feature-name.
  • Associating a role enables immediate use.
  • aws_lambda.invoke waits for the Lambda function's timeout period.
  • RDS uses the associated role to sign invocation requests with SigV4.
  • RDS for MySQL supports the LOAD DATA FROM S3 command.

The first four of these assumptions are not supported by the documentation. Regarding the fifth assumption, no statement was found that supports or contradicts it. Concerning the sixth assumption, while the documentation states that RDS for MySQL lacks the necessary roles and permissions for LOAD DATA FROM S3, no statement was found that says it cannot be used in RDS for MySQL. The basis for each of these points is discussed in Sections 4 through 7 and Section 9.

1.2 What This Article Covers and Does Not Cover

This article focuses on three specific routes:

  • The aws_lambda extension for Aurora PostgreSQL and RDS for PostgreSQL (role association, extension installation, database permissions, arguments and default values for aws_lambda.invoke, wait parameters, error messages).
  • The native Lambda functions lambda_sync and lambda_async for Aurora MySQL (role and cluster parameter configuration, database roles and permissions, considerations when calling from triggers, deprecated stored procedures).
  • The S3-related statements LOAD DATA FROM S3, LOAD XML FROM S3, and SELECT INTO OUTFILE S3 for Aurora MySQL (role and parameter configuration, database roles and permissions, Region, encryption, the record of loaded files).

In addition, this article addresses the networking aspects related to these three routes, as well as what the sources do not state.

This article does not cover the following.

  • The two functions of the aws_s3 extension, the feature names s3Import and s3Export, the network configuration for S3 with PostgreSQL, and the difference in whether FeatureName is required. These topics are covered in the previously published Moving Data Between Amazon S3 and Aurora or RDS for PostgreSQL with the aws_s3 Extension. That article specifically excludes coverage of the aws_lambda extension and the integration of Aurora MySQL with S3. This article will address those two excluded areas.
  • IAM authentication from clients to databases (see IAM Authentication to Databases, Caches, and Streams on AWS on this site). This article covers the opposite direction: calls from the database to AWS services.
  • Types of VPC endpoints and the design of private DNS (see Private Connectivity by Service on AWS Data Services on this site).
  • Lambda concurrency and throttling (see AWS Lambda Concurrency and Scaling Guide on this site).
  • Integration of Aurora with machine learning (using aws_ml, aws_comprehend, aws_sagemaker, aws_bedrock, and machine learning functions within Aurora MySQL).
  • Details of integrating RDS for SQL Server and RDS for Oracle with S3 (one line each in Section 9.3).
  • Exporting DB cluster snapshots to S3.
  • Pricing.

1.3 Sources Read and the Date They Were Checked

The information presented in this article was verified on October 25, 2026. The materials reviewed are as follows:

SourcePages read
Amazon Aurora User Guide (PostgreSQL)Invoking an AWS Lambda function from an Aurora PostgreSQL DB cluster; Examples: Invoking Lambda functions; Lambda function error messages; AWS Lambda function and parameter reference; Integrating Amazon Aurora PostgreSQL with other AWS services
Amazon Aurora User Guide (MySQL)Integrating Amazon Aurora MySQL with other AWS services; Authorizing Amazon Aurora MySQL to access other AWS services on your behalf; Setting up IAM roles to access AWS services; Creating an IAM policy to access Amazon S3 resources; Creating an IAM policy to access AWS Lambda resources; Creating an IAM role to allow Amazon Aurora to access AWS services; Associating an IAM role with an Amazon Aurora MySQL DB cluster; Enabling network communication from Amazon Aurora to other AWS services; Invoking a Lambda function from an Amazon Aurora MySQL DB cluster; Giving Aurora access to Lambda; Invoking a Lambda function with an Aurora MySQL native function; Invoking a Lambda function with an Aurora MySQL stored procedure (deprecated); Loading data into an Amazon Aurora MySQL DB cluster from text files in an Amazon S3 bucket; Saving data from an Amazon Aurora MySQL DB cluster into text files in an Amazon S3 bucket; Recommendations for MySQL features in Aurora MySQL
Amazon Aurora User Guide (common)Integrating Aurora with other AWS services; Requirements and limitations for Aurora serverless; Scaling to Zero ACUs with automatic pause and resume for Aurora serverless
Amazon RDS User GuideInvoking an AWS Lambda function from an RDS for PostgreSQL DB instance; AWS Lambda function and parameter reference; Lambda function error messages; Using a custom DNS server for outbound network access; Restoring a backup into an Amazon RDS for MySQL DB instance; Enabling RDS for SQL Server integration with S3; Configuring IAM permissions for RDS for Oracle integration with Amazon S3
Release notesExtension versions for Amazon Aurora PostgreSQL; Extension versions for Amazon RDS for PostgreSQL; Amazon Aurora PostgreSQL updates; Aurora MySQL database engine updates 2025-11-13 (version 3.11.0)
Amazon RDS API ReferenceAddRoleToDBCluster; AddRoleToDBInstance; DBClusterRole; DBEngineVersion; RestoreDBClusterFromSnapshot
AWS CLI Command Referenceadd-role-to-db-cluster; add-role-to-db-instance; describe-db-engine-versions
AWS Lambda API ReferenceInvoke
AWS re:Post Knowledge CenterHow do I resolve errors when I load data between Amazon Aurora and Amazon S3? (last updated 2025-01-04)
AWS Database BlogTrigger an AWS Lambda function from Amazon RDS for MySQL or Amazon RDS for MariaDB using audit logs and Amazon CloudWatch (2024-02-27); Invoke AWS services directly from Amazon RDS for SQL Server 2025 (2026-07-20); Evaluating the right fit for your Amazon Aurora workloads: provisioned or Serverless v2 (2024-10-23)

In this article, the Aurora aws_lambda page refers to the Invoking an AWS Lambda function from an Aurora PostgreSQL DB cluster page in the Aurora User Guide. the Aurora aws_lambda reference page refers to the AWS Lambda function and parameter reference page in the Aurora User Guide, while the RDS aws_lambda page refers to the Invoking an AWS Lambda function from an RDS for PostgreSQL DB instance page in the RDS User Guide. the Aurora MySQL association page refers to the Associating an IAM role with an Amazon Aurora MySQL DB cluster page, and the Aurora MySQL native function page refers to the Invoking a Lambda function with an Aurora MySQL native function page. the Aurora MySQL LOAD page and the Aurora MySQL SAVE page refer to the pages on loading from and saving to S3. Finally, the Aurora MySQL network page refers to the Enabling network communication from Amazon Aurora to other AWS services page.

Articles from the Knowledge Center and Database Blog are not considered specifications in the user guides. When citing them, this article gives the source and date in the same sentence.

1.4 Names

In this article, different items that share the same or similar spellings are distinguished as follows:

Name in this articleWhat it refers to
IAM roleAn AWS Identity and Access Management role associated with a DB cluster or a DB instance
database roleA MySQL role inside Aurora MySQL, such as AWS_LAMBDA_ACCESS, AWS_LOAD_S3_ACCESS, and AWS_SELECT_S3_ACCESS; granted with GRANT and activated with SET ROLE
feature nameThe value of --feature-name in add-role-to-db-cluster and add-role-to-db-instance (FeatureName in the API), such as Lambda, s3Import, and s3Export
cluster parameterA parameter in a DB cluster parameter group, such as aws_default_lambda_role
EventThe value of the invocation_type argument of aws_lambda.invoke, and the invocation type of lambda_async; this article does not use the word for events in general
VPC endpoint for LambdaAn endpoint in your VPC for the Lambda service, as named by the Aurora aws_lambda page
aws_lambda.endpoint_overrideA parameter of the aws_lambda extension that specifies the Lambda endpoint; not a VPC endpoint
Aurora serverlessThe name the Aurora User Guide uses for DB instances that scale in ACUs (Aurora capacity units)

1.5 How Versions Are Written

Aurora MySQL versions are written as version 2, version 3, and version 8.4, following the style used in the documentation. The documentation refers to versions that support native functions as Aurora MySQL version 2, or Aurora MySQL version 3.01 and higher, and writes the section on database roles as Aurora MySQL version 3 and version 8.4. This article does not combine these two writing styles into a single format.

The versions of the aws_lambda extension were verified against the extension version tables in the release notes on October 25, 2026. The version for Aurora PostgreSQL 18 is 2.1. The newer versions of Aurora PostgreSQL 13 through 17 have 2.0, and the older versions have 1.0. For RDS for PostgreSQL, all versions are listed as 1.0 (versions 18 and 11 are listed as 1). The Aurora PostgreSQL release notes state, regarding version 2.0, Updated the aws_lambda extension to version 2.0, which resolves a performance issue that was present in version 1.0. No statement was found that describes what changed in version 2.1 (see Section 9.1).

2. How to Read the Tables

This section defines the columns in the tables in Sections 3 through 6, as well as how the source of a default is written.

2.1 Columns

The contract tables in Sections 4 through 6 use seven column headers in addition to the first column, Setting. The Setting column, for each route, lists what the user writes, the statement to be executed, and the names of function arguments.

ColumnWhat the cell holds
You SetWhat the user writes, and where (an IAM role association, a cluster parameter, a database grant, a SQL statement, or a function argument)
Allowed ValuesThe values the source lists, as of 2026-10-25
If You Set NothingWhat happens when the user writes nothing
Source of the DefaultWhich source states the value in If You Set Nothing
At the BoundaryWhat happens at an edge: a missing step, a value that is not active yet, a wait that runs out, or a version condition
Where It ShowsWhere the result becomes visible: an error message, an output column, a table, or a status field
No Statement FoundWhat the sources in Section 1.3 do not state

For each route, the contract tables are divided into two tables: What You Write and What Happens. The rows in both tables are in the same order.

The tables in Section 3 arrange the three routes side by side. The first column is labeled Setting, and columns 2 through 4 list Aurora PostgreSQL and RDS for PostgreSQL (aws_lambda), Aurora MySQL (Lambda functions), and Aurora MySQL (S3 statements). Role associations, database permissions, and network paths are listed as rows in this table.

2.2 How the Source of a Default Is Written

In the Source of the Default column, this article writes one of the following eight labels:

LabelWhat it means
Aurora aws_lambda pageBody text of the Aurora aws_lambda page
Aurora aws_lambda reference pageBody text of AWS Lambda function and parameter reference in the Aurora User Guide
RDS aws_lambda pageBody text of the RDS aws_lambda page
Aurora MySQL association pageBody text of Associating an IAM role with an Amazon Aurora MySQL DB cluster
Aurora MySQL native function pageBody text of Invoking a Lambda function with an Aurora MySQL native function
Aurora MySQL LOAD pageBody text of the Aurora MySQL page on loading data from text files in Amazon S3
Aurora MySQL SAVE pageBody text of the Aurora MySQL page on saving data into text files in Amazon S3
No statement foundNo source in Section 1.3 states a value

2.3 No Statement Found, Not Listed, and the Sources Disagree

This article uses different wording for the following three states.

  • No Statement Found: Despite searching the sources in Section 1.3, no text describing that particular matter was found. This corresponds to the No Statement Found column and the phrase "no statement was found" in the main text. This does not mean that the matter does not exist or cannot be done.
  • Not Listed: The list or table lacks an entry for that particular item. In the main text, this is described as "the documentation does not list." This, too, does not mean that the item is unusable.
  • The Sources Disagree: Two different sources provide conflicting information regarding the same matter.

2.4 Values from the Sources and Values Returned in This Configuration

The tables and text in Sections 3 through 7 and Section 9 present only the values from the sources. Values returned in this article's configuration are presented in Section 8, in separate tables from the values of the sources. The values in Section 8 represent this configuration and the records of that day, and are not values guaranteed by the sources.

3. The Three Routes Side by Side

This section places the three routes side by side. Section 3.1 shows who can call and by which means, while Section 3.2 shows the network, waits, and errors.

How Each Engine Gets an IAM Role to Call AWS
How Each Engine Gets an IAM Role to Call AWS

3.1 Who Can Call, and by What Means

SettingAurora PostgreSQL and RDS for PostgreSQL (aws_lambda)Aurora MySQL (Lambda functions)Aurora MySQL (S3 statements)
Statement you runSELECT * FROM aws_lambda.invoke(...)lambda_sync(...) or lambda_async(...)LOAD DATA FROM S3, LOAD XML FROM S3, SELECT INTO OUTFILE S3
Role associationDB cluster (Aurora) or DB instance (RDS)DB clusterDB cluster
Feature name in the example--feature-name LambdaNone in the CLI exampleNone in the CLI example
Cluster parameterNone on the pageaws_default_lambda_roleaws_default_s3_role; in version 2 also aurora_load_from_s3_role and aurora_select_into_s3_role
When it takes effectNo statement foundAfter the primary instance rebootsAfter the primary instance reboots
Database stepCREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE as rds_superuser——
Database privilegeGRANT USAGE on schema aws_lambda and GRANT EXECUTE on its functionsRole AWS_LAMBDA_ACCESS (version 3 and version 8.4); privilege INVOKE LAMBDA (version 2)Roles AWS_LOAD_S3_ACCESS and AWS_SELECT_S3_ACCESS (version 3 and version 8.4); privileges LOAD FROM S3 and SELECT INTO S3 (version 2)
Who can call before the grantOnly rds_superuserNo statement found on the native function pageThe administrative user, granted by default
Activation of the privilege—SET ROLE or activate_all_roles_on_login (version 3)SET ROLE or activate_all_roles_on_login (version 3)
Version conditionAurora PostgreSQL 11.9 and higher; RDS for PostgreSQL by a version listVersion 2, or version 3.01 and higherVersion 3.05 and higher for customer managed AWS KMS keys
Aurora serverlessStated as supported (including Aurora serverless)The documentation does not list itThe documentation does not list it

The "Who can call before the grant" row for the Aurora MySQL S3 route is based on the Aurora MySQL LOAD page and SAVE page, which state, The administrative user for a DB cluster is granted the appropriate role or privilege by default. The same statement was not found on the page describing Aurora MySQL's native functions.

Regarding the "When it takes effect" row, the Aurora MySQL association page places a primary instance reboot at the end of the console instructions, while the CLI examples use method=pending-reboot for parameter changes. No text describing when the association takes effect was found on the aws_lambda page for PostgreSQL. In this article's configuration, Aurora MySQL 3.10.3's aws_default_lambda_role took effect before a reboot, while the association for Aurora PostgreSQL took effect 59 to about 100 seconds after the status reached ACTIVE (see Sections 8.4 and 8.7). This table gives only the values from the sources, so this row stays unchanged.

Concerning the "Aurora serverless" row, the Aurora serverless requirements page lists two features that are not supported: Database Activity Streams and the cluster cache management for Aurora PostgreSQL. The Lambda and S3 routes for Aurora MySQL are not included in this list. However, no text in the user guide stating that these routes are supported was found either. An AWS Database Blog post (October 23, 2024) states that the features that work with provisioned instances also work with Aurora Serverless instances, with the exception of 2, but it does not name the Lambda and S3 routes. For these two routes, this article writes "the documentation does not list" them, and does not lean toward either supported or unsupported.

3.2 Network, Waits, and Errors

SettingAurora PostgreSQL and RDS for PostgreSQL (aws_lambda)Aurora MySQL (Lambda functions)Aurora MySQL (S3 statements)
Public DBOutbound rule for TCP port 443 to 0.0.0.0/0Outbound connections to the service endpointsOutbound connections to the service endpoints
Private DBNAT gateway, or a VPC endpoint for LambdaNAT, or a VPC endpoint for LambdaNAT, a VPC endpoint for Amazon S3, or an S3 gateway endpoint
DNS conditionRDS for PostgreSQL only: rds.custom_dns_resolution = 1 to use the Lambda VPC endpoint——
Kerberos noteLambda invocations may fail with Lambda VPC endpoints in the AWS Managed Microsoft AD VPCSame, on the Aurora MySQL network page and the Lambda access pageSame, on the Aurora MySQL network page
Default waitaws_lambda.connect_timeout_ms 1000 and aws_lambda.request_timeout_ms 3000No statement found in the user guide; aurora_lambda_request_timeout (default 10 seconds) in the 3.11.0 release notesNo statement found
Error when the endpoint cannot be reachedAWS Lambda client returned 'Unable to connect to endpoint'ERROR 1873 (HY000)ERROR 1871 (HY000) or ERROR 1815 (HY000)
Error when the database privilege is missingpermission denied for schema aws_lambda or permission denied for function invokeAccess denied; you need (at least one of) the Invoke Lambda privilege(s) for this operationNo statement found in the user guide
Error when the IAM role is missingNo statement foundNo statement foundError Code: 1871. Missing Credentials (Knowledge Center)
Error raised by the functionreturned error "Unhandled"No statement found—
Where results showOutput columns status_code, payload, executed_version, log_resultThe return value of the functionmysql.aurora_s3_load_history (load); files and an optional manifest in S3 (save)

The S3 column of the "Error when the IAM role is missing" row is based on an article in the Knowledge Center (last updated January 4, 2025). The article lists two potential causes for the Error Code: 1871. Missing Credentials: a lack of IAM role association with the DB cluster, and the presence of only the role name (rather than the ARN) in the parameter group. The same information was not found in the user guide.

4. The aws_lambda Extension in Aurora PostgreSQL and RDS for PostgreSQL

This section will cover the aws_lambda extension for Aurora PostgreSQL and RDS for PostgreSQL, in the order of role association, the extension and database permissions, function arguments, waits, and errors. The Aurora page and the RDS page contain largely similar content; any differences will be noted by referencing the specific page name.

4.1 Associating the IAM Role

The Aurora aws_lambda page associates roles with a DB cluster using add-role-to-db-cluster. The RDS aws_lambda page associates roles with a DB instance using add-role-to-db-instance. In both examples, the --feature-name Lambda parameter is included.

aws rds add-role-to-db-cluster \
   --db-cluster-identifier my-cluster-name \
   --feature-name Lambda \
   --role-arn arn:aws:iam::444455556666:role/rds-lambda-role \
   --region aws-region

The Aurora page describes this process in the following sentence.

This last step allows your DB cluster's database users to invoke Lambda functions.

The RDS page writes the same sentence with DB instance's database users.

The principal in the role's trust policy is rds.amazonaws.com in both page examples. The policy attached to the role, in the examples, is lambda:InvokeFunction for a specific function. The pages also state that a predefined policy, AWSLambdaRole, which allows invoking all functions, can be used.

Whether the association targets a DB cluster or a DB instance, and whether the API requires FeatureName, along with the values representing the association status (e.g., ACTIVE, PENDING, INVALID), are organized for the aws_s3 extension in Section 4.2 of the previously published Moving Data Between Amazon S3 and Aurora or RDS for PostgreSQL with the aws_s3 Extension. For AddRoleToDBCluster, the FeatureName is marked as Required: No, while for AddRoleToDBInstance, it is Required: Yes. The aws_lambda association also utilizes these two APIs. No statement was found that describes the behavior of aws_lambda.invoke when an association is made without a FeatureName. In this article's configuration, the API rejected an association without a FeatureName for the Aurora PostgreSQL cluster (Section 8.3).

The methods for associating roles are not limited to add-role-to-db-cluster. The API reference for RestoreDBClusterFromSnapshot states the following:

You can use the AssociatedRoles parameter to associate one or more AWS Identity and Access Management (IAM) roles with an Aurora DB cluster when you restore it from a snapshot.

Which feature names are available depends on the engine and version, and DescribeDBEngineVersions returns this information in the SupportedFeatureNames field. The API reference for DBEngineVersion states, The supported features vary by DB engine and DB engine version. No page was found that lists all the feature names.

4.2 The Extension and Database Privileges

After associating the role, install the extension as a user with the rds_superuser privilege. The aws_commons extension is also required, and CASCADE installs it together.

CREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE;

The Aurora page states that the extension can be installed at any time, but that it adds nothing until the VPC and IAM are set up.

the aws_lambda extension adds nothing to your Aurora PostgreSQL DB cluster's capabilities.

The Aurora page also states that the extension is installed on the primary DB instance. Right after installing the extension, only rds_superuser can call.

At this point in the procedures, only you as rds_superuser can invoke your Lambda functions.

To allow other users to call, execute the following two statements.

GRANT USAGE ON SCHEMA aws_lambda TO db_username;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA aws_lambda TO db_username;

Therefore, in the aws_lambda route, a user other than rds_superuser can call only after three steps are completed: associating an IAM role, installing the extension, and granting permissions to the database user. Simply associating a role is not sufficient to allow a database user to call.

4.3 Arguments of aws_lambda.invoke

The reference page describes four ways to write aws_lambda.invoke. These involve passing the function name as a TEXT value, or passing it as part of a structure created by aws_commons.create_lambda_function_arn. Each of these forms takes either a JSON or a JSONB payload. The form that passes the function name as TEXT with a JSON payload is as follows:

aws_lambda.invoke(
IN function_name TEXT,
IN payload JSON,
IN region TEXT DEFAULT NULL,
IN invocation_type TEXT DEFAULT 'RequestResponse',
IN log_type TEXT DEFAULT 'None',
IN context JSON DEFAULT NULL,
IN qualifier VARCHAR(128) DEFAULT NULL,
OUT status_code INT,
OUT payload JSON,
OUT executed_version TEXT,
OUT log_result TEXT)

When passing the function name as part of a structure, the region argument is not included. The Region is included in the structure itself.

According to the reference page, the values for the arguments are as follows:

ArgumentValues on the reference pageDefault
invocation_typeRequestResponse, Event, DryRun; case-sensitiveRequestResponse
log_typeTail (the last 4 KB of the execution log), None; case-sensitiveNone
regionAn AWS Region; an error is raised if it conflicts with the Region in the function_name ARNNULL; the Region from the full ARN, or the Region of the DB instance
qualifierA version or alias; an error is raised if it conflicts with the function_name ARNNULL
contextClient context in JSON or JSONBNULL

Regarding the three possible values for invocation_type, the reference page describes DryRun as follows:

This type of invocation tests access without running the Lambda function.

In contrast, Step 5 of the Aurora aws_lambda page describes the values for this argument as two options: RequestResponse and Event. Only the reference page mentions DryRun. Furthermore, regarding Event, Step 5 states that the response does not include the result payload, while the reference page states returns immediately without a returned payload.

The reference page describes the output status_code as an HTTP status code and refers to the response elements of Lambda Invoke. The Lambda API reference for Invoke states that a successful response returns a status code of 200 for RequestResponse, 202 for Event, and 204 for DryRun. The log_result is only returned when log_type is Tail, and it contains the last 4 KB of the execution log, encoded in Base64.

The description for context in the reference page states, Fields to use include than custom and env. This phrasing is reproduced verbatim in this article.

4.4 Waits

The reference page lists two parameters for the waits of aws_lambda.

ParameterWhat the reference page saysDefaultAllowed values
aws_lambda.connect_timeout_msA dynamic parameter; the maximum wait time while connecting to AWS Lambda10001 - 900000
aws_lambda.request_timeout_msA dynamic parameter; the maximum wait time while waiting for response from AWS Lambda30001 - 900000
aws_lambda.endpoint_overrideThe endpoint used to connect to AWS Lambda; an empty string selects the default endpoint for the Region; a static parameterNo statement foundAn endpoint, or an empty string

The reference page states the default values as follows:

The default values is 3000.

The original text's values is was kept as is. The default value description for aws_lambda.connect_timeout_ms is also written as 1000 in the same format.

aws_lambda.endpoint_override is a static parameter, and the reference page indicates that a database restart is required to apply changes. The page describes the behavior when an empty string is used, but it does not explicitly state that the default value is an empty string.

You must restart the database for this static parameter change to take effect.

The documentation indicates that the default value for the response wait of aws_lambda.invoke is 3000 milliseconds. No statement was found that it waits until the Lambda function's timeout. No statement was found regarding the relationship between the two parameters and PostgreSQL's statement_timeout, whether the database retries after a timeout, or the specific error message displayed when a timeout occurs.

The maximum payload size was not found in the aws_lambda pages. The Lambda API reference for Invoke states the following regarding the maximum size limit on the Lambda side:

The maximum payload size is 6 MB for synchronous invocations and 1 MB for asynchronous invocations.

This text refers to the AWS Lambda API, not the aws_lambda extension. This article does not define this limit as a restriction for aws_lambda.invoke.

4.5 Contract Tables

What You Write
SettingYou SetAllowed ValuesIf You Set NothingSource of the Default
Role associationadd-role-to-db-cluster (Aurora) or add-role-to-db-instance (RDS) with --feature-name LambdaAn IAM role ARN; feature names by SupportedFeatureNamesThe extension adds nothingAurora aws_lambda page
ExtensionCREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE as rds_superuser—aws_lambda.invoke is not installedAurora aws_lambda page
Database grantGRANT USAGE ON SCHEMA aws_lambda and GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA aws_lambdaA database userOnly rds_superuser can invokeAurora aws_lambda page
invocation_typeFunction argumentRequestResponse, Event, DryRun (case-sensitive)RequestResponseAurora aws_lambda reference page
log_typeFunction argumentTail, None (case-sensitive)NoneAurora aws_lambda reference page
regionFunction argument, or the second argument of aws_commons.create_lambda_function_arnAn AWS RegionThe Region from the full ARN, or the Region of the DB instanceAurora aws_lambda reference page
aws_lambda.connect_timeout_msParameter (dynamic)1 - 9000001000Aurora aws_lambda reference page
aws_lambda.request_timeout_msParameter (dynamic)1 - 9000003000Aurora aws_lambda reference page
aws_lambda.endpoint_overrideParameter (static)An endpoint, or an empty string for the default Lambda endpoint for the RegionNo statement foundNo statement found
rds.custom_dns_resolution (RDS for PostgreSQL)DB parameter in a custom DB parameter group0 or 10 (not enabled)RDS aws_lambda page
What Happens
SettingAt the BoundaryWhere It ShowsNo Statement Found
Role associationAllows the database users of the DB cluster or DB instance to invoke Lambda functions, together with the extension and the grantAssociatedRoles of the DB cluster or DB instanceWhen the association takes effect; behavior without FeatureName
ExtensionInstalled on the primary DB instancepg_extension—
Database grantWithout it, a non-superuser gets a permission errorpermission denied for schema aws_lambda—
invocation_typeEvent returns without a payload; DryRun tests access without running the functionstatus_code (200, 202, 204 in the Lambda API Reference)The error for a value in the wrong case
log_typeTail returns the last 4 KB of the execution loglog_result (Base64)—
regionA conflict with the Region in the ARN raises an errorThe error messageThe text of the error
aws_lambda.connect_timeout_ms——The error when the wait runs out
aws_lambda.request_timeout_msThe wait for the response is 3000 ms by default, not the function timeout—The relation to statement_timeout; retries; the error text
aws_lambda.endpoint_overrideA change requires a restart of the database——
rds.custom_dns_resolution (RDS for PostgreSQL)Required to use the Lambda VPC endpoint; a reboot applies it—An equivalent statement on the Aurora aws_lambda page

The No Statement Found entry in the rds.custom_dns_resolution row indicates that the same statement is not found on the aws_lambda page for Aurora. This does not mean that the parameter is absent from Aurora PostgreSQL itself. This article does not explore whether this parameter is present on other pages within Aurora.

4.6 Error Messages

The Aurora Lambda function error messages page lists three types of errors.

  • Configuration issues with the VPC. It notes that a common cause is the absence of an outbound rule on port 443 in the security group.

ERROR:  invoke API failed
DETAIL: AWS Lambda client returned 'Unable to connect to endpoint'.
CONTEXT:  SQL function "invoke" statement 1

  • Insufficient permissions for the user invoking the function. This occurs when the GRANT statements from Section 4.2 are missing.

ERROR:  permission denied for schema aws_lambda
ERROR:  permission denied for function invoke

  • The Lambda function threw an exception.

ERROR:  lambda invocation failed
DETAIL:  "arn:aws:lambda:us-west-2:555555555555:function:my-function" returned error "Unhandled", details: "<Error details string>".

The page includes the following text regarding the third item:

Be sure to handle errors in your Lambda functions or in your PostgreSQL application.

The "insufficient permissions" described on this page refers to permissions for the database user. Error messages related to IAM roles not being associated or role policies not allowing the function were not found on this page or on other aws_lambda pages. The error messages returned in this article's configuration are shown in Sections 8.4 through 8.6.

5. Lambda in Aurora MySQL - Two Steps and a Database Role

This section covers the Aurora MySQL Lambda route in the order of the two-step association, parameters, database roles, native functions, and the deprecated stored procedure.

5.1 Two Steps to Associate the IAM Role

The Aurora MySQL association page states that associating an IAM role with a DB cluster requires two steps.

  1. Using the RDS console, add-role-to-db-cluster, or AddRoleToDBCluster, add the role to the list of associated roles for the DB cluster. The page states, You can add a maximum of five IAM roles for each Aurora DB cluster.
  2. Enter the ARN (Amazon Resource Name) of the associated role(s) in the cluster parameters for the relevant AWS service.

The second step is described in the following sentence:

Set the cluster-level parameter for the related AWS service to the ARN for the associated IAM role.

The CLI example on the page demonstrates running the add-role-to-db-cluster command without the --feature-name parameter.

PROMPT> aws rds add-role-to-db-cluster --db-cluster-identifier my-cluster --role-arn arn:aws:iam::123456789012:role/AllowAuroraLambdaRole

In the example, the cluster parameters are written with method=pending-reboot, the parameter group is attached to the DB cluster, and then the cluster is rebooted. The console instructions follow the reboot of the primary instance with the following sentence:

When the instance has rebooted, your IAM role is associated with your DB cluster.

Therefore, the Aurora MySQL documentation indicates that associating roles and configuring cluster parameters, followed by a reboot, is necessary for the role to be successfully associated with the DB cluster. Neither of the two takes priority, and the user guide does not describe what happens if only one of the steps is performed. For the S3 statements, a Knowledge Center article lists one error for a missing association (Section 3.2).

The FeatureName parameter for AddRoleToDBCluster is marked as Required: No. The absence of --feature-name in the example on the Aurora MySQL page and the inability to use --feature-name with Aurora MySQL are distinct issues. No statement was found that states the latter. In this article's configuration (Aurora MySQL 3.10.3), the API rejected association requests that include --feature-name Lambda, and SupportedFeatureNames returned only Bedrock (Sections 8.2 and 8.3). Furthermore, aws_default_lambda_role was effective before a reboot (Section 8.7).

The Aurora MySQL pages give the order of the two steps in reverse depending on the page. The association page places the role association first, followed by the parameter. The Giving Aurora access to Lambda page and the LOAD and SAVE pages place the parameter first, followed by the role association. This article does not state that either order is correct.

For Aurora global database clusters, the "Giving Aurora access to Lambda" page instructs you to configure parameters, role associations, and outbound connections in the same way across all Aurora clusters in the global database.

5.2 Cluster Parameters

The table on the association page for Aurora MySQL lists the cluster parameters for IAM roles used with other AWS services. The relevant rows are as follows:

ParameterWhat the association page says
aws_default_lambda_roleUsed when invoking a Lambda function from your DB cluster
aws_default_s3_roleUsed for LOAD DATA FROM S3, LOAD XML FROM S3, and SELECT INTO OUTFILE S3; in version 2, used if no IAM role is specified for the statement-specific parameter; in version 3 and version 8.4, always used
aurora_load_from_s3_roleUsed for LOAD DATA FROM S3 and LOAD XML FROM S3; if no IAM role is specified, aws_default_s3_role is used; not available in version 3 and version 8.4
aurora_select_into_s3_roleUsed for SELECT INTO OUTFILE S3; if no IAM role is specified, aws_default_s3_role is used; not available in version 3 and version 8.4

The page includes two statements regarding version 3 and version 8.4.

In Aurora MySQL version 3 and version 8.4, the IAM role specified for this parameter is always used.

In Aurora MySQL version 3 and version 8.4, this parameter isn't available.

The first statement pertains to the row for aws_default_s3_role, while the second statement applies to the rows for aurora_load_from_s3_role and aurora_select_into_s3_role. This means that statements regarding priority only appear between the two S3-specific parameters in version 2 and the aws_default_s3_role. It does not reflect a priority relationship between role association and cluster parameters.

The same table also includes aws_default_logs_role, which is used to send logs to CloudWatch Logs. The two steps for this role are covered in Section 7.2 of Query Auditing in Aurora MySQL and RDS for MySQL on this site.

5.3 Database Roles and Privileges

Apart from the two steps for the IAM role, the database user that calls a function also requires privileges. The Aurora MySQL native functions page separates permissions based on version as follows:

VersionWhat to grantStatement on the page
Version 3 and version 8.4The database role AWS_LAMBDA_ACCESSGRANT AWS_LAMBDA_ACCESS TO user@domain-or-ip-address
Version 2The privilege INVOKE LAMBDAGRANT INVOKE LAMBDA ON *.* TO user@domain-or-ip-address

In version 3, a granted database role might not be active. The Tip on the page says that you can activate it using SET ROLE role_name or SET ROLE ALL, which only applies to the current session. You will need to re-execute SET ROLE after reconnecting. Using the cluster parameter activate_all_roles_on_login will enable all roles for the user upon connection. However, for a stored procedure that a different user calls, the page says to call SET ROLE ALL explicitly at the beginning of the procedure.

The page advises running SET ROLE if you encounter the following error when calling a function:

SQL Error [1227] [42000]: Access denied; you need (at least one of) the Invoke Lambda privilege(s) for this operation

The page also states that when multiple users with the same name exist on different hosts, MySQL selects the user that best matches the host. It recommends ensuring that permissions are granted to the correct user.

5.4 lambda_sync and lambda_async

Aurora MySQL provides two native functions. The page states the versions as follows:

You can call the native functions lambda_sync and lambda_async when you use Aurora MySQL version 2, or Aurora MySQL version 3.01 and higher.

FunctionInvocation type on the pageSyntax
lambda_syncRequestResponse (synchronous)lambda_sync(lambda_function_ARN, JSON_payload)
lambda_asyncEvent (asynchronous)lambda_async(lambda_function_ARN, JSON_payload)

The page includes the following identical text in the descriptions for both functions:

The function returns the result of the Lambda invocation in a JSON payload.

The page says that lambda_async uses the Event invocation type, yet the sentence quoted above says that the function returns the result of the Lambda invocation in a JSON payload. The page therefore does not make clear what lambda_async returns. This article does not state that lambda_async returns the function's result; see Section 8 for the values returned in this configuration.

Regarding calls from a trigger, the page includes the following text:

Triggers aren't run once per SQL statement, but once per row modified, one row at a time.

The page continues by stating that the processing when a trigger runs is synchronous, and that a data-modifying statement returns only after the trigger completes. It notes that invoking these functions from triggers on tables with frequent write operations (such as INSERT, UPDATE, and DELETE) will result in a greater number of Lambda function invocations. For Lambda concurrency on the Lambda side, see AWS Lambda Concurrency and Scaling Guide on this site.

Regarding the JSON format for function results, the page states that version 3 includes JSON functions available in MySQL 8.0, while version 2 does not. It also states that if the Lambda function returns a single value, such as a number or string, JSON parsing is not required.

For the Aurora MySQL Lambda route, no statement was found in the user guide that gives the default wait or the error text when the Lambda function throws an exception. The Aurora MySQL 3.11.0 release notes state, Added a new global variable aurora_lambda_request_timeout to allow users configure AWS Lambda request timeouts (default: 10 seconds). The configuration in Section 8 used version 3.10.3, which is earlier than 3.11.0.

5.5 The Deprecated Stored Procedure mysql.lambda_async

Aurora MySQL previously offered a method for invoking Lambda functions using the mysql.lambda_async stored procedure. This feature is now deprecated, as indicated by the (deprecated) label on the relevant page. The page states:

In Aurora MySQL version 2, the stored procedure mysql.lambda_async is no longer supported.

It further advises, We strongly recommend that you work with native Lambda functions instead. and notes, In Aurora MySQL version 3, the stored procedure isn't available. However, the pages "Integrating Aurora with other AWS services" and "Authorizing Amazon Aurora MySQL to access other AWS services on your behalf" still list this procedure as one potential option. This article does not include this procedure in the comparison of routes.

5.6 Contract Tables

What You Write
SettingYou SetAllowed ValuesIf You Set NothingSource of the Default
Role associationadd-role-to-db-cluster (the CLI example has no --feature-name)An IAM role ARN; up to five roles per DB clusterNo role is associatedAurora MySQL association page
aws_default_lambda_roleCluster parameter in a custom DB cluster parameter groupThe ARN of the associated IAM roleNo statement foundNo statement found
Database role (version 3 and version 8.4)GRANT AWS_LAMBDA_ACCESS TO user@domain-or-ip-addressA database userNo statement found for users without the roleNo statement found
Privilege (version 2)GRANT INVOKE LAMBDA ON *.* TO user@domain-or-ip-addressA database userNo statement found for users without the privilegeNo statement found
Role activation (version 3)SET ROLE in the session, or the cluster parameter activate_all_roles_on_loginSET ROLE role_name or SET ROLE ALLThe granted role may not be activeAurora MySQL native function page
lambda_syncSQL functionA Lambda function ARN and a JSON payload——
lambda_asyncSQL functionA Lambda function ARN and a JSON payload——
What Happens
SettingAt the BoundaryWhere It ShowsNo Statement Found
Role associationNeeded together with the cluster parameterAssociatedRoles of the DB clusterWhat happens with the association alone
aws_default_lambda_roleSet with pending-reboot in the example; the role is associated after the primary instance rebootsParameter group and the member status of the DB clusterWhat happens with the parameter alone
Database role (version 3 and version 8.4)A granted role that is not active gives an access-denied errorAccess denied; you need (at least one of) the Invoke Lambda privilege(s) for this operation—
Privilege (version 2)——The error text
Role activation (version 3)SET ROLE applies only to the current session; a stored procedure called by a different user needs SET ROLE ALLCURRENT_ROLE()—
lambda_syncCalled in a trigger, it runs once per modified row, and the statement returns after the trigger completesThe return valueThe default wait in the user guide (see Section 5.4); the error text for a function error
lambda_asyncUses the Event invocation type; the page also says it returns the result in a JSON payloadThe return valueWhat the returned value contains

6. The S3 Statements in Aurora MySQL

This section covers the three S3 statements of Aurora MySQL. The two steps of role association and cluster parameters are the same as described in Sections 5.1 and 5.2. Here, this section covers what is specific to the S3 statements and the columns that pair with the previously published aws_s3 extension article.

6.1 LOAD DATA FROM S3 and LOAD XML FROM S3

The Aurora MySQL LOAD page begins with the following statement:

In Aurora MySQL, the files are first stored on the local disk, and then imported to the database.

The page continues by stating that once the load process is complete, the local files will be deleted.

The preparations required by the page consist of five steps: creating IAM policies and roles, creating a custom DB cluster parameter group, configuring the ARN (Amazon Resource Name) for the parameters (version 3 and version 8.4 use aws_default_s3_role), associating the role, and establishing outbound connections to S3. For private DB clusters, the page notes that it is possible to create an S3 gateway endpoint.

To execute the statement, the database user must be granted the DB role AWS_LOAD_S3_ACCESS for version 3 and version 8.4, or the LOAD FROM S3 privilege for version 2. The page states that the administrative user of the DB cluster has it by default. In addition, the user must also have INSERT privileges on the database where the data will be loaded.

The page further specifies the following additional requirements:

AspectWhat the Aurora MySQL LOAD page says
URIs3-region://amzn-s3-demo-bucket/file-name-or-prefix; the Region is optional
RegionIf you don't specify a Region value, Aurora loads your file from Amazon S3 in the same Region as your DB cluster
FormatAny text file format supported by the MySQL LOAD DATA INFILE statement; compressed files are not supported
EncryptionIn version 3.05 and higher, objects encrypted with customer managed AWS KMS keys can be loaded with kms:Decrypt; not needed for AWS managed keys or SSE-S3
Global databaseSet the parameter and associate the role for each cluster; only the primary cluster can load data
RecordEvery successful LOAD DATA FROM S3 statement updates mysql.aurora_s3_load_history with an entry for each file loaded

Regarding global databases, the page gives the following reason for asking that the settings be made for every cluster.

Although only the primary cluster in an Aurora global database can load data, another cluster might be promoted by the failover mechanism and become the primary cluster.

6.2 SELECT INTO OUTFILE S3

The Aurora MySQL SAVE page indicates that files are initially saved to a local disk before being exported to S3, and then deleted.

The database user executing the statement requires the AWS_SELECT_S3_ACCESS role in version 3 and version 8.4, or the SELECT INTO S3 privilege in version 2. The administrative user has it by default.

The main conditions outlined on the page are as follows:

AspectWhat the Aurora MySQL SAVE page says
RegionIf you don't specify a Region value, Aurora saves your files into Amazon S3 in the same Region as your DB cluster
File sizeThe default file size threshold is 6 GB; above it, multiple files are created
Large dataFor more than 25 GB, the page recommends multiple statements with different file prefixes
Existing filesWith OVERWRITE ON, files that match the prefix are overwritten; otherwise an error occurs
ManifestWith MANIFEST ON, a manifest file is created after all data files are uploaded
EncryptionSSE_S3 and SSE_KMS are available in version 3.05 and higher; customer managed keys need kms:GenerateDataKey
Session variableaurora_select_into_s3_encryption_default; its default is OFF, which follows the default encryption policy of the bucket
FailureFiles already uploaded remain in the bucket

The syntax of the ENCRYPTION clause on the page is as follows:

[ENCRYPTION {ON | OFF | SSE_S3 | SSE_KMS ['cmk_id']}]

The sentence for more than 25 GB is a recommendation on the page. This article quotes it only as a sentence of the page, and does not describe how to split the data.

6.3 How the S3 Statements Pair with the aws_s3 Extension

Both the S3 statements for Aurora MySQL and the aws_s3 extension for Aurora PostgreSQL and RDS for PostgreSQL allow reading and writing to S3 from the database. The following table compares the aws_s3 side, as organized in the previously published Moving Data Between Amazon S3 and Aurora or RDS for PostgreSQL with the aws_s3 Extension, with the Aurora MySQL side discussed in this article, across four key aspects. Detailed information regarding the aws_s3 side can be found in Sections 5 and 6 of that article.

AspectAurora MySQL S3 statementsaws_s3 extension (previously published article)
How the IAM role is associatedRole association and aws_default_s3_roleRole association with the feature name s3Import or s3Export
Database privilegeRoles AWS_LOAD_S3_ACCESS and AWS_SELECT_S3_ACCESS (version 3 and version 8.4)Not addressed by that article (Section 4.1 of that article)
Region for savingThe Region in the URI; the same Region as the DB cluster if omitted; an example saves to a bucket in a different RegionThe export pages say the Region must be the same as the DB cluster or DB instance
Encryption for savingSSE_S3 and SSE_KMS in version 3.05 and higherThe export pages say buckets encrypted with SSE-S3 are not supported

Regarding the Region row, the Aurora MySQL SAVE page allows a Region in the URI and describes one of its examples as The following statement selects all of the data in the employees table and saves the data into an Amazon S3 bucket that is in a different region from the Aurora MySQL DB cluster. The encryption row only places the statements of the two routes side by side, without saying which suits which situation.

6.4 Roles and Privileges That RDS for MySQL Does Not Have

The LOAD and SAVE pages for Aurora MySQL state:

The AWS_LOAD_S3_ACCESS role and LOAD FROM S3 privilege are specific to Amazon Aurora and are not available for external MySQL databases or RDS for MySQL DB instances.

The AWS_SELECT_S3_ACCESS role and SELECT INTO S3 privilege are specific to Amazon Aurora MySQL and are not available for MySQL databases or RDS for MySQL DB instances.

These two pages further explain that when an Aurora cluster is configured as the replication source and a MySQL database as the recipient, GRANT statements for these roles and privileges cause replication to stop with an error. The pages say that the errors can be skipped, and that on RDS for MySQL mysql_rds_skip_repl_error is used.

The Restoring a backup into an Amazon RDS for MySQL DB instance page of the RDS User Guide describes how to create a new DB instance from a backup file stored in S3. This process does not involve reading S3 using SQL statements.

No statement was found that says Lambda or S3 can be called from SQL in RDS for MySQL or RDS for MariaDB, and no statement was found that says it cannot. A Database Blog article (dated 2024-02-27) describes a configuration where RDS for MySQL and RDS for MariaDB can trigger Lambda functions by sending audit logs to CloudWatch Logs and using subscription filters. While the article says that Lambda provides direct integration with Aurora MySQL, it does not state that SQL calls to Lambda are unsupported in RDS for MySQL. The audit log settings are covered in Query Auditing in Aurora MySQL and RDS for MySQL on this site.

6.5 Contract Tables

What You Write
SettingYou SetAllowed ValuesIf You Set NothingSource of the Default
Role associationadd-role-to-db-cluster (the CLI example has no --feature-name)An IAM role ARN; up to five roles per DB clusterNo role is associatedAurora MySQL association page
aws_default_s3_roleCluster parameter in a custom DB cluster parameter groupThe ARN of the associated IAM roleNo statement foundNo statement found
aurora_load_from_s3_role and aurora_select_into_s3_role (version 2)Cluster parametersThe ARN of the associated IAM roleaws_default_s3_role is usedAurora MySQL association page
Database roles (version 3 and version 8.4)GRANT AWS_LOAD_S3_ACCESS and GRANT AWS_SELECT_S3_ACCESSA database userThe administrative user has them by defaultAurora MySQL LOAD page
LOAD DATA FROM S3 and LOAD XML FROM S3SQL statement with an S3 URIs3-region://amzn-s3-demo-bucket/file-name-or-prefix, a prefix, or a manifestThe same Region as the DB clusterAurora MySQL LOAD page
SELECT INTO OUTFILE S3SQL statement with an S3 URI and optionsMANIFEST, OVERWRITE, ENCRYPTION, FORMATThe same Region as the DB cluster; file size threshold 6 GBAurora MySQL SAVE page
aurora_select_into_s3_encryption_defaultSession variableON, OFF, SSE_S3, SSE_KMSOFF; the default encryption policy of the bucketAurora MySQL SAVE page
What Happens
SettingAt the BoundaryWhere It ShowsNo Statement Found
Role associationNeeded together with the cluster parameterAssociatedRoles of the DB clusterWhat happens with the association alone
aws_default_s3_roleIn version 3 and version 8.4, the role in this parameter is always usedParameter groupWhat happens with the parameter alone
aurora_load_from_s3_role and aurora_select_into_s3_role (version 2)Not available in version 3 and version 8.4Parameter group—
Database roles (version 3 and version 8.4)SET ROLE or activate_all_roles_on_login activates themCURRENT_ROLE()The error text in the user guide
LOAD DATA FROM S3 and LOAD XML FROM S3Files are stored on the local disk first; compressed files are not supported; only the primary cluster of a global database can loadmysql.aurora_s3_load_history—
SELECT INTO OUTFILE S3An existing file with the same prefix gives an error unless OVERWRITE ON; uploaded files remain after a failureFiles and the manifest in S3—
aurora_select_into_s3_encryption_defaultUse either the session variable or the ENCRYPTION clause, not bothThe encryption of the S3 objects—

7. Network Paths

This section places side by side, in the words of the sources, the network through which the three routes reach AWS services from the DB. For VPC endpoint types and private DNS design, see Private Connectivity by Service on AWS Data Services on this site. The network for the aws_s3 extension for PostgreSQL is covered in Section 7 of the previously published Moving Data Between Amazon S3 and Aurora or RDS for PostgreSQL with the aws_s3 Extension.

Network Paths from the Database to Lambda and S3
Network Paths from the Database to Lambda and S3

7.1 The PostgreSQL aws_lambda Pages

Step 1 on the Aurora aws_lambda page begins with the following sentence:

Lambda functions always run inside an Amazon VPC that's owned by the AWS Lambda service.

The DB cluster sends network traffic to this VPC of the Lambda service. The configuration depends on whether the primary DB instance is public or private.

  • Public DB cluster: This occurs when the primary DB instance is located in a public subnet in the VPC and PubliclyAccessible is set to true. You need to create outbound rules in the VPC's security group. The page states this rule as, The outbound rule specifies that TCP can use port 443 to send packets to any IPv4 addresses (0.0.0.0/0).

  • Private DB cluster: This occurs when PubliclyAccessible is set to false, or when the DB instance is located in a private subnet. You can either use a NAT gateway or configure a VPC endpoint for Lambda in the VPC. The page states this as, Or, you can configure your VPC with a VPC endpoint for Lambda.

The page does not give the name of the VPC endpoint type (interface endpoint). This article will refer to it as "a VPC endpoint for Lambda," mirroring the language used in the documentation.

7.2 The Aurora MySQL Network Page

The Aurora MySQL network page lists operations requiring outbound connections, including invoking Lambda functions, accessing S3 files, using AWS KMS for Database Activity Streams, and utilizing SageMaker AI. The page states that Aurora returns the following errors when it cannot connect to a service endpoint:

ERROR 1871 (HY000): S3 API returned error: Network Connection
ERROR 1873 (HY000): Lambda API returned error: Network Connection. Unable to connect to endpoint
ERROR 1815 (HY000): Internal error: Unable to initialize S3Stream

Public DB clusters are marked as publicly accessible and reside within a public subnet of the VPC. All other clusters are private and are configured to connect to internet addresses through NAT. For S3, SageMaker AI, and Lambda, you can alternatively use VPC endpoints associated with the DB cluster's route table. The page further states:

You can also create an S3 gateway endpoint to access your S3 bucket.

Section 7.2 of the previously published aws_s3 article also quotes this sentence. The page also notes that the ephemeral ports for network ACLs might have to be opened.

7.3 A Statement Found Only on the RDS for PostgreSQL Page

The RDS aws_lambda page has a statement, not present on the Aurora page, about using the Lambda VPC endpoint with a private DB instance. The page states that VPC endpoints utilize their own private DNS resolution and continues with the following:

RDS for PostgreSQL can't use the Lambda VPC endpoint until you change the value of the rds.custom_dns_resolution from its default value of 0 (not enabled) to 1.

The steps outlined on the page are: create a custom DB parameter group, set rds.custom_dns_resolution to 1, apply that parameter group to the DB instance, and then reboot the instance to apply the changes. This parameter is also mentioned on the "Using a custom DNS server for outbound network access" page in the RDS User Guide.

This text is not found on the Aurora aws_lambda page. This article highlights this difference between the two pages. It does not state that this parameter is unnecessary or unavailable when using Aurora PostgreSQL.

7.4 Kerberos Authentication and DNS Conflicts

The Aurora and RDS aws_lambda pages, as well as the Giving Aurora access to Lambda page for Aurora MySQL, contain cautionary sections of the same form. The text on the Aurora aws_lambda page reads as follows:

Lambda invocations from your DB cluster may fail if you enable Kerberos authentication and configure Lambda VPC endpoints in your AWS Managed Microsoft AD VPC.

The page explains that when Kerberos authentication is enabled, the DB cluster prioritizes the AWS Managed Microsoft AD DNS servers over the VPC's DNS resolver. If the AWS Managed Microsoft AD DNS contains records for the Lambda endpoint, the endpoint may resolve to an address in the Active Directory VPC rather than the database's VPC, and then the invocation does not succeed. The Aurora MySQL network page includes a similar warning regarding Lambda, S3, SageMaker AI, and AWS KMS endpoints. The documentation uses the phrase may fail. This article does not state that these scenarios will "always fail."

8. What This Configuration Returned

This section presents the results obtained using a small configuration created specifically for this article, reflecting data from October 24, 2026 (UTC). The values presented here are based on this configuration and the data recorded on that day, and do not represent guaranteed values from the source material. These values do not show performance or which route is better. Each time value is one or two records.

8.1 Configuration

ItemValue
RegionUS East (N. Virginia)
Aurora PostgreSQLVersion 17.9 (the default version on that day); aws_lambda 2.0 and aws_commons 1.2 after CREATE EXTENSION; one writer, DB instance class db.serverless, 0.5 to 1 ACUs
Aurora MySQLVersion 3.10.3 (MySQL 8.0.42, the default version on that day); one writer, db.serverless, 0.5 to 1 ACUs; a custom DB cluster parameter group
NetworkPublic subnets; the security group allowed all outbound traffic, except in the steps that removed the outbound rule
Lambda functionsThree Python functions in the same Region: one returns its payload, one sleeps for the given seconds, one raises an exception
IAM rolesOne role for Aurora PostgreSQL with lambda:InvokeFunction on the three functions; one role for Aurora MySQL with the same permission and the S3 actions listed on the S3 policy page for one bucket
Database usersThe master user; on Aurora MySQL, caller_user (granted AWS_LAMBDA_ACCESS, AWS_LOAD_S3_ACCESS, and AWS_SELECT_S3_ACCESS, and running SET ROLE ALL before each call) and app_user; on Aurora PostgreSQL, app_user
Date and time2026-10-24, from 07:46 to 09:05 (UTC)

RDS for PostgreSQL, Lambda VPC endpoints, NAT gateways, Kerberos authentication, and Aurora MySQL versions 2 and 8.4 were not included in this configuration. Account IDs, cluster names, function names, role names, bucket names, endpoints, and Lambda Request IDs have been redacted in this article. In the quoted messages, account IDs have been replaced with 123456789012, and function names have been replaced with my-function.

8.2 Feature Names and Parameters Returned by the API

DescribeDBEngineVersions returned SupportedFeatureNames for the default version of each engine on that day as follows:

EngineDefault versionSupportedFeatureNames returned
aurora-postgresql17.9Bedrock, Comprehend, Lambda, s3Export, s3Import, SageMaker
postgres18.3Lambda, s3Export, s3Import
aurora-mysql8.0.mysql_aurora.3.10.3Bedrock
mysql8.4.11(empty)
mariadb11.8.9(empty)

The default version for aurora-mysql did not return Lambda, s3Import, or s3Export. In this configuration, the Lambda and S3 routes for Aurora MySQL worked without feature names (see Sections 8.3, 8.7, and 8.8).

Default parameter values were obtained using DescribeEngineDefaultClusterParameters and DescribeEngineDefaultParameters.

Parameter group familyParameterAllowedValues returnedApplyType
aurora-postgresql17 (cluster)aws_lambda.connect_timeout_ms10-900000dynamic
aurora-postgresql17 (cluster)aws_lambda.request_timeout_ms10-900000dynamic
postgres18 (instance)aws_lambda.connect_timeout_ms1-900000dynamic
postgres18 (instance)aws_lambda.request_timeout_ms1-900000dynamic
postgres18 (instance)rds.custom_dns_resolution0,1static
aurora-mysql8.0 (cluster)aws_default_lambda_role—dynamic
aurora-mysql8.0 (cluster)aws_default_s3_role—dynamic

For every row, the API did not return a DefaultValue. The allowed values returned for the Aurora PostgreSQL family were 10-900000, which differed from the 1 - 900000 listed on the reference page. In the database, SHOW returned 1s for aws_lambda.connect_timeout_ms and 3s for aws_lambda.request_timeout_ms. When attempting SHOW aws_lambda.endpoint_override, even with the master user, the system returned must be Aurora superuser to examine "aws_lambda.endpoint_override". The aurora-mysql8.0 family also had rows for aws_default_bedrock_role, aws_default_comprehend_role, and aws_default_sagemaker_role.

8.3 API Responses to Role Association

CallResponse in this configuration
Aurora PostgreSQL, add-role-to-db-cluster --feature-name LambdaAccepted; the status moved from PENDING to ACTIVE in about 11 seconds
Aurora PostgreSQL, add-role-to-db-cluster without --feature-nameInvalidParameterValue: The feature-name parameter must be provided with the current operation for the Aurora (PostgreSQL) engine.
Aurora MySQL, add-role-to-db-cluster --feature-name LambdaInvalidParameterValue: The feature name Lambda is not valid for the engine Aurora MySQL.
Aurora MySQL, add-role-to-db-cluster without --feature-nameAccepted; ACTIVE with no feature name in about 11 seconds
Aurora MySQL, aws_default_lambda_role and aws_default_s3_role with ApplyMethod=immediateAccepted; the member status of the DB cluster stayed in-sync; for aws_default_lambda_role, SHOW GLOBAL VARIABLES returned the ARN before any reboot (the step that set aws_default_s3_role rebooted the writer without this check)

Although the API reference indicates that FeatureName for AddRoleToDBCluster is Required: No, in this configuration the API rejected calls without a FeatureName for the Aurora PostgreSQL cluster. Conversely, the API rejected calls with the Lambda feature name when targeting Aurora MySQL clusters.

8.4 When an Association Takes Effect, and When a Removal Does

The association status and whether calls were successful did not change simultaneously within this configuration.

SituationWhat the calls returned in this configuration
Aurora PostgreSQL, ACTIVE with Lambda (first run)unable to access credentials stored with the database instance until at least 68 seconds after ACTIVE; the first success was about 100 seconds after ACTIVE
Aurora PostgreSQL, ACTIVE with Lambda (second run, a call every 10 to 12 seconds)The same error at 47 seconds after ACTIVE; success at 59 seconds
Aurora PostgreSQL, the role removed (first run)A call 2 seconds after the association disappeared succeeded
Aurora PostgreSQL, the role removed (second run)Calls succeeded until 36 seconds after the association disappeared; the error returned at 48 seconds
Aurora PostgreSQL, the same role associated only as s3ImportThe error continued for 600 seconds after ACTIVE
Aurora MySQL, the role association removed with aws_default_lambda_role still setlambda_sync succeeded until 50 seconds after the association disappeared; the error returned at 61 seconds

The full text of the credential error for Aurora PostgreSQL was as follows:

ERROR:  unable to access credentials stored with the database instance
HINT:  Make sure that the desired Amazon Resource Name (ARN) is associated with the feature-name: "Lambda".

In this configuration, aws_lambda.invoke did not succeed with the role associated as s3Import. In the first run, the call made right after the association as s3Import succeeded. This was about 18 seconds after the Lambda association was removed, which is shorter than the 36 seconds during which calls still worked after the removal in the second run. This article does not interpret the initial successful invocation as a result of the s3Import association.

8.5 Calls from Aurora PostgreSQL

The following table shows the results of the calls after the association has been established.

CallResult in this configuration
Two arguments (function ARN and payload)status_code 200; the payload returned by the function; executed_version $LATEST
invocation_type Eventstatus_code 202; payload and executed_version empty
invocation_type DryRunstatus_code 204; payload and executed_version empty
invocation_type event (lower case)ERROR: invoke API failed with Value 'event' at 'invocationType' failed to satisfy constraint: Member must satisfy enum value set: [DryRun, RequestResponse, Event]
log_type Tailstatus_code 200; log_result of 352 characters, 262 characters after Base64 decoding
A Region that conflicts with the ARNERROR: ambiguous region with DETAIL: The region "us-east-1" encoded in the Lambda name does not match the specified region "us-west-2".
aws_commons.create_lambda_function_arnstatus_code 200
app_user without the GRANT statementsERROR: permission denied for schema aws_lambda
app_user after the GRANT statements, also with aws_commons.create_lambda_function_arnstatus_code 200 in both cases
A function that raises an exception, RequestResponseERROR: lambda invocation failed with returned error "Unhandled" and the error message of the function in details
A function that raises an exception, Eventstatus_code 202; no error

For app_user, only the two GRANT statements described in Section 4.2 were run. While no GRANT on the aws_commons schema was run, the call using aws_commons.create_lambda_function_arn was successful.

8.6 Waits and the Network

The following table shows the times for statements, as indicated by psql's \timing command.

CallResult in this configurationTime
A function that sleeps 2 seconds, default waitstatus_code 200About 2.4 seconds
A function that sleeps 5 seconds, default waitERROR: invoke API failed with AWS Lambda client returned 'operation timeout (all attempts including retries) occurred after 3s'.About 3.2 seconds
The same, after SET aws_lambda.request_timeout_ms = 10000status_code 200About 5.4 seconds
The same, with request_timeout_ms 10000 and statement_timeout 2 secondsERROR: canceling statement due to statement timeoutAbout 5.2 seconds
A function that sleeps 5 seconds, Eventstatus_code 202About 0.2 seconds
No outbound rule, default waitsThe same operation timeout … occurred after 3s errorAbout 3.2 seconds
No outbound rule, SET aws_lambda.connect_timeout_ms = 5000The same operation timeout … occurred after 3s errorAbout 3.2 seconds
Outbound rule restoredstatus_code 200About 0.2 seconds

The aws_lambda.request_timeout_ms setting could be changed with SET in the session. Calls with a statement_timeout of 2 seconds did not stop after 2 seconds, but instead resulted in a cancellation error after approximately 5.2 seconds. The records of this configuration do not show that statement_timeout takes effect in the middle of the wait for the Lambda response. With no outbound rule, the error message was the same as the message when the wait runs out, rather than the Unable to connect to endpoint message on the error page. The error message includes the phrase including retries, but the records do not show how many times the DB side tried.

8.7 Lambda in Aurora MySQL

StepResult in this configuration
No role associated, no parameterERROR 63987 (HY000) at line 1: Lambda API returned error: Missing designated IAM role (aws_default_lambda_role)
Role associated, parameter emptyThe same error
Parameter set with ApplyMethod=immediate, before any rebootlambda_sync returned the payload of the function
After a reboot of the writerlambda_sync returned the payload of the function
lambda_asyncReturned {} (an empty JSON object, printed with line breaks)
lambda_async with a function that raises an exceptionReturned {}; no error
lambda_sync with a function that sleeps 5 secondsReturned after the function finished (about 6.9 seconds on the client, including the connection)
lambda_sync with a function that raises an exceptionERROR 63987 (HY000) at line 1: Lambda API returned error: Unhandled. followed by the error object of the function
app_user without AWS_LAMBDA_ACCESSERROR 1227 (42000) at line 1: Access denied; you need (at least one of) the Invoke Lambda privilege(s) for this operation
app_user with AWS_LAMBDA_ACCESS granted, not active (CURRENT_ROLE() returned NONE)The same ERROR 1227
app_user after SET ROLE AWS_LAMBDA_ACCESSlambda_sync returned the payload of the function
No outbound ruleERROR 63987 (HY000) at line 1: Lambda API returned error: Network Connection. curlCode: 28, Timeout was reached after about 137 seconds
Role association removed, parameter still setERROR 63987 (HY000) at line 1: Lambda API returned error: Missing IAM Credentials for specified aws_default_lambda_role

The example on the Aurora MySQL association page writes the parameter with pending-reboot and then reboots. In this configuration (Aurora MySQL 3.10.3), the API returned aws_default_lambda_role as dynamic, a change with immediate was accepted, and lambda_sync succeeded before any reboot. It is not possible to determine from this record whether the same behavior occurs in other versions.

The error number in this configuration was 63987, which is different from ERROR 1873 listed on the Aurora MySQL network page. Furthermore, the error message when there was no outbound rule also differs from the Unable to connect to endpoint message on the page.

8.8 The S3 Statements in Aurora MySQL

StepResult in this configuration
LOAD DATA FROM S3 with no role and no parameterERROR 63985 (HY000) at line 1: S3 API returned error: Both aurora_load_from_s3_role and aws_default_s3_role are not specified, please see documentation for more details, followed by warnings that end with Error (Code 1815): Internal error: Unable to initialize S3Stream
LOAD DATA FROM S3 with the role associated and only aws_default_lambda_role setThe same error
After setting aws_default_s3_role and rebooting the writerThree rows loaded
mysql.aurora_s3_load_historyOne row with load_prefix, file_name, bytes_loaded, and load_timestamp; version_number empty
SELECT INTO OUTFILE S3 with MANIFEST ONTwo objects: demo_export.part_00000 and demo_export.manifest
app_user without AWS_LOAD_S3_ACCESSERROR 1227 (42000) at line 1: Access denied; you need (at least one of) the LOAD FROM S3 privilege(s) for this operation
Role association removed, aws_default_s3_role still setERROR 63985 (HY000) at line 1: S3 API returned error: Missing Credentials: Cannot instantiate S3 Client, followed by Error (Code 1815)

Even in Aurora MySQL 3.10.3, the error messages contained the name aurora_load_from_s3_role from version 2. Because the writer was also rebooted in the step that set aws_default_s3_role, these records cannot decide whether the S3 statements need a reboot. The error message after the role association was removed included Missing Credentials, which a Knowledge Center article also names.

8.9 What This Configuration Cannot Decide

  • The time it takes for associations to take effect, and the time until they cease to function after being removed, are one or two records each. This article cannot say that the same will occur in other configurations or on other days.
  • The effectiveness of ApplyMethod=immediate for Aurora MySQL is based on a record for Aurora MySQL 3.10.3. Version 2 and version 8.4 were not checked.
  • This configuration did not check RDS for PostgreSQL, Lambda VPC endpoints, rds.custom_dns_resolution, or Kerberos authentication.
  • Based on the wording of operation timeout (all attempts including retries), it is not possible to determine the number of retry attempts or the intervals used on the database side.

9. What the Sources Do Not State, and Variations Within the Sources

This section lists the statements that this article searched for but did not find, and places where the wording varies in the sources.

9.1 Statements Not Found

For the items in the following table, no statement was found in the sources in Section 1.3 or in the places listed in the table. None of these instances indicate that the items are nonexistent or impossible to implement.

TopicWhere it was searchedResult
How the request to Lambda or S3 is signed (for example, SigV4)The aws_lambda pages, the Aurora MySQL integration pages, AWS Knowledge searchesNo statement found; the sources state the trust principal rds.amazonaws.com and that the association allows database users to invoke
The relation between aws_lambda.request_timeout_ms and statement_timeoutThe aws_lambda pages, AWS Knowledge searchesNo statement found
Retries by the database after a wait runs outThe aws_lambda pages, the Aurora MySQL native function pageNo statement found
A payload limit of aws_lambda.invokeThe aws_lambda pagesNo statement found; the Lambda API Reference states the Lambda-side limit
The error text when no IAM role is associated (aws_lambda, lambda_sync)The error messages page, the Aurora MySQL pages, AWS Knowledge searchesNo statement found; for the S3 statements, a Knowledge Center article names Error Code: 1871. Missing Credentials
Default waits and function-error text for lambda_syncThe Aurora MySQL native function pageNo statement found; the Aurora MySQL 3.11.0 release notes add aurora_lambda_request_timeout (default 10 seconds)
Whether Aurora MySQL's Lambda and S3 routes work on Aurora serverlessThe Aurora serverless requirements page, the Aurora MySQL pagesThe documentation does not list them as unavailable; no user guide statement that they are available; an AWS Database Blog post (2024-10-23) says the features that work with provisioned instances also work with Aurora Serverless instances, with the exception of 2 (Database Activity Streams and cluster cache management for Aurora PostgreSQL), without naming these routes
A complete list of feature namesThe API Reference, the CLI ReferenceNo statement found; SupportedFeatureNames returns them per engine version
Whether RDS for MySQL or RDS for MariaDB can call Lambda or S3 from SQLThe RDS User Guide MySQL import page, the Aurora MySQL pages, AWS Knowledge searches, the Database BlogNo statement that they can, and no statement that they cannot
What changed between aws_lambda versions 1.0, 2.0, and 2.1The release notes, AWS Knowledge searchesFor 2.0, the Aurora PostgreSQL release notes say it resolves a performance issue that was present in version 1.0; no statement found for 2.1
Whether Aurora MySQL accepts --feature-name for these routesThe Aurora MySQL association page, the API ReferenceNo statement found; FeatureName is Required: No for AddRoleToDBCluster

Regarding the signing row, the Database Blog article for SQL Server 2025 mentions SigV4 in relation to another method for SQL Server (Section 9.3). The sentence in question is not related to the three routes discussed in this article. For the error messages, the behavior when a wait runs out, the behavior on Aurora serverless, and the feature names in the table, Section 8 shows the values returned in this article's configuration. Because the values in Section 8 are not statements of the sources, the results in this table stay unchanged.

9.2 Variations Within the Sources

The following table lists places in the same set of pages where the wording differs. This table does not indicate that any of these instances are errors.

#TopicOne part saysAnother part says
1Values of invocation_typeThe Aurora aws_lambda page, Step 5: RequestResponse and EventThe reference page: RequestResponse, Event, and DryRun
2What lambda_async returnsThe native function page: invoked with the Event invocation typeThe same page: The function returns the result of the Lambda invocation in a JSON payload.
3Order of the two steps (Aurora MySQL)The association page: associate the role, then set the parameterThe Lambda access page and the LOAD and SAVE pages: set the parameter, then associate the role
4mysql.lambda_asyncThe stored procedure page: deprecated, not available in version 3Integrating Aurora with other AWS services and the authorizing page still list it as a way to invoke Lambda
5Version wordingThe native function page: version 2, or … version 3.01 and higherThe same page, for roles: version 3 and version 8.4
6Default value sentenceThe reference page: The default values is 3000.— (the wording of the source, quoted as is)

9.3 Neighboring Routes

In addition to the three routes discussed in this article, there are also routes from RDS to other AWS services. This article lists only the following three, one line each:

  • For RDS for SQL Server and RDS for Oracle, integrating with S3 requires associating a role using the --feature-name S3_INTEGRATION parameter with the add-role-to-db-instance command.
  • Regarding sp_invoke_external_rest_endpoint for RDS for SQL Server 2025, an article on the Database Blog (dated 2026-07-20) notes that AWS services like Amazon SageMaker and Amazon SES require SigV4 signatures for each request, and that sp_invoke_external_rest_endpoint does not perform itself. The article illustrates a configuration that uses API Gateway and Lambda as intermediaries.
  • According to an article on the Database Blog (dated 2024-02-27), a method for triggering Lambda from RDS for MySQL and RDS for MariaDB uses audit logs and a CloudWatch Logs subscription filter (see Section 6.4).

10. Failure Modes

This section lists the failures that arise from the contracts in Sections 4 through 7, categorizing them by symptoms and causes.

Where a Call from the Database Can Fail
Where a Call from the Database Can Fail
SymptomCause in the contractWhere to look
aws_lambda.invoke does not existThe extension is not installedSection 4.2
A non-superuser gets permission denied for schema aws_lambdaThe GRANT statements on the aws_lambda schema are missingSection 4.2
Unable to connect to endpoint from aws_lambda.invokeAn improperly configured VPC security group, such as no outbound rule for TCP port 443Sections 4.6 and 7.1
RDS for PostgreSQL cannot use the Lambda VPC endpointrds.custom_dns_resolution is still 0Section 7.3
A call to a slow function fails while the function is still runningaws_lambda.request_timeout_ms is 3000 ms by defaultSection 4.4
event or requestresponse is rejectedinvocation_type is case-sensitiveSection 4.3
returned error "Unhandled"The Lambda function raised an exceptionSection 4.6
Aurora MySQL lambda_sync fails after the role was associatedaws_default_lambda_role is not set (the sources' steps also reboot the primary instance; this configuration did not need the reboot)Sections 5.1 and 8.7
Access denied; you need (at least one of) the Invoke Lambda privilege(s)The database role AWS_LAMBDA_ACCESS is granted but not active in the sessionSection 5.3
A write-heavy table calls Lambda many timesTriggers run once per modified rowSection 5.4
Error Code: 1871. Missing Credentials from LOAD DATA FROM S3The IAM role is not associated, or the parameter holds a role name instead of an ARN (Knowledge Center)Section 3.2
ERROR 1873 or ERROR 1871 … Network ConnectionThe DB cluster cannot reach the service endpointSection 7.2
SELECT INTO OUTFILE S3 fails on a second runFiles with the same prefix exist and OVERWRITE ON is not specifiedSection 6.2
Lambda calls fail after Kerberos authentication is enabledLambda endpoint records in the AWS Managed Microsoft AD DNSSection 7.4
unable to access credentials stored with the database instance right after the associationIn this configuration, calls did not succeed until 59 to about 100 seconds after the Aurora PostgreSQL association status became ACTIVESection 8.4
operation timeout (all attempts including retries) occurred after 3sIn this configuration, the text for a slow function and for a missing outbound ruleSection 8.6
Missing designated IAM role (aws_default_lambda_role) on Aurora MySQLIn this configuration, the text when the parameter was empty, with or without the role associationSection 8.7

11. Frequently Asked Questions About Calling AWS from Inside Aurora and RDS

Q1. Does Aurora MySQL also associate the IAM role with --feature-name?

The association page for Aurora MySQL requires both associating a role and configuring the ARN in the cluster parameters. The CLI examples on the page do not include --feature-name. The FeatureName parameter in AddRoleToDBCluster is not required. No statement was found that says --feature-name cannot be used with Aurora MySQL, or that says what happens if it is used (Section 5.1). In this article's configuration (Aurora MySQL 3.10.3), the API rejected --feature-name Lambda with the message The feature name Lambda is not valid for the engine Aurora MySQL. (Section 8.3).

Q2. Once the IAM role is associated, can SQL call AWS right away?

The sources do not say so. In PostgreSQL, you need to install an extension and grant permissions to users other than rds_superuser. In Aurora MySQL, you need to write the ARN in the cluster parameters (the sources' steps then reboot the primary instance; in this article's configuration, the parameter took effect before the reboot), and then grant the database role to the database user and activate it (see Sections 4.2, 5.1, 5.3, and 8.7). In this article's configuration, calls failed with a credentials error, and the first successful call came 59 to about 100 seconds after the Aurora PostgreSQL association status reached ACTIVE (see Section 8.4).

Q3. Which takes priority, the role association or the cluster parameter?

Neither takes precedence; the documentation requires both. The concept of precedence only applies between the dedicated S3 parameters for Aurora MySQL version 2 (aurora_load_from_s3_role and aurora_select_into_s3_role) and the aws_default_s3_role. In version 3 and version 8.4, there are no dedicated parameters, and the role specified by aws_default_s3_role is always used (see Section 5.2).

Q4. Does aws_lambda.invoke wait until the Lambda function finishes?

The reference page states that the default value for aws_lambda.request_timeout_ms is 3000 milliseconds. No statement was found that aws_lambda.invoke waits until the Lambda function times out, and no statement was found about the relationship between aws_lambda.request_timeout_ms and statement_timeout (Section 4.4). In this article's configuration, when calling a function that sleeps for 5 seconds using the default settings, an operation timeout (all attempts including retries) occurred after 3s error occurred after approximately 3.2 seconds (Section 8.6).

Q5. Does RDS sign the request with SigV4 using the associated role?

No statement was found in the sources that describes the signing method. Instead, the documentation states that the principal in the role's trust policy is rds.amazonaws.com, and that through association, database users are able to invoke Lambda functions. This article discusses which role is used for authorization and who can make the calls (Section 9.1).

Q6. Can RDS for MySQL use LOAD DATA FROM S3?

The Aurora MySQL LOAD page states that the AWS_LOAD_S3_ACCESS role and the LOAD FROM S3 privilege are not available for RDS for MySQL DB instances. No statement was found that says SQL cannot read from S3 in RDS for MySQL. The RDS User Guide describes using S3 with RDS for MySQL in the context of restoring from backups stored on S3 (Section 6.4).

Q7. Does it work on Aurora serverless?

The aws_lambda page for Aurora PostgreSQL states, Invoking AWS Lambda functions is supported in Aurora PostgreSQL 11.9 and higher (including Aurora serverless). While the Aurora MySQL Lambda and S3 routes do not appear on the list of unsupported features (Section 3.1), no statement was found in the user guide that says they are supported. In the configuration used in this article (Aurora MySQL 3.10.3 with a single db.serverless writer), lambda_sync, LOAD DATA FROM S3, and SELECT INTO OUTFILE S3 worked, and lambda_async returned without an error (Sections 8.7 and 8.8). Whether the function called by lambda_async ran was not checked.

Q8. What is needed to call from a DB in a private subnet?

The PostgreSQL aws_lambda pages list either a NAT gateway or a Lambda VPC endpoint. The Aurora MySQL network page lists either NAT or a VPC endpoint, and mentions that gateway endpoints can also be used with S3. When using a Lambda VPC endpoint with RDS for PostgreSQL, you need to set rds.custom_dns_resolution to 1 (see Section 7).

12. Summary

  • For Aurora PostgreSQL and RDS for PostgreSQL, the aws_lambda route takes three steps: associating an IAM role with --feature-name Lambda, installing the extension, and granting permissions to the database user (the grant is needed for users other than rds_superuser). For Aurora, the association targets the DB cluster; for RDS, it targets the DB instance.
  • For Aurora MySQL, the Lambda and S3 routes require two steps: associating a role and configuring the cluster parameter with an ARN. The steps in the sources include a reboot of the primary instance. Both steps are necessary, and neither is prioritized.
  • For Aurora MySQL version 3 and version 8.4, grant the database roles AWS_LAMBDA_ACCESS, AWS_LOAD_S3_ACCESS, and AWS_SELECT_S3_ACCESS, and ensure they are activated in the session. The LOAD and SAVE pages state that the administrative user of the DB cluster is granted the S3 role or privilege by default.
  • The default wait for the response of aws_lambda.invoke is 3000 milliseconds. The invocation_type is case-sensitive, and DryRun is only documented on the reference page.
  • For a private database, the pages name a NAT gateway or a VPC endpoint. Among the aws_lambda pages, only the RDS for PostgreSQL page states that rds.custom_dns_resolution must be set to 1 to use the Lambda VPC endpoint.
  • No statement was found in the sources about the signing method, the relationship with statement_timeout, or whether SQL calls are possible with RDS for MySQL and RDS for MariaDB.
  • In the configuration described in this article, calls did not succeed until 59 to about 100 seconds after the Aurora PostgreSQL association status became ACTIVE. After the association was removed, calls still succeeded 36 seconds later (Aurora PostgreSQL) and 50 seconds later (Aurora MySQL). Some of the error messages and error codes differed from those described in the documentation.

13. References



References:
Tech Blog with curated related content

Written by Hidekazu Konishi