Skip to content

Run 1: Infrastructure

#CriterionVerification CommandExpected Output
1Alpha001 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)
2arda-frontend-app repository existsgh repo view Arda-cards/arda-frontend-app --json name -q .namearda-frontend-app
3infrastructure repository main branch is accessiblegh repo view Arda-cards/infrastructure --json name -q .nameinfrastructure
4AMPLIFY_GITHUB_ACCESSTOKEN secret exists in GitHub org or infrastructure repoVerify via GitHub Settings UI or gh secret list -R Arda-cards/infrastructureSecret listed
5ARDA_API_KEY_DEMO GitHub org secret existsVerify via GitHub Settings UI or check output of infrastructure/tools/sync-secrets-from-1password.shSecret exists
ArtifactPathFormatDescription
Modified CloudFormation template/infrastructure/src/main/cfn/amplifyBranch.cfn.yamlCloudFormation YAMLAdded EnableAutoBuild parameter and AmplifyBranchName export
New CloudFormation template/infrastructure/src/main/cfn/amplifyExports.cfn.yamlCloudFormation YAMLLightweight export stack for existing Amplify apps
Modified deployment script/infrastructure/amm.shBashAdded mapping constants, updated gate, export stack support
Modified workflow/infrastructure/.github/workflows/amm.ymlGHA YAMLPer-environment secret selection
Modified CDK construct/infrastructure/src/main/cdk/constructs/oam/gh-oidc-provider.tsTypeScriptAdded frontendDeploymentRole()
Git branchdemo branch in arda-frontend-appGit branchCreated off main
#TaskPersonaDepends OnStatusAcceptance Criteria
1.1Create demo branch in arda-frontend-appOperatorPendingBranch exists: git ls-remote --heads origin demo returns a ref
1.2Modify amplifyBranch.cfn.yaml: add EnableAutoBuild parameter (String, default "true", AllowedValues ["true","false"]) and AmplifyBranchName exportAgentPendingTemplate validates; export name is ${Infrastructure}-${Partition}-I-AmplifyBranchName
1.3Create amplifyExports.cfn.yaml: lightweight export template with parameters Infrastructure, Partition, AmplifyAppId, AmplifyBranchNameAgentPendingTemplate validates; exports match naming convention
1.4Modify 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 logicAgent1.2, 1.3PendingConstants present; gate allows Alpha001:demo and SandboxKyle002:kyle; blocks others
1.5Modify amm.yml: use secrets[format('ARDA_API_KEY_{0}', partition)]AgentPendingDynamic secret selection in workflow YAML
1.6Modify 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/demoAgentPendingnpx cdk synth succeeds for both Alpha001 and Alpha002; role appears in synthesized template
1.7Create and merge PR1 (infrastructure): PR containing all changes from tasks 1.2–1.6 to mainOperator1.2–1.6PendingPR approved and merged to infrastructure main
1.8Kyle regression check: Deploy to Kyle (SandboxKyle002/kyle) and verify no regressionsOperator1.7PendingKyle AmplifyBranch stack updates or reports “No changes”; auto-build still true; push to kyle-frontend-app triggers auto-build
1.9Deploy 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.Operator1.1, 1.7, 1.8PendingSee exit criteria below

Who: Operator (or agent via gh CLI)

Terminal window
cd /path/to/arda-frontend-app
git fetch origin main
git push origin origin/main:refs/heads/demo

No code changes — the branch exists solely for the Amplify app connection.

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

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

Who: Agent

File: infrastructure/amm.sh

