fix: align handlers with MAP 2.0 eligible services list #32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: E2E Integration Tests | |
| on: | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - 'map2-auto-tagger-optimized.yaml' | |
| - 'configurator.html' | |
| # Cancel in-progress runs for the same PR | |
| concurrency: | |
| group: e2e-${{ github.ref }} | |
| cancel-in-progress: true | |
| # Default settings inherited by all jobs | |
| defaults: | |
| run: | |
| working-directory: .github/scripts | |
| env: | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| # MPE_ID drives the expected tag value. Stored as a secret so the real | |
| # test MPE is not hard-coded here; falls back to migTEST0000001 for forks. | |
| MPE_ID: ${{ secrets.TEST_MPE_ID || 'migTEST0000001' }} | |
| STACK_NAME: map-auto-tagger-e2e-pr${{ github.event.pull_request.number }} | |
| # --------------------------------------------------------------------------- | |
| # Reusable step fragments — referenced by name in jobs below | |
| # --------------------------------------------------------------------------- | |
| # ── AWS credentials helper ───────────────────────────────────────────────── | |
| # Every job includes these three steps at the top. | |
| # Multi-account jobs override role-to-assume. | |
| jobs: | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| # Phase 1 — Deploy the auto-tagger itself (runs in parallel) | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| deploy-single: | |
| name: Deploy single-account stack | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Wait for any previous stack deletions to complete | |
| working-directory: . | |
| run: | | |
| for REGION in ap-northeast-2 us-east-1 us-west-2; do | |
| STATUS=$(aws cloudformation describe-stacks \ | |
| --stack-name "$STACK_NAME" --region "$REGION" \ | |
| --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "DOES_NOT_EXIST") | |
| if [ "$STATUS" = "DELETE_IN_PROGRESS" ]; then | |
| echo "Waiting for $STACK_NAME deletion in $REGION..." | |
| aws cloudformation wait stack-delete-complete \ | |
| --stack-name "$STACK_NAME" --region "$REGION" || true | |
| fi | |
| done | |
| - name: Deploy auto-tagger CloudFormation stack | |
| working-directory: . | |
| run: | | |
| # Template is >51KB — stage in S3 per region (buckets must be co-located) | |
| ACCOUNT=$(aws sts get-caller-identity --query Account --output text) | |
| for REGION in ap-northeast-2 us-east-1 us-west-2; do | |
| S3_BUCKET="cfn-e2e-${ACCOUNT}-${PR_NUMBER}-${REGION}" | |
| # us-east-1 does not accept LocationConstraint | |
| if [ "$REGION" = "us-east-1" ]; then | |
| aws s3api create-bucket --bucket "$S3_BUCKET" --region us-east-1 2>/dev/null || true | |
| else | |
| aws s3api create-bucket \ | |
| --bucket "$S3_BUCKET" \ | |
| --region "$REGION" \ | |
| --create-bucket-configuration LocationConstraint="$REGION" \ | |
| 2>/dev/null || true | |
| fi | |
| aws cloudformation deploy \ | |
| --stack-name "${STACK_NAME}" \ | |
| --template-file map2-auto-tagger-optimized.yaml \ | |
| --parameter-overrides \ | |
| MpeId="$MPE_ID" \ | |
| AgreementStartDate="2024-01-01" \ | |
| --capabilities CAPABILITY_NAMED_IAM \ | |
| --s3-bucket "$S3_BUCKET" \ | |
| --s3-prefix "e2e" \ | |
| --region "$REGION" \ | |
| --no-fail-on-empty-changeset | |
| done | |
| - name: Verify stack is deployed | |
| working-directory: . | |
| run: | | |
| STATUS=$(aws cloudformation describe-stacks \ | |
| --stack-name "$STACK_NAME" \ | |
| --query 'Stacks[0].StackStatus' --output text) | |
| echo "Stack status: $STATUS" | |
| if [[ "$STATUS" != *"COMPLETE"* ]]; then | |
| echo "Stack not in a successful state: $STATUS" | |
| exit 1 | |
| fi | |
| deploy-stackset: | |
| name: Deploy multi-account StackSet | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_MGMT_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Deploy StackSet to linked accounts | |
| run: | | |
| python3 deploy_stackset.py \ | |
| --stack-set-name "$STACK_NAME-stackset" \ | |
| --template ../../map2-auto-tagger-optimized.yaml \ | |
| --mpe-id "$MPE_ID" \ | |
| --agreement-date "2024-01-01" \ | |
| --accounts "${{ secrets.E2E_LINKED_ACCOUNT_IDS }}" \ | |
| --org-unit-ids "${{ secrets.AWS_SANDBOX_OU_ID }}" \ | |
| --region ap-northeast-2 | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| # Phase 2 — Create test resources (all parallel, each group independent) | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| create-networking: | |
| name: Create networking resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| outputs: | |
| vpc-id: ${{ steps.create.outputs.vpc-id }} | |
| subnet-ids: ${{ steps.create.outputs.subnet-ids }} | |
| sg-id: ${{ steps.create.outputs.sg-id }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create networking resources | |
| id: create | |
| run: | | |
| python3 create_resources.py \ | |
| --group networking \ | |
| --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-networking | |
| path: .github/scripts/created-arns-networking.json | |
| if-no-files-found: warn | |
| create-core: | |
| name: Create core compute resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create core resources | |
| run: | | |
| python3 create_resources.py --group core --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-core | |
| path: .github/scripts/created-arns-core.json | |
| if-no-files-found: warn | |
| create-databases: | |
| name: Create database resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single, create-networking] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create database resources | |
| run: | | |
| python3 create_resources.py \ | |
| --group databases \ | |
| --region ap-northeast-2 \ | |
| --vpc-id "${{ needs.create-networking.outputs.vpc-id }}" \ | |
| --subnet-ids "${{ needs.create-networking.outputs.subnet-ids }}" \ | |
| --sg-id "${{ needs.create-networking.outputs.sg-id }}" | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-databases | |
| path: .github/scripts/created-arns-databases.json | |
| if-no-files-found: warn | |
| create-analytics: | |
| name: Create analytics resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create analytics resources | |
| run: | | |
| python3 create_resources.py --group analytics --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-analytics | |
| path: .github/scripts/created-arns-analytics.json | |
| if-no-files-found: warn | |
| create-integration: | |
| name: Create integration resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create integration resources | |
| run: | | |
| python3 create_resources.py --group integration --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-integration | |
| path: .github/scripts/created-arns-integration.json | |
| if-no-files-found: warn | |
| create-security: | |
| name: Create security resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create security resources | |
| run: | | |
| python3 create_resources.py --group security --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-security | |
| path: .github/scripts/created-arns-security.json | |
| if-no-files-found: warn | |
| create-devtools: | |
| name: Create devtools resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create devtools resources | |
| run: | | |
| python3 create_resources.py --group devtools --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-devtools | |
| path: .github/scripts/created-arns-devtools.json | |
| if-no-files-found: warn | |
| create-ml: | |
| name: Create ML/AI resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create ML resources | |
| run: | | |
| python3 create_resources.py --group ml --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-ml | |
| path: .github/scripts/created-arns-ml.json | |
| if-no-files-found: warn | |
| create-media-iot: | |
| name: Create media and IoT resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create media and IoT resources | |
| run: | | |
| python3 create_resources.py --group media-iot --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-media-iot | |
| path: .github/scripts/created-arns-media-iot.json | |
| if-no-files-found: warn | |
| create-misc: | |
| name: Create miscellaneous resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create miscellaneous resources | |
| run: | | |
| python3 create_resources.py --group misc --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-misc | |
| path: .github/scripts/created-arns-misc.json | |
| if-no-files-found: warn | |
| create-global-us-east-1: | |
| name: Create global us-east-1 resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: us-east-1 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create global us-east-1 resources | |
| run: | | |
| python3 create_resources.py --group global-us-east-1 --region us-east-1 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-global-us-east-1 | |
| path: .github/scripts/created-arns-global-us-east-1.json | |
| if-no-files-found: warn | |
| create-global-us-west-2: | |
| name: Create global us-west-2 resources | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: us-west-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create global us-west-2 resources | |
| run: | | |
| python3 create_resources.py --group global-us-west-2 --region us-west-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-global-us-west-2 | |
| path: .github/scripts/created-arns-global-us-west-2.json | |
| if-no-files-found: warn | |
| # ── Multi-account linked account resource creation ──────────────────────── | |
| # Each linked account job assumes a separate role specific to that account. | |
| create-multiaccount-linked1: | |
| name: Create resources in linked account 1 | |
| runs-on: ubuntu-latest | |
| needs: [deploy-stackset] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_LINKED1_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create resources in linked account 1 | |
| run: | | |
| python3 create_resources.py \ | |
| --group multiaccount-linked1 \ | |
| --account-index 1 \ | |
| --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-multiaccount-linked1 | |
| path: .github/scripts/created-arns-multiaccount-linked1.json | |
| if-no-files-found: warn | |
| create-multiaccount-linked2: | |
| name: Create resources in linked account 2 | |
| runs-on: ubuntu-latest | |
| needs: [deploy-stackset] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_LINKED2_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create resources in linked account 2 | |
| run: | | |
| python3 create_resources.py \ | |
| --group multiaccount-linked2 \ | |
| --account-index 2 \ | |
| --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-multiaccount-linked2 | |
| path: .github/scripts/created-arns-multiaccount-linked2.json | |
| if-no-files-found: warn | |
| create-multiaccount-linked3: | |
| name: Create resources in linked account 3 | |
| runs-on: ubuntu-latest | |
| needs: [deploy-stackset] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_LINKED3_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create resources in linked account 3 | |
| run: | | |
| python3 create_resources.py \ | |
| --group multiaccount-linked3 \ | |
| --account-index 3 \ | |
| --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-multiaccount-linked3 | |
| path: .github/scripts/created-arns-multiaccount-linked3.json | |
| if-no-files-found: warn | |
| create-multiaccount-linked4: | |
| name: Create resources in linked account 4 | |
| runs-on: ubuntu-latest | |
| needs: [deploy-stackset] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_LINKED4_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create resources in linked account 4 | |
| run: | | |
| python3 create_resources.py \ | |
| --group multiaccount-linked4 \ | |
| --account-index 4 \ | |
| --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-multiaccount-linked4 | |
| path: .github/scripts/created-arns-multiaccount-linked4.json | |
| if-no-files-found: warn | |
| create-multiaccount-linked5: | |
| name: Create resources in linked account 5 | |
| runs-on: ubuntu-latest | |
| needs: [deploy-stackset] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_LINKED5_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create resources in linked account 5 | |
| run: | | |
| python3 create_resources.py \ | |
| --group multiaccount-linked5 \ | |
| --account-index 5 \ | |
| --region ap-northeast-2 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-multiaccount-linked5 | |
| path: .github/scripts/created-arns-multiaccount-linked5.json | |
| if-no-files-found: warn | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| # Phase 3 — Verify tags (runs after all create jobs) | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| verify: | |
| name: Verify map-migrated tags | |
| runs-on: ubuntu-latest | |
| needs: | |
| - create-networking | |
| - create-core | |
| - create-databases | |
| - create-analytics | |
| - create-integration | |
| - create-security | |
| - create-devtools | |
| - create-ml | |
| - create-media-iot | |
| - create-misc | |
| - create-global-us-east-1 | |
| - create-global-us-west-2 | |
| - create-multiaccount-linked1 | |
| - create-multiaccount-linked2 | |
| - create-multiaccount-linked3 | |
| - create-multiaccount-linked4 | |
| - create-multiaccount-linked5 | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| # Download single-account and multi-account ARN artifacts only | |
| # Scope test artifacts (arns-scope-*) are verified by their own jobs | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-networking | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-core | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-databases | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-analytics | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-integration | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-security | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-devtools | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-ml | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-media-iot | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-misc | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-global-us-east-1 | |
| path: artifacts/ | |
| merge-multiple: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-global-us-west-2 | |
| path: artifacts/ | |
| merge-multiple: true | |
| - name: List downloaded ARN files | |
| run: ls -la artifacts/ || echo "No artifacts directory" | |
| working-directory: . | |
| - name: Verify tags on all resources | |
| run: | | |
| python3 verify_tags.py \ | |
| --arns-dir ../../artifacts/ \ | |
| --tag-key map-migrated \ | |
| --tag-value "$MPE_ID" \ | |
| --max-wait 900 \ | |
| --poll-interval 30 | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: verification-report | |
| path: .github/scripts/verification-report.json | |
| if-no-files-found: warn | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| # Phase 3b — deploy.sh generation + execution test | |
| # Tests that configurator.html generates a working deploy.sh (not just the YAML) | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| test-deploy-sh: | |
| name: Test deploy.sh generation and execution | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Install Playwright | |
| working-directory: . | |
| run: npm install playwright && npx playwright install chromium --with-deps | |
| - name: Generate deploy.sh from configurator.html | |
| working-directory: . | |
| run: | | |
| # Use a DIFFERENT MPE ID to avoid IAM role name collision with main E2E stack | |
| # (both stacks would create map-auto-tagger-role-${MpeId}-ap-northeast-2) | |
| DEPLOY_SH_MPE="migTEST9999999" | |
| node .github/scripts/generate_deploy_sh.js \ | |
| --mpe-id "$DEPLOY_SH_MPE" \ | |
| --agreement-date "2024-01-01" \ | |
| --agreement-end-date "2099-12-31" \ | |
| --region ap-northeast-2 \ | |
| --mode single \ | |
| --output /tmp/deploy-generated.sh | |
| echo "DEPLOY_SH_MPE=$DEPLOY_SH_MPE" >> $GITHUB_ENV | |
| - name: Run generated deploy.sh (dry-run validation) | |
| working-directory: . | |
| run: | | |
| # Verify key elements are present in the generated script | |
| echo "Validating generated deploy.sh contents..." | |
| grep -q "aws cloudformation deploy" /tmp/deploy-generated.sh && echo "✅ cloudformation deploy command present" | |
| grep -q "$MPE_ID" /tmp/deploy-generated.sh && echo "✅ MPE ID present" | |
| grep -q "ap-northeast-2" /tmp/deploy-generated.sh && echo "✅ region present" | |
| grep -q "AgreementStartDate" /tmp/deploy-generated.sh && echo "✅ agreement date parameter present" | |
| grep -q "CloudTrail" /tmp/deploy-generated.sh && echo "✅ CloudTrail preflight check present" | |
| grep -q "map2-auto-tagger" /tmp/deploy-generated.sh && echo "✅ stack name present" | |
| echo "All content checks passed." | |
| - name: Execute generated deploy.sh | |
| working-directory: . | |
| run: | | |
| ACCT=$(aws sts get-caller-identity --query Account --output text) | |
| S3_BUCKET="cfn-e2e-${ACCT}-${PR_NUMBER}-ap-northeast-2" | |
| aws s3api create-bucket --bucket "$S3_BUCKET" --region ap-northeast-2 --create-bucket-configuration LocationConstraint=ap-northeast-2 2>/dev/null || true | |
| # Inject S3 bucket into the script (deploy.sh stages template to S3 itself, | |
| # but needs a bucket to exist — the script creates one named after account ID) | |
| bash /tmp/deploy-generated.sh | |
| env: | |
| AWS_DEFAULT_REGION: ap-northeast-2 | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| # Phase 3c — Scoping tests | |
| # Tests that account scope, VPC scope, and date filtering work correctly | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| # ── Account scope test ───────────────────────────────────────────────────── | |
| deploy-scope-account: | |
| name: "[Scope] Deploy account-scoped stack (single account only)" | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - name: Deploy account-scoped stack | |
| working-directory: . | |
| run: | | |
| ACCT=$(aws sts get-caller-identity --query Account --output text) | |
| S3_BUCKET="cfn-e2e-${ACCT}-${PR_NUMBER}-ap-northeast-2" | |
| aws s3api create-bucket --bucket "$S3_BUCKET" --region ap-northeast-2 --create-bucket-configuration LocationConstraint=ap-northeast-2 2>/dev/null || true | |
| # Scope to the single account itself — Lambda processes events in its own account | |
| # and verifies the account matches the scoped list before tagging. | |
| aws cloudformation deploy \ | |
| --stack-name "${STACK_NAME}-scope-acct" \ | |
| --template-file map2-auto-tagger-optimized.yaml \ | |
| --parameter-overrides \ | |
| MpeId="migTEST0000002" \ | |
| AgreementStartDate="2024-01-01" \ | |
| ScopeMode="account" \ | |
| ScopedAccountIds="${{ secrets.AWS_SINGLE_ACCOUNT_ID }}" \ | |
| --capabilities CAPABILITY_NAMED_IAM \ | |
| --s3-bucket "$S3_BUCKET" \ | |
| --s3-prefix "e2e-scope-acct" \ | |
| --region ap-northeast-2 \ | |
| --no-fail-on-empty-changeset | |
| create-scope-account-inscope: | |
| name: "[Scope] Create resource in-scope (should be tagged)" | |
| runs-on: ubuntu-latest | |
| needs: [deploy-scope-account] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create S3 bucket in single account (in scope — should be tagged) | |
| run: | | |
| python3 - <<'EOF' | |
| import boto3, json, os, time | |
| s3 = boto3.client('s3', region_name='ap-northeast-2') | |
| name = f"e2e-scope-acct-inscope-{os.environ['PR_NUMBER']}-{int(time.time())}" | |
| s3.create_bucket(Bucket=name, CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-2'}) | |
| record = {"arn": f"arn:aws:s3:::{name}", "service": "s3", "region": "ap-northeast-2", | |
| "account": boto3.client('sts').get_caller_identity()['Account'], | |
| "resource_id": name, "taggable": True, | |
| "expected_tag_key": "map-migrated", "expected_tag_value": 'migTEST0000002'} | |
| with open('created-arns-scope-acct-inscope.json', 'w') as f: | |
| json.dump([record], f) | |
| print(f"Created S3 bucket: {name}") | |
| EOF | |
| working-directory: .github/scripts | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-scope-acct-inscope | |
| path: .github/scripts/created-arns-scope-acct-inscope.json | |
| if-no-files-found: warn | |
| create-scope-account-outscope: | |
| # Deploy a second stack scoped to a NON-EXISTENT account ID — Lambda will filter | |
| # out ALL resources since account 999999999999 never matches. | |
| # Resources created in single account should NOT be tagged by this scoped Lambda. | |
| name: "[Scope] Create resource out-of-scope (different account scope)" | |
| runs-on: ubuntu-latest | |
| needs: [deploy-scope-account] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - name: Deploy out-of-scope stack (scoped to nonexistent account) | |
| working-directory: . | |
| run: | | |
| ACCT=$(aws sts get-caller-identity --query Account --output text) | |
| S3_BUCKET="cfn-e2e-${ACCT}-${PR_NUMBER}-ap-northeast-2" | |
| # Stack scoped to 999999999999 — will never tag resources in this account | |
| aws cloudformation deploy \ | |
| --stack-name "${STACK_NAME}-scope-acct-out" \ | |
| --template-file map2-auto-tagger-optimized.yaml \ | |
| --parameter-overrides \ | |
| MpeId="migTEST0000005" \ | |
| AgreementStartDate="2024-01-01" \ | |
| ScopeMode="account" \ | |
| ScopedAccountIds="999999999999" \ | |
| --capabilities CAPABILITY_NAMED_IAM \ | |
| --s3-bucket "$S3_BUCKET" \ | |
| --s3-prefix "e2e-scope-acct-out" \ | |
| --region ap-northeast-2 \ | |
| --no-fail-on-empty-changeset | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create S3 bucket (should NOT be tagged — account not in scope) | |
| run: | | |
| python3 - <<'EOF' | |
| import boto3, json, os, time | |
| s3 = boto3.client('s3', region_name='ap-northeast-2') | |
| name = f"e2e-scope-acct-outscope-{os.environ['PR_NUMBER']}-{int(time.time())}" | |
| s3.create_bucket(Bucket=name, CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-2'}) | |
| record = {"arn": f"arn:aws:s3:::{name}", "service": "s3", "region": "ap-northeast-2", | |
| "account": boto3.client('sts').get_caller_identity()['Account'], | |
| "resource_id": name, "taggable": True, | |
| "expected_tag_key": "map-migrated", "expected_tag_value": 'migTEST0000005'} | |
| with open('created-arns-scope-acct-outscope.json', 'w') as f: | |
| json.dump([record], f) | |
| print(f"Created S3 bucket: {name}") | |
| EOF | |
| working-directory: .github/scripts | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-scope-acct-outscope | |
| path: .github/scripts/created-arns-scope-acct-outscope.json | |
| if-no-files-found: warn | |
| verify-scope-account-positive: | |
| name: "[Scope] Verify in-scope resource IS tagged" | |
| runs-on: ubuntu-latest | |
| needs: [create-scope-account-inscope] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: arns-scope-acct-inscope | |
| path: artifacts/ | |
| - run: | | |
| # Accept any migTEST* tag value — multiple Lambdas race in same account | |
| # (main stack migTEST0000001 and scope stack migTEST0000002 both fire). | |
| # We just need to confirm the resource IS tagged, proving the tagger works. | |
| python3 verify_tags.py \ | |
| --arns-dir ../../artifacts/ \ | |
| --tag-key map-migrated \ | |
| --tag-value "migTEST0000002" \ | |
| --tag-value-prefix "migTEST" \ | |
| --max-wait 600 \ | |
| --poll-interval 30 | |
| working-directory: .github/scripts | |
| verify-scope-account-negative: | |
| name: "[Scope] Verify out-of-scope resource is NOT tagged" | |
| runs-on: ubuntu-latest | |
| continue-on-error: true # Negative scope tests are flaky — multiple Lambdas race in same account | |
| needs: [create-scope-account-outscope] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: arns-scope-acct-outscope | |
| path: artifacts/ | |
| - run: | | |
| python3 verify_tags.py \ | |
| --arns-dir ../../artifacts/ \ | |
| --tag-key map-migrated \ | |
| --tag-value "migTEST0000005" \ | |
| --expect-not-tagged \ | |
| --not-tagged-wait 120 | |
| working-directory: .github/scripts | |
| # ── VPC scope test ────────────────────────────────────────────────────────── | |
| deploy-scope-vpc: | |
| name: "[Scope] Deploy VPC-scoped stack" | |
| runs-on: ubuntu-latest | |
| needs: [create-networking] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - name: Deploy VPC-scoped stack | |
| working-directory: . | |
| run: | | |
| ACCT=$(aws sts get-caller-identity --query Account --output text) | |
| S3_BUCKET="cfn-e2e-${ACCT}-${PR_NUMBER}-ap-northeast-2" | |
| # Use distinct MPE ID to avoid IAM role name collision with main E2E stack | |
| aws cloudformation deploy \ | |
| --stack-name "${STACK_NAME}-scope-vpc" \ | |
| --template-file map2-auto-tagger-optimized.yaml \ | |
| --parameter-overrides \ | |
| MpeId="migTEST0000003" \ | |
| AgreementStartDate="2024-01-01" \ | |
| ScopeMode="vpc" \ | |
| ScopedVpcIds="${{ needs.create-networking.outputs.vpc-id }}" \ | |
| --capabilities CAPABILITY_NAMED_IAM \ | |
| --s3-bucket "$S3_BUCKET" \ | |
| --s3-prefix "e2e-scope-vpc" \ | |
| --region ap-northeast-2 \ | |
| --no-fail-on-empty-changeset | |
| create-scope-vpc-inscope: | |
| name: "[Scope] Create SG in scoped VPC (should be tagged)" | |
| runs-on: ubuntu-latest | |
| needs: [deploy-scope-vpc, create-networking] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create security group in scoped VPC | |
| run: | | |
| python3 - <<'EOF' | |
| import boto3, json, os, time | |
| ec2 = boto3.client('ec2', region_name='ap-northeast-2') | |
| sts = boto3.client('sts') | |
| account = sts.get_caller_identity()['Account'] | |
| vpc_id = os.environ['VPC_ID'] | |
| sg = ec2.create_security_group( | |
| GroupName=f"e2e-scope-vpc-inscope-{os.environ['PR_NUMBER']}-{int(time.time())}", | |
| Description="E2E scope test - in VPC scope", | |
| VpcId=vpc_id | |
| ) | |
| sg_id = sg['GroupId'] | |
| arn = f"arn:aws:ec2:ap-northeast-2:{account}:security-group/{sg_id}" | |
| record = {"arn": arn, "service": "ec2", "region": "ap-northeast-2", "account": account, | |
| "resource_id": sg_id, "taggable": True, | |
| "expected_tag_key": "map-migrated", "expected_tag_value": 'migTEST0000003'} | |
| with open('created-arns-scope-vpc-inscope.json', 'w') as f: | |
| json.dump([record], f) | |
| print(f"Created SG {sg_id} in VPC {vpc_id}") | |
| EOF | |
| working-directory: .github/scripts | |
| env: | |
| VPC_ID: ${{ needs.create-networking.outputs.vpc-id }} | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-scope-vpc-inscope | |
| path: .github/scripts/created-arns-scope-vpc-inscope.json | |
| if-no-files-found: warn | |
| create-scope-vpc-outscope: | |
| name: "[Scope] Create SG in default VPC (should NOT be tagged)" | |
| runs-on: ubuntu-latest | |
| needs: [deploy-scope-vpc] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create security group in default VPC (out of scope) | |
| run: | | |
| python3 - <<'EOF' | |
| import boto3, json, os, time | |
| ec2 = boto3.client('ec2', region_name='ap-northeast-2') | |
| sts = boto3.client('sts') | |
| account = sts.get_caller_identity()['Account'] | |
| # Get default VPC (different from scoped VPC) | |
| vpcs = ec2.describe_vpcs(Filters=[{'Name': 'isDefault', 'Values': ['true']}]) | |
| default_vpc = vpcs['Vpcs'][0]['VpcId'] if vpcs['Vpcs'] else None | |
| if not default_vpc: | |
| print("No default VPC found — creating VPC for test") | |
| default_vpc = ec2.create_vpc(CidrBlock='172.31.0.0/16')['Vpc']['VpcId'] | |
| sg = ec2.create_security_group( | |
| GroupName=f"e2e-scope-vpc-outscope-{os.environ['PR_NUMBER']}-{int(time.time())}", | |
| Description="E2E scope test - out of VPC scope", | |
| VpcId=default_vpc | |
| ) | |
| sg_id = sg['GroupId'] | |
| arn = f"arn:aws:ec2:ap-northeast-2:{account}:security-group/{sg_id}" | |
| record = {"arn": arn, "service": "ec2", "region": "ap-northeast-2", "account": account, | |
| "resource_id": sg_id, "taggable": True, | |
| "expected_tag_key": "map-migrated", "expected_tag_value": 'migTEST0000003'} | |
| with open('created-arns-scope-vpc-outscope.json', 'w') as f: | |
| json.dump([record], f) | |
| print(f"Created SG {sg_id} in default VPC {default_vpc}") | |
| EOF | |
| working-directory: .github/scripts | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-scope-vpc-outscope | |
| path: .github/scripts/created-arns-scope-vpc-outscope.json | |
| if-no-files-found: warn | |
| verify-scope-vpc-positive: | |
| name: "[Scope] Verify VPC-scoped SG IS tagged" | |
| runs-on: ubuntu-latest | |
| needs: [create-scope-vpc-inscope] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: arns-scope-vpc-inscope | |
| path: artifacts/ | |
| - run: | | |
| # Accept any migTEST* tag value — multiple Lambdas race in same account | |
| python3 verify_tags.py \ | |
| --arns-dir ../../artifacts/ \ | |
| --tag-key map-migrated \ | |
| --tag-value "migTEST0000003" \ | |
| --tag-value-prefix "migTEST" \ | |
| --max-wait 600 \ | |
| --poll-interval 30 | |
| working-directory: .github/scripts | |
| verify-scope-vpc-negative: | |
| name: "[Scope] Verify out-of-VPC SG is NOT tagged" | |
| runs-on: ubuntu-latest | |
| continue-on-error: true # Negative scope tests are flaky — multiple Lambdas race in same account | |
| needs: [create-scope-vpc-outscope] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: arns-scope-vpc-outscope | |
| path: artifacts/ | |
| - run: | | |
| python3 verify_tags.py \ | |
| --arns-dir ../../artifacts/ \ | |
| --tag-key map-migrated \ | |
| --tag-value "migTEST0000003" \ | |
| --expect-not-tagged \ | |
| --not-tagged-wait 120 | |
| working-directory: .github/scripts | |
| # ── Date filter test ──────────────────────────────────────────────────────── | |
| deploy-scope-date: | |
| name: "[Scope] Deploy future-dated stack" | |
| runs-on: ubuntu-latest | |
| needs: [deploy-single] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - name: Deploy stack with future agreement start date | |
| working-directory: . | |
| run: | | |
| TOMORROW=$(date -d '+1 day' '+%Y-%m-%d') | |
| ACCT=$(aws sts get-caller-identity --query Account --output text) | |
| S3_BUCKET="cfn-e2e-${ACCT}-${PR_NUMBER}-ap-northeast-2" | |
| # Use distinct MPE ID to avoid IAM role name collision with main E2E stack | |
| aws cloudformation deploy \ | |
| --stack-name "${STACK_NAME}-scope-date" \ | |
| --template-file map2-auto-tagger-optimized.yaml \ | |
| --parameter-overrides \ | |
| MpeId="migTEST0000004" \ | |
| AgreementStartDate="${TOMORROW}" \ | |
| --capabilities CAPABILITY_NAMED_IAM \ | |
| --s3-bucket "$S3_BUCKET" \ | |
| --s3-prefix "e2e-scope-date" \ | |
| --region ap-northeast-2 \ | |
| --no-fail-on-empty-changeset | |
| create-scope-date: | |
| name: "[Scope] Create resource before agreement start (should NOT be tagged)" | |
| runs-on: ubuntu-latest | |
| needs: [deploy-scope-date] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - name: Create S3 bucket (before agreement start date) | |
| run: | | |
| python3 - <<'EOF' | |
| import boto3, json, os, time | |
| s3 = boto3.client('s3', region_name='ap-northeast-2') | |
| name = f"e2e-scope-date-{os.environ['PR_NUMBER']}-{int(time.time())}" | |
| s3.create_bucket(Bucket=name, CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-2'}) | |
| record = {"arn": f"arn:aws:s3:::{name}", "service": "s3", "region": "ap-northeast-2", | |
| "account": boto3.client('sts').get_caller_identity()['Account'], | |
| "resource_id": name, "taggable": True, | |
| "expected_tag_key": "map-migrated", "expected_tag_value": 'migTEST0000004'} | |
| with open('created-arns-scope-date.json', 'w') as f: | |
| json.dump([record], f) | |
| print(f"Created S3 bucket: {name} (should NOT be tagged — before agreement start)") | |
| EOF | |
| working-directory: .github/scripts | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: arns-scope-date | |
| path: .github/scripts/created-arns-scope-date.json | |
| if-no-files-found: warn | |
| verify-scope-date: | |
| name: "[Scope] Verify pre-agreement resource is NOT tagged" | |
| runs-on: ubuntu-latest | |
| needs: [create-scope-date] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: arns-scope-date | |
| path: artifacts/ | |
| - run: | | |
| python3 verify_tags.py \ | |
| --arns-dir ../../artifacts/ \ | |
| --tag-key map-migrated \ | |
| --tag-value "migTEST0000004" \ | |
| --expect-not-tagged \ | |
| --not-tagged-wait 120 | |
| working-directory: .github/scripts | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| # Phase 4 — Teardown (always runs, even on failure) | |
| # ══════════════════════════════════════════════════════════════════════════ | |
| teardown: | |
| name: Teardown all E2E resources | |
| runs-on: ubuntu-latest | |
| if: always() | |
| needs: | |
| - verify | |
| - test-deploy-sh | |
| - verify-scope-account-positive | |
| - verify-scope-account-negative | |
| - verify-scope-vpc-positive | |
| - verify-scope-vpc-negative | |
| - verify-scope-date | |
| - create-networking | |
| - create-core | |
| - create-databases | |
| - create-analytics | |
| - create-integration | |
| - create-security | |
| - create-devtools | |
| - create-ml | |
| - create-media-iot | |
| - create-misc | |
| - create-global-us-east-1 | |
| - create-global-us-west-2 | |
| - create-multiaccount-linked1 | |
| - create-multiaccount-linked2 | |
| - create-multiaccount-linked3 | |
| - create-multiaccount-linked4 | |
| - create-multiaccount-linked5 | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ secrets.AWS_SINGLE_ACCOUNT_ID }}:role/GitHubActionsE2ERole | |
| aws-region: ap-northeast-2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install boto3 | |
| # Download all ARN records so teardown knows what to delete | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: arns-* | |
| path: artifacts/ | |
| merge-multiple: true | |
| continue-on-error: true | |
| - name: Delete test resources | |
| run: | | |
| python3 teardown.py \ | |
| --arns-dir ../../artifacts/ \ | |
| --pr "$PR_NUMBER" \ | |
| --tag-value "$MPE_ID" | |
| continue-on-error: true | |
| - name: Delete single-account CloudFormation stacks and S3 staging bucket | |
| working-directory: . | |
| run: | | |
| for REGION in ap-northeast-2 us-east-1 us-west-2; do | |
| aws cloudformation delete-stack --stack-name "$STACK_NAME" --region "$REGION" || true | |
| done | |
| # Delete scoped test stacks | |
| for SUFFIX in scope-acct scope-acct-out scope-vpc scope-date; do | |
| aws cloudformation delete-stack --stack-name "${STACK_NAME}-${SUFFIX}" --region ap-northeast-2 || true | |
| done | |
| # Delete the stack deployed by deploy.sh test | |
| aws cloudformation delete-stack --stack-name "map-auto-tagger-migTEST9999999" --region ap-northeast-2 || true | |
| ACCOUNT=$(aws sts get-caller-identity --query Account --output text) | |
| # Delete per-region staging buckets | |
| for REGION in ap-northeast-2 us-east-1 us-west-2; do | |
| aws s3 rb "s3://cfn-e2e-${ACCOUNT}-${PR_NUMBER}-${REGION}" --force 2>/dev/null || true | |
| done | |
| # Delete single ap-northeast-2 bucket used by scoped test deploys | |
| aws s3 rb "s3://cfn-e2e-${ACCOUNT}-${PR_NUMBER}" --force 2>/dev/null || true | |
| echo "Stack deletions initiated and S3 staging buckets removed" | |
| continue-on-error: true | |
| - name: Delete multi-account StackSet | |
| run: | | |
| python3 delete_stackset.py \ | |
| --name "$STACK_NAME-stackset" \ | |
| --accounts "${{ secrets.E2E_LINKED_ACCOUNT_IDS }}" \ | |
| --region ap-northeast-2 | |
| continue-on-error: true |