You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
What's Changed
[1.5.9] — 2026-09-08
Added
CloudFormation — a WaitCondition waits for its signals, SignalResource delivers them — the handle's Ref is now a URL the emulator serves (PUT the AWS signal JSON with an empty Content-Type); the wait condition holds the stack until Count distinct SUCCESS signals arrive, a FAILURE or the Timeout rolls it back, signals are published to the stack events, and Fn::GetAtt Wait.Data is the {UniqueId: Data} map. The CreationPolicy form (ResourceSignal, default PT5M) is signalled through the new SignalResource action, by stack name or id. A nested stack now deploys on a worker thread, so a wait condition or custom resource inside it no longer blocks the server. Contributed by @iot-rocket.
CloudFormation — stack-level tags propagate, and the Tags property of the common types reaches the service — the 44 types with a tag property receive the stack tags and the three aws:cloudformation: tags on create and update (a key the template sets wins); AWS::SQS::Queue, AWS::SNS::Topic, AWS::DynamoDB::Table, AWS::Lambda::Function, AWS::Logs::LogGroup and AWS::Kinesis::Stream now store their own Tags where the service's list-tags call reads them. An empty Tags on UpdateStack removes them, more than 50 tags or an aws: key are refused, tags set through a service's own API survive stack updates, and a nested stack passes the tags on. Contributed by @iot-rocket.
CloudFormation — ListImports, UpdateTerminationProtection, SetStackPolicy, GetStackPolicy, CancelUpdateStack and ContinueUpdateRollback — the first four answered InvalidAction, the last two did not exist, so an UPDATE_ROLLBACK_FAILED stack had no way out. Termination protection makes DeleteStack refuse, CancelUpdateStack stops a running update before its next resource ("User Initiated"), and ContinueUpdateRollback retries the failed deletes, honouring ResourcesToSkip. Contributed by @iot-rocket.
CloudFormation — the list and describe actions page — DescribeStacks, ListStacks, DescribeStackEvents, ListStackResources, ListExports, ListImports and ListChangeSets returned everything and ignored NextToken; they now return 100 items per page with a token for the rest (ListExports pages at 100 values on AWS, the others at 1 MB), a foreign token is a ValidationError, and events of one millisecond stay strictly newest-first across pages. Contributed by @iot-rocket.
CloudFormation — dynamic references resolve — {{resolve:ssm:...}}, {{resolve:ssm-secure:...}} and {{resolve:secretsmanager:...}} resolve at provisioning time against the in-process stores, with the version, JSON key and version-stage segments; GetTemplate keeps the literal. On update an ssm reference re-resolves when the template or parameters changed, a secretsmanager reference only when its resource changed, as measured on AWS. Contributed by @iot-rocket.
CloudFormation — DeletionPolicy and UpdateReplacePolicy are honoured — a Retain resource now stays (with a DELETE_SKIPPED event) on stack delete, on removal from the template and on replacement; RetainExceptOnCreate and DeleteStack's RetainResources behave as the API documents; Snapshot deletes, since the emulator takes no snapshots. Contributed by @iot-rocket.
Fixed
Lambda — the Docker executor extracts each code and layer zip once — every cold start unpacked the code and layers into a fresh temporary directory that accumulated (a 30 MB function wrote 60 MB of disk per cold start). Extraction is now content-addressed into one shared read-only directory per distinct zip, so a repeat cold start writes nothing; entries are swept when the referencing function or layer version goes, and a state reset clears the cache.
S3 Tables / Glue — the Iceberg REST catalogs honour upgrade-format-version — the commit action a Spark job sends for the format-version3 table property was silently dropped, so the table kept reporting version 2; real S3 Tables supports Iceberg v3. Both catalogs now apply it atomically: re-asserting the current version is a no-op, a downgrade or a version above 3 is refused with 400 and commits nothing.
CloudFormation — Fn::Cidr, Fn::GetAZs, Fn::FindInMap and the condition functions follow AWS — Fn::Cidr now splits the block it is given (was 10.0.{i}.0/… always; IPv6 included), Fn::GetAZs answers the stack's own zones (was a fabricated a/b/c), Fn::FindInMap gains DefaultValue and fails a missing key with Template error: Unable to get mapping for M::x::y, and Fn::And/Fn::Or/Fn::Not in a value position resolve to a boolean — all measured on AWS. Contributed by @iot-rocket.
S3 — the Multi-Region Access Point alias follows the documented pattern — the alias was 13 uuid-hex characters, so a digit-only draw was possible; it now matches S3's ^[a-z][a-z0-9]*[.]mrap$: a letter, then twelve lowercase letters or digits. Contributed by @iot-rocket.
CloudFormation — parameter constraints are enforced — AllowedPattern, MinLength, MaxLength, MinValue and MaxValue were ignored; they are checked before a stack exists with CloudFormation's message (Parameter 'P' must match pattern ^[a-z]+$, measured) or the ConstraintDescription, per member for a CommaDelimitedList. Contributed by @iot-rocket.
CloudFormation — an unregistered AWS::CloudFormation::* type is unrecognized, not a silent no-op — Macro, HookVersion, ModuleVersion and any typo under the prefix deployed as a placeholder with a fabricated physical id; the pre-flight now refuses them like every other unrecognized type. Contributed by @iot-rocket.
CloudFormation — the stack id addresses GetTemplateSummary and an UPDATE change set — both looked the id up by name and answered "does not exist" while every other action accepted it; DescribeStackResource(s) also answered a request by id with the id in StackName. Contributed by @iot-rocket.
CloudFormation — a change set sees DeletionPolicy, UpdateReplacePolicy and Metadata edits — the diff compared Properties only, so a CDK removalPolicy edit ended FAILED with "didn't contain changes"; those attributes now count as a Modify with Replacement: False, reported in Scope and Details, while a DependsOn-only edit stays a no-change set, as on AWS. Contributed by @iot-rocket.
CloudFormation — a leftover whose delete failed stays visible, and the resource record serves ResourceStatusReason, Metadata and LastUpdatedTimestamp — a resource dropped from the template whose cleanup delete failed vanished from the record while it kept existing, and DeleteStack never retried; it now stays listed as DELETE_FAILED with its reason, the next update and DeleteStack retry it. DescribeStackResource(s) carry ResourceStatusReason; the detail names its timestamp LastUpdatedTimestamp as StackResourceDetail defines (clients dropped the Timestamp element it sent) and returns the resource Metadata with intrinsics interpreted. Contributed by @iot-rocket.