AWS Database Blog

Resilient IAM database authentication with Amazon Aurora Global Database writer endpoint

When you run Amazon Aurora Global Database across multiple AWS Regions for resilience, a cross-Region switchover or failover promotes a secondary Region to primary. If your application uses IAM database authentication for passwordless, token-based access, that promotion creates two problems for a connection:

Problem 1: The signing Region changes. Your Signature Version 4 (SigV4) token must be signed for a specific Region. After a failover, the primary is in a different Region, so a token signed for the old Region no longer works.

Problem 2: The primary or writer cluster resource ID changes. Your rds-db:connect permission authorizes a specific cluster resource ID. The newly promoted primary is a different cluster with a different resource ID, so the old authorization no longer applies.

Routing, notably, is not on that list. The Amazon Aurora Global Database writer endpoint is a single, stable DNS name for the whole Global cluster. Aurora automatically re-points it to the current writer, so your connection string never changes across a failover.

In this post, I show how to compose the Aurora Global Database writer endpoint with IAM authentication so that passwordless access survives a cross-Region switchover or failover with no configuration changes. I sign the token for the primary Region discovered dynamically at connection time, which solves Problem 1. I scope the rds-db:connect permission to every Regional cluster resource ID up front, which solves Problem 2. And I connect through the Global Database writer endpoint so that routing is handled automatically. I then run a planned switchover or failover to prove the pattern holds using the same endpoint, policy, and commands.

Overview

The key insight is that the Global writer endpoint handles routing, and AWS Identity and Access Management (IAM) handles authentication. These two concerns operate independently. You make three design choices so that they work together across a failover:

  1. Connect through the Global writer endpoint. The DNS name stays the same. Aurora automatically points it to the newly promoted primary, so your connection string never has to change.
  2. Sign the token for the current primary Region, discovered dynamically. The generate-db-auth-token command builds the token from four inputs: hostname, port, Region, and username. You keep the hostname pointed at the Global Database writer endpoint but set Region to whichever Region is currently the primary. Your application discovers that Region at connection time by running describe-global-clusters. The writer’s ARN tells you which Region it’s in.
  3. Scope the rds-db:connect permission to every cluster that can become primary. IAM database authentication doesn’t currently support policy condition keys. The least-privilege approach is to list the DbClusterResourceId of each Regional cluster in the IAM policy Resource list. Then authorization succeeds through the same endpoint no matter which cluster is the writer, with no policy edits on failover.

The rest of this post puts these three choices into practice with an AWS Command Line Interface (AWS CLI) walkthrough you can follow along with. It includes a switchover or failover test that confirms everything works without any configuration changes. The walkthrough uses an Amazon Aurora Global Database with a single secondary Region. Where relevant, I’ve included the equivalent commands for both the Amazon Aurora PostgreSQL and Aurora MySQL engines.

Prerequisites

  1. The AWS CLI installed and configured.
  2. An IAM principal (an IAM user or an assumed role) with the permissions needed to run the commands in this post — specifically rds:DescribeDBClusters, rds:ModifyDBCluster, rds:DescribeGlobalClusters, rds:SwitchoverGlobalCluster, iam:CreatePolicy, rds:FailoverGlobalCluster, iam:AttachRolePolicy, iam:DetachRolePolicy, and iam:DeletePolicy.
  3. An Aurora Global Database with two Regions. If you don’t already have one, follow Getting started with Amazon Aurora global databases to either create a new Global Database or add a secondary Region to an existing Aurora cluster.
  4. Basic understanding of IAM authentication with Aurora.
  5. A psql client (PostgreSQL) or mysql client (MySQL) to connect to the Aurora cluster.
  6. Cross-Region network connectivity from your client to both Regional clusters so you can connect after the writer moves.
  7. A test/staging environment where you can perform the steps described in this post.

Step 1: Configure the variables

