QA AWS networking lab for parity with Azure and GCP - #29
Conversation
Bring the AWS lab in line with the Azure (#26) and GCP (#27) QA passes while keeping AWS networking semantics. All changes are under aws/. - Bootstrap with a working private-subnet NAT route, wait for cloud-init and healthy local services, then remove the route to prepare INC-4521. - Move the web server to the public subnet: AWS only serves an instance public IP when the subnet routes to the internet gateway. - Replace the generic HTTP listener with a Flask health API plus postgresql-client, and run real PostgreSQL on the database instance. - Add common.sh and sg-policy.py: verify the API's effective route table, NAT gateway, and observed outbound IP; check Route 53 private DNS through the Amazon and system resolvers on all four instances; probe application health over private IPs; evaluate effective security-group ingress sources across all attached groups, port ranges, references, prefix lists, and IPv6, corroborated by live allowed/denied traffic. - Return 0/1/2 for resolved/unresolved/error, gate token export on all four incidents, and lower the zone's SOA negative TTL during setup. - Look up the AMI in the root module so setup re-runs do not replace instances; make destroy remove instances first, delete unmanaged security groups, and recover IDs from state after a partial destroy. - Rewrite aws/README.md with the platform-correct topology, diagnostics, expected results, propagation caveats, and cleanup guidance. Closes #28 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
AMI drift can replace instances, service errors can be misreported, and cross-referenced groups can still delay cleanup.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Brings the AWS networking lab into parity with the Azure and GCP incident workflows using AWS-native networking behavior.
Changes:
- Adds reliable bootstrap, real Flask/PostgreSQL services, and AWS-specific topology.
- Expands validation for NAT, DNS, application paths, and effective security-group policy.
- Improves setup, cleanup, diagnostics, and student documentation.
File summaries
| File | Description |
|---|---|
.gitignore |
Ignores Python caches and Terraform plans. |
aws/README.md |
Documents topology, incidents, validation, and cleanup. |
aws/scripts/common.sh |
Adds shared connectivity and policy checks. |
aws/scripts/destroy.sh |
Handles unmanaged resources during cleanup. |
aws/scripts/setup.sh |
Verifies bootstrap before preparing faults. |
aws/scripts/sg-policy.py |
Evaluates effective security-group ingress. |
aws/scripts/validate.sh |
Adds detailed incident validation and exit codes. |
aws/terraform/main.tf |
Moves AMI lookup and sequences compute creation. |
aws/terraform/outputs.tf |
Exposes diagnostic resource and instance IDs. |
aws/terraform/modules/compute/main.tf |
Moves web to public subnet and consumes AMI input. |
aws/terraform/modules/compute/outputs.tf |
Exposes instance IDs. |
aws/terraform/modules/compute/variables.tf |
Adds the AMI input. |
aws/terraform/modules/compute/templates/api-init.sh |
Installs and runs the Flask API. |
aws/terraform/modules/compute/templates/bastion-init.sh |
Adds diagnostics and readiness marker. |
aws/terraform/modules/compute/templates/database-init.sh |
Installs and configures PostgreSQL. |
aws/terraform/modules/compute/templates/web-init.sh |
Updates web bootstrap and subnet guidance. |
aws/terraform/modules/dns/main.tf |
Clarifies private-zone behavior. |
aws/terraform/modules/dns/records.tf |
Documents intentionally absent records. |
aws/terraform/modules/network/main.tf |
Adds bootstrap NAT routing and clarifies NACL behavior. |
aws/terraform/modules/network/outputs.tf |
Exposes routing, gateway, and NACL IDs. |
aws/terraform/modules/network/security_groups.tf |
Documents intentional SG faults. |
Review details
- Files reviewed: 20/21 changed files
- Comments generated: 3
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| # depends on the whole network module, and a data source inside it would be | ||
| # deferred (and force instance replacement) on every re-run. | ||
| data "aws_ami" "ubuntu" { | ||
| most_recent = true |
- destroy.sh: destroy the lab's own security groups together with the instances in the first targeted pass so their rules referencing unmanaged groups are revoked, then delete unmanaged groups before the full destroy. Verified live: with a student-created group attached to the API and cross-referenced by the API group, an uninterrupted destroy completed in under three minutes with nothing left behind. - compute: ignore AMI changes on existing instances so a newer Ubuntu image does not replace them on a setup re-run (verified by planning with an older AMI ID: no replacements). - common.sh: check local API and PostgreSQL health separately so each failure names the right service. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
The broad AWS infrastructure, security-policy, and destructive-cleanup changes warrant final human review despite the documented live QA.
Review details
- Files reviewed: 20/21 changed files
- Comments generated: 0 new
- Review effort level: Balanced
|
just fyi in recent merge I removed skills taht do lab qa and replaced to maintence report. |
|
yeah, I will be doing a full end-to-end manual test today |
Manual verificationI ran the lab by hand from the Environment: us-east-1, deployment
Note on token verification: a corrupted token (broken base64 or JSON) is rejected with a non-zero exit and is never reported as valid, but the script exits silently after "Verifying token..." instead of printing "Invalid token format". Not covered in this manual pass (covered by the automated QA in #29): validating after each incident individually, partial INC-4523 repairs, and the rejection cases (internet-gateway route or public IP for INC-4521, wrong or extra DNS answers, hosts-file workarounds, broad or alternate security-group rules). |
Summary
Bring the AWS lab into parity with the four incidents QA'd for Azure (#26) and GCP (#27), using AWS networking semantics. Closes #28. All changes are under
aws/; Azure and GCP are unchanged, and the sharedscripts/dns-validation.shis used as-is.169.254.169.253) and the system resolver on all four instances, including the bastion. Shorten the zone's SOA negative TTL to 60s so repaired records become visible quickly.http.serverwith a Flask health API pluspostgresql-client, run real PostgreSQL on the database instance, and validate API health JSON andpg_isreadyover private IPs.sg-policy.py, an effective security-group evaluator: unions all attached groups, port ranges and all-protocol rules, expands security-group references to current member interfaces, resolves managed prefix lists, flags IPv6 sources, and errors on dual-stack or cross-account/peered topologies. Corroborate with live allowed/denied probes, including internet SSH to the web server's public IP.1) from execution/service errors (2), gate token export on all four passing, and rewriteaws/README.mdwith the platform-correct topology, diagnostics, expected results, caveats, and cleanup.Confirmed bugs fixed
python3 -m http.server, so/healthreturned 404 andncwas the only probe; the database ran a bare TCP listener.FromPort == 22rules on the Terraform-named groups, so port ranges, all-protocol rules, extra attached groups, prefix lists, and referenced-group membership were not evaluated.depends_on, which would have replaced all four instances on every setup re-run.Live QA results (us-east-1, deployment
50b686de)Each case was driven with the AWS CLI as a student would, and corroborated with live probes over SSH (
curl,dig/getent,pg_isready,nc,ping) in addition to the validator's own result. Exit codes:0resolved,1unresolved,2validation error.setup.shvalidate.sh/etc/hostsentry on the bastion with correct cloud DNShttp.serveron 8080 (404) / API stopped / PostgreSQL stopped /pg_isreadyremoveddigremoved from the web instance::/0/32of the bastion's private IP instead of the SG referencenetworking-lab-aws, 4 challenges, correct deployment IDPlatform-specific deviations
/32of the bastion's or API's current private IP is accepted as equivalent (documented in the README). Network ACLs and outbound rules do not substitute for tight inbound rules on the destination group.Tested scope and limitations
terraform fmt -check/validate,shellcheck -xon scripts and cloud-init templates,bash -n,python3 -m py_compile. No regression test suite added.example.comitself, IAM principals with partial permissions (a bad-credential principal was tested), dual-stack VPCs, cross-account/peered SG references, and regions other thanus-east-1. Those topologies produce explicit validation errors.destroy.shnow removes the instances and the lab's own security groups first (revoking rules that reference unmanaged groups), deletes unmanaged groups (identified by state resources, not by text search), then destroys the rest, and resolves IDs from the state file when outputs are gone after a partial destroy. Verified on a third deployment (8bc6cde5) with a student-created group attached to the API and cross-referenced by the API group: one uninterrupted run finished in under three minutes with nothing left behind.Cleanup evidence
Three QA deployments (
50b686de,651d8279,8bc6cde5) were destroyed withdestroy.sh, each with an unmanaged, cross-referenced security group planted (the last two also attached to the API interface). After each: no lab instances, volumes, NAT gateways, Elastic IPs, ENIs, security groups, network ACLs, route tables, VPCs, key pairs, orinternal.testhosted zones remain; the temporary QA VPC and prefix list were deleted; Terraform state is empty;~/.ssh/netlab-keywas removed (none existed before QA). No completion tokens are included.🤖 Generated with Claude Code