What's Changed
[1.5.39] — 2026-11-08
Added
- Secrets Manager —
RemoveRegionsFromReplicationandStopReplicationToReplica— both answeredUnknown action, soterraform destroyof a secret with areplicablock failed. The first deletes the listed regions' replicas and returns the remainingReplicationStatus; the second, called in a replica's region, makes it a standalone secret. Contributed by @kharabasz. - Cognito — attribute verification — adds
GetUserAttributeVerificationCodeandVerifyUserAttribute. A changed email or phone number now becomes unverified and gets a code where the pool auto-verifies it, andAttributesRequireVerificationBeforeUpdatekeeps the old value until the new one is verified. Contributed by @toby6578. - Cognito — hosted UI forgot password and MFA — the hosted sign-in pages now have a forgot-password flow, ask for a TOTP or SMS code after the password, and enrol TOTP where the pool requires MFA. Messages match AWS's classic hosted UI; the pages render straight from
POST /login, and reset codes are checked only withAUTH=true. Contributed by @toby6578. - Cognito — RFC 8707 resource indicators on managed login — on a
ManagedLoginVersion2 domain, aresourcenaming one of the pool's resource servers now becomes the access token'saud, and refreshes keep it. An unregistered one fails the code exchange withinvalid_grant. Contributed by @toby6578. - Cognito — the
PostAuthenticationtrigger —LambdaConfig.PostAuthenticationwas stored and never invoked. It now runs after a password, MFA or challenge sign-in through the API, before tokens are issued and beforeNEW_PASSWORD_REQUIRED, but not on refresh. A failing Lambda fails the sign-in withUserLambdaValidationException,InvalidLambdaResponseExceptionorUnexpectedLambdaException. Reported by @ryuzo-hayashi. - CloudFront —
cf.kvs()in CloudFront Functions —import cf from 'cloudfront'failed incloudfront-js-2.0.get()(string, json or bytes),exists()andmeta()now read the function's associated KeyValueStore; a missing key throwsKeyNotFound, andcf.kvs()in a function without a store throwsInternalError. Reported by @mkusaka. - KMS — the
aws/s3AWS managed key — an S3 write withaws:kmsand no key ID (oralias/aws/s3) was refused. S3 now creates the account'saws/s3key on first use (KeyManagerAWS, AWS's description and key policy, aliasalias/aws/s3) and encrypts with it, as does a bucket default ofaws:kmswithoutKMSMasterKeyID. Contributed by @kharabasz. - S3 — PutObject through another account's access point — it was refused. It now succeeds when the caller's identity policy, the access point policy and the owner's bucket policy all allow it, and lands in the owner's bucket under its default encryption; a missing grant answers AWS's AccessDenied for that step. Contributed by @kharabasz.
Changed
- Secrets Manager — a request body that is not one JSON object — an empty or blank body was read as
{}, and[],nullor a bare string crashed with a 500. Every action now answersSerializationExceptionfor a body that is not a single JSON object (a list names itself, the rest carry no message); whitespace around the object is fine. Contributed by @kharabasz. - Secrets Manager —
DeleteSecreton a primary that still has replicas — it deleted the replicas with the primary. It now answersInvalidParameterException("You can't delete secret … that still has replica regions [...]"), so replicas are removed first; called in a replica's region it answers "Operation not permitted on a replica secret". Contributed by @kharabasz.
Fixed
- RDS — Aurora member reboots no longer stick — after
ModifyDBClusterrotated the master password, a rebooted member stayedrebootingor wentfailed; its readiness check now uses the cluster's password. Deleting an instance no longer recomputes every cluster's status, which left a cluster with a member mid-reboot increating. Contributed by @jayjanssen. - Auto Scaling —
InstanceRequirementslaunch templates and overrides are checked — a plainLaunchTemplatewithInstanceRequirementsnow answersInvalidQueryParameter, and bad overrides (neither or both ofInstanceTypeandInstanceRequirements, mixed kinds, partial weights, duplicates, more than 40) answerValidationErrorwith AWS's messages. Contributed by @kharabasz. - S3 — SSE-KMS keys are resolved through KMS — a write stored the key reference as given and accepted keys that do not exist. It now stores and echoes the key ARN and refuses an unknown key with
KMS.NotFoundExceptionbefore any authorization, as on AWS; a write naming a key MiniStack's KMS does not hold now fails, so create the key first. Contributed by @kharabasz. - S3 — bucket policies on
s3:x-amz-server-side-encryption-aws-kms-key-id— withAUTH=truethe key was never set, so a policy denying uploads under any other KMS key also denied the right one. Writes now carry the key ARN however the key is named, or the bucket default's, and multipart parts carry their upload's key. Contributed by @kharabasz. - Auto Scaling —
DesiredCapacityTypeis reported as AWS reports it — since 1.5.38 every group reportedunits, so Terraform planned a change on every run. Only a group with aMixedInstancesPolicynow has one,vcpuandmemory-mibneedInstanceRequirements, and state saved by 1.5.38 is cleaned on restore. Contributed by @kharabasz. - CloudFront —
Compress: truecompresses responses — origin responses passed through uncompressed. They are now gzipped, or Brotli-encoded when the optionalbrotlipackage is installed, under AWS's conditions (status, size,Content-Type, noContent-Encoding); a strongETagbecomes weak, and the origin gets the normalizedAccept-Encoding(br,gzip,gzip,broridentity). Reported by @skialpine. - Cognito — MFA through the API — a user whose pool requires MFA and who has no factor signed in without one. They now get
MFA_SETUPand, once enrolled, aSOFTWARE_TOKEN_MFAchallenge; a TOTP enrolled on the hosted pages is challenged by the API too, and five wrong codes lock the user out for a growing time, at most 15 minutes. - IAM — request condition keys with
AUTH=true— keys such ass3:signatureversion,s3:x-amz-storage-class,kms:EncryptionContext:*,secretsmanager:VersionStage,ssm:Overwrite,sns:Protocol,ec2:Regionandiam:PermissionsBoundarywere never set, so a policy conditioned on them denied valid requests. They are now set from the request. - S3 —
ListMultiRegionAccessPointspages — the token was a position, so a create or delete between pages skipped or repeated an access point; it now names the last one returned.