Wraps Logo
DocsHome
CDK Reference

@wraps.dev/cdk

AWS CDK construct for deploying Wraps email infrastructure to your AWS account. Zero credentials stored, full AWS ownership, sensible defaults.

Installation

npm install @wraps.dev/cdk

Requirements: Node.js 20+, AWS CDK 2.x, constructs 10.x

Quick Start

TypeScriptemail-stack.ts
import { WrapsEmail } from "@wraps.dev/cdk";import * as cdk from "aws-cdk-lib";const app = new cdk.App();const stack = new cdk.Stack(app, "EmailStack");// Minimal setup with Vercel OIDCconst email = new WrapsEmail(stack, "Email", {  vercel: {    teamSlug: "my-team",    projectName: "my-app",  },});// Access outputsconsole.log("Role ARN:", email.roleArn);console.log("Config Set:", email.configSetName);

Outputs are automatically created as CloudFormation exports (WrapsEmailRoleArn, WrapsEmailConfigSetName, etc.)

With Domain and Event Tracking

TypeScriptwith-domain.ts
const email = new WrapsEmail(stack, "Email", {  vercel: {    teamSlug: "my-team",    projectName: "my-app",  },  domain: "example.com",  events: {    types: ["SEND", "DELIVERY", "BOUNCE", "COMPLAINT", "OPEN", "CLICK"],    storeHistory: true,    retention: "90days",  },});// DKIM records are output for DNS configurationemail.dkimRecords?.forEach((record, i) => {  console.log(`DKIM ${i + 1}: ${record.name} CNAME ${record.value}`);});

Full Configuration

TypeScriptfull-config.ts
import * as cdk from "aws-cdk-lib";const email = new WrapsEmail(stack, "Email", {  // Authentication (choose one)  vercel: {    teamSlug: "my-team",    projectName: "my-app",  },  // Or custom OIDC:  // oidc: {  //   providerUrl: "https://token.actions.githubusercontent.com",  //   audience: "sts.amazonaws.com",  //   subjectPattern: "repo:my-org/my-repo:*",  // },  // Domain configuration  domain: "example.com",  mailFromSubdomain: "mail", // Creates mail.example.com  hostedZoneId: "Z1234567890", // Auto-creates DNS records  // Event tracking  events: {    types: ["SEND", "DELIVERY", "BOUNCE", "COMPLAINT", "OPEN", "CLICK"],    storeHistory: true,    retention: "90days", // "7days" | "30days" | "90days" | "6months" | "1year" | "unlimited"  },  // Email settings  reputationMetrics: true,  tlsRequired: false,  sendingEnabled: true,  // Suppression list  suppressionList: {    enabled: true,    reasons: ["BOUNCE", "COMPLAINT"],  },  // SMTP credentials (for legacy systems)  smtp: {    enabled: false,  },  // CDK removal policy  removalPolicy: cdk.RemovalPolicy.RETAIN,});

Constructor Props

PropertyTypeDescription
vercelVercelOIDCConfigVercel OIDC configuration (teamSlug, projectName)
oidcOIDCConfigCustom OIDC provider (GitHub Actions, GitLab, etc.)
domainstringPrimary sending domain with DKIM
hostedZoneIdstringRoute53 zone ID for automatic DNS records
mailFromSubdomainstringMAIL FROM subdomain (default: "mail")
eventsEventsConfigEvent tracking and history storage
smtpSMTPConfigSMTP credentials for legacy systems
suppressionListSuppressionListConfigBounce/complaint suppression
reputationMetricsbooleanEnable SES reputation metrics (default: true)
tlsRequiredbooleanRequire TLS for outbound emails (default: false)
sendingEnabledbooleanEnable sending (default: true)
removalPolicyRemovalPolicyCDK removal policy for stateful resources

Outputs

PropertyTypeDescription
roleArnstringIAM role ARN for SDK authentication
configSetNamestringSES configuration set name
domainstringPrimary domain (if configured)
dkimRecordsArrayDKIM CNAME records for DNS
tableNamestringDynamoDB table name (if history enabled)
queueUrlstringSQS queue URL (if events enabled)
smtpEndpointstringSMTP endpoint (if SMTP enabled)

Grant Methods

The construct provides CDK-style grant methods for easy IAM permission management.

TypeScriptgrants.ts
import * as lambda from "aws-cdk-lib/aws-lambda";const email = new WrapsEmail(stack, "Email", { /* ... */ });// Create a Lambda functionconst myFunction = new lambda.Function(stack, "MyFunction", {  runtime: lambda.Runtime.NODEJS_20_X,  handler: "index.handler",  code: lambda.Code.fromAsset("./lambda"),});// Grant send permissionsemail.grantSend(myFunction);// Grant read access to email historyemail.grantReadHistory(myFunction);// Grant access to consume events from SQSemail.grantConsumeEvents(myFunction);

Available Grant Methods

MethodDescription
grantSend(grantee)Grant permissions to send emails
grantReadHistory(grantee)Grant read access to email history table
grantConsumeEvents(grantee)Grant access to consume events from SQS

Accessing Underlying Resources

TypeScriptresources.ts
const email = new WrapsEmail(stack, "Email", { /* ... */ });// Access CDK constructs via .resourcesemail.resources.role;           // iam.IRoleemail.resources.configSet;      // ses.IConfigurationSetemail.resources.emailIdentity;  // ses.IEmailIdentity (if domain)email.resources.table;          // dynamodb.ITable (if events.storeHistory)email.resources.queue;          // sqs.IQueue (if events)email.resources.dlq;            // sqs.IQueue (if events)email.resources.eventProcessor; // lambda.IFunction (if events.storeHistory)email.resources.oidcProvider;   // iam.IOpenIdConnectProvider (if OIDC)// Example: Add custom policy to roleemail.resources.role.addToPolicy(  new iam.PolicyStatement({    actions: ["ses:ListIdentities"],    resources: ["*"],  }));

Available Resources

PropertyTypeWhen Available
roleiam.IRoleAlways
oidcProvideriam.IOpenIdConnectProviderIf Vercel or custom OIDC
configSetses.IConfigurationSetAlways
emailIdentityses.IEmailIdentityIf domain is provided
tabledynamodb.ITableIf events.storeHistory is true
queuesqs.IQueueIf events is configured
eventProcessorlambda.IFunctionIf events.storeHistory is true

GitHub Actions OIDC

Use custom OIDC configuration for GitHub Actions or other providers.

TypeScriptgithub-actions.ts
const email = new WrapsEmail(stack, "Email", {  oidc: {    providerUrl: "https://token.actions.githubusercontent.com",    audience: "sts.amazonaws.com",    subjectPattern: "repo:my-org/my-repo:*",  },  domain: "example.com",});

Using with @wraps.dev/email SDK

After deploying, use the @wraps.dev/email SDK to send emails:

TypeScriptsend-email.ts
import { WrapsEmail } from "@wraps.dev/email";const email = new WrapsEmail();await email.send({  from: "hello@example.com",  to: "user@example.com",  subject: "Hello from Wraps!",  html: "<h1>Welcome!</h1>",});

Next Steps

View on npm

Check out the package on npm for the latest version and changelog.

View Package
Email SDK

Learn how to send emails with the @wraps.dev/email SDK.

SDK Reference
AWS CDK Docs

Learn more about AWS CDK and infrastructure as code.

CDK Docs