Read the current amm.sh to understand the existing structure before making changes. The modifications are:

  1. Add mapping constants near the top of the file (after existing variable declarations):

    • AMPLIFY_DEPLOY_TARGETS — array of Infrastructure:Partition pairs
    • AMPLIFY_BRANCH_NAMES — associative array, partition → branch resource name
    • AMPLIFY_APP_REPOS — associative array, Infrastructure:Partitionowner/repo
    • AMPLIFY_REGION_OVERRIDES — associative array, Infrastructure:Partition → region (only for overrides)

    See specification.md — amm.sh Mapping Constants for the exact values.

  2. 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
  3. Use AMPLIFY_APP_REPOS for Repo/AppName. Replace the hardcoded kyle-frontend-app:

    Terminal window
    amplify_repo="${AMPLIFY_APP_REPOS[${amplify_target}]}"
    if [[ -z "${amplify_repo}" ]]; then
    echo "ERROR: No Amplify app repo configured for ${amplify_target}"
    exit 1
    fi
    amplify_app_name="${amplify_repo##*/}" # Derive AppName from repo (e.g., "arda-frontend-app")
  4. Use AMPLIFY_BRANCH_NAMES for the branch parameter:

    Terminal window
    branch_name="${AMPLIFY_BRANCH_NAMES[${partition}]}"
  5. Pass EnableAutoBuild=false for non-Kyle targets (or more precisely, pass false for any partition where auto-build should be disabled — for now, demo):

    Terminal window
    enable_auto_build="true"
    if [[ "${partition}" == "demo" ]]; then
    enable_auto_build="false"
    fi

    Pass as --parameter-overrides ... "EnableAutoBuild=${enable_auto_build}" in the AmplifyBranch stack deployment.

  6. Add lightweight export stack deployment logic for use during cutover (Run 4). This can be a function that deploys amplifyExports.cfn.yaml for partitions not in AMPLIFY_DEPLOY_TARGETS but that need CloudFormation exports. Deployment region is always us-east-1.

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.

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-app scoped to refs/heads/main, refs/heads/patch, refs/heads/demo
  • Permissions:
    • amplify:StartJob, amplify:GetJob, amplify:GetApp, amplify:GetBranch on arn:aws:amplify:${region}:${account}:apps/*
    • cloudformation:ListExports on *
  • Expose via GhOidcProviderBuilt interface

Validation: npx cdk synth for both Alpha001 and Alpha002 infrastructure apps

Who: Operator

Create a PR in infrastructure containing all changes from tasks 1.2–1.6:

  • amplifyBranch.cfn.yamlEnableAutoBuild parameter + AmplifyBranchName export
  • amplifyExports.cfn.yaml — new lightweight export template
  • amm.sh — mapping constants, gate update, export stack logic
  • amm.yml — per-environment secret selection
  • gh-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.

Who: Operator

  1. Deploy to Kyle first: trigger the amm workflow with SandboxKyle002/kyle or run amm.sh SandboxKyle002 kyle locally.
  2. Verify the Kyle AmplifyBranch stack updates successfully (or reports “No changes to deploy”).
  3. Verify Kyle auto-build is still enabled:
    Terminal window
    aws amplify get-branch --app-id {kyle-app-id} --branch-name main \
    --region us-east-1 --query "branch.enableAutoBuild"
    Expected: true
  4. Push a test commit to kyle-frontend-app main and confirm auto-build triggers.

Who: Operator

Option A — GitHub Actions workflow:

  1. Confirm PR1 is merged to main.
  2. Trigger the amm.yml workflow with environment Alpha001/demo.

Option B — Local deployment:

  1. Configure AWS CLI for Alpha001 (009765408297).
  2. Override the API key for demo:
    Terminal window
    export ARDA_API_KEY="$(op read 'op://Arda-DemoOAM/ARDA-API-KEY/password')"
  3. 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 dev or ./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 OIDC
on: workflow_dispatch
permissions:
id-token: write
contents: read
jobs:
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-identity

Trigger 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.

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.

#CriterionVerification CommandExpected Output
1demo branch exists in arda-frontend-appgit ls-remote --heads https://github.com/Arda-cards/arda-frontend-app demoRef listed
2amplifyBranch.cfn.yaml validatesaws cloudformation validate-template --template-body file://src/main/cfn/amplifyBranch.cfn.yamlNo errors
3amplifyExports.cfn.yaml validatesaws cloudformation validate-template --template-body file://src/main/cfn/amplifyExports.cfn.yamlNo errors
4Kyle auto-build unchangedaws amplify get-branch --app-id {kyle-app-id} --branch-name main --region us-east-1 --query "branch.enableAutoBuild"true
5Demo Amplify stacks deployedaws cloudformation describe-stacks --stack-name Alpha001-demo-Amplify --region us-east-1 --query "Stacks[0].StackStatus"CREATE_COMPLETE or UPDATE_COMPLETE
6Demo auto-build disabledaws amplify get-branch --app-id {demo-app-id} --branch-name demo --region us-east-1 --query "branch.enableAutoBuild"false
7CloudFormation export: AmplifyAppIdaws cloudformation list-exports --region us-east-1 --output text --query "Exports[?Name=='Alpha001-demo-I-AmplifyAppId'].Value"An app ID string
8CloudFormation export: AmplifyBranchNameaws cloudformation list-exports --region us-east-1 --output text --query "Exports[?Name=='Alpha001-demo-I-AmplifyBranchName'].Value"demo
9IAM role exists (Alpha001)aws iam get-role --role-name Alpha001-API-GitHubActionFrontEnd --query "Role.RoleName"Alpha001-API-GitHubActionFrontEnd
10IAM role exists (Alpha002)aws iam get-role --role-name Alpha002-API-GitHubActionFrontEnd --query "Role.RoleName"Alpha002-API-GitHubActionFrontEnd
11OIDC assumption worksTrigger test-oidc.yaml on demo branch; check workflow logaws sts get-caller-identity succeeds
12Demo site loadscurl -s -o /dev/null -w "%{http_code}" https://demo.alpha001.app.arda.cards200
13PR1 merged to infrastructure maingh pr list -R Arda-cards/infrastructure --state merged --search "frontend pipeline"PR merged

None — this is the first run.

ArtifactConsumer RunPath/Location
demo branchRun 2arda-frontend-app repo
CloudFormation exports (demo)Run 2, 3Alpha001-demo-I-AmplifyAppId, Alpha001-demo-I-AmplifyBranchName
IAM roles (both accounts)Run 2, 3, 4AWS IAM
amplifyExports.cfn.yamlRun 4infrastructure/src/main/cfn/amplifyExports.cfn.yaml
amm.sh with export stack supportRun 4infrastructure/amm.sh
test-oidc.yaml (temporary)Run 2 (to be deleted)arda-frontend-app/.github/workflows/test-oidc.yaml