In this step, you define the shell variables that the rest of the walkthrough reuses, such as the primary and secondary Region names and your account ID. Run every AWS CLI command and set shell variables in this post from a Bash shell (Linux, macOS Terminal, or Git Bash on Windows) with the AWS CLI configured. You can run these commands as any IAM principal that has the permissions listed in Prerequisites.

1.1 Get the Global Database identifier

Run the following command to capture the Global Database identifier (also called the global cluster identifier):

aws rds describe-global-clusters \
--query "GlobalClusters[].GlobalClusterIdentifier" \
--output text

If the command returns a single identifier, capture it directly into a variable named GDI (Global Database identifier):

GDI=$(aws rds describe-global-clusters \
--query "GlobalClusters[].GlobalClusterIdentifier" \
--output text)
echo "Global Database Identifier=$GDI"

If you have multiple Aurora Global Database setups, the describe-global-clusters command returns multiple identifiers. Set GDI to the one you want to use:

GDI=<GLOBAL_DATABASE_IDENTIFIER>

1.2 Capture cluster, Region, and AWS account ID details

Here, you dynamically derive the DB cluster IDs, the Regions of both the primary and secondary clusters, and the AWS account ID. You store each in its own variable for reuse later in the post. This walkthrough assumes you already have an Aurora Global Database spanning two Regions. If you have multiple secondary Regions, adjust the commands as needed or set these variables manually.

# Getting ARN of the writer (primary) cluster:
PRIMARY_ARN=$(aws rds describe-global-clusters \
--global-cluster-identifier "$GDI" \
--query "GlobalClusters[0].GlobalClusterMembers[?IsWriter==\`true\`].DBClusterArn|[0]" \
--output text)

# Getting ARN of the secondary (reader) cluster:
SECONDARY_ARN=$(aws rds describe-global-clusters \
--global-cluster-identifier "$GDI" \
--query "GlobalClusters[0].GlobalClusterMembers[?IsWriter==\`false\`].DBClusterArn|[0]" \
--output text)

# Deriving the DB cluster IDs, the Regions and the AWS account ID:
# Aurora cluster ARN format: arn:aws:rds:<region>:<account>:cluster:<cluster-id>
# Field 4 = region, field 5 = account id, field 7 = cluster id
PRIMARY_REGION=$(echo "$PRIMARY_ARN" | cut -d: -f4)
SECONDARY_REGION=$(echo "$SECONDARY_ARN" | cut -d: -f4)
ACCOUNT_ID=$(echo "$PRIMARY_ARN" | cut -d: -f5)
PRIMARY_CLUSTER_ID=$(echo "$PRIMARY_ARN" | cut -d: -f7)
SECONDARY_CLUSTER_ID=$(echo "$SECONDARY_ARN" | cut -d: -f7)
echo "PRIMARY_REGION=$PRIMARY_REGION"
echo "SECONDARY_REGION=$SECONDARY_REGION"
echo "ACCOUNT_ID=$ACCOUNT_ID"
echo "PRIMARY_CLUSTER_ID=$PRIMARY_CLUSTER_ID"
echo "SECONDARY_CLUSTER_ID=$SECONDARY_CLUSTER_ID"

1.3 Confirm (or enable) IAM authentication on both clusters

This walkthrough focuses on the IAM authentication configuration that makes the deployment failover-resilient. IAM database authentication is managed per DB cluster and must be enabled on every Regional cluster, so a connection authenticates no matter which Region is primary.

aws rds describe-db-clusters \
--db-cluster-identifier "$PRIMARY_CLUSTER_ID" \
--query 'DBClusters[0].IAMDatabaseAuthenticationEnabled' --output text \
--region "$PRIMARY_REGION"

If it returns false, enable IAM authentication on the cluster in the primary Region:

aws rds modify-db-cluster \
--db-cluster-identifier "$PRIMARY_CLUSTER_ID" \
--enable-iam-database-authentication \
--apply-immediately \
--region "$PRIMARY_REGION"

Repeat the preceding step for the secondary cluster with its identifier and Region:

