What's Changed
New Contributors
- @jbschooley made their first contribution in #1549
[1.5.3] — 2026-08-28
Added
- Step Functions — the JSONata query language — a state machine declaring
QueryLanguage: JSONatanow evaluates its{% ... %}expressions through a full JSONata engine:$statesand workflow variables bind as documented, the six Step Functions functions ($partition,$range,$hash,$random,$uuid,$parse) are registered, failures surface asStates.QueryEvaluationErrorwith the JSONata error code leading the cause (T2010: ...), a malformed expression is refused atCreateStateMachine/UpdateStateMachinewithInvalidDefinition(INVALID_JSONATA_EXPRESSIONnaming the field's path) as AWS refuses it, a non-ISO$toMillisargument and a zero-length-matching$replaceregex draw AWS'sD3110/D1004, and evaluation carries AWS's 1-second timeout.$evalis absent, as on AWS. Reported by @facuparedes. - IoT Core — jobs delivered over MQTT — the reserved
$aws/things/<t>/jobs/#request topics (get,start-next,<jobId>/getincluding$next,<jobId>/update) answer on theiraccepted/rejectedtopics from the same store the HTTP plane uses, withjobDocumentas a JSON object over MQTT (a string over HTTP, as on AWS) and rejections carrying the stringErrorCodevalues plus the execution's state on version and state-transition conflicts;notifyfires when the pending set changes andnotify-nextonly when the queue front changes.stepTimeoutInMinutesandexecutionNumberare accepted but ignored. Contributed by @iot-rocket. - IoT Core — provisioning templates, and
AWS::IoT::ProvisioningTemplate—CreateProvisioningTemplateand the four other template operations answeredUnsupported IoT pathand the CloudFormation type rolled back as unsupported; both now work with the wire shapes of the real service (ResourceAlreadyExistsExceptionon duplicates, absent-not-emptydescription, 1-36 char names, atemplateBodywithout anAWS::IoT::Certificateresource refused). Storage + CRUD only: the fleet-provisioning MQTT workflow is not implemented and versions are not modeled. Contributed by @iot-rocket. - API Gateway — registered custom domains route the data plane — a request addressed by a registered domain fell through host-pattern service guessing (typically into S3, or into IoT when the name contained
iot.); it now resolves through the domain's base-path mappings before any guessing — longest base path wins,"(none)"is the root mapping, a mapping's stage is authoritative — matching theBASE_PATH_MAPPING_ONLYrouting mode the records default to. Unregistered hosts are unchanged. Contributed by @iot-rocket. - CloudFormation — in-place update handlers — a stack update fell through to a destructive re-create for 106 of 132 registered types, wiping published Lambda versions, DynamoDB items, SQS messages and IAM attachments;
AWS::Lambda::Function,AWS::DynamoDB::Table, the four API Gateway types,AWS::IoT::TopicRule,AWS::SNS::Topic,AWS::SQS::Queue,AWS::Logs::LogGroup,AWS::S3::BucketPolicy,AWS::IAM::RoleandAWS::IAM::ManagedPolicynow update in place through their service's own APIs, replacing only for genuinely create-only properties, as CloudFormation documents per property. Contributed by @iot-rocket. - S3 — replication delivers, with
x-amz-replication-status— a bucket's replication configuration was stored and echoed but never acted on: no object ever reached the destination andHeadObjectshowed no replication metadata. A write (put, POST upload, copy, or multipart complete) matching an Enabled rule's prefix now lands a copy in the destination bucket with its own version, the source's metadata, storage class override, and tags; the source object answersReplicationStatus: COMPLETED(orFAILEDwhen the destination is gone or no longer versioned) and the replica answersREPLICA, on current and version-addressed reads alike. The copy is synchronous so tests see a deterministic status. Delete-marker replication and replica re-replication are not modeled. Reported by @cringdahl.
Fixed
- CloudFormation — a resource that cannot be deleted fails the operation — a missing delete handler was a log warning and
DeleteStackreportedDELETE_COMPLETEwhile resources lived on; the stack now landsDELETE_FAILED(failed resources retained for a retry, exports kept, deleted siblings gone) and a failed rollback landsROLLBACK_FAILED/UPDATE_ROLLBACK_FAILED, per the documented lifecycle.AWS::Lambda::Versiongained a real delete handler (itsRefnow returns the qualified version ARN, as on AWS) andAWS::AppSync::GraphQLSchemaone that removes the stored schema. Contributed by @iot-rocket. - IoT Core — an HTTP shadow write publishes the reserved-topic notifications —
UpdateThingShadowover the REST data plane stored state and emitted nothing, so a topic rule on.../shadow/update/acceptedfired for MQTT updates only; an accepted HTTP update now publishesupdate/accepted/delta/documents(and a delete itsdelete/accepted) through the same emission code as the MQTT bridge, which also fixed thedocumentsenvelope on both transports: it now echoes the request'sclientTokenand carriesstate+metadata+versiononly. Contributed by @iot-rocket. - IoT Core — device-plane job timestamps were milliseconds, 1000x off —
iot-jobs-dataresponses served epoch milliseconds where the API reference words every stamp "in seconds since the epoch"; every device-plane stamp, HTTP and MQTT alike, is now whole epoch seconds. Contributed by @iot-rocket. - Step Functions — execution status changes are published to EventBridge — real Step Functions automatically emits
source: aws.states/detail-type: "Step Functions Execution Status Change"to the default bus whenever a standard execution changes status; MiniStack ran the execution and published nothing, so a rule matching those events never fired and applications waiting on them hung with no error anywhere. EveryStartExecutionnow emitsRUNNINGand its completionSUCCEEDED,FAILED(witherror/causeandREDRIVABLE) orABORTEDonStopExecution, carrying the documented detail fields with epoch-millisecond dates; payloads over 248 KiB are excluded and flagged viainputDetails/outputDetails, andStartSyncExecution(the express-flavored path) emits nothing, as on AWS. Reported by @moonyseven. - ECS — a service's tasks register in its target groups — a
loadBalancersblock was stored and never acted on, soDescribeTargetHealthstayed empty and every request through the load balancer fell to the listener's default action; a service now reconciles its target groups from its running tasks' addresses (awsvpc tasks carry their address asattachments[].details[privateIPv4Address], where real ECS reports it), withdrawing only its own registrations so manually registered targets and a second service sharing the group survive, as on AWS. Contributed by @jbschooley. - ECS — an
awsvpctask no longer publishes host ports — eachawsvpctask has its own network namespace on AWS, so container ports never bind on the host; publishing them made two tasks sharing a container port collide with a Docker bind error that cannot happen on Fargate. Onlybridgeandhostmodes publish. Contributed by @jbschooley. - ELBv2 — a rule condition sent as a typed config is read — only the flat legacy
Valueslist was parsed, so a rule created by Terraform (which sendsPathPatternConfig/HostHeaderConfig/HttpRequestMethodConfig/SourceIpConfig) stored an empty condition and never fired; both shapes now parse,DescribeRulesechoes the typed config alongsideValuesas AWS does, and the data-plane matcher recognizes AWS'shttp-request-methodfield name. Contributed by @jbschooley.