Layer Deployment (GovCloud) #120
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
| # Partitioned Layer Publish | |
| # --- | |
| # This workflow publishes a specific layer version in an AWS account based on the partition input. | |
| # | |
| # We pull the version of the layer and store them as artifacts, then we upload them to each of the Partitioned AWS accounts. | |
| # | |
| # A number of safety checks are performed to ensure safety. | |
| # | |
| # === Automated activities === | |
| # 1. [Setup] configure partition-specific regions, partition names, and STS audience based on target partition (China/GovCloud) | |
| # 2. [Download] retrieve the specified layer version from the main AWS partition (us-east-1) and store as artifacts | |
| # 3. [Copy & Verify] deploy the layer to all regions in the target partition and validate layer deployment by comparing SHA256, description, and version numbers | |
| # | |
| # === Manual activities === | |
| # 1. After the `make-release` workflow finishes and the PR for the documentation update gets created, trigger this workflow manually via `workflow_dispatch` with partition inputs for each China and GovCloud partitions | |
| # 2. Monitor deployment progress and verify successful layer publication across all target regions | |
| # 3. Once this workflow is completed, the PR for the documentation update can me merged | |
| # | |
| # CodeQL Security Note: | |
| # This workflow uses dynamic secret access via secrets[format(...)] which triggers | |
| # an "Excessive Secrets Exposure" alert. However, this is safe because: | |
| # - Secrets are scoped per environment (China/GovCloud Gamma/Prod) | |
| # - Each job only accesses secrets for its specific partition and region | |
| # - No global secrets array containing mixed credentials (API keys, PEM files, etc.) | |
| # - The secrets object is already minimally scoped to the environment being used | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| partition: | |
| description: Partition to deploy to | |
| type: choice | |
| options: | |
| - China | |
| - GovCloud | |
| name: Layer Deployment (Partitions) | |
| run-name: Layer Deployment (${{ inputs.partition }}) | |
| permissions: {} | |
| jobs: | |
| # This job configures partition-specific settings including regions, partition names, and STS audience based on the target partition (China or GovCloud) selected in the workflow inputs. | |
| setup: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| regions: ${{ format('{0}{1}', steps.regions_china.outputs.regions, steps.regions_govcloud.outputs.regions) }} | |
| partition: ${{ format('{0}{1}', steps.regions_china.outputs.partition, steps.regions_govcloud.outputs.partition) }} | |
| aud: ${{ format('{0}{1}', steps.regions_china.outputs.aud, steps.regions_govcloud.outputs.aud) }} | |
| steps: | |
| - id: regions_china | |
| name: Partition (China) | |
| if: ${{ inputs.partition == 'China' }} | |
| run: | | |
| echo regions='["cn-north-1"]'>> "$GITHUB_OUTPUT" | |
| echo partition='aws-cn'>> "$GITHUB_OUTPUT" | |
| echo aud='sts.amazonaws.com.cn'>> "$GITHUB_OUTPUT" | |
| - id: regions_govcloud | |
| name: Partition (GovCloud) | |
| if: ${{ inputs.partition == 'GovCloud' }} | |
| run: | | |
| echo regions='["us-gov-east-1", "us-gov-west-1"]'>> "$GITHUB_OUTPUT" | |
| echo partition='aws-us-gov'>> "$GITHUB_OUTPUT" | |
| echo aud='sts.amazonaws.com'>> "$GITHUB_OUTPUT" | |
| # This job downloads the specified layer version from the main AWS partition (us-east-1) and stores both the layer zip file and metadata as GitHub Actions artifacts for use in deployment. | |
| download: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: read | |
| environment: Prod (Readonly) | |
| steps: | |
| - name: Configure AWS Credentials | |
| uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_IAM_ROLE }} | |
| aws-region: us-east-1 | |
| mask-aws-account-id: true | |
| - name: Get Latest Layer Version | |
| id: get_latest_layer_version | |
| run: | | |
| set -euo pipefail | |
| LAYER_VERSION=$(aws lambda list-layer-versions --layer-name AWSLambdaPowertoolsTypeScriptV2 --query 'LayerVersions[0].Version' --output text --region us-east-1) | |
| echo "LAYER_VERSION=$LAYER_VERSION" >> $GITHUB_OUTPUT | |
| - name: Grab Zip | |
| env: | |
| VERSION: ${{ steps.get_latest_layer_version.outputs.LAYER_VERSION }} | |
| run: | | |
| set -euo pipefail | |
| aws --region us-east-1 lambda get-layer-version-by-arn --arn "arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:${VERSION}" --query 'Content.Location' | xargs curl -L -o AWSLambdaPowertoolsTypeScriptV2.zip | |
| aws --region us-east-1 lambda get-layer-version-by-arn --arn "arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:${VERSION}" > AWSLambdaPowertoolsTypeScriptV2.json | |
| - name: Store Zip | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: AWSLambdaPowertoolsTypeScriptV2.zip | |
| path: AWSLambdaPowertoolsTypeScriptV2.zip | |
| retention-days: 1 | |
| if-no-files-found: error | |
| - name: Store Metadata | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: AWSLambdaPowertoolsTypeScriptV2.json | |
| path: AWSLambdaPowertoolsTypeScriptV2.json | |
| retention-days: 1 | |
| if-no-files-found: error | |
| # Copies the Layer to the Gamma Environment in the selected partition | |
| deploy-gamma: | |
| name: Deploy Gamma Layer | |
| needs: [setup, download] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| uses: ./.github/workflows/layers_partitions_deploy.yml | |
| with: | |
| environment: Gamma | |
| partition: ${{ inputs.partition }} | |
| arn_partition: ${{ needs.setup.outputs.partition }} | |
| regions: ${{ needs.setup.outputs.regions }} | |
| aud: ${{ needs.setup.outputs.aud }} | |
| secrets: inherit | |
| # Copies the Layer to the Prod Environment in the selected partition | |
| deploy-prod: | |
| name: Deploy Prod Layer | |
| needs: [setup, download, deploy-gamma] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| uses: ./.github/workflows/layers_partitions_deploy.yml | |
| with: | |
| environment: Prod | |
| partition: ${{ inputs.partition }} | |
| arn_partition: ${{ needs.setup.outputs.partition }} | |
| regions: ${{ needs.setup.outputs.regions }} | |
| aud: ${{ needs.setup.outputs.aud }} | |
| secrets: inherit |