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.
Install
npx skillscat add go-to-k/cdkd/new-provider Install via the SkillsCat registry.
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)
- Service name (e.g.,
Check if provider already exists in
src/provisioning/providers/andsrc/provisioning/register-providers.ts.Read an existing provider as reference for the pattern. Use a simple one like
src/provisioning/providers/ssm-parameter-provider.tsorsrc/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 whichList*+ListTags*(or equivalent) lookup-by-tag pair lets you find a resource by itsaws:cdk:pathtag? 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
ResourceProviderinterface (create, update, delete, getAttribute, import) - Take clients from
getAwsClients(), or build your own SDK client with...ambientClientDefaults()(../../utils/ambient-client-defaults.js) spread FIRST — a bareawsClientDefaults()drops a library caller's explicit credentials and failsambient-client-defaults-fence.test.ts(#3588) - Follow ESM import conventions (
.jsextension) - Return proper
physicalIdandattributesfrom create
Import method — copy the shape from a similar provider rather than
writing it from scratch:s3-bucket-provider.tsfor a tag-ARRAY service,lambda-function-provider.tsfor a tag-MAP one,kms-provider.tsfor a
service with no template name property. The shape is: resolve an explicit
physical id first (resolveExplicitPhysicalId(input, '<NameField>'), i.e.
the--resourceoverride orProperties.<NameField>) and verify it with aGet/Head/Describecall; otherwise, withinput.cdkPathpresent,
walk the service'sList*paginator, fetch tags per resource and matchaws:cdk:paththroughmatchesCdkPath(CDK_PATH_TAGin../import-helpers.js).Notes:
- Return
null(not throw) when the resource is not found — caller
treats this as "skipped" rather than failure. attributes: {}is fine;Fn::GetAttreconstructs missing
attributes at deploy time viaconstructAttribute(seesrc/deployment/intrinsic-function-resolver.ts).- For services whose
ListTagsreturns aRecord<string,string>
map instead of aTag[]array (Lambda, SQS), read the value at
keyCDK_PATH_TAGdirectly instead of going throughmatchesCdkPath. - For services with NO template-supplied name field (KMS Key,
CloudFront Distribution), skip step 1's name fallback — only
the explicit-override path and tag lookup apply. - Some services don't support tagging or
ListTagsrequires extra
IAM. If tag lookup is impractical, document that limitation in
the method's doc comment and rely on--resourceoverrides.
Register the provider in
src/provisioning/register-providers.ts:- Add import for the new provider
- Add
registry.register('AWS::Service::Resource', new ServiceResourceProvider())inregisterAllProviders()
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 runpnpm add @aws-sdk/client-{service}.Run typecheck, lint, build, and tests to verify everything works.
Create integration test by invoking
/new-integwith 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
.jsextension 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