aws rds describe-db-clusters \
--db-cluster-identifier "$SECONDARY_CLUSTER_ID" \
--query 'DBClusters[0].IAMDatabaseAuthenticationEnabled' --output text \
--region "$SECONDARY_REGION"

aws rds modify-db-cluster \
--db-cluster-identifier "$SECONDARY_CLUSTER_ID" \
--enable-iam-database-authentication \
--apply-immediately \
--region "$SECONDARY_REGION"

1.4 Record both cluster resource IDs and endpoints

You need the DbClusterResourceId and endpoint of each Regional cluster in the following steps. Capture them for both Regions using the following commands:

# Primary: resource ID + writer endpoint in one call
read -r PRIMARY_RESOURCE_ID PRIMARY_CLUSTER_ENDPOINT < <(aws rds describe-db-clusters \
--db-cluster-identifier "$PRIMARY_CLUSTER_ID" \
--query 'DBClusters[0].[DbClusterResourceId, Endpoint]' \
--output text \
--region "$PRIMARY_REGION")

# Secondary: resource ID + reader endpoint in one call
read -r SECONDARY_RESOURCE_ID SECONDARY_CLUSTER_ENDPOINT < <(aws rds describe-db-clusters \
--db-cluster-identifier "$SECONDARY_CLUSTER_ID" \
--query 'DBClusters[0].[DbClusterResourceId, ReaderEndpoint]' \
--output text \
--region "$SECONDARY_REGION")

echo "PRIMARY_RESOURCE_ID=$PRIMARY_RESOURCE_ID"
echo "PRIMARY_CLUSTER_ENDPOINT=$PRIMARY_CLUSTER_ENDPOINT"
echo "SECONDARY_RESOURCE_ID=$SECONDARY_RESOURCE_ID"
echo "SECONDARY_CLUSTER_ENDPOINT=$SECONDARY_CLUSTER_ENDPOINT"

With --output as text and a multi-field query like [DbClusterResourceId, Endpoint], the two values come back tab-separated on one line, and read splits them into the two variables.

Step 2: Create the IAM policy scoped to both clusters

In this step, define the database user and create the IAM policy with the required permission.

2.1 Set the database user variable

First, store the database user name, app_user, in a shell variable named db_user. You create this user inside the database of the primary cluster later in Step 3.

db_user=app_user

2.2 Create the policy

The following command writes the policy document to a JSON file:

cat > rds-connect-policy.json <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "rds-db:connect",
            "Resource": [
                "arn:aws:rds-db:${PRIMARY_REGION}:${ACCOUNT_ID}:dbuser:$PRIMARY_RESOURCE_ID/$db_user",
                "arn:aws:rds-db:${SECONDARY_REGION}:${ACCOUNT_ID}:dbuser:$SECONDARY_RESOURCE_ID/$db_user"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "rds:DescribeGlobalClusters",
            "Resource": "arn:aws:rds::${ACCOUNT_ID}:global-cluster:$GDI"
        }
    ]
}
EOF

The policy contains two statements:

  • The first statement grants rds-db:connect, the minimum permission required to authenticate to the database with IAM authentication. Its Resource list includes one ARN for each Regional cluster, built from that cluster’s resource ID (from Step 1.4) and the database user (app_user). Because the policy covers both Regions, IAM authentication keeps working after a switchover or failover, and you don’t need to change the policy.
  • The second statement grants rds:DescribeGlobalClusters, scoped to your global cluster. Your application needs this permission to discover the current primary Region at connection time, as shown in Step 4 and Step 5. Without it, the discovery call fails with an AccessDenied error.

The following command uses this JSON file to create a new IAM policy and returns the policy ARN. For more information, see Creating and using an IAM policy for IAM database access.

# putting policy name in a variable
policy_name=aurora-gdb-iam-connect-app_user

# creating the policy
aws iam create-policy \
--policy-name $policy_name \
--policy-document file://rds-connect-policy.json

2.3 Attach the policy

