What's Changed
[1.4.21] — 2026-08-20
Added
- IoT Core — native mTLS MQTT listener on port 8883 — the embedded broker now also accepts MQTT over TLS on 8883 (
IOT_MTLS_ENABLED=0turns it off,IOT_MTLS_PORTmoves it), on by default whencryptographyis present, so AWS IoT Device SDK binaries can connect. The broker certificate comes from the local CA (GET /_ministack/iot/ca.pem); a client certificate is optional (none is served underMINISTACK_ACCOUNT_ID, like an unsigned WebSocket upgrade) and an unknown or non-ACTIVEcertificate is refused with a0x05CONNACK. Contributed by @iot-rocket. - RDS — replicated Aurora PostgreSQL readers survive StopDBCluster / StartDBCluster and warm boot — under
MINISTACK_RDS_PG_CLUSTER_REPLICATION,StopDBClusternow stops the reader containers alongside the writer andStartDBClusterrevives each reader by re-cloning from the writer; the same revival runs on warm boot, so a persisted reader comes back as a real hot standby instead of being demoted to a writer alias. Contributed by @Kiran01bm. - CloudFormation —
AWS::SES::ConfigurationSetandAWS::SES::ConfigurationSetEventDestination— a template carrying an SES configuration set no longer fails with "Unsupported resource type"; both resource types provision (registered in the classic and v2 SES stores,Refreturns the set name, the event destination round-trips), CloudFormation-provisioning fidelity only. Contributed by @ryan-bennett.
Fixed
- API Gateway (REST) — routing is on the resource+method pair, not the resource alone — a request a matched resource does not serve (a methodless intermediate node, a CORS-preflight-only node, or an undeclared verb) now falls through to a
{proxy+}elsewhere in the tree as it does on AWS; only an exact resource+method match keeps the request, and routing precedes authorization. Supersedes the 1.4.16 change that answered a methodless resource403. Contributed by @iot-rocket. - Step Functions — an unimplemented optimized service integration fails instead of silently succeeding — a Task using an
arn:aws:states:::<service>:<action>integration MiniStack does not implement fell through to echoing its input back asSUCCEEDED; it now fails withStates.Runtimenaming the unimplemented resource. Reported by @iwasakar. - CloudFormation — a replacement of a custom-named resource is refused instead of destroying data — an update requiring replacement of a resource with an explicit physical name (for example changing a DynamoDB key attribute's type on a table that sets
TableName) now fails and rolls back toUPDATE_ROLLBACK_COMPLETEwithCloudFormation cannot update a stack when a custom-named resource requires replacing. Rename <name> and update the stack again., leaving the resource and its data intact. Reported by @iot-rocket. - CloudFormation — change sets report a valid status, fail when execution fails, and do not outlive their stack —
ExecuteChangeSetwrote the invalidEXECUTE_COMPLETEintoStatus, breaking the CDK'sStatus == CREATE_COMPLETEgate.Statusnow staysCREATE_COMPLETEwhileExecutionStatusmoves toEXECUTE_COMPLETEorEXECUTE_FAILEDon the deployment outcome. A no-change set endsFAILED, a missing set returnsChangeSetNotFound(404), a duplicate name isAlreadyExistsException, deleting a stack removes its change sets, executing one deletes the others, and a directUpdateStackmarks pending setsOBSOLETE. Reported by @iot-rocket. - RDS — Aurora engine versions are validated on non-create writes and global inheritance —
ModifyDBInstance,ModifyDBCluster,CreateGlobalCluster,ModifyGlobalCluster, and global-inheritedCreateDBClusternow reject engine versions the catalog does not advertise; modify paths returnInvalidParameterCombination/Cannot find upgrade target from {current} with requested version {requested}.,ModifyGlobalClusterpropagates an accepted version to every member, and a member moved to a different major than its global is refused. Contributed by @Kiran01bm. - RDS — global Aurora stop/start preserves topology and MySQL replication —
StopDBClusterandStartDBClusterare now limited to sole-member global databases (InvalidDBClusterStateFault, 400), deleting a primary's last instance preserves compute other global members still need, and a successful recreate resets stale MySQL replica state before re-linking replication. Contributed by @Kiran01bm. - S3 — a conditional delete of an absent key is answered correctly —
DeleteObjectwithIf-Matchon a key that is not there now returns204(deleting an already-gone key is done), andIf-Match: *is honored as an existence check — it holds against any present object and returns412 PreconditionFailedwhen the key is absent — rather than being compared as a literal ETag. Contributed by @gaul. - S3 — multipart uploads carry their parts' checksums through to a composite —
CreateMultipartUploadrecords the checksum algorithm,UploadPartvalidates and echoes each part's checksum, and completion builds the AWS composite (<digest>-<parts>, the digest of the parts' digests) read back throughChecksumModeasCOMPOSITE; a mismatch isBadDigest. Contributed by @gaul.