yamlcdk
v0.0.9
Published
yamlcdk (AWS Cloud Development YAML) is a TypeScript CLI that compiles YAML-defined AWS infrastructure to CDK/CloudFormation deployments.
Readme
yamlcdk
yamlcdk ("AWS YAML for CDK") is a CLI for defining AWS infrastructure in YAML, turning it into AWS CDK/CloudFormation stacks, and running the usual deployment workflow from the command line: initialize config, validate it, synthesize a template, diff changes, deploy, and remove stacks.
yamlcdk supports three input formats:
- yamlcdk format — a concise, purpose-built YAML schema (see
examples/service.yml) - Serverless Framework YAML —
serverless.ymlfor AWS, mapped onto yamlcdk's current compiler model (seeexamples/serverless.yml) - CloudFormation YAML — native CloudFormation templates with
AWSTemplateFormatVersion(seeexamples/cloudformation.yml)
The correct format is detected automatically based on file content. This README is focused on CLI users. If you are developing yamlcdk itself, use DEVELOPER.md (workflow/tests) and ARCHITECTURE.md (internal design).
About This Project
Development & Philosophy
This project is built with AI assistance—primarily GPT Codex 5.3 and Claude Opus 4.6—in places where it makes sense. It's designed to be simple for both AI and human developers to modify and extend. The philosophy, guidelines, and architecture are author-driven; contributions to both features and architecture are welcome.
Vision & Goals
yamlcdk combines the simplicity of YAML configuration with the power and maturity of AWS CDK, delivering a lightweight integration that follows CDK conventions while keeping infrastructure definitions approachable. The goal is to support YAML-based infrastructure as code while enabling full testing, validation, and CDK integration—bringing both YAML and CDK strengths into a single CLI.
Format Support & Maturity
yamlcdk supports three input formats with different maturity levels:
- yamlcdk format — The primary, fully-featured format with complete support for all features. Recommended for new projects.
- CloudFormation YAML — Native CloudFormation templates are supported with limited scope today, but support will grow as more features are added.
- Serverless Framework YAML — Basic compatibility is provided for Serverless configs mapped onto yamlcdk's compiler model. Some plugins are supported natively, but there is no goal to support all plugins. Current support is best-effort for common use cases.
Format stability policy (alpha):
- yamlcdk format is still work-in-progress. Breaking schema/behavior changes are currently allowed, and migrations are not guaranteed during alpha.
- Serverless Framework and CloudFormation inputs should keep stable user-facing behavior as yamlcdk evolves.
- Internal canonicalization/adaptation for Serverless and CloudFormation may change when needed to align with the yamlcdk compiler model, but those internal changes should not introduce additional external breakage.
Contributor expectation: when a change intentionally alters user-facing behavior, call it out explicitly in docs/release notes with impact and upgrade guidance.
Roadmap & Contributions
yamlcdk is currently in the alpha phase. Plugin support is not extensively planned for the alpha phase, but once alpha is complete, we will have a better understanding of the architecture and plugin strategy going forward. Contributions are welcome for features, architecture improvements, documentation, and examples.
Requirements
- Node.js 20+
- AWS credentials or profile access for the account you plan to target
- A config file: yamlcdk YAML (
yamlcdk.yml), Serverless Framework YAML (serverless.yml), or a CloudFormation YAML template
Install and run
Installed CLI (recommended)
npx yamlcdk --helpYou can also install it in a project:
npm i -D yamlcdk
npx yamlcdk --helpFrom a checkout of this repository (maintainer/development flow)
npm install
npm run build
node dist/cli.js --helpDuring local development you can run the CLI without building first:
npm run dev -- --helpAll examples below use yamlcdk. If you are running from a checkout, replace yamlcdk with node dist/cli.js after npm run build, or with npm run dev -- while developing locally.
Quick start
Create a starter config, validate it, synthesize the template, then deploy it:
yamlcdk init -c yamlcdk.yml
yamlcdk validate -c yamlcdk.yml
yamlcdk synth -c yamlcdk.yml --region us-east-1 > stack.template.json
yamlcdk deploy -c yamlcdk.yml --region us-east-1To start with a CloudFormation template instead:
yamlcdk init -c template.yml --format cloudformation
yamlcdk validate -c template.yml
yamlcdk synth -c template.yml --region us-east-1 > stack.template.jsonTo start with a Serverless Framework config instead:
yamlcdk init -c serverless.yml --format serverless
yamlcdk validate -c serverless.yml
yamlcdk synth -c serverless.yml --region us-east-1 > stack.template.jsonIf your stack needs a bootstrapped CDK environment, run npx cdk bootstrap manually (details below).
You can also start from examples/service.yml (yamlcdk format), examples/serverless.yml (Serverless format), or examples/cloudformation.yml (CloudFormation format) for broader samples.
Commands
| Command | What it does | Options |
| --- | --- | --- |
| init | Create a starter config file. | -c, --config <path> (default: yamlcdk.yml), -f, --format <format> (yamlcdk, serverless, or cloudformation, default: yamlcdk) |
| validate | Validate config and print a synthesized report (overview + detail tables). | shared AWS flags (config defaults to yamlcdk.yml) + --output <text|json> |
| synth | Synthesize a CloudFormation template and print it to stdout. | shared AWS flags |
| diff | Show the CDK diff for the stack. | shared AWS flags |
| deploy | Deploy the stack. | shared AWS flags + --require-approval |
| remove | Destroy the stack. | shared AWS flags + --force |
Shared flags
The following flags are available on validate, synth, diff, deploy, and remove:
-c, --config <path>- config file path. Defaults toyamlcdk.ymlonvalidate; required onsynth,diff,deploy, andremove.--region <region>- AWS region override.--profile <profile>- AWS profile override.--account <account>- AWS account override.
validate prints a local synthesized report (no AWS API calls), for example:
Validation report (overview):
Stage | Region | Section | Type | Name | Status
dev | us-east-1 | Resources | AWS::Lambda::Function | hello-dev | valid
Outputs summary:
Name | Type | Status | Summary
HttpApiUrl | Output | valid | {"Value":{"Fn::Join":[...]}}
AWS::Lambda::Function details:
Name | Status | memory | timeout | cors | linkedEvents
hello-dev | valid | 256 | 10 | ... | ...Command-specific flags:
validate --output <text|json>- choose human-readable tables (text, default) or machine-readable report JSON (json).deploy --require-approval- keep approval for security-related changes. When omitted, yamlcdk deploys with approval disabled. This flag is not supported whenprovider.deployment.cloudFormationServiceRoleArnis set.remove --force- skip the destroy confirmation prompt. Use this in CI or any non-interactive shell.
CDK bootstrap (manual when required)
yamlcdk does not run cdk bootstrap for you. Bootstrap is still required for environments that depend on CDKToolkit bootstrap resources (for example many DefaultStackSynthesizer-based deployments).
Run bootstrap directly with CDK (typically once per account/region):
npx cdk bootstrap aws://123456789012/us-east-1
npx cdk bootstrap aws://123456789012/us-east-1 --profile my-profileTo skip the synthesized bootstrap version rule when you are intentionally managing deployment infrastructure:
- yamlcdk format:
provider.deployment.requireBootstrap: false - Serverless format:
provider.deployment.requireBootstrap: false(or mapped explicit infrastructure viaprovider.deploymentBucket.name/provider.iam.deploymentRole) - CloudFormation format:
Metadata.yamlcdk.deployment.requireBootstrap: false
requireBootstrap: false controls the synthesized bootstrap rule only; it does not guarantee that every deployment mode is bootstrapless.
Config file shape
yamlcdk supports three input formats. The format is auto-detected based on file content.
yamlcdk format
yamlcdk uses YAML. examples/service.yml shows a fuller sample, and src/config/schema.ts is the exact schema.
Top-level shape:
service: my-service
provider:
region: us-east-1
stage: dev
functions: {}
storage:
s3: {}
dynamodb: {}
messaging:
sqs: {}
sns: {}
iam:
statements: {}service and provider
service is required. provider controls deployment defaults:
region- default AWS regionstage- logical stage name; defaults todevaccount- target AWS accountprofile- AWS profile to usestackName- override the default stack name (<service>-<stage>, sanitized)tags- extra stack tagss3.cleanupRoleArn- required if any S3 bucket enablesautoDeleteObjects: truerestApi.apiKeyRequired- require API keys on all REST API routesrestApi.cloudWatchRoleArn- use an existing API Gateway CloudWatch role (yamlcdk does not create one by default)deployment- advanced deployment overrides
Example:
service: demo-api
provider:
region: us-east-1
stage: dev
stackName: demo-api-dev
profile: my-profile
tags:
Team: platform
s3:
cleanupRoleArn: arn:aws:iam::123456789012:role/MyS3CleanupRole
restApi:
apiKeyRequired: true
cloudWatchRoleArn: arn:aws:iam::123456789012:role/MyApiGatewayCloudWatchRolefunctions
Each function defines a Lambda plus optional build settings, IAM references, and events:
functions:
hello:
handler: src/handlers/hello.handler
runtime: nodejs20.x
timeout: 10
memorySize: 256
environment:
STAGE: dev
iam:
- readUsers
build:
mode: typescript
events:
http:
- method: GET
path: /helloUseful fields:
handler- required module path and export, for examplesrc/handlers/hello.handlerruntime- optional Lambda runtimetimeout/memorySize- optional Lambda settingsenvironment- optional Lambda environment variables (scalar strings or CloudFormation intrinsics)iam- eitheriam.statementskeys or a single IAM role ARNbuild.mode-typescript(default),esbuild,external, ornone(skip build, use handler path as-is)build.command,build.cwd,build.handler- external build settingsbuild.esbuild- esbuild options forbuild.mode: esbuild(requiresesbuildinstalled in the customer project)events- see the event types belowrestApi.apiKeyRequired- per-function REST API key requirement when the global provider setting is not set
Environment values can be plain strings or CloudFormation intrinsic functions (Ref, Fn::GetAtt, Fn::Sub, Fn::Join):
functions:
worker:
handler: src/worker.handler
environment:
STAGE: dev
QUEUE_URL:
Ref: JobsQueue
TABLE_ARN:
Fn::GetAtt: [OrdersTable, Arn]
COMPOSED_ARN:
Fn::Sub: "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:my-queue"Unsupported object shapes are rejected with an explicit error.
Example external build:
functions:
hello:
handler: src/handlers/hello.handler
build:
mode: external
command: npm run build:hello
cwd: .
handler: dist/handlers/hello.handlerExample esbuild build:
functions:
hello:
handler: src/handlers/hello.handler
runtime: nodejs22.x
build:
mode: esbuild
esbuild:
minify: true
sourcemap: inline
external:
- aws-sdk
define:
process.env.NODE_ENV: '"production"'build.mode: esbuild expects esbuild to be installed in the customer project (for example npm install -D esbuild).
Supported build.esbuild options:
| Option | Type | Notes |
| --- | --- | --- |
| bundle | boolean | Defaults to true |
| minify | boolean | Enables all minification passes |
| minifyWhitespace | boolean | Fine-grained minify option |
| minifyIdentifiers | boolean | Fine-grained minify option |
| minifySyntax | boolean | Fine-grained minify option |
| sourcemap | boolean \| inline \| external \| linked \| both | true maps to --sourcemap |
| target | string \| string[] | Defaults from runtime (nodejs20.x -> node20, nodejs22.x -> node22, nodejs24.x -> node24) |
| platform | node \| browser \| neutral | Defaults to node |
| format | cjs \| esm \| iife | Defaults to cjs |
| external | string[] | Passed as repeated --external:<pkg> |
| inject | string[] | Passed as repeated --inject:<path> |
| define | Record<string, string> | Value must be a JS expression string |
| loader | Record<string, string> | Per-extension loader mapping |
| keepNames | boolean | Preserves class/function names |
| treeShaking | boolean | Emits --tree-shaking=true/false |
| pure | string[] | Passed as repeated --pure:<name> |
| ignoreAnnotations | boolean | Controls --ignore-annotations |
| banner | Record<string, string> | Passed as repeated --banner:<lang>=<text> |
| footer | Record<string, string> | Passed as repeated --footer:<lang>=<text> |
| tsconfig | string | Path to tsconfig for esbuild |
| charset | ascii \| utf8 | Emits --charset=<value> |
| legalComments | none \| inline \| eof \| linked \| external | Emits --legal-comments=<value> |
iam
Define reusable IAM statements under iam.statements, then reference them from functions:
iam:
statements:
readUsers:
actions:
- dynamodb:GetItem
- dynamodb:Query
resources:
- users
functions:
hello:
handler: src/handlers/hello.handler
iam:
- readUsersNotes:
- IAM
resourcesaccepts either<resourceName>orref:<resourceName>for yamlcdk-managed S3 buckets, DynamoDB tables, SQS queues, and SNS topics. - A function can also use a direct role ARN instead of statement keys, for example:
iam: ["arn:aws:iam::123456789012:role/MyExistingRole"] - Do not mix statement keys and a role ARN in the same function.
storage.s3
storage:
s3:
uploads:
versioned: true
autoDeleteObjects: falseFields:
versioned- enable bucket versioningautoDeleteObjects- delete objects during stack removal; opt-in only
Notes:
- If any bucket sets
autoDeleteObjects: true, you must also setprovider.s3.cleanupRoleArn. - Without
autoDeleteObjects: true, buckets stay retain-safe on removal.
storage.dynamodb
storage:
dynamodb:
users:
partitionKey:
name: pk
type: string
sortKey:
name: sk
type: string
billingMode: PAY_PER_REQUEST
stream: NEW_AND_OLD_IMAGESFields:
partitionKey- requiredsortKey- optionalbillingMode-PAY_PER_REQUESTorPROVISIONEDstream-NEW_IMAGE,OLD_IMAGE,NEW_AND_OLD_IMAGES, orKEYS_ONLY
If you use a DynamoDB stream event on a function, the table must set stream.
messaging.sqs
messaging:
sqs:
jobs:
visibilityTimeout: 30Fields:
visibilityTimeout- queue visibility timeout in seconds
messaging.sns
messaging:
sns:
events:
topicName: events-topic.fifo
displayName: Events
fifoTopic: true
contentBasedDeduplication: true
fifoThroughputScope: MessageGroup
kmsMasterKeyId: alias/aws/sns
signatureVersion: "2"
tracingConfig: Active
archivePolicy:
MessageRetentionPeriod: "7"
dataProtectionPolicy:
Name: events-policy
deliveryStatusLogging:
- protocol: lambda
successFeedbackSampleRate: "100"
tags:
Team: platform
subscriptions:
- type: sqs
target: jobs
- type: lambda
target: processor
filterPolicy:
severity:
- high
- protocol: https
endpoint: https://example.com/webhookFields:
- Topic properties:
topicName,displayName,fifoTopic,contentBasedDeduplication,fifoThroughputScope,kmsMasterKeyId,signatureVersion,tracingConfig,archivePolicy,dataProtectionPolicy,deliveryStatusLogging, andtags. subscriptionsis optional and supports:- managed targets:
{ type: sqs|lambda, target: <managed resource name> } - direct endpoints:
{ protocol: <sns protocol>, endpoint: <endpoint> }
- managed targets:
- Subscription attributes (optional):
deliveryPolicy,filterPolicy,filterPolicyScope,rawMessageDelivery,redrivePolicy,region,replayPolicy,subscriptionRoleArn.
Use functions.<name>.events.sns when you want a Lambda to subscribe to a topic.
functions.<name>.url
Creates a Lambda Function URL for a function:
functions:
hello:
handler: src/handlers/hello.handler
url:
authType: NONE
invokeMode: RESPONSE_STREAM
cors:
allowedMethods:
- GET
- POST
allowOrigins:
- https://example.com
allowHeaders:
- Content-Type
exposeHeaders:
- X-Trace-Id
allowCredentials: true
maxAge: 300Fields:
authType-AWS_IAMorNONE(defaults toAWS_IAM)invokeMode-BUFFEREDorRESPONSE_STREAM(defaults toBUFFERED)cors.allowCredentials- include credentials in CORS requestscors.allowHeaders- allowed request headerscors.allowedMethods- allowed methods:GET,PUT,HEAD,POST,DELETE,PATCH,OPTIONS, or*cors.allowOrigins- allowed originscors.exposeHeaders- response headers exposed to callerscors.maxAge- preflight cache duration in seconds
Notes:
- Function URLs are configured per function, not under
events. - yamlcdk currently supports direct function URLs only; alias-qualified URLs are out of scope.
- Public URLs (
authType: NONE) synthesize the required Lambda invoke permissions automatically.
Function event types
For S3, SQS, SNS, and DynamoDB events, reference yamlcdk-managed resources with either <name> or ref:<name>.
http
Creates API Gateway HTTP API routes:
functions:
hello:
handler: src/handlers/hello.handler
events:
http:
- method: GET
path: /hellorest
Creates API Gateway REST API routes:
functions:
hello:
handler: src/handlers/hello.handler
restApi:
apiKeyRequired: true
events:
rest:
- method: POST
path: /ordersUse provider.restApi.apiKeyRequired to require API keys for all REST routes. If that global setting is not present, functions.<name>.restApi.apiKeyRequired can control it per function.
s3
Subscribes a Lambda to S3 bucket notifications:
functions:
thumbnailer:
handler: src/handlers/thumbnailer.handler
events:
s3:
- bucket: uploads
events:
- s3:ObjectCreated:*Supported S3 event names:
s3:ObjectCreated:*s3:ObjectCreated:Puts3:ObjectCreated:Posts3:ObjectCreated:Copys3:ObjectCreated:CompleteMultipartUploads3:ObjectRemoved:*s3:ObjectRemoved:Deletes3:ObjectRemoved:DeleteMarkerCreated
sqs
Subscribes a Lambda to an SQS queue:
functions:
worker:
handler: src/handlers/worker.handler
events:
sqs:
- queue: jobs
batchSize: 10sns
Subscribes a Lambda to an SNS topic:
functions:
notifier:
handler: src/handlers/notifier.handler
events:
sns:
- topic: eventsdynamodb
Subscribes a Lambda to a DynamoDB stream:
functions:
projector:
handler: src/handlers/projector.handler
events:
dynamodb:
- table: users
batchSize: 100
startingPosition: LATESTstartingPosition can be LATEST or TRIM_HORIZON. The table referenced by table: must have stream enabled under storage.dynamodb.
eventbridge
Creates EventBridge rules for schedules or event patterns:
functions:
scheduler:
handler: src/handlers/scheduler.handler
events:
eventbridge:
- schedule: rate(5 minutes)
- eventPattern:
source:
- my.app
detail-type:
- order.created
- eventPattern:
source:
- marketing
detail-type:
- SEND_EMAIL
eventBus: arn:aws:events:us-east-1:123456789012:event-bus/custom-busEach entry must define at least one of schedule or eventPattern. Optionally specify eventBus with an event bus ARN to target a custom bus (omit or set to "default" for the default bus).
Serverless Framework format
yamlcdk can also load AWS serverless.yml files and adapt the supported subset onto the same compiler model used by yamlcdk format.
Detection is aimed at real Serverless AWS configs (service, provider.name: aws) and is intended for serverless.yml / serverless.yaml.
Supported top-level surface today:
serviceplugins(detectsserverless-esbuild)custom.esbuild(mapped to canonical function esbuild build options)provider.name,provider.stage,provider.region,provider.runtime,provider.timeout,provider.memorySize,provider.stackName,provider.profile,provider.tagsprovider.iam.deploymentRole,provider.deploymentBucket.namefunctions.*.handler,runtime,timeout,memorySize,environment(including CloudFormation intrinsics like!Ref,!GetAtt,!Sub,!Join),role,url,build,skipEsbuild- function events:
http,httpApi,schedule,s3,sns,sqs,stream(DynamoDB only), andeventBridge(witheventBus,pattern,schedule) - raw
resources.Resources/resources.Outputs
Supported Serverless variable sources today:
${self:...}${sls:stage}${sls:service}${aws:region}${aws:accountId}when the account is available via config or environment${opt:...}from CLI options, with optional fallback, for example${opt:memory, 1024}withyamlcdk deploy --memory 2048${env:VAR_NAME}reads the OS environment variableVAR_NAME, with optional fallback, for example${env:DB_HOST, 'localhost'}${file(path):selector}with optional fallback, for example${file(./global.yml):custom.region, 'us-east-1'}
.env file support
yamlcdk automatically loads .env files from the same directory as the YAML definition file:
.env— base environment variables, always loaded when present.env.{stage}— stage-specific overrides (e.g.,.env.prod,.env.dev), loaded when the stage is known
Loading rules:
.envfiles are optional — missing files are silently ignored.- OS environment takes precedence: values already set in the OS environment are never overridden by
.envfiles. - Stage-specific files take precedence over
.env:.env.prodvalues override.envvalues (but not OS environment). - The stage is determined from the
--stageCLI option (via${opt:stage}). - No variable interpolation is performed inside
.envfiles — they use plainKEY=VALUEsyntax.
Example .env:
# Database config
DB_HOST=localhost
DB_PORT=5432
API_KEY="my-secret-key"Example YAML using ${env:...}:
functions:
api:
handler: src/handlers/api.handler
environment:
DB_HOST: ${env:DB_HOST, 'localhost'}
DB_PORT: ${env:DB_PORT, '5432'}
API_KEY: ${env:API_KEY}file(path) resolution rules:
pathis resolved relative to the YAML file containing the expression.selectoruses dotted path lookup in the referenced YAML document.- Nested variables are supported in both
pathandselector. - Missing values fail validation unless a fallback alternative resolves.
- Variables inside imported files (e.g.
${self:provider.stage}) resolve against the imported file first, then fall back to the entry/root document context. This allows imported files to reference values defined in the main configuration file. - The same
${file(path):selector}behavior is also available for yamlcdk and CloudFormation input files.
Example:
service: demo-api
provider:
name: aws
stage: ${opt:stage, 'dev'}
region: us-east-1
runtime: nodejs20.x
iam:
deploymentRole: arn:aws:iam::638914547607:role/AldoDefaultCFNRole
deploymentBucket:
name: aldo-serverless-build-omni-hybris-lab-dev-us-east-1
functions:
hello:
handler: src/handlers/hello.handler
environment:
STAGE: ${sls:stage}
url:
cors: true
events:
- http: GET /hello
- httpApi: POST /hello
- sqs:
arn: !GetAtt JobsQueue.Arn
batchSize: 10
resources:
Resources:
JobsQueue:
Type: AWS::SQS::Queue
Properties:
VisibilityTimeout: 30Notes:
- yamlcdk keeps Serverless support scoped to the current compiler model, not the full Serverless Framework surface.
serverless-esbuildcompatibility is compile-oriented only (esbuild build detection and option mapping). Serverless lifecycle/packaging/watch features are out of scope.- If
pluginsincludesserverless-esbuildorcustom.esbuildexists, functions default tobuild.mode: esbuild. - Build option precedence is
functions.<name>.build.esbuild>custom.esbuild> yamlcdk defaults. functions.<name>.skipEsbuild: trueopts a function out of automatic esbuild mode and falls back to inferredtypescript/none.resources.Resourcesare adapted through the existing CloudFormation path and merged into the Serverless-derived model.- Top-level Serverless config is primary; custom resources may augment generated functions and managed resources, but not override generated function logical IDs.
provider.deploymentBucket.namemaps to yamlcdkprovider.deployment.fileAssetsBucketName.provider.iam.deploymentRolemaps to yamlcdkprovider.deployment.cloudFormationExecutionRoleArn.provider.deployment.requireBootstrapmaps to yamlcdkprovider.deployment.requireBootstrap.- With that mapped pair, yamlcdk uses explicit deployment infrastructure and does not synthesize the CDK bootstrap version rule for the stack.
- External SQS/SNS/DynamoDB event targets are not supported yet by the current yamlcdk domain model.
CloudFormation format
yamlcdk can also accept native CloudFormation YAML templates as input. This is useful when you have existing CloudFormation templates and want to manage them through yamlcdk's deployment workflow.
A CloudFormation template is auto-detected when the file contains AWSTemplateFormatVersion or a Resources section with Type: AWS::* entries.
Metadata section
Service-level config that yamlcdk needs (service name, stage, region, etc.) is provided in the Metadata.yamlcdk section. If omitted, defaults are used (service name derived from filename, stage dev, region us-east-1).
AWSTemplateFormatVersion: "2010-09-09"
Metadata:
yamlcdk:
service: my-service
stage: dev
region: us-east-1
tags:
Team: platform
s3:
cleanupRoleArn: arn:aws:iam::123456789012:role/MyS3CleanupRole
deployment:
fileAssetsBucketName: my-cdk-assets
useCliCredentials: trueAll Metadata.yamlcdk fields are optional:
service- service name (defaults to filename)stage- logical stage name (defaults todev)region- AWS region (defaults toAWS_REGIONorus-east-1)account,profile- AWS account and profiletags- extra stack tagss3.cleanupRoleArn- required if usingautoDeleteObjectsrestApi.cloudWatchRoleArn- existing API Gateway CloudWatch roledeployment- same advanced deployment overrides as the yamlcdk format
Build handling
For each AWS::Lambda::Function, yamlcdk checks if the handler source file exists as TypeScript (e.g. src/handlers/hello.ts for Handler: src/handlers/hello.handler). If it does, the function is compiled with tsc (same as the yamlcdk format). If no .ts file is found, the handler path is used as-is (build.mode: none), assuming the code is already built or will be provided at the handler location.
Supported resource types
The following CloudFormation resource types are extracted and mapped to the yamlcdk compiler model:
| CloudFormation Type | What it maps to |
| --- | --- |
| AWS::Lambda::Function | Lambda functions (handler, runtime, timeout, memorySize, environment) |
| AWS::Lambda::Url | Lambda Function URLs attached to functions (authType, invokeMode, CORS) |
| AWS::S3::Bucket | S3 buckets (versioning, notification config) |
| AWS::DynamoDB::Table | DynamoDB tables (keys, billing mode, streams) |
| AWS::SQS::Queue | SQS queues (visibility timeout) |
| AWS::SNS::Topic | SNS topics |
| AWS::SNS::Subscription | SNS subscriptions (sqs and lambda protocols) |
| AWS::Lambda::EventSourceMapping | SQS and DynamoDB stream event triggers on functions |
| AWS::Events::Rule | EventBridge schedule and event pattern rules targeting functions |
| AWS::ApiGatewayV2::Api/Route/Integration | HTTP API routes targeting functions |
Unsupported resource types in the template are silently ignored.
AWS::SNS::Topic adaptation preserves the topic properties currently exposed by yamlcdk's SNS model (for example FIFO/content-deduplication/KMS/signature/tracing/archive/data-protection/logging/tags), and AWS::SNS::Subscription adaptation preserves supported subscription attributes (for example filtering, raw delivery, redrive, replay, and role ARN) when they can be represented in the canonical model.
For AWS::Lambda::Url, yamlcdk currently supports direct function URLs only: TargetFunctionArn must resolve to a Lambda function resource in the same template via !Ref or !GetAtt, and Qualifier is not supported yet.
Cross-resource references
CloudFormation intrinsic functions are supported for cross-resource wiring:
!Ref LogicalId— reference another resource!GetAtt LogicalId.Attribute— get a resource attribute!Sub,!Join,!Select,!If,!Equals, etc. — parsed but only!Refand!GetAttare used for resource resolution
For example, an EventSourceMapping uses !Ref and !GetAtt to link a Lambda function to an SQS queue:
Resources:
HelloFunction:
Type: AWS::Lambda::Function
Properties:
Handler: src/hello.handler
Runtime: nodejs20.x
JobsQueue:
Type: AWS::SQS::Queue
HelloSqsTrigger:
Type: AWS::Lambda::EventSourceMapping
Properties:
FunctionName: !Ref HelloFunction
EventSourceArn: !GetAtt JobsQueue.Arn
BatchSize: 10Example
See examples/cloudformation.yml for a complete CloudFormation template demonstrating all supported resource types and event wiring patterns.
Deployment overrides
Use provider.deployment when you need to control how CDK assets and deployment roles are handled.
provider:
deployment:
fileAssetsBucketName: my-cdk-assets-us-east-1
imageAssetsRepositoryName: my-cdk-assets-ecr
useCliCredentials: true
qualifier: hnb659fds
requireBootstrap: falseSupported fields:
fileAssetsBucketName- pre-created bucket for CDK file assetsimageAssetsRepositoryName- pre-created ECR repository for CDK image assetscloudFormationServiceRoleArn- deploy withaws cloudformation deploy --role-arnfor template-only stackscloudFormationExecutionRoleArn- CloudFormation execution role for CDK deployment modedeployRoleArn- CDK deploy rolequalifier- custom CDK bootstrap qualifieruseCliCredentials- publish assets with the active CLI credentialsrequireBootstrap- override bootstrap version rule behavior
Important rules:
- If you set asset locations (
fileAssetsBucketNameorimageAssetsRepositoryName) withoutdeployRoleArn, yamlcdk infersuseCliCredentials: true. useCliCredentials: truecannot be combined withdeployRoleArn.useCliCredentials: truecan be combined withcloudFormationExecutionRoleArnwhen you want the CLI credentials to publish assets and start the deployment, but CloudFormation to execute the stack operation with that role.cloudFormationServiceRoleArncannot be combined withdeployRoleArnorcloudFormationExecutionRoleArn.cloudFormationServiceRoleArnis for template-only stacks. It is not supported for stacks that synthesize CDK asset metadata, such as Lambda code or container image assets.- If you use explicit deployment infrastructure, yamlcdk disables the bootstrap version rule unless you set
requireBootstrapyourself. requireBootstrap: falsedoes not make role-based CDK deployments bootstrapless by itself; role-based CDK deploys can still require a bootstrapped environment.
When adapting examples/service.yml, choose one supported deployment mode at a time: CLI-credentials mode, role-based CDK mode, or CloudFormation service-role mode.
Operational notes
- Region resolution order is: CLI
--region->provider.region->AWS_REGION->us-east-1. provider.stagedefaults todev.- If
provider.stackNameis not set, yamlcdk uses a sanitized<service>-<stage>stack name. - yamlcdk adds
ServiceandStagestack tags automatically, then applies any extraprovider.tags. - Generated resource names are stage-scoped. For example, logical names like
jobsorusersbecome physical resource names with the stage suffix. deploydoes not run bootstrap automatically. Runnpx cdk bootstrap ...manually when your deployment mode requires it.- If
removeruns in a non-interactive shell, pass--force. synthprints the generated CloudFormation template to stdout.deployprints CloudFormation stack outputs after a successful deployment when available.
More reading
examples/service.yml- yamlcdk format config exampleexamples/serverless.yml- Serverless Framework format config exampleexamples/cloudformation.yml- CloudFormation format config examplesrc/config/schema.ts- exact yamlcdk config schema- DEVELOPER.md - contributor setup, workflow, and test strategy
- ARCHITECTURE.md - plugin system and compiler/runtime architecture