Attach the returned policy ARN to the IAM role your application uses to connect to Aurora, such as its Amazon Elastic Compute Cloud (Amazon EC2) instance role or AWS Lambda execution role. Replace <IAM_ROLE> with that role’s name.

aws iam attach-role-policy \
--role-name <IAM_ROLE> \
--policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/${policy_name}

Step 3: Create the database user mapped to IAM

In this step, create a database user called app_user that matches the IAM policy created in Step 2.2.

Aurora PostgreSQL

First, connect to the primary cluster as the master user using the following command, and enter the master password when prompted:

psql "host=$PRIMARY_CLUSTER_ENDPOINT port=5432 sslmode=verify-full \
sslrootcert=global-bundle.pem dbname=demodb user=masteruser"

Modify the following parameters as needed:

sslrootcert=global-bundle.pem: AWS enforces SSL/TLS connections for IAM-based logins to make sure that these sensitive authentication tokens are safely encrypted while crossing the network. Download this file from Download certificate bundles for Amazon RDS.

dbname=demodb: I use a demodb database. If you already have an Aurora cluster, use your existing database name. There’s no need to create a new one for IAM authentication. If you’re setting this up on a brand-new cluster and don’t have an application database yet, you can create one first.

user=masteruser: Replace masteruser with the master user of your Aurora cluster.

After you connect to demodb on the primary cluster, create the IAM-mapped user and grant the necessary permissions. The user replicates automatically to the secondary cluster.

CREATE USER app_user;
GRANT rds_iam TO app_user;
GRANT CONNECT ON DATABASE demodb TO app_user;

(Optional) Verify that the user replicated to the secondary cluster (connect as the master user, read-only):

psql "host=$SECONDARY_CLUSTER_ENDPOINT port=5432 sslmode=verify-full \
sslrootcert=global-bundle.pem dbname=demodb user=masteruser" \
-c "SELECT rolname FROM pg_roles WHERE rolname = 'app_user';"

Aurora MySQL

If you are using the MariaDB client, use the following command:

mysql --host=$PRIMARY_CLUSTER_ENDPOINT --port=3306 --user=masteruser \
--ssl-ca=global-bundle.pem --ssl-verify-server-cert -p

If you are using the Oracle MySQL client, use the following command:

mysql --host=$PRIMARY_CLUSTER_ENDPOINT --port=3306 --user=masteruser \
--ssl-ca=global-bundle.pem --ssl-mode=VERIFY_IDENTITY -p

Enter the master password when prompted, then run:

CREATE USER 'app_user' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
GRANT SELECT ON demodb.* TO 'app_user'@'%';

(Optional) Verify that the user replicated to the secondary cluster:

If you are using the MariaDB client:

mysql --host=$SECONDARY_CLUSTER_ENDPOINT --port=3306 --user=masteruser \
--ssl-ca=global-bundle.pem --ssl-verify-server-cert -p \
-e "SELECT User, Host FROM mysql.user WHERE User = 'app_user';"

If you are using the Oracle MySQL client:

mysql --host=$SECONDARY_CLUSTER_ENDPOINT --port=3306 --user=masteruser \
--ssl-ca=global-bundle.pem --ssl-mode=VERIFY_IDENTITY -p \
-e "SELECT User, Host FROM mysql.user WHERE User = 'app_user';"

Step 4: Connect through the Global Database writer endpoint

First, get the Aurora Global Database writer endpoint by running the following command:

GW_ENDPOINT=$(aws rds describe-global-clusters \
--global-cluster-identifier "$GDI" \
--query "GlobalClusters[0].Endpoint" --output text)
echo "Global writer endpoint: $GW_ENDPOINT"

# Confirm the primary Region:
echo "Current primary Region: $PRIMARY_REGION"

Generate an IAM authentication token using the Global writer endpoint as the hostname and the current primary as the signing Region, then connect over TLS.

Aurora PostgreSQL:

