AW

Manages AWS Aurora configurations, including Serverless v2, RDS Proxy, and Data API. Ensures efficient connection management for cloud databases.

Install

mkdir -p .claude/skills/aws-aurora && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/5669" && unzip -o skill.zip -d .claude/skills/aws-aurora && rm skill.zip

Installs to .claude/skills/aws-aurora

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

AWS Aurora Serverless v2, RDS Proxy, Data API, connection pooling
65 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Configure Aurora Serverless v2 scaling
  • Implement RDS Proxy for connection pooling
  • Enable Data API for HTTP-based access
  • Manage IAM database authentication
  • Monitor database performance metrics

How it works

It provides patterns for serverless database interaction by abstracting connection management through RDS Proxy or Data API.

Inputs & outputs

You give it
Database query or configuration request
You get back
Database connection or execution result

When to use aws-aurora

  • Configure Aurora Serverless v2 scaling
  • Set up RDS Proxy for connection pooling
  • Implement Data API for serverless database access
  • Optimize RDS connection strategies

About this skill

AWS Aurora Skill

Amazon Aurora is a MySQL/PostgreSQL-compatible relational database with serverless scaling, high availability, and enterprise features.

Sources: Aurora Docs | Serverless v2 | RDS Proxy


Core Principle

Use RDS Proxy for serverless, Data API for simplicity, connection pooling always.

Aurora excels at ACID-compliant workloads. For serverless architectures (Lambda), always use RDS Proxy or Data API to handle connection management. Never open raw connections from Lambda functions.


Aurora Options

OptionBest For
Aurora Serverless v2Variable workloads, auto-scaling (0.5-128 ACUs)
Aurora ProvisionedPredictable workloads, maximum performance
Aurora GlobalMulti-region, disaster recovery
Data APIServerless without VPC, simple HTTP access
RDS ProxyConnection pooling for Lambda, high concurrency

Connection Strategies

Strategy 1: RDS Proxy (Recommended for Lambda)

Lambda → RDS Proxy → Aurora
         (pool)
  • Connection pooling and reuse
  • Automatic failover handling
  • IAM authentication support
  • Works with existing SQL clients

Strategy 2: Data API (Simplest for Serverless)

Lambda → Data API (HTTP) → Aurora
  • No VPC required
  • No connection management
  • Higher latency per query
  • Limited to Aurora Serverless

Strategy 3: Direct Connection (Not for Lambda)

App Server → Aurora
(persistent connection)
  • Only for long-running servers (ECS, EC2)
  • Manage connection pool yourself
  • Not suitable for serverless

RDS Proxy Setup

Create Proxy (AWS Console/CDK)

// CDK example
import * as rds from 'aws-cdk-lib/aws-rds';

const proxy = new rds.DatabaseProxy(this, 'Proxy', {
  proxyTarget: rds.ProxyTarget.fromCluster(cluster),
  secrets: [cluster.secret!],
  vpc,
  securityGroups: [proxySecurityGroup],
  requireTLS: true,
  idleClientTimeout: cdk.Duration.minutes(30),
  maxConnectionsPercent: 90,
  maxIdleConnectionsPercent: 10,
  borrowTimeout: cdk.Duration.seconds(30)
});

Connect via Proxy (TypeScript/Node.js)

// lib/db.ts
import { Pool } from 'pg';
import { Signer } from '@aws-sdk/rds-signer';

const signer = new Signer({
  hostname: process.env.RDS_PROXY_ENDPOINT!,
  port: 5432,
  username: process.env.DB_USER!,
  region: process.env.AWS_REGION!
});

// IAM authentication
async function getPool(): Promise<Pool> {
  const token = await signer.getAuthToken();

  return new Pool({
    host: process.env.RDS_PROXY_ENDPOINT,
    port: 5432,
    database: process.env.DB_NAME,
    user: process.env.DB_USER,
    password: token,
    ssl: { rejectUnauthorized: true },
    max: 1,  // Single connection for Lambda
    idleTimeoutMillis: 120000,
    connectionTimeoutMillis: 10000
  });
}

// Usage in Lambda
let pool: Pool | null = null;

export async function handler(event: any) {
  if (!pool) {
    pool = await getPool();
  }

  const result = await pool.query('SELECT * FROM users WHERE id = $1', [event.userId]);
  return result.rows[0];
}

Proxy Configuration Best Practices

# Key settings for Lambda workloads
MaxConnectionsPercent: 90        # Use most of DB connections
MaxIdleConnectionsPercent: 10    # Keep some idle for bursts
ConnectionBorrowTimeout: 30s     # Wait for available connection
IdleClientTimeout: 30min         # Close idle proxy connections

# Monitor these CloudWatch metrics:
# - DatabaseConnectionsCurrentlyBorrowed
# - DatabaseConnectionsCurrentlySessionPinned
# - QueryDatabaseResponseLatency

Data API (HTTP-based)

Enable Data API

# Must be Aurora Serverless
aws rds modify-db-cluster \
  --db-cluster-identifier my-cluster \
  --enable-http-endpoint

TypeScript with Data API Client v2

npm install data-api-client
// lib/db.ts
import DataAPIClient from 'data-api-client';

const db = DataAPIClient({
  secretArn: process.env.DB_SECRET_ARN!,
  resourceArn: process.env.DB_CLUSTER_ARN!,
  database: process.env.DB_NAME!,
  region: process.env.AWS_REGION!
});

// Simple query
const users = await db.query('SELECT * FROM users WHERE active = :active', {
  active: true
});

