# School AWS account deployment

Status: **prepared, not executed**. The school account is authorised for the
project, but deployment requires an attended session with valid school
credentials, the school account ID, an approved administrator `/32`, and
confirmation that CloudFormation may create the IAM roles used by the optional
recovery stack.

## Deployment objective

Use the school account for the assessed demonstration. Keep the personal
account as a separately owned test bed and fallback. Do not connect the two
accounts, share VPN pre-shared keys, or reuse account-specific resource IDs.

The package is account-neutral:

- `vpn1-onprem-us-east-1.yaml` — simulated on-premises VPC, strongSwan and test
  host, Flow Logs and retained evidence bucket.
- `vpn1-awspublic-eu-west-1.yaml` — AWS hub VPC, Apache workload, VPN #1,
  optional staged VPN #2, Flow Logs, CloudTrail, SNS and VPN alarms.
- `hub-alb-eu-west-1.yaml` — internet-facing ALB for the hub's existing EC2.
- `hub-recovery-eu-west-1.yaml` — optional cold recovery controller and ASG,
  desired capacity zero.
- `eg334s-azure-cell.bicep` — Azure VNet, workload and optional VPN gateway.

Azure remains in Bernard's Singapore tenant unless the team approves a
different tenant. Temporary cloud-only tenant members are an access-control
choice, not a prerequisite for the AWS school deployment.

## Gates before any write

1. Run `./scripts/preflight-school-account.sh` with the school AWS profile.
2. Record the returned account ID in the deployment evidence; confirm it is not
   the personal account.
3. Confirm the caller can use CloudFormation, EC2, VPC, Elastic Load Balancing,
   CloudWatch, CloudTrail, S3 and SNS in `us-east-1` and `eu-west-1`.
4. Confirm whether `iam:CreateRole`, `iam:PassRole` and
   `CAPABILITY_NAMED_IAM` are allowed. If not, deploy the core and ALB only;
   mark automated recovery **provisional** until the lecturer/admin supplies a
   permitted role.
5. Supply one real administrative public IPv4 `/32`. The templates reject
   `0.0.0.0/0`.
6. Create or nominate an EC2 key pair in each AWS region. Key-pair names are
   regional.
7. Confirm quotas for three EC2 instances, two Site-to-Site VPN connections,
   one VGW, one ALB, two Elastic IPs and the required VPCs/subnets.
8. Never place a VPN PSK, private key or cloud credential in Git, the dashboard,
   the report, the deck or a recording.

## Account-safe sequence

### 1. Authenticate and prove the target

```bash
export EG334S_AWS_PROFILE=school
export EG334S_ADMIN_CIDR=203.0.113.10/32   # replace with the approved real /32
AWS_PROFILE="$EG334S_AWS_PROFILE" ./scripts/preflight-school-account.sh
```

Stop if the account ID is unexpected.

### 2. Validate before deployment

```bash
./scripts/validate-iac.sh
AWS_PROFILE="$EG334S_AWS_PROFILE" aws cloudformation validate-template \
  --region us-east-1 \
  --template-body file://docs/iac/vpn1-onprem-us-east-1.yaml
AWS_PROFILE="$EG334S_AWS_PROFILE" aws cloudformation validate-template \
  --region eu-west-1 \
  --template-body file://docs/iac/vpn1-awspublic-eu-west-1.yaml
```

`validate-template` checks schema, not behaviour. A change set is still required
before execution.

### 3. Deploy the two AWS core stacks

Create a change set for each template and inspect it before execution. Use new
school-account stack names such as:

- `eg334s-school-onprem`
- `eg334s-school-hub`
- `eg334s-school-alb`
- `eg334s-school-recovery`

Pass the approved `/32`, regional key-pair names and cross-stack outputs as
parameters. Do not copy any VPC, subnet, EC2, VGW, CGW, VPN, ALB or target-group
ID from the personal account.

### 4. Establish VPN #1

The strongSwan Elastic IP created in the school account becomes the hub
template's customer-gateway address. Retrieve the generated tunnel endpoints
and PSK from the school account at deployment time and place the PSK only in
the protected strongSwan configuration. Test:

1. AWS reports the connection `available`.
2. At least one tunnel is `UP`.
3. The on-premises test host reaches the hub private address with ICMP.
4. HTTP returns the expected page.

### 5. Integrate Azure and VPN #2

Rebuild the Azure gateway only for an attended window. The Azure gateway public
IP becomes the AWS customer-gateway parameter. Pass the AWS-generated PSK to
Azure as a secure deployment parameter. Record control-plane and data-plane
evidence, then park the gateway again if the team retains the cost-control
decision.

### 6. Add the ALB and optional recovery

Deploy the ALB with the school hub's VPC, two public subnets and existing hub
EC2 ID. Verify HTTP through the ALB and target health. Deploy recovery only if
IAM is permitted. Keep desired capacity at zero outside a drill.

The personal account's 244-second recovery result is transferable as design
evidence, not as proof of the school account. The school account needs its own
attended cutover result before the claim is repeated there.

### 7. Optional direct VPN #3

A direct Virginia-to-Azure VPN is the cost-controlled way to meet a new
requirement for Azure to reach the simulated on-premises VPC without replacing
the VGW with Transit Gateway. It is **not part of the current deployed baseline**
and remains provisional because it adds another VPN connection, another peer
definition, route/security changes and an extra test surface. Implement only
after VPN #1 and VPN #2 are stable and the team accepts the Azure gateway cost.

### 8. Evidence and teardown

Run the eight recording chapters in `docs/VIDEO_CAPTURE_PLAN.md`. At the end:

1. Delete recovery, then ALB.
2. Delete VPN #2 borrower resources.
3. Delete the school hub owner stack.
4. Delete the school on-premises stack.
5. Delete or park the Azure resource group as approved.
6. Run `./scripts/verify-teardown.sh` against every account, region and
   subscription.
7. Record intentionally retained CloudTrail, Flow Log, S3, SNS, CloudWatch and
   public-dashboard evidence resources explicitly.

## Rollback and stop conditions

Stop rather than improvise when the account ID is wrong, the administrator CIDR
is not a valid `/32`, IAM is denied, quota is insufficient, a change set
replaces an owner resource unexpectedly, cost alarms are missing, or a required
query fails. Label the affected capability **provisional** and preserve the
failure output for the report.