PGPASSWORD="$(aws rds generate-db-auth-token \
--hostname "$GW_ENDPOINT" --port 5432 \
--region "$PRIMARY_REGION" --username "$db_user")"

psql "host=$GW_ENDPOINT port=5432 sslmode=verify-full \
sslrootcert=global-bundle.pem dbname=demodb user="$db_user" \
password=$PGPASSWORD" \
-c "SELECT current_user, aurora_db_instance_identifier() AS instance_name, CASE WHEN pg_is_in_recovery() THEN 'Secondary (Reader)' ELSE 'Primary (Writer)' END AS region_role;"

The output looks similar to the following:

current_user | instance_name          | region_role
-------------+------------------------+------------------
app_user     | apg-primary-instance-1 | Primary (Writer)

This query returns three columns that together prove who you connected as and which instance/role you landed on:

  1. current_user: The database user you’re authenticated as. It confirms you connected as app_user (through the IAM token, not a password).
  2. instance_name: The name of the specific Aurora DB instance you’re connected to. This tells you exactly which instance in which Region served your connection. In the preceding example, it’s apg-primary-instance-1.
  3. region_role (the CASE expression): Uses pg_is_in_recovery() to determine whether this instance is a writer or a reader. pg_is_in_recovery() returns true on a reader/standby, since it’s still applying replication, so the instance is labeled Secondary (Reader). On the writer/primary it returns false, so the instance is labeled Primary (Writer).

Aurora MySQL:

MYSQLPASSWORD="$(aws rds generate-db-auth-token \
--hostname "$GW_ENDPOINT" --port 3306 \
--region "$PRIMARY_REGION" --username "$db_user")"

mysql --host="$GW_ENDPOINT" --port=3306 --user="$db_user" \
--enable-cleartext-plugin \
--ssl-ca=global-bundle.pem \
--password="$MYSQLPASSWORD" \
-e "SELECT current_user(),@@aurora_server_id AS server_id,
IF(@@innodb_read_only = 0, 'Primary (Writer)', 'Secondary (Reader)') AS region_role;"

This query returns the following three columns:

  1. current_user(): The database user you’re authenticated as.
  2. server_id (@@aurora_server_id): The name of the specific Aurora DB instance you’re connected to. This tells you exactly which instance in which Region served your connection.
  3. region_role (the IF expression): Uses @@innodb_read_only to determine whether this instance is a writer or a reader. @@innodb_read_only is 1 on a reader/standby, since it only accepts read traffic, so the instance is labeled Secondary (Reader). On the writer/primary it is 0, so the instance is labeled Primary (Writer).

Step 5: Test database resilience

Promoting a secondary DB cluster to be primary can happen in two ways: a switchover or a failover. In this step, you test whichever option you choose, using the same Global writer endpoint, IAM policy, and connection commands from Step 4. Run only one of the following options during your test:

Option 1: Switchover

Use a switchover for planned operational procedures, such as maintenance or disaster recovery drills, when all Aurora clusters and the services they interact with are healthy. Trigger a planned switchover to the secondary Region:

aws rds switchover-global-cluster \
--global-cluster-identifier "$GDI" \
--target-db-cluster-identifier arn:aws:rds:${SECONDARY_REGION}:${ACCOUNT_ID}:cluster:${SECONDARY_CLUSTER_ID} \
--region "$PRIMARY_REGION"

Option 2: Managed failover

Use a failover to recover from an unplanned event, such as a Regional impairment. Unlike a switchover, a failover doesn’t wait for replication to catch up. Because Aurora replicates asynchronously, it can lose writes that hadn’t reached the secondary. Managed failover requires compatible engine versions on the primary and secondary clusters. If your database versions are incompatible, see Performing manual failovers for Aurora global databases.

Run this step only in a test environment, because it can result in data loss:

aws rds failover-global-cluster \
--region "$SECONDARY_REGION" \
--global-cluster-identifier "$GDI" \
--target-db-cluster-identifier "$SECONDARY_ARN" \
--allow-data-loss

