Repository navigation
Conversation
…dFront VPC origin subnets In an account with VPC Block Public Access enabled, the CloudFront VPC origin for the internal Yjs ALB fails to create, because CloudFront refuses endpoint subnets that Block Public Access covers. The first apply fails about 25 minutes in. Add vpc_block_public_access_exclusion (default false). When true, the networking module creates an allow-bidirectional exclusion for each of the two private subnets, and a new vpc_origin_subnet_ids output, which depends on the exclusions, feeds the Yjs server module so the ALB and the VPC origin wait for them. The public subnets and the VPC are never excluded. The private subnets route only through NAT, the ALB is internal and its security group admits only the CloudFront origin-facing prefix list, so the exclusion opens no new internet ingress path. Document the variable in dev.tfvars.example and add a troubleshooting entry to the setup guide. A hardening test pins the default, the private subnet scope and the ordering. Fixes aws-samples#644
|
@vivibui thanks for this PR. The approach makes sense to me: CloudFront VPC origins are blocked by BPA, and Did you test the application after the deployment (opening a document in the collaborative editor, running an agent stage), and which BPA mode was the account in ( Looking at the docs, I think the fix only fully works in
Since we have no VPC endpoints, the Yjs ECS task (ECR pull, Cognito JWKS), the VPC Lambdas and the AgentCore runtime in VPC mode all rely on the NAT gateway. In a I think we would need to add an with |
In block-bidirectional mode, VPC Block Public Access also blocks NAT gateways. The NAT gateways sit in the public subnets, which the first change left covered, so in such an account the VPC origin would deploy but the private subnets would lose internet egress (ECR image pulls, Cognito JWKS, the VPC Lambdas and the AgentCore runtime in VPC mode). When vpc_block_public_access_exclusion is true, also create an allow-egress exclusion for each NAT gateway's subnet. Egress-only exclusions keep inbound internet traffic blocked and have no effect in block-ingress mode, where NAT egress is already allowed. vpc_origin_subnet_ids now waits for both exclusions so the Yjs task can pull its image on the first apply. Update the variable descriptions, the tfvars example and the setup guide to cover both modes, and extend the hardening test. Suggested in review.
| endpoints in a subnet with Block Public Access enabled. …' | ||
| ``` | ||
|
|
||
| The account enables [VPC Block Public Access](https://docs.aws.amazon.com/vpc/latest/userguide/security-vpc-bpa.html), and CloudFront VPC origins cannot reach the internal Yjs ALB in subnets it covers. Check the account mode with `aws ec2 describe-vpc-block-public-access-options`. If `ExclusionsAllowed` is `allowed`, set the following in your environment's `.tfvars` and re-run the deployment: |
There was a problem hiding this comment.
[P2] Retrying the failed VPC origin still hits a name collision
This entry starts after VPC origin creation has already failed, but enabling the flag and rerunning does not recover the tainted origin. Its fixed name and create_before_destroy cause the replacement to hit EntityAlreadyExists, as tracked in #648. Connecting these instructions to the recovery procedure in #650 would let users complete the retry; that procedure also needs its guard that no distribution references the failed origin.
There was a problem hiding this comment.
Good catch, thank you! That's exactly what happened on our first deployment: enabling the flag and re-running hit EntityAlreadyExists until we deleted the failed origin by hand.
fea3239 adds a step to this entry: the failed create leaves the VPC origin tainted, so before re-running, follow Re-running after a failed VPC Origin fails with EntityAlreadyExists, the recovery entry from #650. #650 (6679d83) now has the guard you asked for. It looks up the distributions that reference the origin (list-distributions filtered on VpcOriginConfig.VpcOriginId) and deletes the origin only when there are none. The re-run is a separate step once the delete has finished. I ran the lookup and the guard against a live stack: for an origin a distribution uses, it reports the distribution and refuses to delete.
The two entries sit at the same spot in setup.md, so the reference resolves once #650 is in. If you merge #650 first, I'll rebase this PR on it straight away so the two entries end up next to each other.
Setting vpc_block_public_access_exclusion after a deployment already failed is not enough on its own: the failed VPC origin is tainted, and the re-run then fails with EntityAlreadyExists. Tell readers to follow the recovery entry for that error before re-running. Refs aws-samples#648
|
Thank you @jeromevdl and @eipasteur! Both points are addressed now (752575e for the BPA modes, fea3239 for the retry path, details in the inline thread). @jeromevdl, you were right about bidirectional mode, and a live test confirms it. Original test. The first account was in The fix. 752575e follows your suggestion:
Live test in
One thing I wanted to check: the AgentCore runtime uses its own subnets, which have no exclusion and stay Negative control. I then deleted only the NAT subnet's egress exclusion, which leaves the stack as it was with the first commit:
The VPC has S3 and DynamoDB gateway endpoints, but SSM, the ECR API, STS, Cognito, CodeCommit and Bedrock all go through the NAT gateway, so this is the failure you predicted. Re-applying Terraform recreated only the exclusion, and every check passed again, including the Yjs service recovering on its own. Screenshots of the collaborative editor, the agent settings and the intent run follow in the next comment. |
|
Screenshots from the Collaborative Compose page: live edit through CloudFront → VPC origin → internal ALB → Yjs (status bar: Connected) Admin → Agents: platform Bedrock connection ready Intent run: Inception completed (reverse engineering + requirements analysis), waiting at the requirements review gate |
|
@eipasteur @jeromevdl let me know once either of you have reviewed and if further changes needed |
jeromevdl
left a comment
There was a problem hiding this comment.
As mentioned in the #650, I would merge the 2 PRs (add the 650 here).
Minor: line 787 says to re-run before line 793 says not to. Please adjust the order, something like: "set the following, delete the failed VPC origin (see …), then re-run."



Issue #, if available: Fixes #644
Description of changes:
Problem
In an account with VPC Block Public Access (BPA) enabled, the first apply fails about 25 minutes in, when the CloudFront VPC origin for the internal Yjs ALB is created:
CloudFront VPC origins can't use subnets that BPA covers, and the stack has no way to exclude the ALB's subnets. Details in #644.
Solution
vpc_block_public_access_exclusion(bool, defaultfalse), passed to the networking module.true,module.networkingcreates:aws_vpc_block_public_access_exclusion.private:allow-bidirectionalfor the two private subnets.aws_vpc_block_public_access_exclusion.nat:allow-egressfor each NAT gateway's subnet (1 outsideprod, 2 inprod). Inblock-bidirectionalmode BPA also blocks NAT gateways, so without this the private subnets would lose egress. It has no effect inblock-ingressmode.vpc_origin_subnet_ids: the same IDs asprivate_subnet_ids, withdepends_onboth exclusions.module.yjs_servernow takes its subnets from it, so the ALB and the VPC origin are created, and the Yjs task pulls its image, only after the exclusions exist.dev.tfvars.exampledocuments the variable, anddocs/getting-started/setup.mdgets a troubleshooting entry for the error above. If the deployment already failed, the entry first sends readers to the recovery steps for the tainted VPC origin (docs(setup): recovery for EntityAlreadyExists after a failed CloudFront VPC origin #650, [Bug]: A failed CloudFront VPC origin create can't be retried (EntityAlreadyExists on replacement) #648) before they re-run.Security notes
false, nothing is created and the plan doesn't change.internal = true, and its security group admits only the CloudFront origin-facing managed prefix list.allow-bidirectionalis the only exclusion mode that lifts ingress blocking, which the VPC origin needs. The NAT gateway subnets get onlyallow-egress, which keeps inbound internet traffic blocked and grants nothing beyond whatblock-ingressmode already allows.Testing
scripts/test/terraform-hardening.test.mjspins thefalsedefault, both exclusions (subnets, modes, counts), and the ordering throughvpc_origin_subnet_ids.node --test scripts/test/terraform-hardening.test.mjs: 9 passed.terraform testplan of the networking module gave 2 private + 1 NAT exclusions indev, 2 NAT exclusions inprod, and none with the defaultfalse.terraform fmt -check -recursive,terraform validate -no-tests, and theauth-domain,waf,yjs,managed-environmentsandlambda-packagingterraform testsuites pass locally (Terraform 1.12.1).npm run format,npm run lintandnpm run testpass.block-ingressaccount (first commit): the private-subnet exclusions were created in 4–5 minutes, the VPC origin reachedDeployed, the Yjs target group was healthy, the AgentCore runtime wasREADY, and Yjs and realtime WebSockets connected through CloudFront → VPC origin → internal ALB → ECS. In a second account without BPA, the defaultfalseproduced no plan diff.block-bidirectionalaccount (752575e, fresh deploy): all three exclusions active; VPC originDeployed; Yjs task healthy; AgentCoreREADY; the collaborative editor, a CodeCommit-backed space and an agent intent (Claude Code,bugfix) ran throughreverse-engineeringto the first gate and on torequirements-analysis. The AgentCore runtime's own subnets need no exclusion: they egress through the excluded NAT subnet.ResourceInitializationError … unable to retrieve secrets from ssm. Re-applying Terraform recreated just that exclusion and everything recovered.Impact
None unless the variable is set to
true. Movingmodule.yjs_serverto the new output doesn't change any subnet IDs, so existing deployments see no diff.By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.