What's Changed
[1.5.35] — 2026-10-30
Added
- API Gateway —
PutRestApi—PUT /restapis/{id}answered 404, so Terraform'saws_api_gateway_rest_apiwith abodyfailed; it now imports an OpenAPI or Swagger definition (JSON or YAML) inmergemode (the default) oroverwritemode, which also removes the API's authorizers, and in both modes the API takes its name frominfo.titleits description frominfo.description(removed when absent) and itsversionfrominfo.version. An unknown API answersInvalid API identifier specified <account>:<id>, a body that is no definitionUnable to determine OAS/Swagger versionand a badmodeAWS's enum validation message.ImportRestApinow imports its definition too, where it created an empty API namedunnamed. Reported by @mindsers. - API Gateway — client certificates —
GenerateClientCertificate,GetClientCertificate,GetClientCertificates,UpdateClientCertificateandDeleteClientCertificate, with a 6-character id, a self-signed PEM certificate (C=US, L=Seattle, CN=ApiGateway) valid for one year, tags on the certificate's ARN, and AWS's errors:Invalid client certificate id specified(404, and 400 for a stage's/clientCertificateIdpatch) andInvalid patch path '<path>' specified for op '<op>'. Must be one of: [/description]. Reported by @mindsers. - API Gateway — domain name access associations —
CreateDomainNameAccessAssociation,GetDomainNameAccessAssociations,DeleteDomainNameAccessAssociationandRejectDomainNameAccessAssociationfor private custom domain names, named by theirdomainNameArn, with the ARN.../domainnameaccessassociations/domainname/<name>+<domainNameId>/vpcesource/<vpce>and tags on it. A duplicate, an unknown domain or a VPC endpoint EC2 doesn't hold answer 400BadRequestException"The domain name access association between this VPC endpoint and domain name already exists.", "Domain not found" and " is not a valid VPC endpoint id"; rejecting an association of your own, or any after the domain is deleted, answers 404 "This private custom domain name doesn't have any domain name access associations." and keeps it. Reported by @mindsers. - ELBv2 — listener certificates —
AddListenerCertificates,DescribeListenerCertificatesandRemoveListenerCertificates, as on AWS: one certificate per call,CertificateNotFoundfor a certificate ACM doesn't hold, the default certificate listed last withIsDefaulttrue and never removed. Reported by @kharabasz. - IAM — service-specific credentials and server certificates — clients that call
ListServiceSpecificCredentialsorListServerCertificatesgotInvalidAction.CreateServiceSpecificCredential,ListServiceSpecificCredentials,UpdateServiceSpecificCredential,ResetServiceSpecificCredentialandDeleteServiceSpecificCredentialnow answer: a CodeCommit or Keyspaces credential is aServiceUserName(<user>-at-<account>) andServicePassword, a Bedrock, Claude Platform on AWS, CloudWatch or CloudWatch Logs one aServiceCredentialAliasandServiceCredentialSecretwith theExpirationDatefromCredentialAgeDays; the password or secret is returned only on create and reset, another service answersNotSupportedService(404), andUserNamemay be omitted by an IAM-user caller while a non-user caller without it getsInvalidInput.UploadServerCertificate,ListServerCertificates,GetServerCertificate(with itsCertificateChain),UpdateServerCertificate,DeleteServerCertificateandListServerCertificateTagskeep names unique across paths, parseExpirationfrom the PEM (left out on the slim image, which has nocryptography), and answerMalformedCertificatefor a body that is not a certificate. Contributed by @pingedbrain.
Fixed
- API Gateway — custom domain name responses — a regional domain name now has its
domainNameArnarn:aws:apigateway:<region>::/domainnames/<name>,certificateUploadDateand ad-<10 characters>.execute-api.<region>.amazonaws.comregional name, and responses leave out the fields AWS doesn't send for the endpoint type, empty values among them;endpointConfigurationcarriesipAddressTypeandtagsappear onGetDomainName. Reported by @cupidchan. - API Gateway — private custom domain names — the
domainNameId1.5.34 gave a private domain had 8 characters where AWS's has 10; a private domain now also defaultsipAddressTypetodualstack, and apolicystatement onexecute-api:/*is returned naming the domain's ownexecute-apiARN, as on AWS. Reported by @mindsers. - AppConfig —
KmsKeyArnis built from the identifier as given — 1.5.34 resolved an alias to its key's ARN and only reported aKmsKeyArnfor a key MiniStack's KMS held; as on AWS, a key ARN or alias ARN is kept, a key id becomesarn:aws:kms:<region>:<account>:key/<id>and an alias namearn:aws:kms:<region>:<account>:alias/<name>, without checking the key exists. A hosted version created under a profile with a key carries itsKmsKeyArn, andStartDeploymentof such a version answers "KmsKeyIdentifier required when deploying a hosted configuration version that is encrypted with a customer managed key (CMK)" without aKmsKeyIdentifier, and KMS's messages for a key that does not exist, is disabled or is in another account. Reported by @kharabasz. - AppConfig —
ListDeploymentsand tag errors — deployments are listed newest first withConfigurationProfileIdandTypeUSER, andListTagsForResource,TagResourceandUntagResourceanswer AWS's errors for an ARN without an account id (400) and another account's ARN (403AccessDeniedException). Reported by @kharabasz. - Auth — HTTP/2 clients that sign
:authority— withAUTH=true, a request signed with an IAM user or STS session key over HTTP/2, as the JavaScript SDK v3 does for Kinesis, Bedrock Runtime and other clients, answeredSignatureDoesNotMatch: Hypercorn passes:authorityto the app ashost, so it was signed as empty. A signed:authoritynow takes thehostvalue. Reported by @ScriptSmith. - Auto Scaling —
MixedInstancesPolicy—CreateAutoScalingGroupandUpdateAutoScalingGroupdropped it, so the group reported no launch template; it is now kept, in CloudFormation too, with the launch template's id and name filled in,Overrides[]when none are given and AWS'sInstancesDistributiondefaults, and the group then has noLaunchTemplate. A group with both aLaunchTemplateand aMixedInstancesPolicy, or with no launch source at all, answers "Valid requests must contain either LaunchTemplate, LaunchConfigurationName, InstanceId or MixedInstancesPolicy parameter." Reported by @kharabasz. - Auto Scaling — launch template request checks — a
LaunchTemplatewith both or neither ofLaunchTemplateIdandLaunchTemplateNameanswers "Valid requests must contain either launchTemplateId or LaunchTemplateName", a version other than$Default,$Latestor a number "Invalid launch template version: either '$Default', '$Latest', or a numeric version are allowed.", and an unknown id "Malformed launch template Id: " or, for a shortlt-id or one in another region, "The specified launch template, with template ID , does not exist.", on create and update, as on AWS. Reported by @kharabasz. - CloudFront —
UpdateFunctionreturns its ETag where the SDKs read it — AWS sendsUpdateFunction's ETag in a header namedETtag, which is where botocore and the other SDKs read it; MiniStack sentETag, so an SDK client got no ETag back and Terraform'saws_cloudfront_functionfailed to publish a code change withInvalidIfMatchVersion. Reported by @kharabasz. - CloudFront — Functions LIVE versions, publish, delete and precondition errors — each stage now counts its own versions:
PublishFunctionmoves LIVE to its next version, with the ETag of that version number, and leaves DEVELOPMENT's ETag unchanged, where 1.5.34 copied DEVELOPMENT's ETag to LIVE.PublishFunctionno longer sends anETagheader,DeleteFunctionof a function a distribution uses answers 409FunctionInUse"Cannot delete function , it is in use by distributions", and a staleIf-Matchon publish or delete answersPreconditionFailed"The request failed because it didn't meet the preconditions in one or more request-header fields." Reported by @kharabasz. - CloudFront — viewer requests to an alternate domain name — the data plane served a distribution only at its
<label>.cloudfront.netname; a request whoseHostis one of itsAliasesfell through to path-style S3 (NoSuchBucket). It is now served by the distribution that claims that name, as on AWS: theHostheader chooses it, case-insensitively and ignoring the port; an exact alias beats every wildcard;*.Smatches any host ending in.S, at any depth, but notSitself; and the longest matching wildcard wins, whichever distribution is newer. A host another service claims (an API Gateway custom domain, a Function URL, an S3 virtual host, an OpenSearch Serverless collection, a load balancer) still goes to that service. The viewer function sees theHostlower-cased and without its port, and a SigV4-signed API call is never treated as viewer traffic. Contributed by @skialpine. - EC2 — launch templates keep
InstanceRequirements—CreateLaunchTemplateandCreateLaunchTemplateVersiondropped it, soaws_launch_templateplanned a change on every run; it is now returned as sent, and a template data with bothInstanceTypeandInstanceRequirementsanswersInvalidParameterCombination"Either the instance type or the instance requirements can be specified in the request, but not both." Reported by @kharabasz. - ECS — capacity provider strategies have their
base— a strategy item given withoutbaseis reported withbase0 on the service and its deployments, and on the cluster's default strategy fromCreateCluster,PutClusterCapacityProviders,DescribeClustersand CloudFormation, as on AWS. Reported by @kharabasz. - ElastiCache — a serverless cache with a user group enforces it — the cache's engine had no users, so any client connected as
default; the group's users now exist in the engine with their access strings and passwords,defaultis off unless the group holds a user nameddefault, and an unauthenticated command answersNOAUTH Authentication required.. Aniamuser logs in with its token, which is not verified. Reported by @kharabasz. - ElastiCache — host ports already in use are skipped — a cache took the next host port from a counter without checking it was free, so a port held by another container or process sent a serverless cache to
create-failed; ports in use are now skipped. Reported by @kharabasz. - ElastiCache — IAM users and authentication modes —
CreateUserandModifyUserignoredAuthenticationMode, so an IAM user was reported as needing no password; users now reportAuthentication{"Type": "iam"}or{"Type": "password", "PasswordCount": n}and theirMinimumEngineVersion, and refuse an IAM user whose name differs from its id, an IAM user with passwords and ano-password-requiredValkey user with AWS's messages.ModifyUseranswersmodifying. Reported by @kharabasz. - EventBridge Scheduler —
EventBridgeParametersare validated and an event bus target publishes as AWS does —CreateScheduleandUpdateScheduleaccepted anyTarget.EventBridgeParameters; they now answer AWS'sSerializationExceptionfor parameters or members sent as the wrong JSON type, then AWS's aggregatedValidationExceptionfor a missing or emptyDetailTypeorSource, aDetailTypeover 128 or aSourceover 256 characters, and aSourceoutside AWS's pattern (such as one starting withaws.or holding a line break), before the schedule or group is looked up and for any target type. An event a schedule puts on an event bus now has emptyresourcesinstead of the schedule ARN, and an event bus target withoutEventBridgeParametersno longer publishes anaws.schedulerevent. Contributed by @kharabasz. - EventBridge —
PutEventsto another account's event bus — an entry whoseEventBusNameis the ARN of a bus another account owns in the same region failed withResourceNotFoundException, so no other account could publish to a bus. The event is now delivered to the owner's rules and keeps the publisher'saccount. UnderAUTH=truethe bus policy (aPutPermissiongrant orPolicy) must allow the caller, with anevents:sourcecondition checked for each entry; otherwise the whole request answersAccessDeniedException"User: is not authorized to perform: events:PutEvents on resource: because no resource-based policy allows the events:PutEvents action", naming the first refusing bus in request order. A bus that does not exist refuses the same way. Contributed by @kharabasz. - EventBridge —
PutPermissionwith aPolicy— the policy was ignored andDescribeEventBusreturned a generic statement, so Terraform showed drift; it now replaces the bus's policy and is returned compact, the legacy form produces AWS's statement, and a malformed policy, a statement on another resource, or aPolicycombined withAction,Principal,StatementIdorConditionanswer AWS'sValidationExceptionmessages. Reported by @kharabasz. - KMS — another account's key ARN — a key named by another account's key ARN answered
NotFoundException; for the operations AWS allows across accounts it is now used from its owner's account, and withAUTH=trueits key policy must allow the caller (root included), else AWS'sAccessDeniedException"User: is not authorized to perform: kms: on this resource because the resource does not exist in this Region, no resource-based policies allow access, or a resource-based policy explicitly denies access", the same answer as for a key that doesn't exist. Reported by @kharabasz. - Lambda — cross-account Kinesis mappings follow AWS's access checks —
CreateEventSourceMappingon another account's stream now checks the stream's policy underAUTH=true: the function's role needsDescribeStream,DescribeStreamSummary,GetRecords,GetShardIteratorandListShards, and a missing stream or grant answers AWS'sCannot access stream ...message. UnderAUTH=truea running mapping needs onlyGetRecords; without it the mapping stops and reports AWS'sPROBLEM: User: ... is not authorized to perform ...result (namingDescribeStreamwhen the whole grant is gone), and resumes when the grant returns. A mapping on a missing stream in its own account answersStream not found. Contributed by @Jolley71717. - RDS — global cluster
Endpointand Aurora PostgreSQL versions — global clusters reportEndpoint<id>.global-<12 characters>.global.rds.amazonaws.com, even with no members, soaws_rds_global_cluster.endpointis filled in; a global cluster also reportsEngineLifecycleSupport,StorageEncryptionType(sse-rds, orsse-kmswhen encrypted) and a 16-characterGlobalClusterResourceId, leaves out an emptyDatabaseName, and Aurora PostgreSQL defaults to 17.9; andDescribeDBEngineVersionslists the current Aurora PostgreSQL versions, adding 14.24, 15.19, 16.15, 17.11 and 18.6. Reported by @kharabasz and @mindsers. - Route 53 —
InvalidChangeBatchmessages — a duplicateCREATEand a missingDELETEanswer AWS's bracketed messages,[Tried to create resource record set [name='<name.>', type='<type>'] but it already exists]and[Tried to delete resource record set [name='<name.>', type='<type>'] but it was not found]. Reported by @kharabasz. - S3 — an explicit Deny in a bucket policy applies to root — with
AUTH=true, the account's root credentials skipped the bucket policy, so a Deny stopped IAM users but not root; root is now refused with AWS's "with an explicit deny in a resource-based policy" message, and can still get, put and delete the bucket policy. Reported by @kharabasz.
Removed
Makefile— its targets only wrappeddocker build,docker runanddocker compose, and nothing used it.