Run federated queries on Amazon RDS for PostgreSQL (IAM authentication)
This page describes how to configure Databricks Lakehouse Federation to run federated queries on Amazon RDS for PostgreSQL using AWS Identity and Access Management (IAM) authentication instead of a username and password. Authentication uses a Unity Catalog service credential that references an AWS IAM role. For general PostgreSQL federation setup with username and password, see Run federated queries on PostgreSQL.
IAM authentication for Amazon RDS for PostgreSQL is available on Databricks on AWS only, because it relies on an AWS IAM role referenced by a service credential.
Before you begin
Before you can run federated queries on Amazon RDS for PostgreSQL using IAM authentication, you must meet the following requirements.
Databricks requirements
- A workspace enabled for Unity Catalog.
- Databricks compute that uses Databricks Runtime 18 LTS or above and Standard or Dedicated access mode.
- The
CREATE CONNECTIONprivilege on the Unity Catalog metastore attached to the workspace. - The
CREATE SERVICE CREDENTIALprivilege on the metastore.
AWS requirements
- An Amazon RDS for PostgreSQL instance.
- The ability to create IAM roles and policies.
- Permission to connect to the RDS instance to create database users.
Configure AWS IAM authentication
Complete the following steps in AWS to enable IAM authentication on your RDS for PostgreSQL instance and create the database user, IAM policy, and IAM role that Unity Catalog uses to connect.
Step 1: Enable IAM authentication on the Amazon RDS instance
Create or modify your RDS for PostgreSQL instance to enable IAM database authentication. For instructions, see Enabling and disabling IAM database authentication in the AWS documentation.
Step 2: Create the Amazon RDS database user
Connect to the RDS instance and create a database user that authenticates using IAM. For PostgreSQL, grant the user the rds_iam role:
CREATE USER db_userx;
GRANT rds_iam TO db_userx;
Grant the user the privileges it needs on the databases and tables you want to query. For more information, see Creating a database account using IAM authentication in the AWS documentation.
Step 3: Set up the AWS IAM policy
Create an IAM policy that allows the rds-db:connect action for the database user you created. For example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["rds-db:connect"],
"Resource": ["arn:aws:rds-db:us-west-2:111122223333:dbuser:db-ABCDEFGHIJKL01234/db_userx"]
}
]
}
The resource ARN uses the format arn:aws:rds-db:<region>:<account-id>:dbuser:<DbiResourceId>/<db-user>. The <DbiResourceId> segment must be the RDS resource ID (for example, db-ABCDEFGHIJKL01234), not the DB instance identifier. Using the instance identifier results in an access-denied error at connection time.
To find the resource ID, run:
aws rds describe-db-instances --db-instance-identifier <instance-name> --query 'DBInstances[0].DbiResourceId'
Alternatively, find the resource ID on the Configuration tab of your database instance in the Amazon RDS console.
For more information, see Creating and using an IAM policy for IAM database access in the AWS documentation.
Step 4: Create the AWS IAM role
Create an IAM role that Unity Catalog can assume to authenticate to your database:
-
In the AWS IAM console, go to Roles and click Create role.
-
For Trusted entity type, select Custom trust policy.
-
In the Custom trust policy editor, paste the following policy. This is a placeholder: after you create the service credential in Databricks, you replace it with the trust policy that Databricks generates. The
PrincipalandActionare required; theConditionblock is optional at this stage.JSON{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": ["arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL"]
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "0000"
}
}
}
]
} -
Click Next. On the Add permissions page, select the IAM policy you created in Set up the IAM policy.
-
Click Next, enter a Role name, and click Create role.
-
Note the role's ARN. You provide it when you create the service credential.
For more information about IAM roles with custom trust policies, see Creating a role using custom trust policies in the AWS documentation.
Step 5: Create the Databricks service credential
Create a Unity Catalog service credential that references the IAM role ARN from the previous step. For detailed steps, see Create service credentials.
After you create the service credential, finish configuring the IAM role's trust policy:
- In the Service credential created dialog, copy the entire trust policy shown, then click Done.
- Return to your IAM role in the AWS console, open the Trust relationships tab, and replace the placeholder trust policy with the one you copied. This adds your service credential's external ID and makes the role self-assuming.
Note the name of the service credential. You reference it when you create the connection.
Create a connection
A connection specifies a path and credentials for accessing an external database system. To create a connection, you can use Catalog Explorer or the CREATE CONNECTION SQL command in a Databricks notebook or the Databricks SQL query editor.
You can also use the Databricks REST API or the Databricks CLI to create a connection. See POST /api/2.1/unity-catalog/connections and Unity Catalog commands.
Permissions required: Metastore admin or user with the CREATE CONNECTION privilege.
- Catalog Explorer
- SQL
- In your Databricks workspace, click
Catalog.
- At the top of the Catalog pane, click the
Add icon and select Create a connection from the menu.
- On the Connection basics page of the Set up connection wizard, enter a user-friendly Connection name.
- Select a Connection type of PostgreSQL.
- For Auth type, select Service Credential.
- (Optional) Add a comment.
- Click Next.
- On the Authentication page, enter the following connection properties for your PostgreSQL RDS instance:
- Host: For example,
postgres-demo.lb123.us-west-2.rds.amazonaws.com - Port: For example,
5432 - User: The IAM database user you created. For example,
db_userx - AWS region: The region of the RDS instance. For example,
us-west-2
- Host: For example,
- Click Next.
- On the Connection details page, for Service credential, select the service credential you created in Create the service credential.
- Click Create connection.
- On the Catalog basics page, enter a name for the foreign catalog. A foreign catalog mirrors a database in an external data system so that you can query and manage access to data in that database using Databricks and Unity Catalog.
- (Optional) Click Test connection to confirm that it works.
- Click Create catalog.
- On the Access page, select the workspaces in which users can access the catalog you created. You can select All workspaces have access, or click Assign to workspaces, select the workspaces, and then click Assign.
- Change the Owner who can manage access to all objects in the catalog. Start typing a principal in the text box, and then click the principal in the returned results.
- Grant Privileges on the catalog. Click Grant:
- Specify the Principals who will have access to objects in the catalog. Start typing a principal in the text box, and then click the principal in the returned results.
- Select the Privilege presets to grant to each principal. All account users are granted
BROWSEby default.- Select Data Reader from the drop-down menu to grant
readprivileges on objects in the catalog. - Select Data Editor from the drop-down menu to grant
readandmodifyprivileges on objects in the catalog. - Manually select the privileges to grant.
- Select Data Reader from the drop-down menu to grant
- Click Grant.
- Click Next.
- On the Metadata page, specify tags key-value pairs. For more information, see Apply tags to Unity Catalog securable objects.
- (Optional) Add a comment.
- Click Save.
Run the following command in a notebook or the Databricks SQL query editor. Providing the credential option instead of a password creates an IAM-authenticated connection.
CREATE CONNECTION <connection-name> TYPE postgresql
OPTIONS (
host '<hostname>',
port '<port>',
user '<iam-user>',
aws_region '<region>',
credential '<service-credential-name>'
);
Create a foreign catalog
If you use the UI to create a connection to the data source, foreign catalog creation is included and you can skip this step.
If you use the UI to create a connection to the data source, foreign catalog creation is included and you can skip this step.
A foreign catalog mirrors a database in an external data system so that you can query and manage access to data in that database using Databricks and Unity Catalog. To create a foreign catalog, you use a connection to the data source that has already been defined.
To create a foreign catalog, you can use Catalog Explorer or the CREATE FOREIGN CATALOG SQL command in a Databricks notebook or the SQL query editor. You can also use the Databricks REST API or the Databricks CLI to create a catalog. See POST /api/2.1/unity-catalog/catalogs and Unity Catalog commands.
Permissions required: CREATE CATALOG permission on the metastore and either ownership of the connection or the CREATE FOREIGN CATALOG privilege on the connection.
- Catalog Explorer
- SQL
-
In your Databricks workspace, click
Catalog to open Catalog Explorer.
-
At the top of the Catalog pane, click the
Add icon and select Add a catalog from the menu.
Alternatively, from the Quick access page, click the Catalogs button, and then click the Create catalog button.
-
Follow the instructions for creating foreign catalogs in Create catalogs.
Run the following SQL command in a notebook or SQL query editor. Items in brackets are optional. Replace the placeholder values:
<catalog-name>: Name for the catalog in Databricks.<connection-name>: The connection object that specifies the data source, path, and access credentials.<database-name>: Name of the database you want to mirror as a catalog in Databricks.
CREATE FOREIGN CATALOG [IF NOT EXISTS] <catalog-name> USING CONNECTION <connection-name>
OPTIONS (database '<database-name>');