Skip to content

Layer Deployment (GovCloud) #118

Layer Deployment (GovCloud)

Layer Deployment (GovCloud) #118

# 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