DSQL
Serverless Postgres on Aurora DSQL. IAM auth over TLS, schemas and roles declared in code, and optional multi-region clusters.
A side-effect resource with no outputs — it runs AWS IAM GRANT for the given database roles against the given IAM identity. You rarely construct it directly: calling .grant() on a DSQL component creates it for you.
Minimal
The smallest config that deploys.
import { App } from '@anvil-cloud/sdk';
import * as anvil from '@anvil-cloud/sdk';
export default new App({
run(ctx) {
const db = new anvil.aws.DSQL('db', {
schemas: [{ name: 'app', roles: [{ name: 'app_rw', grants: ['SELECT', 'INSERT', 'UPDATE'] }] }],
});
const fn = new anvil.aws.Lambda('processor', {
runtime: 'nodejs24.x',
handler: 'functions/processor/index.handler',
});
// The same as db.grantConnect(fn, { schemas: [{ schema: 'app', roleName: 'app_rw' }] }).
// targetRoleArn can be any IAM role, e.g. an ECS task role.
new anvil.aws.DSQLConnect('processor-connect', {
clusterArns: db.clusterArns,
targetRoleArn: fn.roleArn,
targetName: 'processor',
dbRoles: ['app_rw'],
declaredRoles: db.declaredRoles,
rolesTableName: db.rolesTableName,
});
},
});import anvil_cloud as anvil
def infra(ctx: anvil.Context):
db = anvil.aws.DSQL("db",
schemas=[{"name": "app", "roles": [{"name": "app_rw", "grants": ["SELECT", "INSERT", "UPDATE"]}]}],
)
fn = anvil.aws.Lambda("processor",
runtime="nodejs24.x",
handler="functions/processor/index.handler",
)
# The same as db.grant_connect(fn, schemas=[{"schema": "app", "role_name": "app_rw"}]).
# target_role_arn can be any IAM role, e.g. an ECS task role.
anvil.aws.DSQLConnect("processor-connect",
cluster_arns=db.cluster_arns,
target_role_arn=fn.role_arn,
target_name="processor",
db_roles=["app_rw"],
declared_roles=db.declared_roles,
roles_table_name=db.roles_table_name,
)
anvil.App(run=infra)package main
import (
"github.com/anvil-cloud/anvil/sdk/go/anvil"
anvilaws "github.com/anvil-cloud/anvil/sdk/go/anvil/aws"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
anvil.Run(anvil.AppConfig{
Run: func(ctx *anvil.Context) error {
db, err := anvilaws.NewDSQL(ctx.PulumiCtx(), "db", &anvilaws.DSQLArgs{
Schemas: anvilaws.DSQLSchemaArray{
anvilaws.DSQLSchemaArgs{
Name: pulumi.String("app"),
Roles: anvilaws.DSQLRoleArray{
anvilaws.DSQLRoleArgs{
Name: pulumi.String("app_rw"),
Grants: anvilaws.DSQLGrantArray{anvilaws.DSQLGrant("SELECT"), anvilaws.DSQLGrant("INSERT"), anvilaws.DSQLGrant("UPDATE")},
},
},
},
},
})
if err != nil {
return err
}
fn, err := anvilaws.NewLambda(ctx.PulumiCtx(), "processor", &anvilaws.LambdaArgs{
Runtime: anvilaws.LambdaRuntime_Nodejs24_x,
Handler: pulumi.String("functions/processor/index.handler"),
})
if err != nil {
return err
}
// Go has no grantConnect yet, so this is how Go grants connect access.
// TargetRoleArn can be any IAM role, e.g. an ECS task role.
_, err = anvilaws.NewDSQLConnect(ctx.PulumiCtx(), "processor-connect", &anvilaws.DSQLConnectArgs{
ClusterArns: db.ClusterArns,
TargetRoleArn: fn.RoleArn,
TargetName: pulumi.String("processor"),
DbRoles: pulumi.StringArray{pulumi.String("app_rw")},
DeclaredRoles: db.DeclaredRoles,
RolesTableName: db.RolesTableName,
})
return err
},
})
}Arguments
Names below are TypeScript (camelCase). In Python use snake_case (e.g. dataClassification → data_classification); in Go use PascalCase on the Args struct (e.g. DataClassification).
clusterArns requiredmap<string, string> Map of region to cluster ARN from the DSQL component. Used to scope the dsql:DbConnect IAM policy.
targetRoleArn requiredstring IAM execution role ARN of the compute resource (Lambda, ECS task, etc.) that will connect to the cluster.
targetName requiredstring Logical name of the compute resource. Used for naming child resources.
dbRoles array Postgres database role names to map this IAM identity to. One mapping is created per role; the bootstrap Lambda runs AWS IAM GRANT "<role>" TO the target for each. The compute connects as whichever role it chooses at runtime. Each must be declared in the DSQL component's schemas.
declaredRoles map<string, string> Pass dsql.declaredRoles from the DSQL component. Required with dbRoles: a role that isn't declared there fails the deploy.
dbRoleSchemas map<string, string> Maps a role in dbRoles to the schema you expect it in. Optional; a role declared in another schema fails the deploy. grantConnect fills it in for you.
rolesTableName string DynamoDB table name for role bootstrap. Pass dsql.rolesTableName from the DSQL component. Optional — omit when roles are not configured.
Attributes
Outputs available once the resource is deployed.
This component has no attributes.