Skip to content

v1.5.8

Latest

Choose a tag to compare

@Nahuel990 Nahuel990 released this 05 Sep 01:01
b2b5510

What's Changed

[1.5.8] — 2026-09-05

Added

  • CloudFormation — AWS::IoT::ThingGroup provisions — a stack carrying a thing group rolled back with Unsupported resource type while the thing-group API worked. The type now provisions through CreateThingGroup (ThingGroupProperties and ParentGroupName applied, a name generated when ThingGroupName is omitted), Ref returns the thing group id and Fn::GetAtt serves Arn and Id, as the resource reference documents; ThingGroupProperties updates in place, while ThingGroupName and ParentGroupName require replacement, a parent change under an unchanged custom name getting CloudFormation's own refusal. QueryString (dynamic groups) and Tags are accepted without effect: the service models neither. Contributed by @iot-rocket.
  • CloudFront — the policy, OAC and function types provision from CloudFormationAWS::CloudFront::CachePolicy, OriginRequestPolicy, ResponseHeadersPolicy, OriginAccessControl and Function had complete APIs and no provisioner, so a CDK app declaring any of them rolled the stack back with Unsupported resource type. Each now provisions by converting its properties to the element the service's own config parser accepts, Ref/Fn::GetAtt return the documented values (policy Id, OAC Id, function FunctionARN), deletes are wired, and an update replaces rather than mutating in place. Contributed by @mm-salesqueze.
  • S3 — Multi-Region Access Points deploy and serveAWS::S3::MultiRegionAccessPoint rolled the stack back with Unsupported resource type and the MRAP hostname resolved nowhere. The type now provisions, minting the .mrap-suffixed alias S3 uses and remembering its member buckets, and <alias>.accesspoint.s3-global.amazonaws.com resolves onto the existing virtual-hosted S3 path — the member whose bucket region matches the request region is served, else the first. SigV4A is not verified, consistent with the documented no-SigV4 stance, and the s3control control plane is not included. Contributed by @mm-salesqueze.
  • RDS — planned Aurora MySQL switchover runs on the data planeSwitchoverGlobalCluster (and FailoverGlobalCluster without data loss allowed) on a provisioned two-member Aurora MySQL 8 global cluster now performs a coordinated no-data-loss writer exchange: the source writer is fenced and drained, GTID convergence awaited, replication reversed and verified, and the promoted target verified writable, with conflicting mutations blocked mid-operation and recovery state persisted across restarts — an interrupted switchover is repaired by retrying the same request. Non-native configurations and AllowDataLoss=true keep the metadata-only path. Contributed by @Areson.
  • RDS — FailoverDBCluster promotes replicated PostgreSQL readers — with MINISTACK_RDS_PG_CLUSTER_REPLICATION=1, failover now calls pg_promote() on the selected hot standby, makes it the writer endpoint, and re-clones the former writer with pg_basebackup as a read-only standby. Metadata changes only after promotion succeeds; shared-container clusters retain their existing metadata-only behavior. Contributed by @Kiran01bm.