// Insert with returning
const result = await db.query(
  'INSERT INTO users (email, name) VALUES (:email, :name) RETURNING *',
  { email: '[email protected]', name: 'Test User' }
);

// Transaction
const transaction = await db.transaction();
try {
  await transaction.query('UPDATE accounts SET balance = balance - :amount WHERE id = :from', {
    amount: 100, from: 1
  });
  await transaction.query('UPDATE accounts SET balance = balance + :amount WHERE id = :to', {
    amount: 100, to: 2
  });
  await transaction.commit();
} catch (error) {
  await transaction.rollback();
  throw error;
}

Python with boto3

# requirements.txt
boto3>=1.34.0

# db.py
import boto3
import os

rds_data = boto3.client('rds-data')

CLUSTER_ARN = os.environ['DB_CLUSTER_ARN']
SECRET_ARN = os.environ['DB_SECRET_ARN']
DATABASE = os.environ['DB_NAME']


def execute_sql(sql: str, parameters: list = None):
    """Execute SQL via Data API."""
    params = {
        'resourceArn': CLUSTER_ARN,
        'secretArn': SECRET_ARN,
        'database': DATABASE,
        'sql': sql
    }

    if parameters:
        params['parameters'] = parameters

    return rds_data.execute_statement(**params)


def get_user(user_id: int):
    result = execute_sql(
        'SELECT * FROM users WHERE id = :id',
        [{'name': 'id', 'value': {'longValue': user_id}}]
    )
    return result.get('records', [])


def create_user(email: str, name: str):
    result = execute_sql(
        'INSERT INTO users (email, name) VALUES (:email, :name) RETURNING *',
        [
            {'name': 'email', 'value': {'stringValue': email}},
            {'name': 'name', 'value': {'stringValue': name}}
        ]
    )
    return result.get('generatedFields')


# Transaction
def transfer_funds(from_id: int, to_id: int, amount: float):
    transaction = rds_data.begin_transaction(
        resourceArn=CLUSTER_ARN,
        secretArn=SECRET_ARN,
        database=DATABASE
    )
    transaction_id = transaction['transactionId']

    try:
        execute_sql(
            'UPDATE accounts SET balance = balance - :amount WHERE id = :id',
            [
                {'name': 'amount', 'value': {'doubleValue': amount}},
                {'name': 'id', 'value': {'longValue': from_id}}
            ]
        )

        execute_sql(
            'UPDATE accounts SET balance = balance + :amount WHERE id = :id',
            [
                {'name': 'amount', 'value': {'doubleValue': amount}},
                {'name': 'id', 'value': {'longValue': to_id}}
            ]
        )

        rds_data.commit_transaction(
            resourceArn=CLUSTER_ARN,
            secretArn=SECRET_ARN,
            transactionId=transaction_id
        )
    except Exception as e:
        rds_data.rollback_transaction(
            resourceArn=CLUSTER_ARN,
            secretArn=SECRET_ARN,
            transactionId=transaction_id
        )
        raise e

Prisma with Aurora

Setup (VPC Connection via RDS Proxy)

npm install prisma @prisma/client
npx prisma init
// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String
  posts     Post[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
  createdAt DateTime @default(now())
}

Environment

# Use RDS Proxy endpoint
DATABASE_URL="postgresql://user:[email protected]:5432/mydb?schema=public&connection_limit=1"

Lambda Handler with Prisma

// handlers/users.ts
import { PrismaClient } from '@prisma/client';

// Reuse client across invocations
let prisma: PrismaClient | null = null;

function getPrisma(): PrismaClient {
  if (!prisma) {
    prisma = new PrismaClient({
      datasources: {
        db: { url: process.env.DATABASE_URL }
      }
    });
  }
  return prisma;
}

export async function handler(event: any) {
  const db = getPrisma();

  const users = await db.user.findMany({
    include: { posts: true },
    take: 10
  });

  return {
    statusCode: 200,
    body: JSON.stringify(users)
  };
}

Aurora Serverless v2

Capacity Configuration

// CDK
const cluster = new rds.DatabaseCluster(this, 'Cluster', {
  engine: rds.DatabaseClusterEngine.auroraPostgres({
    version: rds.AuroraPostgresEngineVersion.VER_15_4
  }),
  serverlessV2MinCapacity: 0.5,  // Minimum ACUs
  serverlessV2MaxCapacity: 16,   // Maximum ACUs
  writer: rds.ClusterInstance.serverlessV2('writer'),
  readers: [
    rds.ClusterInstance.serverlessV2('reader', { scaleWithWriter: true })
  ],
  vpc,
  vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }
});

Capacity Guidelines

WorkloadMin ACUsMax ACUs
Dev/Test0.52
Small Production28
Medium Production432
Large Production8128

Handle Scale-to-Zero Wake-up

// Data API Client v2 handles this automatically
// For direct connections, implement retry logic:

import { Pool } from 'pg';

async function queryWithRetry(
  pool: Pool,
  sql: string,
  params: any[],
  maxRe

---

*Content truncated.*

When not to use it

  • For non-AWS Aurora/RDS databases
  • When using long-running persistent server connections in Lambda

Prerequisites

AWS Aurora clusterSecrets Manager access

Limitations

  • Data API limited to Aurora Serverless
  • Requires specific IAM permissions

How it compares

It enforces connection pooling and serverless-specific patterns, preventing the common anti-pattern of opening raw connections from Lambda.

Compared to similar skills

aws-aurora side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
aws-aurora (this skill)14moReviewIntermediate
local-cluster-manager227dReviewIntermediate
rds07moReviewAdvanced
supabase-load-scale127dCautionAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry