github ministackorg/ministack v1.5.1

5 hours ago

What's Changed

New Contributors

[1.5.1] — 2026-08-25

Added

  • SNS — GetPlatformApplicationAttributes / SetPlatformApplicationAttributes — both actions answered 400 InvalidAction, so terraform plan on an aws_sns_platform_application failed at refresh. Get returns the attribute map, Set merges the supplied entries, with InvalidParameter (400) for a missing parameter and NotFound (404) for an unknown application; CreatePlatformApplication also seeds Enabled=true, as AWS reports for a new application. Contributed by @jgrumboe.
  • Step Functions — States.StringSplit and States.Hash intrinsics — both raised States.Runtime: Unsupported intrinsic function, and splitting $$.Execution.Id on : is how a machine recovers its own region and account id. StringSplit treats every character of its second argument as a delimiter and keeps no empty member; Hash computes the five published algorithms as lowercase hex, shares the base64 intrinsics' 10,000-character cap, and refuses any other algorithm. Contributed by @bandle.
  • RDS — RDS Proxy (control plane)CreateDBProxy and the twelve other proxy operations answered InvalidAction, so an aws_db_proxy definition could not be applied at all. Proxies, endpoints, the default target group and registered targets now create, describe, modify and delete with the documented shapes, defaults, constraints and faults; creating a proxy also creates its default endpoint and default target group, as AWS does. Metadata only — nothing listens on the proxy hostname. Reported by @jmreicha.
  • EC2 — opt-in launch options for instance containers (EC2_DOCKER_FLAGS) — an image that boots an operating system (systemd as PID 1) needs container options the fixed launch arguments cannot express. EC2_DOCKER_FLAGS takes a docker-CLI-style string (--privileged, --cap-add, -e, -v, ...) applied to every instance container; unset, nothing changes, and --init is refused. Contributed by @iot-rocket.

Changed

  • Docker — the slim image ships the MySQL IAM auth plugins — the plugins were compiled only into the -full flavor, so on the slim image Aurora MySQL IAM authentication silently disabled itself. The slim build now copies the plugin tree from the published full image, pinned to the release's digest so both flavors carry the same tree. Contributed by @Areson.

Fixed

  • IAM — a resource-scoped policy works for JSON-protocol services (AUTH=true)extract_resource_arn read SQS, ACM, SSM and CloudWatch parameters from the query form only, so for current SDKs the resource fell back to * and every queue-, certificate-, parameter- or alarm-scoped statement denied. The request body is now read too, and SQS also resolves a queue addressed by path. Reported by @rsimples.
  • IAM — kms:Decrypt resolves the key from the ciphertext (AUTH=true)Decrypt and ReEncrypt carry no KeyId for a symmetric key, so the resource fell back to * and a policy naming the key allowed Encrypt but denied Decrypt. The key id is now recovered from the ciphertext blob the same way the KMS handler recovers it. Reported by @rsimples.
  • Lambda — CreateFunction with an unresolvable role answers 400, not 500 (AUTH=true) — the role check's error was swallowed inside config building, so the client got 500 InternalError and a half-created record was left behind. The role is now validated before anything is stored, answering 400 InvalidParameterValueException. Reported by @rsimples.
  • Cognito — group membership records the resolved UsernameAdminAddUserToGroup stored the caller-supplied name, which in a UsernameAttributes = ["email"] pool is an alias rather than the user key, so ListUsersInGroup dropped the member and AdminRemoveUserFromGroup never matched it. Both now key on the resolved Username. Contributed by @Lukasdoe.
  • Cognito — AdminDeleteUser deletes the user an email alias resolves to — the delete was keyed on the caller-supplied name after resolving the alias, so it raised KeyError, answered 500 InternalError, and the user survived; a delete-then-create seed failed UsernameExistsException on every run after the first. Contributed by @Lukasdoe.
  • S3 — a presigned upload no longer drops the x-amz-* headers it was signed with — SigV4 lets a presigned URL hoist the operation's x-amz-* headers into the query string, and real S3 applies them as the headers they stand for; MiniStack only read headers, so a presigned PutObject stored the object without its metadata. Hoisted params are now folded back into the headers before routing, an explicitly sent header still winning. Contributed by @dennmart.
  • S3 — a supplied checksum is verified, however it arrives — an x-amz-checksum-* value was only checked when the request also named x-amz-sdk-checksum-algorithm, so a mismatched value was stored unread and echoed on later reads as though verified, and a checksum sent as an aws-chunked trailer never arrived at all. Every supplied value is now recomputed (BadDigest on mismatch) and trailing headers are lifted into the request headers. Contributed by @gaul.
  • Step Functions — the aws-sdk:cloudwatchlogs integration routes — Step Functions names CloudWatch Logs by its SDK service id, so the documented arn:aws:states:::aws-sdk:cloudwatchlogs:createLogGroup failed States.Runtime before dispatch; only the endpoint-prefix spelling logs, which AWS does not accept, was registered. The documented name now dispatches, takes PascalCase Parameters, and surfaces errors as CloudWatchLogs.*. Contributed by @bandle.
  • Glue — a Spark job's own SDK clients reach MiniStack — only the S3A endpoint was configured, so a bare boto3.client("s3") in a job script escaped to real AWS and failed InvalidAccessKeyId. The container now carries AWS_ENDPOINT_URL, and because the Glue 4.0 image's botocore predates that variable, a bootstrap defaults every client's endpoint_url before running the script unchanged.
  • CloudFormation — Fn::Sub honors the ${!Literal} escape — the leading ! was not recognized, so ${!Literal} rendered as !Literal with the braces consumed and registered a false dependency; an AWS::IoT::Policy pinned to ${!iot:Connection.Thing.ThingName} deployed with a document matching nothing. It now renders as the literal ${Literal}. Contributed by @maximoosemine. Reported by @iot-rocket.
  • EventBridge — dotted pattern keys resolve to the nested path — Event Ruler joins keys with ., so {"detail.name": [...]} and the nested spelling are the same rule on AWS, but the 1.4 matcher read a dotted key as one literal segment and such a rule silently matched nothing; dotted-form rules that delivered on 1.3.x stopped after upgrading. Pattern keys are now split on . when the compiler extends the path. Contributed by @prandogabriel.
  • IoT Core — an unresolvable action role fails CreateTopicRule instead of silently dropping the rule (AUTH=true) — the role-check error was discarded and the API answered 200 {} while storing nothing. CreateTopicRule / ReplaceTopicRule now answer 400 InvalidRequestException (Unable to assume role: {arn}) as real IoT does, and the CloudFormation provisioner fails the resource. Contributed by @iot-rocket.
  • RDS — Aurora PostgreSQL major-version selectors return the matching catalogDescribeDBEngineVersions treated EngineVersion=16 as an exact version and returned nothing; major-only selectors now return every advertised minor in that family, and DefaultOnly=true narrows to AWS's configured default minor for that major. Contributed by @jayjanssen.

Don't miss a new ministack release

NewReleases is sending notifications on new releases.