Info

IAM database authentication provides secure, token-based access to your RDS cluster without storing database passwords.


Step 1: Enable IAM Authentication on the RDS Cluster

The IAM authentication is controlled by the iam_database_authentication_enabled parameter in the module configuration.

module "aurora_cluster" {
  # ... other configuration ...
 
  iam_database_authentication_enabled = true
 
  # ... rest of configuration ...
}

Then apply:

terragrunt apply

Step 2: Create IAM Policy for Database Access

Create an IAM policy that allows users/services to connect to the RDS cluster.

Policy Structure

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["rds-db:connect"],
      "Resource": [
        "arn:aws:rds-db:<region>:<account-id>:dbuser:<dbi-resource-id>/<db-user-name>"
      ]
    }
  ]
}

Resource ARN Format

  • <region> — Is the AWS Region for the DB instance (e.g. eu-west-1).
  • <account-id> — Is the AWS account number for the DB instance.
  • <dbi-resource-id> — Is the identifier for the DB instance. This identifier is unique to an AWS Region and never changes. In the example policy, the identifier is db-ABCDEFGHIJKL01234. To find a DB instance resource ID in the AWS Management Console for Amazon RDS, choose the DB instance to see its details. Then choose the Configuration tab. The Resource ID is shown in the Configuration section.
  • <db-user-name> — Is the name of the database account to associate with IAM authentication.

Terraform Example

data "aws_iam_policy_document" "rds_iam" {
  statement {
    effect  = "Allow"
    actions = ["rds-db:connect"]
 
    resources = [
      "arn:aws:rds-db:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:dbuser:${module.aurora_backoffice.cluster_resource_id}/${local.iam_db_user}"
    ]
  }
}
 
resource "aws_iam_policy" "rds_iam_auth_policy" {
  name   = "rds-iam-auth"
  policy = data.aws_iam_policy_document.rds_iam.json
}

Note

The ARN is built dynamically using data.aws_region, data.aws_caller_identity, and the cluster’s cluster_resource_id output — no hardcoded values needed.

JSON Example (for reference)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["rds-db:connect"],
      "Resource": [
        "arn:aws:rds-db:us-east-2:123456789012:dbuser:db-ABCDEFGHIJKL01234/jane_doe",
        "arn:aws:rds-db:us-east-2:123456789012:dbuser:db-ABCDEFGHIJKL01234/mary_roe"
      ]
    }
  ]
}

Step 3: Create IAM Database User

Create an IAM database user that maps to your IAM role or user. Connect to the database and run:

CREATE USER <db-user-name> WITH LOGIN;
 
GRANT rds_iam TO <db-user-name>;
 
GRANT ALL PRIVILEGES ON DATABASE <database-name> TO <db-user-name>;
 
GRANT SELECT, INSERT, UPDATE, DELETE
  ON ALL TABLES IN SCHEMA public
  TO <db-user-name>;

Warning

The rds_iam grant is required — it tells RDS to authenticate this user via IAM tokens instead of a password.


Step 4: Generate Authentication Token

Generate an authentication token for the IAM user:

# Generate a database authentication token (valid for 15 minutes)
TOKEN=$(aws rds generate-db-auth-token \
  --hostname <rds-endpoint> \
  --port <port> \
  --region <region> \
  --username <db-user-name>)
 
echo $TOKEN

Note

The token is valid for 15 minutes but the database connection itself can persist beyond that once established.


Step 5: Connect from Kubernetes

To connect to the database using IAM authentication from a Kubernetes pod:

5.1 — Create IAM Role with the policy from Step 2

Ensure the role has a trust policy allowing EKS Pod Identity / IRSA to assume it.

5.2 — Create a Kubernetes Service Account

apiVersion: v1
kind: ServiceAccount
metadata:
  name: <app-service-account>
  namespace: <namespace>

5.3 — Bind Pod Identity to the IAM Role

Associate the service account with the IAM role via EKS Pod Identity or IRSA so the pod can call rds generate-db-auth-token.