| name | new-provider |
| description | Scaffold a new SDK Provider for a given AWS resource type (e.g., AWS::SES::EmailIdentity). Creates provider file, registers it, and generates test boilerplate. |
| argument-hint | <AWS::Service::Resource> |
New Provider Scaffold
You are scaffolding a new SDK Provider for cdkd.
Input
The user provides an AWS resource type like AWS::SES::EmailIdentity.
Steps
-
Parse the resource type to determine:
- Service name (e.g.,
SES)
- Resource name (e.g.,
EmailIdentity)
- AWS SDK client package (e.g.,
@aws-sdk/client-ses)
- Provider file name (e.g.,
ses-email-identity-provider.ts)
-
Check if provider already exists in src/provisioning/providers/ and src/provisioning/register-providers.ts.
-
Read an existing provider as reference for the pattern. Use a simple one like src/provisioning/providers/ssm-parameter-provider.ts or src/provisioning/providers/logs-log-group-provider.ts.
-
Read the AWS SDK docs or infer the API calls needed:
- CREATE: Which API creates this resource? What does it return (physical ID, attributes)?
- UPDATE: Which API updates this resource?
- DELETE: Which API deletes this resource?
- getAttribute: Which attributes might be needed for
Fn::GetAtt?
- import: Which API verifies a resource exists by physical id (
Get* / Describe* / Head*), and which List* + ListTags* (or equivalent) lookup-by-tag pair lets you find a resource by its aws:cdk:path tag? See "Import method" under step 5 — most providers follow the same shape.
-
Create the provider file at src/provisioning/providers/{service}-{resource}-provider.ts:
- Import the AWS SDK client and commands
- Implement
ResourceProvider interface (create, update, delete, getAttribute, import)
- Use
getAwsClient from ../../utils/aws-client-factory.js for client creation
- Follow ESM import conventions (
.js extension)
- Return proper
physicalId and attributes from create
Import method — copy this shape from a similar provider (e.g.
s3-bucket-provider.ts for tag-array services, lambda-function-provider.ts
for tag-map services, kms-provider.ts for services with no
template name property):
import { matchesCdkPath, resolveExplicitPhysicalId, CDK_PATH_TAG } from '../import-helpers.js';
import type { ResourceImportInput, ResourceImportResult } from '../../types/resource.js';
async import(input: ResourceImportInput): Promise<ResourceImportResult | null> {
const explicit = resolveExplicitPhysicalId(input, '<NameField>');
if (explicit) {
try {
await this.client.send(new <||>({ ... explicit ... }));
{ : explicit, : {} };
} (err) {
(err <>) ;
err;
}
}
(!input.) ;
: | ;
{
list = ..( ({ ...(token && { : token }) }));
( item list. ?? []) {
(!item.) ;
tags = ..( ({ : item. }));
((tags., input.)) {
{ : item., : {} };
}
}
token = list.;
} (token);
;
}
-
Register the provider in src/provisioning/register-providers.ts:
- Add import for the new provider
- Add
registry.register('AWS::Service::Resource', new ServiceResourceProvider()) in registerAllProviders()
-
Create test file at tests/unit/provisioning/providers/{service}-{resource}-provider.test.ts:
- Mock the AWS SDK client
- Test create (verify API call, physicalId, attributes)
- Test update (verify API call)
- Test delete (verify API call)
- Test delete idempotency (not-found treated as success)
- Test import explicit-override path (knownPhysicalId verified, attrs returned)
- Test import tag-based lookup (List + ListTags + cdkPath match)
- Test import not-found (returns
null, does not throw)
-
Check if @aws-sdk/client-{service} is already in package.json. If not, tell the user to run pnpm add @aws-sdk/client-{service}.
-
Run typecheck, lint, build, and tests to verify everything works.
-
Create integration test by invoking /new-integ with a test name based on the resource type (e.g., ses-email-identity). The integ test should create a minimal CDK stack using the new resource type.
Important
- Follow the exact patterns used by existing providers
- Always use
.js extension in imports (ESM)
- Physical ID should match what CloudFormation uses for that resource type
- Include delete idempotency (not-found errors treated as success)
- Do NOT add the SDK client package yourself; tell the user if it's missing
- Always create an integration test after the provider is implemented