Wait for the switchover or failover to complete and for the global cluster status to return to Available.

Rediscovery of the Region

Run the same discovery as before, using the same Global writer endpoint, IAM policy, and commands. The only difference is that discovery now returns the promoted primary, so the token is signed for that Region automatically. During a Regional impairment, the discovery call must reach a healthy Region, so pass --region with any healthy member Region to the describe-global-clusters command. Without --region, the command uses the client’s default Region. If that Region is the impaired former primary, discovery fails and the application can’t sign a token, even though the writer endpoint has already moved.

# Getting ARN of the new writer (primary) cluster:
PRIMARY_ARN=$(aws rds describe-global-clusters \
--global-cluster-identifier "$GDI" \
--region "$SECONDARY_REGION" \
--query "GlobalClusters[0].GlobalClusterMembers[?IsWriter==\`true\`].DBClusterArn|[0]" \
--output text)

# Aurora cluster ARN format: arn:aws:rds:<region>:<account>:cluster:<cluster-id>
# Field 4 = region
PRIMARY_REGION=$(echo "$PRIMARY_ARN" | cut -d: -f4)

GW_ENDPOINT=$(aws rds describe-global-clusters \
--global-cluster-identifier "$GDI" \
--region "$SECONDARY_REGION" \
--query "GlobalClusters[0].Endpoint" --output text)

echo "Current primary Region: $PRIMARY_REGION"
echo "Global writer endpoint: $GW_ENDPOINT"

From the preceding command you will see that the primary Region is now the Region that was previously the secondary.

Generate a new IAM authentication token with the same command as before.

Aurora PostgreSQL:

PGPASSWORD="$(aws rds generate-db-auth-token \
--hostname "$GW_ENDPOINT" --port 5432 \
--region "$PRIMARY_REGION" --username "$db_user")"

psql "host=$GW_ENDPOINT port=5432 sslmode=verify-full \
sslrootcert=global-bundle.pem dbname=demodb user="$db_user" \
password=$PGPASSWORD" \
-c "SELECT current_user, aurora_db_instance_identifier() AS instance_name, CASE WHEN pg_is_in_recovery() THEN 'Secondary (Reader)' ELSE 'Primary (Writer)' END AS region_role;"

The output looks like the following:

current_user | instance_name                     | region_role
-------------+-----------------------------------+------------------
app_user     | test-global-instance-1-us-east-2c | Primary (Writer)

After the switchover or failover, running the same query against the same endpoint returns a different instance name (in my example, it’s test-global-instance-1-us-east-2c), one in the other Region. The role still shows as Primary (Writer). This demonstrates that the endpoint re-pointed to the current primary Region on its own, and IAM authentication kept working, with no changes on your side.

Aurora MySQL:

MYSQLPASSWORD="$(aws rds generate-db-auth-token \
--hostname "$GW_ENDPOINT" --port 3306 \
--region "$PRIMARY_REGION" --username "$db_user")"

mysql --host="$GW_ENDPOINT" --port=3306 --user="$db_user" \
--enable-cleartext-plugin \
--ssl-ca=global-bundle.pem \
--password="$MYSQLPASSWORD" \
-e "SELECT current_user(),@@aurora_server_id AS server_id,
IF(@@innodb_read_only = 0, 'Primary (Writer)', 'Secondary (Reader)') AS region_role;"

This proves the pattern works. With a stable endpoint, a dynamically discovered signing Region, and a policy that already covers both clusters, you change nothing. Passwordless authentication survives the switchover or failover.

With and without the Amazon Aurora Global Database writer endpoint

Without the Aurora Global writer endpoint, you connect to a Regional cluster endpoint (for example, my-cluster.cluster-xxxx.us-east-1.rds.amazonaws.com). After a switchover or failover, that endpoint becomes read-only. Your application must then detect the promotion and re-point to the new primary Region’s cluster endpoint, typically through custom discovery, an Amazon Route 53 CNAME you update, or a redeploy. IAM authentication still needs the correct signing Region either way. The Global Database writer endpoint removes the routing half of the problem by giving you one stable name, managed by Aurora, for both routing and your SigV4 hostname.

