What changed in the fine print
Every gotcha added, fixed, re-verified or removed, taken from the repo history. Also as an Atom feed for your reader.
· fix(content): respalda con fuente o reformula los hallazgos de la verificación de centralized-audit-logging
commit 6d37065
- FixedAWSCloudTrail creates the organization trail in member accounts even if the bucket or key validation fails(sources changed)
Show the change
CloudTrail creates the organization trail in member accounts even if a resource validation fails; the documentation gives an incorrect bucket policy and insufficient permissions to encrypt with a KMS key as examples. A successful apply doesn't prove there is delivery. Check get-trail-status: if there is a problem with the bucket, the LatestDeliveryError field shows the S3 error (it only appears for problems with the destination bucket, not for requests that time out). Fix it with the bucket policy, or by creating another bucket and calling update-trail.
- FixedAWSIn the official example, an organization trail's bucket policy needs its own statement and the logs are accessible only to management
Show the change
Scope of the source: the official example is a bucket owned by the organization's management account; the documentation doesn't cover a bucket in another account (such as this module's log archive account), so test it in a non-production environment. The bucket of an organization trail needs a policy that lets CloudTrail write the organization's logs: the official example has three statements (GetBucketAcl, PutObject on the management account prefix and PutObject on the AWSLogs/o-<organization id>/ prefix). The aws:SourceArn must be the ARN of a trail owned by the management account, using that account's ID. That policy doesn't give access to users in member accounts: by default, the organization's log files are accessible only to the management account. List explicitly who you want to grant read access to and don't assume member accounts can read.
- FixedAWSIf a multi-Region trail's home Region is opt-in, only accounts that enabled that Region send activity(sources changed)
Show the change
If the organization trail is multi-Region and its home Region is an opt-in Region, member accounts don't send activity to the trail unless they opt into that Region; the documentation's example is Europe (Spain): only accounts that enabled it send their activity. Organization trails created in the console are multi-Region. Choose a Region that is enabled by default as the home Region, or verify that each account enabled the Region; if an account doesn't show up in the bucket, check this point.
- FixedAWSA misconfigured trail retries delivery for 30 days and those attempts are charged(sources changed)
Show the change
If the trail is misconfigured (for example, the bucket is unreachable), CloudTrail attempts to redeliver the log files to the bucket for 30 days, and those delivery attempts are subject to standard CloudTrail charges. To avoid charges on a misconfigured trail you need to delete it. Fix the bucket policy and the key policy before creating the trail (in Terraform, with a depends_on of the trail on both) and check get-trail-status afterwards.
· fix(content): respalda con fuente o reformula los hallazgos de la verificación de preventive-guardrails
commit 004f543
- FixedAWSTest SCPs and RCPs in an OU or test accounts before moving up to the root; removing FullAWSAccess without a replacement cuts all actions
Show the change
AWS strongly recommends not attaching an SCP to the root without testing its impact on the accounts: create an OU and move accounts into it one at a time, or in small groups, so you don't lock anyone out of key services. For RCPs it recommends starting with test accounts, moving up through the OUs and reviewing CloudTrail for Access Denied errors. Also, don't remove the FullAWSAccess policy without modifying it or replacing it with another that has the allowed actions: otherwise all AWS actions from member accounts fail. For an S3 policy, after each change check the effective policy of representative accounts with DescribeEffectivePolicy.
· fix(content): respalda con fuente o reformula los hallazgos de la verificación de protected-origin-cdn
commit ff55dad
- FixedAzureWith Private Link to storage, a container without anonymous access requires authorized requests, for example with SAS
Show the change
Front Door's guide for a Storage origin says that if the blob or container doesn't permit anonymous access, requests against it must be authorized, for example with shared access signatures, and lists as a common mistake not using SAS against an account that doesn't allow anonymous access. According to the same guide, public internet access to the account is disabled once the private endpoint is enabled.
So you have to choose:Ifathe containerwith anonymousdoesn'tblobpermitread,anonymousreachableaccess,onlydon'tthroughconnect theprivate endpoint, or SAS on requests. Decide explicitly andorigindon'twithoutleaveauthorizing thecontainer private without SAS.requests. - FixedGCPIf the bucket stays public, signed URLs don't protect the content
Show the change
For signed URLs to protect the content, the origin must not grant public access: the documentation says to remove the allUsers (and allAuthenticatedUsers, if applicable) read permissions from the bucket, which is commonly left public during testing. Even without public access, anyone who already has permission on the bucket, such as OWNER, can access Cloud Storage without a signed URL. And a signed URL gives time-limited access to anyone who holds it, whether or not they have a Google Account. The same page warns that Cloud CDN doesn't block requests without a Signature query parameter or Cloud-CDN-Cookie cookie (it rejects those with invalid parameters) and that the origin must validate signatures and accept or reject unsigned requests. Check that the bucket has neither allUsers nor allAuthenticatedUsers before calling the entry closed, and sign only HTTPS URLs.
· feat(content): patrón borrador centralized-audit-logging con Terraform validado
commit 3a7ea88
- NewAzureThe Activity Log is deleted after 90 days; to keep it longer you have to export it with a diagnostic setting
- NewAzureA diagnostic setting on the management group doesn't capture every subscription-level event
- NewAzureThe destination can be in another subscription if whoever creates the setting has RBAC access to both
- NewAzureA destination storage account with virtual networks must allow trusted services and can't be Premium
- NewAzureExporting the Activity Log to Log Analytics has no ingestion charge; retention is charged only past 90 days
- NewAWSCloudTrail creates the organization trail in member accounts even if the bucket or key validation fails
- NewAWSAn organization trail's bucket policy needs its own statement, and by default only management reads the logs
- NewAWSIf a multi-Region trail's home Region is opt-in, only accounts that enabled that Region send activity
- NewAWSLogs encrypted with KMS can only be read by whoever has kms:Decrypt: grant it before attaching the key to the trail
- NewAWSEnabling integrity validation delivers digest files, but validates nothing
- NewAWSA misconfigured trail retries delivery for 30 days and those attempts are charged
- NewGCPAn organization or folder sink with includeChildren set to false only exports the parent resource's own logs
- NewGCPThe sink doesn't export until its writer identity has write permission on the destination
- NewGCPIf the destination is a project, Admin Activity and System Event logs aren't stored in it without a sink of its own
- NewGCPAn aggregated sink that intercepts takes logs away from the child projects' sinks
- NewGCPA destination inside a VPC Service Controls perimeter requires an ingress rule for the sink's identity
- NewGCPData Access logs are enabled at the source, at organization or folder level; the sink only routes what exists
- NewGCPA bucket's retention in an organization or folder can't be extended, and locking a bucket is irreversible
· feat(content): patrón preventive-guardrails (borrador) con Terraform validado
commit e42985e
- NewAzureWith deny, an existing account that doesn't comply can't take configuration changes until it's fixed
- NewAzureWith the audit effect, the account with anonymous access is created anyway
- NewAzureIn DoNotEnforce mode the assignment evaluates compliance without applying the effect
- NewAzureAn Azure Policy exemption only expires if you set expiresOn, and once expired it stays as a record
- NewAWSSCPs don't reach the management account or service-linked roles
- NewAWSAn SCP doesn't stop external principals accessing an organization's bucket; that's what RCPs are for
- NewAWSAn S3 policy applies to all S3 resources in the accounts it reaches: the exception is handled by OU or account
- NewAWSWith the S3 policy, public access that already existed is ignored; it isn't removed
- NewAWSTest the policy in an OU before attaching it to the root; removing FullAWSAccess without a replacement cuts all actions
- NewAWSDisabling the SCP policy type in a root detaches all SCPs, and the attachments are lost
- NewGCPWith the constraint enforced, allUsers permissions that already existed stay in place, overridden
- NewGCPThe exception to the constraint is made per project, and a bucket with the enforced setting stays protected
- NewGCPThe storage.publicAccessPrevention constraint isn't among those that support dry-run
- NewGCPPrevention takes time to apply and doesn't affect signed URLs
· feat(content): patrón protected-origin-cdn (borrador) con Terraform en las tres nubes
commit 4b9b896
- NewAzureWith Private Link to storage, a container without anonymous access requires authorized requests, for example with SAS
- NewAzureAn origin group can't mix public origins and Private Link origins
- NewAWSCloudFront's access to the bucket is limited to your distribution with the AWS:SourceArn condition
- NewAWSA bucket configured as a website endpoint can't use OAC
- NewAWSWith SSE-KMS the distribution also needs permission on the key
- NewGCPCloud CDN reads the bucket with its own service account, which appears when you add the first key
- NewGCPIf the bucket stays public, signed URLs don't protect the content
- NewGCPCloud CDN caches responses to signed requests regardless of the origin's Cache-Control
· fix(content): ajusta a su fuente las frases parciales de gcp que dejó la segunda verificación
commit 651a32f
- FixedGCPPrincipals use the project number, and permissions take minutes to propagate
Show the change
TheWhenprincipalSetgrantingandrolesthetoworkload_identity_providerexternalyouidentitiespassyoutouse theaction areprojectprojects/NUMBER/locations/global/...,number, not the projectID.ID: the principalSet is principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/.... Also, an IAM change usually applies within 2 minutes but can take 7 ormore, so a freshly configured pipeline can fail its first run with nothing actually wrong.more. - FixedGCPTo Type 1 and 2 targets queries come from 35.199.192.0/19; with Type 2, on-premises needs a route to it
Show the change
Cloud DNS
doesn'tusesusetheyour35.199.192.0/19VPC'srangeIPsfortoallforward:customers,everyandqueryit is the source of queries toaTypeforwarding1targetandcomesTypefrom235.199.192.0/19.targetsThe(VPC internal IPs and on-premisesfirewallovermustVPNalloworUDPInterconnect).andTypeTCP353targetsfromusethatGooglerange,Public DNS source ranges, and for Type 4 the range depends on the IPs the name resolves to. For a Type 2 target, on-premises needs areturnroutethrough thetoVPN35.199.192.0/19tunnelswhoseornextInterconnecthopattachmentsis in the sameVPC. With BGPVPC,that'sthrough acustomCloudadvertisementVPNontunneltheor a CloudRouter.InterconnectWithoutVLANtheattachment.route,WiththeBGPon-premisesthat'sDNSagetscustomtheroutequeryadvertisementandon thereplyCloudisRouter'slost.BGP session. - FixedGCPPrivate Google Access gives reach to Google APIs; filtering the bucket's origin is another control(sources changed)
Show the change
PrivateVMGoogleinstancesAccessthat onlyletshaveVMsinternalwithoutIPpublicaddressesIPscan use Private Google Access to reach GoogleAPIs.APIsToandrestrictservices. That solves reachability, not origin filtering. Bucket IP filtering lets youneedrestrict access to the bucket based on client IPfilteringrangesorand VPCServicenetworks,Controls.and works alongside IAM. - FixedGCP"Internal" is a network control; authentication is separate IAM
Show the change
With internal ingress, Cloud Run
rejectsonly accepts requestsnotfromcomingsourcesfromsuch as VPCs in the sameprojectproject,(ora VPC SCperimeter)perimeter or an internal Application Load Balancer, and fromotherproductsGooglesuchservices,asevenCloudviaScheduler, Cloud Tasks, Eventarc, Pub/Sub or Workflows if they're in the same project or perimeter and use the default run.app URL. Other sources, including the internet, can't reach it. But IAM authentication still applies: the client must present an ID token and its service account needs roles/run.invoker.
· fix(content): ajusta a su fuente las frases parciales de aws que dejó la segunda verificación
commit acdfa6c
- FixedAWSFor GitHub, IAM doesn't use the thumbprint to verify (and you don't need to set it)
Show the change
IAM validates GitHub's certificate against its library of trusted root CAs, so thumbprint_list is optional and, in the Terraform provider, for IdPs like GitHub it's stored but not used for verification. Thumbprints only come into play if the IdP uses a certificate not signed by one of those CAs, or if AWS can't retrieve the TLS certificate or TLS v1.3 is required.
Many old modules still hardcode a thumbprint "that must be rotated": for GitHub that's not what breaks login. - FixedAWSForwarding from on-premises to the VPC's .2 address isn't supported
Show the change
The VPC resolver (CIDR baseAWS+states2)thatanswersforwardingresourcesprivateinDNSthequeriesVPC.toAWSanystatesVPCthatCIDRforwardingbasequeries+to2itaddress from on-premises or other VPC DNS servers isn't supported and cangivecause unstableresults, even if it sometimes seems to work. That's what the inbound endpoint isresults.for,Instead,justAWSlikerecommendsAzure'susingoraGCP'sResolver inboundpolicy.endpoint. - FixedAWSThe private hosted zone must be associated with the inbound endpoint's VPC
Show the change
The inbound endpoint resolves with what its VPC sees. IfFor thezone is associated only with application VPCs,VPCon-premisesResolvergetstoNXDOMAINresolveeveninboundthoughDNSeverythingqueriesresolvesusingfinethefromrecordstheinVMs.aInprivatemulti-accounthostedsetups,zone, the zone mustalsobe associated with thehubVPCVPC.where you created the inbound endpoint. - FixedAWSBlock Public Access and disabled ACLs are default on new buckets (but declare them anyway)
Show the change
SinceBy default, Object Ownership is BucketOwnerEnforced and all ACLs are disabled. AWS announced that, starting in April20232023, S3enableswould enable Block Public Access anddisablesdisable ACLs on all newbuckets (Object Ownership set to BucketOwnerEnforced).buckets,It'swith nolonger "the"changedifferenceforwithexistingAzure.ones. Still declare them in IaC:existing buckets didn't change, anddeclaring the state prevents drift if someone edits them in the console. - FixedAWSThe IAM auth token lasts 15 minutes and is only used to open the connection
Show the change
The token expires after 15 minutes and is used only to authenticate: it doesn't affect the session once established, but
an expired token makes a new connection request fail. An app that opens a connection per request must generate a freshiftokenyoueachtrytime;tokeepconnectawithpoolanandexpiredrefreshtoken, thetoken when openingconnectionnewisconnections.rejected. - FixedAWSFargate in a private subnet without NAT needs several paid VPC endpoints
Show the change
To pull the image
and ship logswithout internet egress, the task needs ECR (api and dkr)and CloudWatch Logsinterface endpoints, plus the S3 gateway endpoint (where ECR stores layers). If it uses the awslogs log driver, it also needs the CloudWatch Logs interface endpoint. Each interface endpoint is billed hourly per AZ. The alternative (NAT Gateway) is also billed hourly and per GB. - FixedAWSHTTPS on an internal ALB still needs an SSL server certificate
Show the change
To create an HTTPS listener you must deploy at least one SSL server certificate (from ACM or IAM). ACM
requires proving domain ownership for a public certificate via DNS, email or HTTP, andcannot validate resources in a VPC private hosted zone or any other private domain, even if the ALB is internal. ACM does not validate domain ownership for imported certificates or for certificates signed by a private CA. - FixedAWSLet Secrets Manager manage the master user password
Show the change
With manage_master_user_password = true, RDS generates the master password and stores it in Secrets Manager. The Terraform provider doesn't allow combining it with password, and RDS doesn't support it in some scenarios (for example Blue/Green deployments), so decide upfront.
· fix(content): ajusta a su fuente las frases parciales de azure que dejó la segunda verificación
commit 6efb439
- FixedAzureThe scale rule authenticates with the identity property, not auth
Show the change
KEDA queriesFor thequeue length on its own. Toscalehaveruleitto use a managed identity,the scale rule usesset the identity property instead of auth. The portalcan'tdoesn'tconfiguresupport it: use IaC or CLI. - FixedAzureRole assignments are per account or container; by prefix you need ABAC conditions
Show the change
In S3AzureyouStoragescopesupportstherolepolicyassignmentstoforarn:...:bucket/incoming/*bothandstorageinaccountsGCPandyoublobusecontainers.IAMToConditionsscope byprefix. In Azure a role assignment reaches the container at minimum; to scopeprefixbyor path you need ABAC conditions on the roleassignment.assignment (Blob prefix and Blob path attributes). Simple alternative: a container dedicated to ingestion (what this module does). - FixedAzurePrivate Endpoint without a private DNS zone: the service firewall can answer 403
Show the change
Creating the Private Endpoint is not enough: the FQDN <account>.blob.core.windows.net must resolve to the private IP via the privatelink.blob.core.windows.net zone linked to the VNet (or your hybrid DNS). If it resolves to the public
IP,IP and theserviceaccountfirewallhas a firewall, it rejects the request with 403 and looks like a permissions issue. - FixedAzureARM adds Entra admins; the app's role is created with SQL
Show the change
Terraform/ARM addsEntra principals are added as administrators(azure_pg_admin,fromCREATEROLE,theCREATEDB).Azure portal or the ARM API. With isAdmin=true, pgaadauth_create_principal gives them azure_pg_admin, CREATEROLE and CREATEDB. For the app identity to be a regular user, an Entra admin can run pgaadauth_create_principal('<name>', false, false). For managed identities and service principals the name is the display name. The module outputs the exact SQL. - FixedAzureStopping the database stops compute billing, but it restarts on its own after 7 days
Show the change
ACA can go down to zero replicas, butPostgreSQL Flexible bills compute while it's on. Stopping it stops compute billing (not storage), but the service automatically restarts it after 7 days. For dev environments, automate the stop instead of relying on a manual one.
· fix(content): respalda o recorta los hallazgos de la verificación independiente de hub-and-spoke
commit 99b711a
- FixedAzureSpoke-to-spoke through the firewall needs a UDR in every spoke and peerings that accept forwarded traffic
Show the change
VNet peering is a nontransitive relationship: two spokes peered with the same hub can't see each other. For the hub to connect them, the subnets in each spoke need a UDR pointing to Azure Firewall as the default gateway, and the peerings must accept forwarded traffic.
If either is missing, spoke-to-spoke traffic either doesn't arrive or doesn't go through the firewall.Make the UDR part of onboarding each spoke, not a separate manual step. - FixedAWSWithout appliance mode on the inspection attachment, request and response can cross different AZs
Show the change
When appliance mode isn't enabled, the transit gateway
keepsattempts to keep traffic in the originating AZ. With it enabled, it selects a single network interface in the inspection VPC using a flow hash for the life of the flow and uses the same one for return traffic, so bidirectional traffic is symmetric. A stateful firewall needs to see both the request and the response. Enable it on the inspection VPC's attachment(in Terraform, appliance_mode_support = "enable")and connect exactly one transit gateway to that VPC: with several, AWS doesn't guarantee flow stickiness. Changing it on an existing attachment can alter its current routing. - FixedGCPRoutes to on-premises and custom static routes don't cross the peering unless you turn on export and import
Show the change
Subnet routes are always exchanged (except IPv4 subnet routes using privately used public IPv4 addresses), but dynamic routes and IPv4 static routes without network tags with a next hop other than the default internet gateway aren't exported or imported by default. You enable them with --export-custom-routes on the VPC that has them and --import-custom-routes on the one that receives them. Static routes with network tags or with the default internet gateway as next hop can't be exported or imported.
ATospokeprovidethatadoesn'tpathimportfrom on-premises to thehub'speeredroutesVPC,can'tyoureachalsoon-premiseshavethroughto configure Cloud Router custom advertisement mode with thehub.peered VPC's subnet ranges. - FixedGCPWith Network Connectivity Center the design changes: there are limits to using peering between VPC spokes
Show the change
NCC VPC spokes
exchangecan export and import all subnet routeswithfrom the otherspokes on theVPChub.spokes. You can't use VPC Network Peering between two VPC spokes that are also connected through an NCC hub, and static route exchange across VPC spokes isn'tsupported,supported.andYouincanthehavestarantopologyNCC-connectedNCCVPCdoesn'tspokeconnectpeeredthewith a separate VPC that isn't part of NCC, and use peering between two VPC spokes in the edge groupto eachofother.aChoosehubthewithmodelstarbeforetopology,creatingbecausetheNCCVPCs,doesn'tbecauseconnectyouthecan'tspokesmixinthemthatbetweengroupthetosameeachspokes.other. - FixedGCPThe firewall endpoint is zonal, a VPC associates with only one endpoint per zone, and it only inspects traffic that a rule selects
Show the change
A firewall endpoint is a zonal resource, and the association links it to a VPC network in the same zone. A VPC network can associate with only one endpoint per zone, organization-level or project-level. Cloud NGFW redirects traffic to the endpoint only when it matches a policy rule with the apply_security_profile_group action.
ToAncoverendpointthecanzonesbewhereattachedworkloadstorun,onecreateoronemoreendpointVPC networks in the same zone, and if a VPC network spans several zones you attach oneassociationendpoint per zone; in a zoneandwithpernoVPC,endpointandattachedcheckthere is no layer 7 inspection. Check that every flow to inspect has its rule.
· fix(content): respalda o recorta los hallazgos de la verificación independiente de controlled-egress
commit df57e76
- FixedAzureWithout an explicit outbound method the VM uses an IP that Microsoft owns and can change
Show the change
A VM without an explicit outbound method gets a default outbound public IP. That IP is owned by Microsoft and can change without notice, so it is no good for a third-party allowlist. For the API version released after March 31, 2026, subnets in new VNets have defaultOutboundAccess set to false; existing VNets don't change, and new VMs in them keep getting the default IP unless the subnet is made private. Tools that pin an earlier API version (the doc names Terraform) leave the value as null, which allows implicit outbound access. Declare an explicit method (NAT Gateway) and set the subnet to private explicitly; existing VMs must be stopped and deallocated for the change to take effect.
WithoutIn a private subnet without explicit outbound, Windows Update and Windows activation don't work. - FixedAzureNAT Gateway and Azure Firewall are billed hourly, plus per GB processed
Show the change
The NAT Gateway pricing page charges resource hours and data processed (outbound and return traffic), and states that the hourly rate is charged regardless of the NAT gateway having subnets or public IPs attached; bandwidth charges also apply. Azure Firewall charges a fixed hourly fee per deployment, regardless of scale, plus a per-GB processed charge.
With both in the path, both meters run.If you don't need to filter by destination, the NAT gateway alone already gives the fixed IP without the firewall. - FixedAWSThe Network Firewall domain list relies on the SNI or Host, not on IPs, and by default looks at its own VPC's traffic
Show the change
For HTTPS, Network Firewall uses the SNI from the TLS handshake and for HTTP the Host header; it doesn't pause the connection to do DNS lookups or evaluate IPs, so it relies on what the client asserts. A domain list can't scope by port or by a single protocol: for that you need Suricata or 5-tuple stateful rules. By default inspection uses the CIDR of the firewall's VPC as HOME_NET; to filter traffic from other VPCs (for example through a transit gateway) you must set HOME_NET to include those CIDRs. With the Allow action the firewall denies non-matching traffic only if the policy uses default action order; under strict order that denial doesn't apply. If you also want to validate the domain the destination IP was resolved for, the AWS_ROUTE_53_RESOLVED_DOMAIN target exists.
- FixedGCPCloud NAT allocates ports per VM: the default minimum is low and you need to size the ports
Show the change
Each NAT IP address offers 64,512 TCP source ports. If you don't specify the minimum ports per VM, the default applies: 64 with static allocation and 32 with dynamic, and for Public NAT the default allocation is static. With static allocation a VM can't use more than its allocated ports, even during traffic bursts.
In addition, the gateway can process 1,024 simultaneous connections to each unique destination 3-tuple.The doc recommends dynamic allocation if egress usage varies, but it can't be combined with endpoint-independent mapping and, while additional ports are being allocated, you might see timeouts or latency. Dropped packets are loggedonly ifwhen youturn onuse Cloud NAT logging to turn on error logging. The module enables dynamic allocation and error logging. - FixedGCPCloud NAT adds up four charges: gateway per hour, GiB processed, external IPs per hour and outbound transfer(sources changed)
Show the change
For Public NAT, the pricing page defines the total cost as the gateway's hourly cost plus the cost per GiB processed by the gateway, the hourly cost of the external IP addresses it uses and the cost of outbound data transfer. The gateway's hourly price depends on the number of VMs using it and is capped at 32 VMs. When budgeting, add up all four parts: with static IPs reserved for the allowlist, each IP is charged hourly. Separately, the Cloud NGFW pricing page says that when a traffic flow is evaluated by a rule containing Cloud NGFW Standard features you are charged for data processing, and it lists FQDN objects among those features.
- FixedGCPFQDN objects resolve to IPs: no wildcards, capped at 32 IPv4 and 32 IPv6, and not suited for googleapis.com
Show the change
Cloud NGFW periodically resolves each FQDN object to IPs, following the VPC's Cloud DNS name resolution order. It doesn't support wildcards (`*`) or top-level domains. Each FQDN object maps to a maximum of 32 IPv4 and 32 IPv6 addresses, and the extra ones are dropped. If the answer is NXDOMAIN, has no usable IP or the DNS server is unreachable, the object is ignored. The doc says to avoid A records with a TTL under 90 seconds and notes that most Google domain names, such as googleapis.com, fall under these situations: it recommends IP addresses or address groups. It also can't be used if the VPC has an outbound server
policy.policy with an alternative name server. A DNS query can return different answers depending on the client's location, so the programmed IPs may not include every address of the domain. Use FQDNs for third-party APIs with stable DNS and check each domain's TTL. - FixedGCPTraffic to Google APIs doesn't leave through Cloud NAT: it goes through Private Google Access
Show the change
The Cloud NAT doc says that traffic sent to Google APIs and services is routed through Private Google Access, even when the VM uses Public NAT.
Those calls don't leave with the NAT IPs, so a control that depends on the egress IP doesn't apply to those destinations. Don't expect to see the NAT IP on those calls, and treatTreat Google domains separately in the egress rules.
· fix(content): respalda o recorta los hallazgos de la verificación independiente de app-secrets
commit 2c819ba
- FixedAzureThe Private Endpoint isn't enough: if the private zone isn't linked to the VNet, the vault resolves to its public IP
Show the change
For the VNet to reach the vault through the Private Endpoint you need a private zone named exactly privatelink.vaultcore.azure.net, linked to that VNet and holding the vault's A record. If the zone isn't linked, the query returns the public IP. With public network access disabled and no firewall allow-list, the service rejects every request at that
ingress, so the symptom is an access error, not public traffic.ingress. From on-premises you need conditional forwarders for vault.azure.net and vaultcore.azure.net to a resolver with access to Azure resolution (see the hybrid private DNS pattern). The vault name still resolves in public DNS even when the vault is private: don't put environment or customer in the name if that's part of your threat model. - FixedAzureKey Vault tells you the secret is about to expire; changing the credential at the third party is yours to build
Show the change
Thirty days before a secret's expiration date, Key Vault publishes the SecretNearExpiry event to Event Grid. To rotate, you have to create the event subscription and provide the function that creates the new version in the vault and updates the external service. Microsoft's tutorial shows it for a SQL Server password. Between those two steps there can be a lag during which the vault's secret doesn't authenticate, and if a step fails Event Grid retries for two hours. The
event depends on the secret having an expiration date. If the vault is private, the function has to reach it: thetwo-credential tutorial's template asks for a Premium plan only when the vault is behind a firewall. - FixedAzureKey Vault encrypts secrets with a service-owned key hierarchy; in AWS and GCP you pick a key of your own
Show the change
Key Vault stores all secrets as encrypted data, with a service-owned key hierarchy, and the documentation states that this encryption is transparent and requires no action from you. The keys you store in Key Vault serve, for example, as a wrapping key (BYOK) to encrypt Azure Storage data. In AWS, when you create a secret you can pick a KMS customer managed key, and in GCP a Cloud KMS key (CMEK). If a compliance requirement demands controlling the key of the secrets store itself, check that Key Vault covers it before choosing it; the key role in this pattern is partial in Azure.
- FixedAWSYou pay per secret, per replica, per KMS key and per endpoint hour and AZ
Show the change
Secrets Manager charges based on the number of secrets stored and API calls made. A replica counts as a distinct secret and is billed separately; creating new versions when rotating isn't charged and neither is a secret marked for deletion. Each KMS key you create has a monthly cost (prorated hourly), and the interface endpoint is billed for each hour it stays provisioned in each AZ. Use one subnet per AZ you actually need, one secret per credential, and replicas only if another region requires them. Each GetSecretValue is a billable call: read the secret at startup or cache the value.
- FixedGCPThe latest alias can roll out a bad value immediately; in production reference a version number
Show the change
The latest alias points to the most recently added version. Google describes it as convenient for development but problematic for some production workloads, because a bad value can be rolled out immediately and cause a service-wide outage. The best practices guide asks to reference secrets by version number and deploy changes through your release process, and to disable a version before destroying it so the step is reversible. Every rotation adds a
version and moves latest:version: resolve the number when rotating, store it in the deploy configuration and read it at startup. - FixedGCPReading the secret value is a Data Access log, and those logs are off by default
Show the change
AccessSecretVersion requires a DATA_READ permission and generates a Data Access audit log. Those logs are disabled by default for all services except some BigQuery ones, so you have to enable them explicitly.
In the meantime, AdminOperationsActivitythatlogsmodifyrecordversionschanges(add,todisable,thedestroy)secretarebutADMIN_WRITEnotandwhogoreadtotheAdminvalue.Activity. The best practices guide recommends enabling data access logs to analyze AccessSecretVersion requests, and doing it at the folder or organization level so you don't configure it in every project. - FixedGCPPrivate Google Access doesn't cover regional endpoints, which are the ones for Secret Manager's regional service
Show the change
Private Google Access is a per-subnet setting: it lets VMs that only have an internal IP reach the external IPs of Google APIs, and has no effect on instances with an external IP. If you disable it, those VMs lose access. It doesn't support regional and multi-regional endpoints, the ones ending in rep.googleapis.com. Secret Manager's regional service is accessed through a regional endpoint (secretmanager.<location>.rep.googleapis.com in the documentation's examples) and its secrets can only be accessed from that region.
ForGooglethatdocumentsyouhowneedtoause Private Service Connectendpointendpoints tothereach regional endpoints.
· feat(content): borrador del patrón app-secrets (secretos de aplicación)
commit 120904b
- NewAzureA deleted vault keeps its name during retention, and recovering it loses the role assignments
- NewAzureWith access policies, whoever can write the vault can grant themselves secret access; with RBAC they can't
- NewAzureThe Private Endpoint isn't enough: if the private zone isn't linked to the VNet, the vault resolves to its public IP
- NewAzureKey Vault tells you the secret is about to expire; changing the credential at the third party is yours to build
- NewAzureWithout a diagnostic setting, nobody records who read the secret
- NewAzureIn Key Vault you don't pick the key that encrypts the secrets; in AWS and GCP you do
- NewAzureEvery secret read is a billable operation, and the Private Endpoint is billed hourly
- NewAWSThe rotation function must reach Secrets Manager, and in a VPC without internet that means an endpoint
- NewAWSThe endpoint's default policy allows full access to Secrets Manager
- NewAWSRequiring the endpoint in the secret's policy also denies anyone reading from outside the VPC
- NewAWSThe secret's name, description, tags and rotation settings aren't encrypted
- NewAWSWith your own CMK, reading the secret needs permission on both the secret and the key
- NewAWSYou pay per secret, per replica, per KMS key and per endpoint hour and AZ, even if nobody reads
- NewGCPThe latest alias rolls out a bad value immediately; in production reference a version number
- NewGCPSecret Manager doesn't rotate the credential: it publishes a SECRET_ROTATE message and someone has to do the change
- NewGCPReading the secret value is a Data Access log, and those logs are off by default
- NewGCPPrivate Google Access doesn't cover regional endpoints, which are the ones for Secret Manager's regional service
- NewGCPThe CMEK key must be in the replica's location, and if you disable or destroy it the secret becomes unreadable
- NewGCPWith user-managed replication, a region outage fails writes, and the locations can't be changed
- NewGCPEvery rotation adds an active version, and a disabled version keeps billing
· feat(content): add controlled-egress pattern draft (topology and gotchas)
commit a3a6bb6
- NewAzureWithout an explicit outbound method the VM uses an IP that Microsoft owns and can change
- NewAzureA Standard NAT gateway is zonal, and moving to StandardV2 forces new egress IPs
- NewAzureA 0.0.0.0/0 route to the firewall overrides the subnet's NAT gateway: attach it to AzureFirewallSubnet
- NewAzureNetwork FQDN rules require DNS proxy and don't allow wildcards; application rules cover only HTTP/S and MSSQL
- NewAzureNAT Gateway and Azure Firewall are billed hourly even with no traffic, plus per GB processed
- NewAWSA zonal NAT gateway lives in a single AZ: sharing it across AZs is a single point of failure
- NewAWSEach NAT gateway IP supports up to 55,000 simultaneous connections to the same destination
- NewAWSThe NAT gateway charges per hour and per GB processed; one NAT per AZ multiplies the fixed part
- NewAWSThe Network Firewall domain list looks only at HTTP/HTTPS, by SNI or Host, and only at its own VPC's traffic
- NewAWSNetwork Firewall charges per endpoint per AZ and per GB; with the NAT gateway in the same path, AWS waives the NAT charge
- NewGCPCloud NAT allocates ports per VM: the default minimum is low and each destination has its own connection cap
- NewGCPCloud NAT adds up four charges: gateway per hour, GiB processed, external IPs per hour and outbound transfer
- NewGCPEgress is allowed by an implied rule: Cloud NAT is not the destination control
- NewGCPFQDN objects resolve to IPs: no wildcards, capped at 32 IPv4 and 32 IPv6, and not suited for googleapis.com
- NewGCPTraffic to Google APIs doesn't leave through Cloud NAT: it goes through Private Google Access
· feat(content): hub-and-spoke con inspección centralizada (borrador) y capability managed-firewall
commit 5732151
- NewAzureSpoke-to-spoke through the firewall needs a UDR in every spoke and peerings that accept forwarded traffic
- NewAzureA summarized UDR loses to the more specific peering route, and traffic bypasses the firewall
- NewAzureThe firewall subnet must be named AzureFirewallSubnet, at least /26, and doesn't support NSGs
- NewAzureFor spokes to use the hub's gateway you need three peering flags, and the spoke can't have its own gateway
- NewAzureAzure Firewall charges a fixed hourly fee per deployment, plus data processing
- NewAWSWithout appliance mode on the inspection attachment, request and response can cross different AZs
- NewAWSWith the default route table every attachment sees every other, and inspection never runs
- NewAWSOnly resources in AZs with an attachment ENI can reach the transit gateway
- NewAWSA firewall endpoint can't filter its own subnet's traffic, and using another AZ's endpoint adds cross-zone charges
- NewAWSEach attachment and each firewall endpoint is billed hourly, and data is billed per GB on both services
- NewGCPTwo spokes peered with the same hub can't see each other: peering doesn't provide transitive routing
- NewGCPRoutes to on-premises and custom static routes don't cross the peering unless you turn on export and import
- NewGCPWith Network Connectivity Center the design changes: it can't be combined with peering between the same spokes
- NewGCPThe firewall endpoint is zonal, associates with a VPC per zone, and only inspects traffic that a rule selects
· fix(content): respalda la comparación con SQS, prolija el envoltorio y agrega la guía de setup del mantenedor
commit 073bfb8
· fix(content): respalda con fuente o recorta 17 gotchas parciales y sube el timeout del test del changelog
commit 82d0459
- FixedAWSLimit the event source mapping's concurrency, not just the function's
Show the change
Onscaling_config.maximum_concurrencyalimitsmessagehowspikemanyLambdaconcurrentscalesinstancesfastofandthe function the queue canoverwhelminvoke. It's an event source mapping setting, independent of thedownstreamfunction'sdatabasereservedorconcurrencyAPI.andscaling_config.maximum_concurrencyfreelimitsofhowcharge,manyandconcurrentitinvocationskeepstheone queuetriggers,fromwithoutusing all of thesidereservedeffectsconcurrencyofor thefunction'saccount's concurrency quota. Note: the reserved concurrency(whichmustcanbealsogreatercausethanthrottlingorandequalretries).to the sum of the maximums of all the function's event sources; otherwise Lambda might throttle your messages. - FixedGCPWith push, the ack is the HTTP response and must arrive within the ack deadline
Show the change
Pub/Sub considers the message processed when the endpoint responds
2xx. Ifwiththe102,worker200,takes201,longer202thanorthe204;ackanydeadlineother(maxcode600iss),aPub/SubnackredeliversanditPub/Subwhileresendsit'sthestillmessage.running.TheAlignsameack_deadline_secondshappenswithif theCloudworkerRuntakesservicelongertimeoutthanand,theforacklongdeadline:jobs,Pub/SubuseredeliverspullitorwhileCloudit'sRunstillJobs.running. - FixedGCPPub/Sub offers exactly-once delivery, but only on pull subscriptions
Show the change
It's the only one ofPub/Subthesupportspattern'sexactly-oncethreedeliveryservicesonly withnative exactly-once delivery,pullbutsubscriptions: push (what triggers Cloud Run) doesn't supportit. Withit,push,becauseasthewithclientServicedoesn'tBusknowandwhetherSQSPub/SubStandard,received theworkerresponsemustandbeprocessedidempotent.it. - FixedAWSThere's only one OIDC provider per URL per account
Show the change
Creating a second provider for token.actions.githubusercontent.com in the same account
failsfails:withIAMEntityAlreadyExists.doesn't let you register the same URL twice in an account. If each repo ships its own Terraform stack with the provider inside, the second apply breaks. Create it once (in the account stack) and reference it with the data source; the module supports that with create_oidc_provider = false. - FixedAWSFor GitHub, the thumbprint is no longer used (and you don't need to set it)
Show the change
IAM validates GitHub's certificate against its library of trusted root CAs, so thumbprint_list is optional and, in the Terraform
provider sinceprovider,5.0forand,IdPsiflikeset,GitHub it's stored but not used for verification. Thumbprints only come into play if the IdP uses a certificate not signed by one of those CAs, or if AWS can't retrieve the TLS certificate or TLS v1.3 is required. Many old modules still hardcode a thumbprint "that must be rotated": for GitHub that's not what breaks login. - FixedGCPIdentifiers use the project number, and permissions take minutes to propagate
Show the change
The principalSet and the workload_identity_provider you pass to the action are projects/NUMBER/locations/global/..., not the project
ID: with the ID, the token exchange fails.ID. Also, an IAM change usually applies within 2 minutes but can take 7 or more, so a freshly configured pipeline can fail its first run with nothing actually wrong. - FixedAWSA forward rule beats a private hosted zone with the same name(sources changed)
Show the change
If a VPC has a FORWARD rule for corp.example.com and also a corp.example.com private hosted zone, the rule wins. Among rules the most specific wins, and a SYSTEM rule excludes a subdomain from forwarding.
In Azure it's the other way around: the linked private zone is checked before the ruleset. - FixedGCPForwarded queries come from 35.199.192.0/19, and on-premises must be able to reply to it
Show the change
Cloud DNS doesn't use your VPC's IPs to forward: every query to a forwarding target comes from 35.199.192.0/19. The on-premises firewall must allow UDP and TCP 53 from that range, and on-premises needs a return route through the VPN tunnels or Interconnect attachments in the same
VPC and region.VPC. With BGP that's a custom advertisement on the Cloud Router. Without the route, the on-premises DNS gets the query and the reply islost: it looks like a timeout.lost. - FixedAzurePrivate Endpoint without a private DNS zone = 403 from the VNet(sources changed)
Show the change
Creating the Private Endpoint is not enough: the FQDN <account>.blob.core.windows.net must resolve to the private IP via the privatelink.blob.core.windows.net zone linked to the VNet (or your hybrid DNS). If it resolves to the public IP,
withthepublicserviceaccessfirewalldisabledrejects the requestfailswith 403 and looks like a permissions issue. - FixedAWSExpiration is asynchronous, but billing stops at the expiration date(sources changed)
Show the change
S3 queues expirations and
can take days to physicallyprocessesdelete.themUnlikeasynchronously:Azure,anywhereyoufromdon'tdayspaytostorageweeksforcananpassexpiredbetweenobjecttheevenexpirationifdateitandstilltheshowsactualupdeletion.inYou'relistings.notSamechargedasfor theotherexpirationclouds:orit'sfornottheastoragesecuritytimecontrol,ofthean objectremains readablethatuntilhasit'salreadydeleted.expired. - FixedAWSIncomplete multipart uploads keep being billed(sources changed)
Show the change
PartsS3fromkeeps the parts of a multipart uploadthatuntilneveryoucompletedcompletetakeorupstopstorageit, anddon'ttheirshowstorageupiswhenbilledlistingtheobjects.whole time. Always add an AbortIncompleteMultipartUploadrule; ingestion bucketsrule:areabortingwherethetheyuploadpiledeletesupthemost.parts. - FixedGCPPrivate Google Access doesn't restrict who reaches the bucket
Show the change
Private Google Access only lets VMs without public IPs reach Google APIs.
The bucket still accepts authenticated requests from the internet.To restrict origin you need bucket IP filtering or VPC ServiceControls; the latter is organization-level and often out of reach for an application team.Controls. - FixedAzureStopping the database stops compute billing, but it restarts on its own after 7 days(sources changed)
Show the change
ACA can go down to zero replicas, but PostgreSQL Flexible bills compute while it's on. Stopping it stops compute billing (not storage), but the service automatically restarts it after 7 days. For dev environments, automate the stop instead of relying on a manual one.
- FixedAWSFargate in a private subnet without NAT needs several paid VPC endpoints(sources changed)
Show the change
To pull the image and ship logs without internet egress, the task needs ECR (api and dkr) and CloudWatch Logs interface endpoints, plus the S3 gateway endpoint (where ECR stores layers). Each interface endpoint is billed hourly per
AZ: it's the fixed cost that doesn't exist in ACA or Cloud Run.AZ. The alternative (NAT Gateway) is also billed hourly and per GB. - FixedGCPCloud SQL's private IP goes over a VPC peering that isn't transitive
Show the change
Private services access is implemented with VPC Network Peering to Google's network.
AnotherItVPConlypeeredallowswithconnectionsyoursfromcan'tonereachVPC,theanddatabase,peeringanddoesn'tforprovideon-premisestransitiveyourouting:mustanotherexportVPCcustompeeredrouteswithonyours can't reach thepeering.database. If your topology is hub-and-spoke, consider Private Service Connect instead of PSA.
· fix(content): respalda con fuente o recorta 11 gotchas de iam y security marcados como parciales
commit ca78528
- FixedAzureThe scaler needs an identity too, not just the container
Show the change
KEDA queries the queue length on its own.
IfTothehavenamespaceithasuselocalaauthmanageddisabled,identity, the scale rulemust useuses themanagedidentity(identity_id on the rule); a connectionpropertystringinsteadwon'tofwork.auth. The portal can't configure it: use IaC or CLI. - FixedAzureWith Contributor the pipeline can't create role assignments(sources changed)
Show the change
Contributor
lacksdoesMicrosoft.Authorization/roleAssignments/write.not allow assigning roles in Azure RBAC (it excludes Microsoft.Authorization/*/Write). If your Terraform assigns roles (say, an app's identity on a Key Vault),applyContributorfailsiswithnotAuthorizationFailed.enough. The quick fix is giving the pipeline Owner or User Access Administrator, which is exactly what you don't want. The right fix is Role Based Access Control Administrator with a condition limiting which roles it can assign (and excluding privileged ones). - FixedAWSIf the job declares an environment, the sub no longer contains the branch(sources changed)
Show the change
GitHub
buildsincludes thesubenvironment inprioritytheorder:subenvironment,whenthenthepull_request,job references one; pull_request and the ref onlythenappear if theref.job doesn't reference an environment. A job on main with environment production presents repo:org/repo:environment:production, so a trust policy expecting repo:org/repo:ref:refs/heads/main rejects AssumeRoleWithWebIdentity.Same on Azure and GCP; here the error is "Not authorized to perform sts:AssumeRoleWithWebIdentity". - FixedAzureThe smallest RBAC scope is the container, not the prefix(sources changed)
Show the change
In S3 you scope the policy to arn:...:bucket/incoming/* and in GCP you use IAM Conditions by prefix. In Azure a role assignment reaches the container at minimum; to scope by path you need ABAC conditions on the role assignment. Simple alternative: a container dedicated to ingestion (what this module does).
- FixedAWSBlock Public Access and disabled ACLs are already default (but declare them anyway)(sources changed)
Show the change
Since April 2023
new buckets are createdS3withenables Block Public Access and disables ACLs onandallObjectnew buckets (Object Ownership set toBucketOwnerEnforced.BucketOwnerEnforced). It's no longer "the" difference with Azure. Still declare them in IaC:olderexisting buckets didn't change, and declaring the state prevents drift if someone edits them in the console. - FixedAzureARM adds Entra admins; the app's role is created with SQL
Show the change
Terraform/ARM adds Entra principals as administrators (azure_pg_admin, CREATEROLE, CREATEDB). For the app identity to
havebeleastaprivilege,regular user, an Entra adminmustcan run pgaadauth_create_principal('<name>', false,false) and then the GRANTs.false). For managed identities and service principals the name is the display name. The module outputs the exact SQL. - FixedAWSHTTPS on an internal ALB still needs a certificate for a domain you control
Show the change
TheTo create an HTTPS listenerneeds anyouACMmustcertificate.deployAatpublicleastACMonecertificateSSLisservervalidatedcertificatevia(fromDNSACM oremailIAM).forACMarequiresrealproving domainevenownershipiffortheaALBpubliciscertificateinternal;viatheDNS,alternativeemailisorAWSHTTP,PrivateandCA,cannotwhichvalidatehasresources in amonthlyVPCfee.privateInhostedACAzoneandorCloudanyRunothertheprivateplatformdomain,manageseven if thedefaultALBdomain'siscertificate.internal. - FixedAWSThe master user always exists; let Secrets Manager manage its password(sources changed)
Show the change
With manage_master_user_password = true, RDS generates the master password and stores it in Secrets
Manager: it never goesManager.throughThevariablesTerraformorproviderTerraformdoesn'tstate.allowIt'scombiningincompatibleit withpassing apassword,passwordandmanually,RDSanddoesn'tisn'tsupportsupportedit in some scenarios (for example Blue/Green deployments), so decide upfront. - FixedGCP"Internal" is a network control; authentication is separate IAM(sources changed)
Show the change
With internal ingress, Cloud Run rejects requests not coming from VPCs in the same project (or VPC SC perimeter) or from other Google services, even via the run.app URL.
On top of that, byButdefaultIAMitauthenticationrequiresstillrun.routes.invoke:applies: the client mustsendpresent an ID tokenfrom an identity with roles/run.invoker. In ACAandthe internal ALB the network is the only control unless you additsauthserviceinaccounttheneedsapp.roles/run.invoker.
· fix(content): corrige dos gotchas de AWS señalados por la pre-verificación
commit d6e8bba
- FixedAWSForwarding from on-premises to the VPC's .2 address isn't supported(sources changed)
Show the change
The VPC resolver (CIDR base + 2) answers resources in the VPC. AWS states that forwarding queries to it from on-premises or other DNS servers isn't supported and can give unstable results, even if it sometimes seems to work. That's what the inbound endpoint is for, just like Azure's or GCP's inbound policy.
- NewAWSThe IAM auth token lasts 15 minutes and is only used to open the connection
- RemovedAWSIAM auth has a new-connections-per-second limit
· feat(patterns): hybrid private DNS (on-premises <-> cloud)
commit a5321b0
- NewAzureEach endpoint needs its own delegated subnet, and the resolver is tied to one VNet and one region
- NewAzureIn Azure the linked private zone wins over the ruleset; in AWS it's the other way around
- NewAzureLinking the ruleset to the hub, with a rule pointing at its own inbound endpoint, creates a loop
- NewAzureA wildcard "." rule must resolve public names, and 168.63.129.16 can't be a target
- NewAzureDNS Private Resolver isn't compatible with Azure Lighthouse or ExpressRoute FastPath
- NewAWSEach endpoint IP is an ENI billed hourly, and the minimum is two per endpoint
- NewAWSForwarding from on-premises to the VPC's .2 address isn't supported
- NewAWSThe private hosted zone must be associated with the inbound endpoint's VPC
- NewAWSA forward rule beats a private hosted zone with the same name
- NewAWSIt's 10,000 QPS per IP, but with connection tracking it can drop to 1,500
- NewGCPForwarded queries come from 35.199.192.0/19, and on-premises must be able to reply to it
- NewGCPWith standard routing, a non-RFC 1918 target is queried over the internet
- NewGCPThe inbound policy takes one IP from every subnet, not one per region or two per endpoint
· feat(patterns): secretless CI/CD deployments with OIDC federation
commit c33734d
- NewAzureThe subject must match exactly, with no wildcards, and there are at most 20 credentials per identity
- NewAzureA freshly created credential can fail with AADSTS70021 for a few minutes
- NewAzureCreating several credentials in parallel on the same identity returns 409
- NewAzureWith Contributor the pipeline can't create role assignments
- NewAzureSince 2026-07-15, new, renamed or transferred repos use a different sub format
- NewAWSIAM requires a sub condition, but accepts one that still leaves the door open
- NewAWSIf the job declares an environment, the sub no longer contains the branch
- NewAWSThere's only one OIDC provider per URL per account
- NewAWSFor GitHub, the thumbprint is no longer used (and you don't need to set it)
- NewAWSThe session lasts 1 hour by default, and role chaining caps it at 1 hour regardless
- NewGCPWithout attribute_condition, GitHub's shared issuer lets any repo in
- NewGCPCondition on numeric IDs, not on org and repo names
- NewGCPA deleted pool locks its ID for about 30 days
- NewGCPDirect access without a service account doesn't work with every service
- NewGCPIdentifiers use the project number, and permissions take minutes to propagate
· feat(content): two new patterns, 26 capabilities and pattern scaffolder
commit 1277919
- NewAzurePeek-lock is at-least-once, not exactly-once
- NewAzureThe dead-letter queue uses the queue's quota if nobody drains it
- NewAzureThe scaler needs an identity too, not just the container
- NewAWSThe queue's visibility timeout must be at least 6 times the Lambda timeout
- NewAWSWithout ReportBatchItemFailures, one failed message retries the whole batch
- NewAWSIn Standard queues, the message expires in the DLQ based on when it entered the original queue
- NewAWSLimit the event source mapping's concurrency, not just the function's
- NewGCPDead-lettering doesn't work without permissions for the Pub/Sub service agent
- NewGCPA dead-letter topic without a subscription drops messages
- NewGCPWith push, the ack is the HTTP response and must arrive within the ack deadline
- NewGCPPub/Sub offers exactly-once delivery, but only on pull subscriptions
- NewAzureThe ACA subnet can't be resized and its minimum size depends on the environment type
- NewAzureAn internal environment doesn't resolve its own domain from the VNet
- NewAzureIn PostgreSQL Flexible, VNet integration vs. Private Endpoint is a one-time choice
- NewAzureARM can only create Entra admins; the app's role is created with SQL
- NewAzureThe Entra token for PostgreSQL isn't requested for the server FQDN
- NewAzureThe database doesn't scale to zero, and if you stop it, it restarts after 7 days
- NewAWSThe IAM database user is created with SQL, and with rds_iam it stops accepting passwords
- NewAWSIAM auth has a new-connections-per-second limit
- NewAWSFargate in a private subnet without NAT needs several paid VPC endpoints
- NewAWSHTTPS on an internal ALB still needs a certificate for a domain you control
- NewAWSThe master user always exists; let Secrets Manager manage its password
- NewGCPIn Postgres, a Service Account's IAM user drops ".gserviceaccount.com"
- NewGCPUnlike Azure and AWS, the IAM login is created via API, without SQL
- NewGCPCloud SQL's private IP goes over a VPC peering that isn't transitive
- NewGCP"Internal" is a network control; authentication is separate IAM
- NewGCPEnforce connectors so nobody connects "around" them
· feat(content): content-as-code schema, validator and object-storage-ttl pattern
commit 7276221
- NewAzureThe policy takes up to 24 h to apply and runs in the background
- NewAzureWith soft delete on, "delete" does not free capacity
- NewAzureIn Azure the filter prefix includes the container name
- NewAzureThe smallest RBAC scope is the container, not the prefix
- NewAzurePrivate Endpoint without a private DNS zone = 403 from the VNet
- NewAWSExpiration is asynchronous, but billing stops at the expiration date
- NewAWSOn a versioned bucket, Expiration deletes nothing
- NewAWSIncomplete multipart uploads are billed and invisible
- NewAWSBlock Public Access and disabled ACLs are already default (but declare them anyway)
- NewAWSThe Gateway Endpoint is free, but only works within the VPC and region
- NewAWSA Deny on aws:SourceVpce locks you out too
- NewGCPSoft delete is on by default (7 days) and makes ephemeral data more expensive
- NewGCPLifecycle changes can take up to 24 h and actions are asynchronous
- NewGCProles/storage.objectCreator is not enough to overwrite
- NewGCPPrivate Google Access doesn't restrict who reaches the bucket
- NewGCPUniform bucket-level access + public access prevention is the pair to declare