Fixed

  • CloudFormation — stack updates stop destroying resources — a changed property on a type without an update handler fell through to a destructive re-create: generated-identity types came back empty under a new id with the old resource orphaned (Cognito pools and clients, Secrets Manager secrets, API Gateway authorizers and deployments), name-keyed ones wiped their data (Kinesis records, ECR images, group members, alarm state and history), and others failed the stack outright (any Route53 record edit, any EventBus property change). Nineteen types now update in place through their service's own APIs — AWS::Cognito::UserPool/UserPoolClient/IdentityPool/UserPoolGroup (including EnabledMfas via SetUserPoolMfaConfig), AWS::SecretsManager::Secret (a changed value becomes the new AWSCURRENT, same ARN, history kept), AWS::Kinesis::Stream, AWS::ECR::Repository, AWS::DynamoDB::GlobalTable, AWS::Events::EventBus, AWS::Events::Rule, AWS::CodeBuild::Project, AWS::Route53::RecordSet, AWS::Scheduler::Schedule, AWS::StepFunctions::StateMachine, AWS::CloudWatch::Alarm, AWS::IAM::Policy, AWS::ApiGateway::Authorizer, AWS::ApiGateway::Deployment and AWS::KMS::Alias — only the properties the resource references mark Replacement replace (the new resource is created before the old one is removed, and a custom-named resource requiring replacement gets CloudFormation's own refusal), and a property the template drops reverts to its create default. The engine gains real replacement semantics: when an update returns a new physical id, the predecessor is deleted in a cleanup phase, as CloudFormation does after UPDATE_COMPLETE. Contributed by @iot-rocket.
  • CloudFormation — AWS::Lambda::Permission is replaced on update and removed on delete — a stack update that changed a permission fell through to the create handler and appended a second statement, a permission declared without the legacy Id was never removed at all, and EventSourceToken, FunctionUrlAuthType, InvokedViaFunctionUrl, PrincipalOrgID and SourceAccount were dropped on the way to the statement. Every property of the type requires replacement, so an update now removes the old statement and adds the new one under a fresh generated Sid — the resource's physical id, the shape real CloudFormation mints — and all nine documented properties reach the statement as conditions. Contributed by @iot-rocket.
  • CloudFormation — a failed update keeps the pre-existing resources when it rolls back — the rollback of a failed stack update deleted every resource the run had touched, and a run touches every resource in the template: unchanged resources and resources updated in place went down together with what the update had actually created. The rollback now deletes only what the update created and replacements under a new physical id; a resource that kept its physical id is left standing. An in-place change is not reverted, and a replacement's old resource, already removed by the update, is not recreated. Contributed by @iot-rocket.
  • CloudFormation — a rolled-back update reports what the stack ran before — after UPDATE_ROLLBACK_COMPLETE, GetTemplate returned the template that failed and DescribeStacks the failed update's parameters and tags, so a cdk diff after a failed deploy compared against the wrong base. The rollback now restores the previous template body, parameters and tags together with the resources and outputs. Contributed by @iot-rocket.
  • CloudFormation — an export counts as in use only when a stack imports itDeleteStack searched the serialized templates of every other stack for the export name, so a stack that merely carried the name in a string value blocked the delete, while an import through a resolved Fn::ImportValue argument did not. The check now walks the other stacks' Fn::ImportValue uses and resolves their arguments against those stacks' own parameters, as CloudFormation does. Contributed by @iot-rocket.
  • CloudFormation — UpdateStack without changes is refused — an identical TemplateBody, or UsePreviousTemplate with unchanged parameters, ran an empty update where CloudFormation answers ValidationError: No updates are to be performed., so a "deploy until nothing changes" loop never ended. The request is refused when the template, every resolved parameter and the tags (when sent) equal what the stack runs; a changed parameter value or tag set is still an update. Contributed by @iot-rocket.
  • CloudFormation — unrecognized resource types are rejected up front, Fn::GetAtt to a missing attribute fails the stack — a template with a resource type the emulator does not know provisioned every resource ahead of it before rolling back; CreateStack, UpdateStack, CreateChangeSet and ValidateTemplate now refuse it synchronously with CloudFormation's own Template format error: Unrecognized resource types: [...] and leave no stack behind, and dynamic references ({{resolve:ssm:...}}, {{resolve:secretsmanager:...}}), which the emulator does not resolve, are refused the same way. Fn::GetAtt to an attribute a resource does not expose answered with the physical id, a silently wrong value; it now fails the operation with Requested attribute X does not exist in schema for T, and outputs are resolved before the success path commits, so a failing output rolls back too and registers no export. Contributed by @iot-rocket.
  • CloudFormation — DeleteChangeSet of a change set that does not exist succeeds — it answered ChangeSetNotFound (404) where a real account answers a plain success, so the CDK — which removes a possible leftover cdk-deploy-change-set before every deploy and only tolerates ChangeSetNotFoundException — aborted every cdk deploy of an already deployed stack. The stack is now resolved by name or stack ID first; a stack that does not exist is still a ValidationError. Contributed by @iot-rocket.
  • CloudFormation — AWS::Events::Rule reports the rule ARN the EventBridge service reportsFn::GetAtt Arn was built with the bus name in every case, so a rule on the default bus answered rule/default/<name> while DescribeRule for the same rule answered rule/<name>. The provisioner now derives the ARN through the service's own helper: no bus segment on the default bus, rule/<bus>/<name> on a custom one. Contributed by @iot-rocket.
  • CloudFormation — AWS::Cognito::UserPool reads UserPoolName — the provisioner read PoolName, the API's name for the property, where the resource reference defines UserPoolName, so every pool declared with the documented property came up under a generated <stack>-<logical id> name. UserPoolName is honoured now; PoolName stays accepted for templates written against MiniStack. Contributed by @iot-rocket.
  • CloudWatch — PutMetricAlarm keeps the state timestamp of an existing alarm — re-putting an alarm stamped a fresh StateUpdatedTimestamp on every call, so an alarm that had been in ALARM for an hour reported a state change that never happened whenever its configuration was touched. The state, its reason and its timestamp now stay across the re-put and only AlarmConfigurationUpdatedTimestamp moves, as the API reference documents; both request encodings. Contributed by @iot-rocket.
  • IAM enforcement — the remaining S3 operations authorize as S3 documents them — with AUTH=true, a browser POST Object was checked as s3:DeleteObject, a request naming a versionId as the unversioned action, DeleteObjects once against the bucket ARN (so a grant on arn:aws:s3:::bucket/* denied every batch delete), CopyObject / UploadPartCopy without s3:GetObject on the source, and fifteen sub-resources fell to the method default. Each now maps to the action the S3 reference lists, a versionId resolves to the *Version* action, and both enforcement sites run the per-request checks (per key, source object, attributes pair, governance bypass). Contributed by @iot-rocket.
  • DynamoDB — PartiQL and validation parity measured against real DynamoDBExecuteStatement serves SELECT from "table"."index" (membership, projection, ordering and consumed capacity follow the index; an LSI reaches back to the base table for unprojected attributes, a GSI rejects them), document paths in SET/REMOVE, OR predicates and RETURNING MODIFIED OLD/NEW * computed from the paths actually changed; BatchExecuteStatement reports per-statement error entries and ExecuteTransaction validates every member before applying anything. Query and Scan answer the Select/ProjectionExpression refusals with real DynamoDB's wording, a KeyConditionExpression on a nested attribute is rejected (KeyConditionExpressions cannot have conditions on nested attributes), ConsumedCapacity lands on the index arm for index reads, and writes validate secondary-index key values — wrong-typed or empty as a ValidationException on single writes and as a positional cancellation reason in transactions. Reported by the paritysuite.org project.
  • Lambda — durable executions emit the complete history event set — four of the documented history event types were never emitted. Each handler invocation now records InvocationCompleted; DurableConfig.ExecutionTimeout is enforced — the execution lands TIMED_OUT with an ExecutionTimedOut event and every in-flight chained invoke gets its own ChainedInvokeTimedOut; StopDurableExecution marks in-flight chained invokes with ChainedInvokeStopped; and ChainedInvokeStarted is on the log before a fast child can complete.
  • Cognito — the PreSignUp trigger fires on plain SignUp — only federated sign-ups invoked it; a pool's LambdaConfig.PreSignUp now runs before the user is persisted, fail-closed: autoConfirmUser confirms the account (no code delivery), autoVerifyEmail/autoVerifyPhone mark the attributes, and a rejecting or failing trigger blocks the sign-up with UserLambdaValidationException, per the trigger's documented contract.
  • STS — sessions expire and the store stops growingGetCallerIdentity with expired temporary credentials answers 403 ExpiredToken ("The security token included in the request is expired", the documented STS error), and expired sessions are evicted as new ones register — previously every AssumeRole and vended identity-pool credential lived in memory forever.