# Generate Phase: Documentation Generation > Loaded by generate.md LAST, after all other artifact generation sub-files complete. **Execute ALL steps in order. Do not skip or optimize.** ## Overview Produce comprehensive migration documentation from all generated artifacts. This runs LAST because it references all previously generated plans and artifacts. **Outputs:** - `MIGRATION_GUIDE.md` — Step-by-step migration guide organized by phase - `README.md` — Quick start, artifact catalog, and architecture overview - `STARTUP_PROGRAMS.md` — AWS startup program eligibility and credit guidance (AI track only) ## Prerequisites At least one generation JSON must exist in `$MIGRATION_DIR/`: - `generation-infra.json` (infrastructure migration plan) - `generation-ai.json` (AI migration plan) - `generation-billing.json` (billing-only migration plan) Scan for all generated artifacts: - `terraform/` directory (Terraform configurations) - `scripts/` directory (migration scripts) - `ai-migration/` directory (AI provider adapter and test harness) If **no** generation JSON exists: **STOP**. Output: "No migration plans found. Stage 1 of Generate phase did not complete." ## Output Structure ``` $MIGRATION_DIR/ ├── MIGRATION_GUIDE.md # Detailed step-by-step migration guide └── README.md # Quick reference and artifact catalog ``` ## Step 1: Generate MIGRATION_GUIDE.md Build a phase-based migration guide that adapts sections based on which tracks ran. ### Document Structure The MIGRATION_GUIDE.md follows this structure: - Title: `# GCP to AWS Migration Guide` - Subtitle: `> Generated by GCP to AWS Migration Advisor` - Table of Contents (auto-generated from sections) - Section 1: Prerequisites (always included) #### Prerequisites Section Content #### Pre-migration: root user security - **Enable root MFA (ACCT.05).** Operators must complete root MFA setup before first console sign-in. The plugin does not manage MFA devices. - **Restrict use of the root user (ACCT.02).** Store root credentials in a password manager; use only for account recovery or the small handful of tasks that require root. Do not use for daily work. - **Remove any root access keys.** Root access keys should not exist; if any are present, delete them before any migration work. - **Plan for day-to-day access via IAM Identity Center (ACCT.03, ACCT.04, ACCT.13).** Creating IAM Identity Center users, group-based permission sets, and short-lived credentials is out of scope for this plan and is covered by the landing-zone spec. Include these checklists: - AWS Account Setup: account created, IAM user, AWS CLI, Terraform >= 1.5.0 - GCP Access: project access, gcloud CLI, service account with export permissions - Tools Required: terraform, aws-cli, gcloud, docker, jq - If AI track ran: add python >= 3.9, boto3 ### Conditional Sections #### IF infrastructure track ran (generation-infra.json exists) Generate the following sections: **Section 2: Infrastructure Setup** — Deploy AWS Infrastructure subsection with numbered steps: 1. Review Terraform configurations in `terraform/` (main.tf, variables.tf, domain .tf files) 1. Initialize and plan: `cd terraform/ && terraform init && terraform plan -out=migration.tfplan` 1. Review the plan output carefully before applying 1. Apply: `terraform apply migration.tfplan` Post-Infrastructure Tasks checklist: verify resources, check security groups, validate IAM roles. **Section 3: Data Migration** — **Include ONLY if `scripts/02-migrate-data.sh`, `scripts/03-migrate-containers.sh`, or `scripts/04-migrate-secrets.sh` exist.** If NONE of these scripts were generated, skip Section 3 entirely. Include only subsections for scripts that were generated: Database Migration subsection (only if `scripts/02-migrate-data.sh` exists) with numbered steps: 1. Run prerequisites check: `./scripts/01-validate-prerequisites.sh` 1. Execute data migration (dry run first): `./scripts/02-migrate-data.sh` then `./scripts/02-migrate-data.sh --execute` 1. Validate data integrity: `./scripts/05-validate-migration.sh` Container Image Migration (only if `scripts/03-migrate-containers.sh` exists): `./scripts/03-migrate-containers.sh` (dry run, then `--execute`) Secrets Migration (only if `scripts/04-migrate-secrets.sh` exists): `./scripts/04-migrate-secrets.sh` (dry run, then `--execute`) **Section 4: Service Migration** — Per-cluster migration steps from generation-infra.json, organized by creation_order depth. **Graviton Migration Notes** — Include when any compute resource in `aws-design.json` has `graviton.target_architecture == "arm64"` (see `references/shared/graviton.md`). Add a short subsection in Section 4 listing: - Which services were migrated to ARM64 (Graviton) and their instance types/runtime platform - Any `conditional`-tier services with their `caveats[]` (for example, "verify native extension `X` has an arm64 build") - The build step: container images must be built for arm64 (`docker build --platform linux/arm64`) - A recommendation to validate with a load test post-migration (Graviton physical cores may allow further downsizing — not reflected in the cost estimate) If `cpu_architecture` is `x86` (user opted out) or no compute targets arm64, skip this subsection. **Human Expertise Advisory (BigQuery / deferred analytics)** — If any service has `human_expertise_required: true` for BigQuery or `aws_service` is **`Deferred — specialist engagement`**, include a prominent callout in Section 4 next to that service: > **Specialist engagement required (BigQuery):** This plugin **does not** choose an AWS analytics or warehouse target (no Athena/Redshift/Glue recommendation). Engage your **AWS account team** and/or a **data analytics migration partner** before data warehouse, lake, or SQL analytics design. BigQuery work involves query patterns, data movement, ETL/ELT, and BI integration that must be assessed by specialists. #### IF AI track ran (generation-ai.json exists) Generate the following section: **Section 5: AI Migration** with subsections: - Setup Bedrock Access: run `./setup_bedrock.sh`, enable model access in AWS Console - Deploy Provider Adapter: review adapter file, update TODO markers, deploy with application - Run A/B Comparison: `python ai-migration/test_comparison.py --quick`, review results, verify quality >= 90% - Gradual Rollout: shadow mode, 10% traffic, scale to 100%, disable Vertex AI after 48 hours stable #### IF billing-only track ran (generation-billing.json exists) Generate the following section: **Section 2: Billing-Only Limitations** — Include blockquote warning that the plan was generated from billing data only. Before Proceeding subsection recommending IaC discovery or manual audit. Using the Skeleton Terraform subsection with steps to find and resolve TODO markers. ### Common Sections (always included) **AWS Credits callout (only when generation-ai.json exists):** > 💡 **Before incurring costs:** Check [STARTUP_PROGRAMS.md](./STARTUP_PROGRAMS.md) for AWS Activate credits that apply to Bedrock and infrastructure costs. Credits do not apply retroactively — apply before running `terraform apply`. **Cutover section** with subsections: - Pre-Cutover Checklist (from generation plan) - Execute Cutover (DNS switch, traffic migration, monitoring) - Post-Cutover Monitoring (24-48 hour watch, then 30-day monitoring) **Validation and Cleanup section** with subsections: #### Post-migration: remove unused default VPC (ACCT.09) Confirm first that no resources depend on the default VPC: ```bash aws ec2 describe-instances --filters "Name=vpc-id,Values=" \ --region ``` Delete the default VPC (this also deletes default subnets, route tables, and internet gateway associations): ```bash aws ec2 delete-vpc --vpc-id --region ``` If the command fails with dependency errors, investigate the listed resources before retrying. Do not force-delete. - Validation Steps checklist: services responding, performance thresholds, data integrity, cost tracking - GCP Teardown checklist (after stability period): archive data, delete resources, disable billing **Troubleshooting section** with a Common Issues table: | Issue | Cause | Resolution | | -------------------------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | Terraform apply fails | Missing permissions | Check IAM role has required policies | | Database connection refused | Security group rules | Verify inbound rules allow app subnet CIDR | | Container image pull fails | ECR authentication | Run `aws ecr get-login-password` | | Bedrock InvokeModel fails | Model access not enabled | Enable in AWS Console | | High latency after migration | Suboptimal instance sizing | Review CloudWatch metrics and right-size | | `validation-report.json` shows `passed_degraded_offline` | Provider registry was unreachable when Generate ran | From a network-connected shell, run `cd terraform/ && terraform init && terraform validate` to complete the skipped checks | Rollback Procedure subsection (from generation plan). A one-line "rollback via DNS" note is NOT sufficient — cutover is the highest-stress, lowest-judgment moment of the migration, and this subsection is the runbook the reader executes at 2am. It MUST contain: 1. **Triggers — when to pull it:** concrete criteria, not vibes (e.g., "error rate > X% for 10 minutes on the validation checks in `05-validate-migration.sh`", "data validation row counts diverge", "p99 latency > 2x GCP baseline after 30 minutes"). State who decides if the team is more than one person. 2. **Steps — exact commands:** the literal DNS change to restore (record, old value, new value, TTL implications given the cutover TTL), what to stop on the AWS side, and how to confirm traffic is back on GCP. 3. **The data question — answer it explicitly:** rows written to the AWS database after cutover do NOT exist in Cloud SQL. State the chosen posture for this stack: (a) brief write-freeze before rollback + export the delta, (b) accept loss of the post-cutover window (viable for low-write apps — say so if Q12 said `steady`/low), or (c) reverse sync required (name the tool). Never leave this implicit — a DNS rollback with unresolved writes silently loses customer data. 4. **RTO:** how long the rollback takes end-to-end, dominated by DNS TTL. ### Footer End the document with: ``` --- Generated by GCP to AWS Migration Advisor ``` ## Step 2: Generate README.md Build a quick-reference README for the migration artifacts. ### README Structure The README.md follows this structure: - Title: `# GCP to AWS Migration Artifacts` - Subtitle: `> Generated by GCP to AWS Migration Advisor` Immediately after the subtitle, before any other section, write a conditional **Start here** callout block. Include only the lines that apply to what was actually generated: ```markdown > **Start here** > > - **AI migration:** `cd ai-migration && ./setup_bedrock.sh --dry-run`, then re-run with `--execute` when ready > - **Infrastructure:** `cd terraform && terraform init && terraform plan -out migration.tfplan`, then `terraform apply migration.tfplan` > - **Both tracks:** complete AI setup first, then run Terraform ``` **Conditional rules:** - Omit the AI line entirely if `ai-migration/` was not generated - Omit the Infra line entirely if `terraform/` was not generated - Omit the "Both" line if only one track ran - If neither directory exists (billing-only run), omit the Start here block entirely #### Next steps Numbered steps: 1. If AI track ran: `cd ai-migration && ./setup_bedrock.sh` (dry run), then `--execute` when ready 1. If infra track ran: `cd terraform && terraform init && terraform plan`, then `terraform apply migration.tfplan` 1. Run migration scripts: `./scripts/01-validate-prerequisites.sh` 1. If AI track ran: Set up AI: `cd ai-migration/ && ./setup_bedrock.sh` 1. If AI track ran: Review AWS credits: [STARTUP_PROGRAMS.md](./STARTUP_PROGRAMS.md) — apply before incurring costs 1. Review the full Migration Guide: [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) #### Artifact Catalog Table with columns: Artifact, Description, Status. List all generated files/directories. Subsections: - Migration Plans (Stage 1): list generation-*.json files - Infrastructure (Stage 2): list .tf files, **`terraform/README.md`** (when infra Terraform was generated), and migration scripts if they exist - AI Migration (Stage 2): list adapter, test harness, setup script if they exist - Documentation: MIGRATION_GUIDE.md and README.md #### Architecture Overview - Source (GCP): list GCP services from design artifacts - Target (AWS): list AWS services from design artifacts with region - Migration Approach: summary from generation plans (phased/fast-track/conservative) #### Cost Summary #### Security baseline costs **Scenario A — Tier 1 alone** (no compliance declared in Q2): Per-unit pricing verified against the AWS Pricing API for us-east-1 on 2026-05-04; accuracy ±25%. | Resource | Monthly cost | Notes | | ----------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------ | | Account alternate contacts | $0 | Free (ACCT.01) | | IAM password policy | $0 | Free (ACCT.06) | | S3 account-level PAB | $0 | Free (ACCT.08) | | EBS default encryption | $0 | Free (defense-in-depth; KMS encrypt/decrypt is negligible for EBS) | | IAM Access Analyzer | $0 | Free for external-access analyzers on your own account (ACCT.11) | | IMDSv2 account default | $0 | Free (defense-in-depth) | | CloudTrail trail | $0 for events (first trail per region free); S3 storage ~$0.50–3/mo | Management events only (ACCT.07) | | S3 bucket for CloudTrail logs | ~$0.50–3/mo | Storage + PUT requests | | AWS Budgets (1 budget) | $0 | First 2 budgets per account are free (ACCT.10) | | GuardDuty | $0 for 30 days, then ~$2–25/mo | Scales with VPC traffic and API calls (defense-in-depth) | | **Total estimate** | **$3–30/mo after trial** | GuardDuty is the dominant line item | To skip the baseline, delete `terraform/baseline.tf` before running `terraform apply`. **Scenario B — Tier 1 + compliance-conditional** (SOC 2 / PCI / HIPAA / FedRAMP declared in Q2): Per-unit pricing verified against the AWS Pricing API for us-east-1 on 2026-05-04; accuracy ±25%. Tier 1 subtotal (as in Scenario A above): **$3–30/mo after trial**. Additional compliance-conditional resources: | Resource | Monthly cost | Notes | | --------------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------- | | AWS Config (account-level recorder) | ~$2–10/mo | $0.003 per CI continuous mode; daily mode cheaper, lower signal | | S3 bucket for Config delivery | ~$0.20–1/mo | Storage + PUT requests; same retention as CloudTrail | | AWS Security Hub (FSBP + any extra standards) | $0 for 30 days, then ~$1–15/mo | Tiered per-check + per-resource (Fargate-only startups pay nothing for EC2 dimension) | | **Compliance-conditional subtotal** | **~$3–25/mo after Security Hub trial** | | | **Grand total** | **~$6–55/mo after both free trials** | | **Compliance notes**: - Security Hub does NOT provide a HIPAA-specific standard. FSBP covers many overlapping controls; for full HIPAA attestation, engage a qualified HIPAA auditor and review the [AWS HIPAA Eligible Services Reference](https://aws.amazon.com/compliance/hipaa-eligible-services-reference/). - FedRAMP compliance uses NIST 800-53 at the agency level, but this mapping is not directly subscribable in Security Hub — engage your AWS account team for FedRAMP attestation. To skip the compliance-conditional section only, delete the block between `########## Compliance-Conditional ##########` and `########## End Compliance-Conditional ##########` in `terraform/baseline.tf` before `terraform apply`. To skip the baseline entirely, delete `terraform/baseline.tf`. Table from estimation artifacts with: Current GCP Monthly, Projected AWS Monthly (use **Balanced** tier for the primary AWS column when `estimation-infra.json` exists), Timeline. **Only include a "GCP data transfer egress (est.)" column when `estimation-infra.json` exists and `migration_cost_considerations.billing_data_available` is `true`.** Do **not** add columns or rows for human labor, professional services, or other people-time migration costs. If billing data is unavailable, add a note below the table: "GCP data transfer egress estimates require billing data. Provide a billing export and re-run discovery to see vendor egress projections." **How to read cost tiers** (required when infra estimates include Premium / Balanced / Optimized): - The three AWS monthly totals are **scenarios** for the **same** architecture, ordered **high → mid → low** estimate. - **Premium** — _Highest resilience / highest monthly estimate in this model_ - **Balanced** — _Default scenario; compare GCP to this first_ - **Optimized** — _Lower monthly estimate; reservations / Spot / storage trade-offs assumed_ - **Terraform:** The `terraform/` directory (when present) implements **one** stack, aligned with the **Balanced** scenario. **Premium** and **Optimized** are not separate generated folders — see `terraform/README.md` and the `migration_summary` output in `outputs.tf`. Include a compact three-tier row or table if the executive report does, matching figures from `estimation-infra.json`. **Combined estimated AWS monthly run rate (required when both `estimation-infra.json` and `estimation-ai.json` exist):** Call this a recurring cloud-service run rate, never TCO. State that staffing, operations, support, migration labor, and other ownership costs are excluded. | | GCP monthly | AWS Balanced monthly | | -------------- | ------------------------------------------------- | ------------------------------------------------ | | Infrastructure | from `current_costs.gcp_monthly` | from `projected_costs.aws_monthly_balanced` | | AI / ML | from `current_costs.gcp_monthly_ai_spend` | from `cost_comparison.projected_bedrock_monthly` | | **Combined** | sum only when every source baseline is comparable | sum | Note BigQuery/deferred services excluded if applicable. If any GCP source baseline is partial or not comparable, show "Not comparable" rather than a combined GCP total or overall savings percentage. **Security baseline in README:** When `estimation-infra.json` → `projected_costs.breakdown.security_baseline` exists, include a sub-table with component costs (GuardDuty, CloudTrail S3, etc.) from `components` — not only static ranges. #### Key Decisions Bullet list from design and generation artifacts: Compute, Database, Storage, and AI/ML (if applicable) with GCP service, AWS service, and rationale. For each GCP→AWS mapping, add how it was chosen using `design-refs/fast-path.md` → **User-facing vocabulary**: **Standard pairing**, **Tailored to your setup**, or **Estimated from billing only** (from the design artifact’s `confidence` field). For any service with `human_expertise_required: true`, append: "(Specialist guidance recommended — contact your AWS account team)". #### Fill-In Checklist (replaces the old "TODO Items" grep hint) Scan every generated artifact (`terraform/`, `scripts/`, `ai-migration/`) for placeholders (`TODO`, `ACCOUNT_ID`, `<...>` tokens, `example.com` values) and render them as ONE consolidated table — this is the reader's single "before you can apply" list. One row per **value**, not per occurrence (the same billing email appearing in four places is one row listing all four locations). **Step 2b generates only `terraform.tfvars.example`** (the real `terraform.tfvars` is gitignored and never generated), so row 0 is always the copy step — every other row that points at `terraform.tfvars` depends on it having been done first: ```markdown ## Fill-in checklist — [N] values needed before `terraform plan` | # | Value | Where to set it | Where to get it | | --- | ----------------------------------- | ---------------------------------- | -------------------------------------------------------------- | | 0 | Create your real tfvars file | `terraform/` | `cp terraform.tfvars.example terraform.tfvars` — do this first | | 1 | AWS account ID | `terraform/main.tf` backend bucket | `aws sts get-caller-identity --query Account --output text` | | 2 | Ops/billing/security contact emails | `terraform.tfvars` | Your team — real inboxes, not aliases you don't read | | 3 | ECR image URI | `terraform.tfvars` | After first `docker push` — see Phase 2 | | 4 | Cloud SQL source host | env var for `scripts/02-*.sh` | Cloud SQL console → instance → Public/Private IP | | ... | | | | ``` Every "Where to get it" cell must contain a concrete command, console path, or artifact reference — never just "your value here". Include the same table (or a link to it) in MIGRATION_GUIDE.md's Prerequisites section, and keep the grep one-liner underneath as a verification aid: ```bash grep -rn "TODO" terraform/ scripts/ ai-migration/ 2>/dev/null # should return nothing when the checklist is done ``` #### Footer End with: `Generated by GCP to AWS Migration Advisor` ### Populate from artifacts - **Artifact catalog**: List all files actually generated (check for directory/file existence) - **Architecture overview**: Extract from `aws-design.json`, `aws-design-ai.json`, or `aws-design-billing.json` - **Cost summary**: Extract from `estimation-infra.json`, `estimation-ai.json`, or `estimation-billing.json`; include **How to read cost tiers** when three infra tiers exist; state **Balanced** as primary vs GCP and Terraform alignment per `terraform/README.md` when present - **Key decisions**: Extract from design artifact `rationale` fields and map `confidence` to user-facing labels per `design-refs/fast-path.md` → **User-facing vocabulary** - **Migration shape**: Extract from `generation-*.json` `migration_plan.duration_drivers` (approach + ordered stages; operational windows like watch periods may be stated as procedure — never staffing estimates or week/hour figures) ## Step 3: Self-Check After generating documentation, verify: 1. **All file references are valid**: Every file path mentioned in MIGRATION_GUIDE.md exists in the artifact directory 1. **Commands are syntactically correct**: All bash commands use correct syntax 1. **No unresolved placeholders**: All `[placeholder]` values are replaced with actual data from artifacts 1. **Conditional sections match**: Only sections for tracks that actually ran are included 1. **Fill-in checklist is complete**: row 0 is the `cp terraform.tfvars.example terraform.tfvars` step, every placeholder (`TODO`, `ACCOUNT_ID`, `<...>`, `example.com`) present in generated artifacts appears in the Fill-in checklist table, and every row's "Where to get it" cell contains a concrete command, console path, or artifact reference 1. **Cost figures match**: Values in README.md match estimation artifacts 1. **Timeline matches**: Week counts match generation plan artifacts 1. **Rollback instructions match**: Rollback Procedure subsection contains all four contract elements from above — (1) triggers with concrete criteria tied to `05-validate-migration.sh` checks, (2) exact DNS/restore commands with TTL implications, (3) an explicit post-cutover-writes data posture (write-freeze + delta / accepted loss / reverse sync by name), and (4) RTO — and those steps match the generation plan. A one-line "rollback via DNS" fails this check. ## Phase Completion Report the list of generated files to the parent orchestrator. **Do NOT update `.phase-status.json`** — the parent `generate.md` handles phase completion. Before reporting completion, enforce artifact output gate: - `MIGRATION_GUIDE.md` exists. - `README.md` exists. - Conditional sections in docs match tracks that actually ran (infra/ai/billing). - Referenced artifact paths in docs exist. If this gate fails: STOP and output: "generate-artifacts-docs did not produce complete documentation artifacts." Output: ``` Generated documentation: - MIGRATION_GUIDE.md ([N] sections, covering [tracks that ran]) - README.md (artifact catalog, architecture overview, cost summary) Sections included: - [List which conditional sections were generated based on tracks that ran] ```