Best practices

  • Enforce TLS: Always connect with sslmode=verify-full and the RDS global bundle (--ssl-ca for MySQL). Non-TLS connections are rejected.
  • Enumerate every cluster ARN: IAM database authentication doesn’t support policy condition keys, so list the rds-db:connect resource ARN for each Regional cluster’s DbClusterResourceId. Add the new cluster’s ARN whenever you attach a secondary Region to the Global Database.
  • Discover the signing Region dynamically, and cache it: Don’t hardcode --region. Read the current primary Region from describe-global-clusters, cache it in memory, and refresh it only when authentication fails or the connection drops. This control plane call is subject to throttling, so calling it for every connection can throttle your application, especially during a connection storm after a failover.
  • Handle token lifetime and DNS caching: Authentication tokens are valid for 15 minutes, so generate a fresh one per connection attempt. For details, see IAM database authentication. Also, respect the writer endpoint’s DNS TTL instead of caching resolved IPs indefinitely, so clients pick up the re-pointing promptly.
  • Keep the Regions symmetric: Use non-overlapping virtual private cloud (VPC) CIDRs for cross-Region connectivity and keep cluster parameter groups at parity so behavior is identical after a switchover or failover.
  • Use the AWS Advanced Drivers where available: Most production applications connect through a database driver, not the AWS CLI. The AWS Advanced JDBC Wrapper and the AWS Advanced Python Wrapper wrap the standard PostgreSQL and MySQL drivers and add an IAM authentication plugin. The plugin generates and refreshes authentication tokens for you. The JDBC wrapper also includes Aurora Global Database support with a Global Database failover plugin that reconnects your application when the primary Region changes. If a wrapper is available for your language and driver, use it rather than building this logic yourself. For Java applications, see Unlock Amazon Aurora’s Advanced Features with Standard JDBC Driver using AWS Advanced JDBC Wrapper.

Clean up

This walkthrough added an IAM policy and an IAM-mapped database user. If you no longer need them, remove them after you finish the walkthrough.

Remove the IAM policy (detach from any roles/users first):

# Detach the policy from the IAM role first
aws iam detach-role-policy \
--role-name <IAM_ROLE> \
--policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/${policy_name}

aws iam delete-policy \
--policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/${policy_name}

For Aurora PostgreSQL, connect to the primary cluster, revoke the database privilege, and drop the IAM-mapped user:

REVOKE CONNECT ON DATABASE demodb FROM app_user;
DROP USER app_user;

For Aurora MySQL, run the following command on the primary cluster:

DROP USER 'app_user'@'%';

If you created an Aurora Global Database to follow this post, delete it using the steps in Deleting an Amazon Aurora global database.

Conclusion

In this post, I showed how the Amazon Aurora Global Database writer endpoint and IAM database authentication compose into a passwordless, failover-resilient access pattern. The Global Database writer endpoint handles routing through a stable DNS name that Aurora re-points automatically. IAM handles authentication independently. By connecting through the Global Database writer endpoint, signing the token for the dynamically discovered primary Region, and scoping the rds-db:connect policy to every Regional cluster resource ID, your application keeps authenticating across a cross-Region switchover or failover. It requires no configuration changes. To get started, work through the walkthrough in a test account, then run the switchover to see the pattern hold. For more details, see Amazon Aurora Global Database, IAM database authentication, Diving deep into the new Amazon Aurora Global Database writer endpoint, and Using switchover or failover in Amazon Aurora Global Database.

 


About the author

Raunak Gupta

Raunak Gupta

Raunak is a Sr. Database Solution Architect at AWS. He has been with AWS for more than six years and is also an Amazon Aurora and RDS subject matter expert. With over 18 years of professional experience, he provides technical assistance on database operational performance and database best practices to enterprise customers.