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
email-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
with-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
full-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
| Property | Type | Description |
|---|---|---|
vercel | VercelOIDCConfig | Vercel OIDC configuration (teamSlug, projectName) |
oidc | OIDCConfig | Custom OIDC provider (GitHub Actions, GitLab, etc.) |
domain | string | Primary sending domain with DKIM |
hostedZoneId | string | Route53 zone ID for automatic DNS records |
mailFromSubdomain | string | MAIL FROM subdomain (default: "mail") |
events | EventsConfig | Event tracking and history storage |
smtp | SMTPConfig | SMTP credentials for legacy systems |
suppressionList | SuppressionListConfig | Bounce/complaint suppression |
reputationMetrics | boolean | Enable SES reputation metrics (default: true) |
tlsRequired | boolean | Require TLS for outbound emails (default: false) |
sendingEnabled | boolean | Enable sending (default: true) |
removalPolicy | RemovalPolicy | CDK removal policy for stateful resources |
Outputs
| Property | Type | Description |
|---|---|---|
roleArn | string | IAM role ARN for SDK authentication |
configSetName | string | SES configuration set name |
domain | string | Primary domain (if configured) |
dkimRecords | Array | DKIM CNAME records for DNS |
tableName | string | DynamoDB table name (if history enabled) |
queueUrl | string | SQS queue URL (if events enabled) |
smtpEndpoint | string | SMTP endpoint (if SMTP enabled) |
Grant Methods
The construct provides CDK-style grant methods for easy IAM permission management.
grants.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
| Method | Description |
|---|---|
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
resources.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
| Property | Type | When Available |
|---|---|---|
role | iam.IRole | Always |
oidcProvider | iam.IOpenIdConnectProvider | If Vercel or custom OIDC |
configSet | ses.IConfigurationSet | Always |
emailIdentity | ses.IEmailIdentity | If domain is provided |
table | dynamodb.ITable | If events.storeHistory is true |
queue | sqs.IQueue | If events is configured |
eventProcessor | lambda.IFunction | If events.storeHistory is true |
GitHub Actions OIDC
Use custom OIDC configuration for GitHub Actions or other providers.
github-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:
send-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 PackageEmail SDK
Learn how to send emails with the @wraps.dev/email SDK.
SDK ReferenceAWS CDK Docs
Learn more about AWS CDK and infrastructure as code.
CDK Docs
