Run 1: Infrastructure
Entry Criteria
Section titled “Entry Criteria”| # | Criterion | Verification Command | Expected Output |
|---|---|---|---|
| 1 | Alpha001 demo partition CDK infrastructure is deployed (Cognito, Aurora, API Gateway, DNS) | aws cloudformation list-exports --region us-east-1 --output text --query "Exports[?Name=='Alpha001-demo-API-GatewayBaseUrl'].Value" | A URL (e.g., https://demo.alpha001.io.arda.cards) |
| 2 | arda-frontend-app repository exists | gh repo view Arda-cards/arda-frontend-app --json name -q .name | arda-frontend-app |
| 3 | infrastructure repository main branch is accessible | gh repo view Arda-cards/infrastructure --json name -q .name | infrastructure |
| 4 | AMPLIFY_GITHUB_ACCESSTOKEN secret exists in GitHub org or infrastructure repo | Verify via GitHub Settings UI or gh secret list -R Arda-cards/infrastructure | Secret listed |
| 5 | ARDA_API_KEY_DEMO GitHub org secret exists | Verify via GitHub Settings UI or check output of infrastructure/tools/sync-secrets-from-1password.sh | Secret exists |
Artifact Specifications
Section titled “Artifact Specifications”| Artifact | Path | Format | Description |
|---|---|---|---|
| Modified CloudFormation template | /infrastructure/src/main/cfn/amplifyBranch.cfn.yaml | CloudFormation YAML | Added EnableAutoBuild parameter and AmplifyBranchName export |
| New CloudFormation template | /infrastructure/src/main/cfn/amplifyExports.cfn.yaml | CloudFormation YAML | Lightweight export stack for existing Amplify apps |
| Modified deployment script | /infrastructure/amm.sh | Bash | Added mapping constants, updated gate, export stack support |
| Modified workflow | /infrastructure/.github/workflows/amm.yml | GHA YAML | Per-environment secret selection |
| Modified CDK construct | /infrastructure/src/main/cdk/constructs/oam/gh-oidc-provider.ts | TypeScript | Added frontendDeploymentRole() |
| Git branch | demo branch in arda-frontend-app | Git branch | Created off main |
Task List
Section titled “Task List”| # | Task | Persona | Depends On | Status | Acceptance Criteria |
|---|---|---|---|---|---|
| 1.1 | Create demo branch in arda-frontend-app | Operator | — | Pending | Branch exists: git ls-remote --heads origin demo returns a ref |
| 1.2 | Modify amplifyBranch.cfn.yaml: add EnableAutoBuild parameter (String, default "true", AllowedValues ["true","false"]) and AmplifyBranchName export | Agent | — | Pending | Template validates; export name is ${Infrastructure}-${Partition}-I-AmplifyBranchName |
| 1.3 | Create amplifyExports.cfn.yaml: lightweight export template with parameters Infrastructure, Partition, AmplifyAppId, AmplifyBranchName | Agent | — | Pending | Template validates; exports match naming convention |
| 1.4 | Modify amm.sh: add AMPLIFY_DEPLOY_TARGETS, AMPLIFY_BRANCH_NAMES, AMPLIFY_APP_REPOS, AMPLIFY_REGION_OVERRIDES constants; update gate condition; pass EnableAutoBuild=false for demo; add lightweight export stack deployment logic | Agent | 1.2, 1.3 | Pending | Constants present; gate allows Alpha001:demo and SandboxKyle002:kyle; blocks others |
| 1.5 | Modify amm.yml: use secrets[format('ARDA_API_KEY_{0}', partition)] | Agent | — | Pending | Dynamic secret selection in workflow YAML |
| 1.6 | Modify gh-oidc-provider.ts: add frontendDeploymentRole() with permissions amplify:StartJob, amplify:GetJob, amplify:GetApp, amplify:GetBranch, cloudformation:ListExports; OIDC scope repo:Arda-cards/arda-frontend-app for refs/heads/main, refs/heads/patch, refs/heads/demo | Agent | — | Pending | npx cdk synth succeeds for both Alpha001 and Alpha002; role appears in synthesized template |
| 1.7 | Create and merge PR1 (infrastructure): PR containing all changes from tasks 1.2–1.6 to main | Operator | 1.2–1.6 | Pending | PR approved and merged to infrastructure main |
| 1.8 | Kyle regression check: Deploy to Kyle (SandboxKyle002/kyle) and verify no regressions | Operator | 1.7 | Pending | Kyle AmplifyBranch stack updates or reports “No changes”; auto-build still true; push to kyle-frontend-app triggers auto-build |
| 1.9 | Deploy demo environment: Trigger amm.yml workflow with Alpha001/demo (or run amm.sh Alpha001 demo locally). Deploy IAM roles to both accounts via amm.sh. | Operator | 1.1, 1.7, 1.8 | Pending | See exit criteria below |
Task Details
Section titled “Task Details”Task 1.1: Create demo branch
Section titled “Task 1.1: Create demo branch”Who: Operator (or agent via gh CLI)
cd /path/to/arda-frontend-appgit fetch origin maingit push origin origin/main:refs/heads/demoNo code changes — the branch exists solely for the Amplify app connection.
Task 1.2: Modify amplifyBranch.cfn.yaml
Section titled “Task 1.2: Modify amplifyBranch.cfn.yaml”Who: Agent
File: infrastructure/src/main/cfn/amplifyBranch.cfn.yaml
Change 1 — Add EnableAutoBuild parameter to the Parameters section:
EnableAutoBuild: Type: String Default: "true" AllowedValues: ["true", "false"] Description: "Whether Amplify auto-builds on push to the connected branch"Change 2 — Update the AWS::Amplify::Branch resource to use the parameter:
EnableAutoBuild: !Ref EnableAutoBuild(Replace the current hardcoded EnableAutoBuild: true)
Change 3 — Add export to Outputs section:
AmplifyBranchName: Description: The Amplify branch resource name Value: !Ref Branch Export: Name: !Sub "${Infrastructure}-${Partition}-I-AmplifyBranchName"Validation: aws cloudformation validate-template --template-body file://src/main/cfn/amplifyBranch.cfn.yaml
Task 1.3: Create amplifyExports.cfn.yaml
Section titled “Task 1.3: Create amplifyExports.cfn.yaml”Who: Agent
File: infrastructure/src/main/cfn/amplifyExports.cfn.yaml
AWSTemplateFormatVersion: "2010-09-09"Description: "Publish Amplify App ID and Branch Name as CloudFormation exports for existing manually-created Amplify apps"
Parameters: Infrastructure: Type: String Partition: Type: String AmplifyAppId: Type: String Description: "The existing Amplify App ID" AmplifyBranchName: Type: String Description: "The Amplify branch resource name"
Outputs: AmplifyAppId: Value: !Ref AmplifyAppId Export: Name: !Sub "${Infrastructure}-${Partition}-I-AmplifyAppId" AmplifyBranchName: Value: !Ref AmplifyBranchName Export: Name: !Sub "${Infrastructure}-${Partition}-I-AmplifyBranchName"Validation: aws cloudformation validate-template --template-body file://src/main/cfn/amplifyExports.cfn.yaml
Task 1.4: Modify amm.sh
Section titled “Task 1.4: Modify amm.sh”Who: Agent
File: infrastructure/amm.sh
Read the current amm.sh to understand the existing structure before making changes. The modifications are:
-
Add mapping constants near the top of the file (after existing variable declarations):
AMPLIFY_DEPLOY_TARGETS— array ofInfrastructure:PartitionpairsAMPLIFY_BRANCH_NAMES— associative array, partition → branch resource nameAMPLIFY_APP_REPOS— associative array,Infrastructure:Partition→owner/repoAMPLIFY_REGION_OVERRIDES— associative array,Infrastructure:Partition→ region (only for overrides)
See specification.md — amm.sh Mapping Constants for the exact values.
-
Update the Amplify gate condition (currently around line 464-465). Replace the infrastructure-level exclusion with a check against
AMPLIFY_DEPLOY_TARGETS:Terminal window amplify_target="${infrastructure}:${partition}"if [[ " ${AMPLIFY_DEPLOY_TARGETS[*]} " == *" ${amplify_target} "* ]]; then -
Use
AMPLIFY_APP_REPOSfor Repo/AppName. Replace the hardcodedkyle-frontend-app:Terminal window amplify_repo="${AMPLIFY_APP_REPOS[${amplify_target}]}"if [[ -z "${amplify_repo}" ]]; thenecho "ERROR: No Amplify app repo configured for ${amplify_target}"exit 1fiamplify_app_name="${amplify_repo##*/}" # Derive AppName from repo (e.g., "arda-frontend-app") -
Use
AMPLIFY_BRANCH_NAMESfor the branch parameter:Terminal window branch_name="${AMPLIFY_BRANCH_NAMES[${partition}]}" -
Pass
EnableAutoBuild=falsefor non-Kyle targets (or more precisely, passfalsefor any partition where auto-build should be disabled — for now,demo):Terminal window enable_auto_build="true"if [[ "${partition}" == "demo" ]]; thenenable_auto_build="false"fiPass as
--parameter-overrides ... "EnableAutoBuild=${enable_auto_build}"in theAmplifyBranchstack deployment. -
Add lightweight export stack deployment logic for use during cutover (Run 4). This can be a function that deploys
amplifyExports.cfn.yamlfor partitions not inAMPLIFY_DEPLOY_TARGETSbut that need CloudFormation exports. Deployment region is alwaysus-east-1.
Task 1.5: Modify amm.yml
Section titled “Task 1.5: Modify amm.yml”Who: Agent
File: infrastructure/.github/workflows/amm.yml
Update the ARDA_API_KEY environment variable from the hardcoded Kyle/Stage reference to dynamic selection:
ARDA_API_KEY: "${{ secrets[format('ARDA_API_KEY_{0}', steps.partition.outputs.partition)] }}"The step name steps.partition.outputs.partition must match the actual step that extracts the partition name. Read the current workflow to identify the correct step reference.
The other four secrets (ARDA_SIGNUP_KEY, HUBSPOT_CLIENT_KEY, HUBSPOT_PAT, PYLON_WIDGET_KEY) are shared across environments and remain unchanged.
Task 1.6: Modify gh-oidc-provider.ts
Section titled “Task 1.6: Modify gh-oidc-provider.ts”Who: Agent
File: infrastructure/src/main/cdk/constructs/oam/gh-oidc-provider.ts
Read the existing file to understand the pattern used for the three existing roles (Infrastructure, Management, Service). Add a fourth role following the same pattern:
- Method name:
frontendDeploymentRole()(private) - Role name:
${prefix}-API-GitHubActionFrontEnd - OIDC trust:
repo:Arda-cards/arda-frontend-appscoped torefs/heads/main,refs/heads/patch,refs/heads/demo - Permissions:
amplify:StartJob,amplify:GetJob,amplify:GetApp,amplify:GetBranchonarn:aws:amplify:${region}:${account}:apps/*cloudformation:ListExportson*
- Expose via
GhOidcProviderBuiltinterface
Validation: npx cdk synth for both Alpha001 and Alpha002 infrastructure apps
Task 1.7: Create and Merge PR1
Section titled “Task 1.7: Create and Merge PR1”Who: Operator
Create a PR in infrastructure containing all changes from tasks 1.2–1.6:
amplifyBranch.cfn.yaml—EnableAutoBuildparameter +AmplifyBranchNameexportamplifyExports.cfn.yaml— new lightweight export templateamm.sh— mapping constants, gate update, export stack logicamm.yml— per-environment secret selectiongh-oidc-provider.ts— frontend IAM role
Branch name: jmpicnic/frontend-pipeline/infrastructure-changes
The PR must include a CHANGELOG.md update in the infrastructure repository.
This PR must be merged to main before the Kyle regression check or demo deployment, since the amm.yml workflow runs from main.
CI validation: The infrastructure repo’s ci.yaml workflow automatically runs npx cdk synth on every PR push. This provides automated validation of the CDK changes (Task 1.6) — the PR cannot merge if CDK synth fails. CloudFormation template validation (Tasks 1.2, 1.3) should still be run manually or added as a CI step, since ci.yaml does not validate raw CloudFormation templates.
Task 1.8: Kyle Regression Check
Section titled “Task 1.8: Kyle Regression Check”Who: Operator
- Deploy to Kyle first: trigger the
ammworkflow withSandboxKyle002/kyleor runamm.sh SandboxKyle002 kylelocally. - Verify the Kyle
AmplifyBranchstack updates successfully (or reports “No changes to deploy”). - Verify Kyle auto-build is still enabled:
Expected:
Terminal window aws amplify get-branch --app-id {kyle-app-id} --branch-name main \--region us-east-1 --query "branch.enableAutoBuild"true - Push a test commit to
kyle-frontend-appmainand confirm auto-build triggers.
Task 1.9: Deploy Demo Environment
Section titled “Task 1.9: Deploy Demo Environment”Who: Operator
Option A — GitHub Actions workflow:
- Confirm PR1 is merged to
main. - Trigger the
amm.ymlworkflow with environmentAlpha001/demo.
Option B — Local deployment:
- Configure AWS CLI for Alpha001 (
009765408297). - Override the API key for demo:
Terminal window export ARDA_API_KEY="$(op read 'op://Arda-DemoOAM/ARDA-API-KEY/password')" - Run:
./amm.sh Alpha001 demo
Deploy IAM roles to both accounts:
- Alpha001:
./amm.sh Alpha001 demo(covers the CDK infrastructure stack including the new role) - Alpha002:
./amm.sh Alpha002 devor./amm.sh Alpha002 stage(either triggers the CDK infrastructure stack)
OIDC verification: Create a temporary minimal workflow on the demo branch of arda-frontend-app:
# .github/workflows/test-oidc.yaml (temporary — delete in Run 2)name: Test OIDCon: workflow_dispatchpermissions: id-token: write contents: readjobs: test: runs-on: ubuntu-latest steps: - uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::009765408297:role/Alpha001-API-GitHubActionFrontEnd aws-region: us-east-1 - run: aws sts get-caller-identityTrigger this workflow on the demo branch. If sts get-caller-identity succeeds, the role is correctly configured. Delete this workflow file when the real workflows are created in Run 2.
Internal Dependency Graph
Section titled “Internal Dependency Graph”1.1 (demo branch) ──────────────────────────────────────────────────────┐1.2 (amplifyBranch.cfn.yaml) ──┐ │1.3 (amplifyExports.cfn.yaml) ─┤ │1.5 (amm.yml) ─────────────────┤ │1.6 (gh-oidc-provider.ts) ─────┤ │ ├──→ 1.4 (amm.sh) ──→ 1.7 (PR1) ──→ 1.8 (Kyle check) ──→ 1.9 (Deploy)Tasks 1.1, 1.2, 1.3, 1.5, 1.6 can be done in parallel. Task 1.4 depends on 1.2 and 1.3 (needs to know the template names and parameter names). Task 1.7 (PR1) depends on all code changes being ready. Task 1.8 depends on PR1 being merged. Task 1.9 depends on 1.8 passing and 1.1 being complete.
Exit Criteria
Section titled “Exit Criteria”| # | Criterion | Verification Command | Expected Output |
|---|---|---|---|
| 1 | demo branch exists in arda-frontend-app | git ls-remote --heads https://github.com/Arda-cards/arda-frontend-app demo | Ref listed |
| 2 | amplifyBranch.cfn.yaml validates | aws cloudformation validate-template --template-body file://src/main/cfn/amplifyBranch.cfn.yaml | No errors |
| 3 | amplifyExports.cfn.yaml validates | aws cloudformation validate-template --template-body file://src/main/cfn/amplifyExports.cfn.yaml | No errors |
| 4 | Kyle auto-build unchanged | aws amplify get-branch --app-id {kyle-app-id} --branch-name main --region us-east-1 --query "branch.enableAutoBuild" | true |
| 5 | Demo Amplify stacks deployed | aws cloudformation describe-stacks --stack-name Alpha001-demo-Amplify --region us-east-1 --query "Stacks[0].StackStatus" | CREATE_COMPLETE or UPDATE_COMPLETE |
| 6 | Demo auto-build disabled | aws amplify get-branch --app-id {demo-app-id} --branch-name demo --region us-east-1 --query "branch.enableAutoBuild" | false |
| 7 | CloudFormation export: AmplifyAppId | aws cloudformation list-exports --region us-east-1 --output text --query "Exports[?Name=='Alpha001-demo-I-AmplifyAppId'].Value" | An app ID string |
| 8 | CloudFormation export: AmplifyBranchName | aws cloudformation list-exports --region us-east-1 --output text --query "Exports[?Name=='Alpha001-demo-I-AmplifyBranchName'].Value" | demo |
| 9 | IAM role exists (Alpha001) | aws iam get-role --role-name Alpha001-API-GitHubActionFrontEnd --query "Role.RoleName" | Alpha001-API-GitHubActionFrontEnd |
| 10 | IAM role exists (Alpha002) | aws iam get-role --role-name Alpha002-API-GitHubActionFrontEnd --query "Role.RoleName" | Alpha002-API-GitHubActionFrontEnd |
| 11 | OIDC assumption works | Trigger test-oidc.yaml on demo branch; check workflow log | aws sts get-caller-identity succeeds |
| 12 | Demo site loads | curl -s -o /dev/null -w "%{http_code}" https://demo.alpha001.app.arda.cards | 200 |
| 13 | PR1 merged to infrastructure main | gh pr list -R Arda-cards/infrastructure --state merged --search "frontend pipeline" | PR merged |
Handoff
Section titled “Handoff”Artifacts Consumed (from previous runs)
Section titled “Artifacts Consumed (from previous runs)”None — this is the first run.
Artifacts Produced (for subsequent runs)
Section titled “Artifacts Produced (for subsequent runs)”| Artifact | Consumer Run | Path/Location |
|---|---|---|
demo branch | Run 2 | arda-frontend-app repo |
| CloudFormation exports (demo) | Run 2, 3 | Alpha001-demo-I-AmplifyAppId, Alpha001-demo-I-AmplifyBranchName |
| IAM roles (both accounts) | Run 2, 3, 4 | AWS IAM |
amplifyExports.cfn.yaml | Run 4 | infrastructure/src/main/cfn/amplifyExports.cfn.yaml |
amm.sh with export stack support | Run 4 | infrastructure/amm.sh |
test-oidc.yaml (temporary) | Run 2 (to be deleted) | arda-frontend-app/.github/workflows/test-oidc.yaml |
Copyright: © Arda Systems 2025-2026, All rights reserved