-
Notifications
You must be signed in to change notification settings - Fork 406
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(layer): publish SAR v2 via Github actions (#1585)
Co-authored-by: Heitor Lessa <[email protected]>
- Loading branch information
1 parent
fd7c235
commit be64e4e
Showing
7 changed files
with
268 additions
and
43 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,8 +8,7 @@ on: | |
workflow_dispatch: | ||
inputs: | ||
latest_published_version: | ||
description: "Latest PyPi published version to rebuild latest docs for, e.g. v1.22.0" | ||
default: "v2.0.0" | ||
description: "Latest PyPi published version to rebuild latest docs for, e.g. v2.0.0" | ||
required: true | ||
# workflow_run: | ||
# workflows: ["Publish to PyPi"] | ||
|
@@ -23,6 +22,8 @@ jobs: | |
defaults: | ||
run: | ||
working-directory: ./layer | ||
outputs: | ||
release-tag-version: ${{ steps.release-notes-tag.outputs.RELEASE_TAG_VERSION }} | ||
steps: | ||
- name: checkout | ||
uses: actions/checkout@v3 | ||
|
@@ -46,11 +47,12 @@ jobs: | |
poetry export --format requirements.txt --output requirements.txt | ||
pip install -r requirements.txt | ||
- name: Set release notes tag | ||
id: release-notes-tag | ||
run: | | ||
RELEASE_INPUT=${{ inputs.latest_published_version }} | ||
LATEST_TAG=$(git describe --tag --abbrev=0) | ||
RELEASE_TAG_VERSION=${RELEASE_INPUT:-$LATEST_TAG} | ||
echo RELEASE_TAG_VERSION="${RELEASE_TAG_VERSION:1}" >> "$GITHUB_ENV" | ||
echo RELEASE_TAG_VERSION="${RELEASE_TAG_VERSION:1}" >> "$GITHUB_OUTPUT" | ||
- name: Set up QEMU | ||
uses: docker/setup-qemu-action@8b122486cedac8393e77aa9734c3528886e4a1a8 # v2.0.0 | ||
# NOTE: we need QEMU to build Layer against a different architecture (e.g., ARM) | ||
|
@@ -62,7 +64,7 @@ jobs: | |
npm install -g [email protected] | ||
cdk --version | ||
- name: CDK build | ||
run: cdk synth --context version="$RELEASE_TAG_VERSION" -o cdk.out | ||
run: cdk synth --context version="${{ steps.release-notes-tag.outputs.RELEASE_TAG_VERSION }}" -o cdk.out | ||
- name: zip output | ||
run: zip -r cdk.out.zip cdk.out | ||
- name: Archive CDK artifacts | ||
|
@@ -90,3 +92,23 @@ jobs: | |
# stage: "PROD" | ||
# artefact-name: "cdk-layer-artefact" | ||
# environment: "layer-prod" | ||
|
||
deploy-sar-beta: | ||
needs: build-layer | ||
uses: ./.github/workflows/reusable_deploy_v2_sar.yml | ||
secrets: inherit | ||
with: | ||
stage: "BETA" | ||
artefact-name: "cdk-layer-artefact" | ||
environment: "layer-beta" | ||
package-version: ${{ needs.build-layer.outputs.release-tag-version }} | ||
|
||
deploy-sar-prod: | ||
needs: deploy-sar-beta | ||
uses: ./.github/workflows/reusable_deploy_v2_sar.yml | ||
secrets: inherit | ||
with: | ||
stage: "PROD" | ||
artefact-name: "cdk-layer-artefact" | ||
environment: "layer-prod" | ||
package-version: ${{ needs.build-layer.outputs.release-tag-version }} |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
name: Deploy V2 SAR | ||
|
||
# SAR deployment process | ||
# | ||
# 1. This workflow starts after the layer artifact is produced on `publish_v2_layer` | ||
# 2. We use the same layer artifact to ensure the SAR app is consistent with the published Lambda Layer | ||
# 3. We publish the SAR for both x86_64 and arm64 (see `matrix` section) | ||
# 4. We use `sam package` and `sam publish` to publish the SAR app | ||
# 5. We remove the previous Canary stack (if present) and deploy a new one to test the SAR App. We retain the Canary in the account for debugging purposes | ||
# 6. Finally the published SAR app is made public on the PROD environment | ||
|
||
permissions: | ||
id-token: write | ||
contents: read | ||
|
||
env: | ||
NODE_VERSION: 16.12 | ||
AWS_REGION: eu-west-1 | ||
SAR_NAME: aws-lambda-powertools-python-layer-v2 | ||
TEST_STACK_NAME: serverlessrepo-v2-powertools-layer-test-stack | ||
|
||
on: | ||
workflow_call: | ||
inputs: | ||
stage: | ||
description: "Deployment stage (BETA, PROD)" | ||
required: true | ||
type: string | ||
artefact-name: | ||
description: "CDK Layer Artefact name to download" | ||
required: true | ||
type: string | ||
package-version: | ||
description: "The version of the package to deploy" | ||
required: true | ||
type: string | ||
environment: | ||
description: "GitHub Environment to use for encrypted secrets" | ||
required: true | ||
type: string | ||
|
||
jobs: | ||
deploy-sar-app: | ||
runs-on: ubuntu-latest | ||
environment: ${{ inputs.environment }} | ||
strategy: | ||
matrix: | ||
architecture: ["x86_64", "arm64"] | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
- name: AWS credentials | ||
uses: aws-actions/configure-aws-credentials@v1 | ||
with: | ||
aws-region: ${{ env.AWS_REGION }} | ||
role-to-assume: ${{ secrets.AWS_LAYERS_ROLE_ARN }} | ||
- name: AWS credentials SAR role | ||
uses: aws-actions/configure-aws-credentials@v1 | ||
id: aws-credentials-sar-role | ||
with: | ||
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} | ||
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} | ||
aws-session-token: ${{ env.AWS_SESSION_TOKEN }} | ||
role-duration-seconds: 1200 | ||
aws-region: ${{ env.AWS_REGION }} | ||
role-to-assume: ${{ secrets.AWS_SAR_V2_ROLE_ARN }} | ||
- name: Setup Node.js | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: ${{ env.NODE_VERSION }} | ||
- name: Download artifact | ||
uses: actions/download-artifact@v3 | ||
with: | ||
name: ${{ inputs.artefact-name }} | ||
- name: Unzip artefact | ||
run: unzip cdk.out.zip | ||
- name: Configure SAR name | ||
run: | | ||
if [[ "${{ inputs.stage }}" == "BETA" ]]; then | ||
SAR_NAME="test-${SAR_NAME}" | ||
fi | ||
echo SAR_NAME="${SAR_NAME}" >> "$GITHUB_ENV" | ||
- name: Adds arm64 suffix to SAR name | ||
if: ${{ matrix.architecture == 'arm64' }} | ||
run: echo SAR_NAME="${SAR_NAME}-arm64" >> "$GITHUB_ENV" | ||
- name: Deploy SAR | ||
run: | | ||
# From the generated LayerStack cdk.out artifact, find the layer asset path for the correct architecture. | ||
# We'll use this as the source directory of our SAR. This way we are re-using the same layer asset for our SAR. | ||
asset=$(jq -jc '.Resources[] | select(.Properties.CompatibleArchitectures == ["${{ matrix.architecture }}"]) | .Metadata."aws:asset:path"' cdk.out/LayerV2Stack.template.json) | ||
# fill in the SAR SAM template | ||
sed -e "s|<VERSION>|${{ inputs.package-version }}|g" -e "s/<SAR_APP_NAME>/${{ env.SAR_NAME }}/g" -e "s|<LAYER_CONTENT_PATH>|./cdk.out/$asset|g" layer/sar/template.txt > template.yml | ||
# SAR needs a README and a LICENSE, so just copy the ones from the repo | ||
cp README.md LICENSE "./cdk.out/$asset/" | ||
# Package the SAR to our SAR S3 bucket, and publish it | ||
sam package --template-file template.yml --output-template-file packaged.yml --s3-bucket ${{ secrets.AWS_SAR_S3_BUCKET }} | ||
sam publish --template packaged.yml --region "$AWS_REGION" | ||
- name: Deploy BETA canary | ||
if: ${{ inputs.stage == 'BETA' }} | ||
run: | | ||
if [[ "${{ matrix.architecture }}" == "arm64" ]]; then | ||
TEST_STACK_NAME="${TEST_STACK_NAME}-arm64" | ||
fi | ||
echo "Check if stack does not exist" | ||
stack_exists=$(aws cloudformation list-stacks --query "StackSummaries[?(StackName == '$TEST_STACK_NAME' && StackStatus == 'CREATE_COMPLETE')].{StackId:StackId, StackName:StackName, CreationTime:CreationTime, StackStatus:StackStatus}" --output text) | ||
if [[ -n "$stack_exists" ]] ; then | ||
echo "Found test deployment stack, removing..." | ||
aws cloudformation delete-stack --stack-name "$TEST_STACK_NAME" | ||
aws cloudformation wait stack-delete-complete --stack-name "$TEST_STACK_NAME" | ||
fi | ||
echo "Creating canary stack" | ||
echo "Stack name: $TEST_STACK_NAME" | ||
aws serverlessrepo create-cloud-formation-change-set --application-id arn:aws:serverlessrepo:${{ env.AWS_REGION }}:${{ steps.aws-credentials-sar-role.outputs.aws-account-id }}:applications/${{ env.SAR_NAME }} --stack-name "${TEST_STACK_NAME/serverlessrepo-/}" --capabilities CAPABILITY_NAMED_IAM | ||
CHANGE_SET_ID=$(aws cloudformation list-change-sets --stack-name "$TEST_STACK_NAME" --query 'Summaries[*].ChangeSetId' --output text) | ||
aws cloudformation wait change-set-create-complete --change-set-name "$CHANGE_SET_ID" | ||
aws cloudformation execute-change-set --change-set-name "$CHANGE_SET_ID" | ||
aws cloudformation wait stack-create-complete --stack-name "$TEST_STACK_NAME" | ||
echo "Waiting until stack deployment completes..." | ||
echo "Exit with error if stack is not in CREATE_COMPLETE" | ||
stack_exists=$(aws cloudformation list-stacks --query "StackSummaries[?(StackName == '$TEST_STACK_NAME' && StackStatus == 'CREATE_COMPLETE')].{StackId:StackId, StackName:StackName, CreationTime:CreationTime, StackStatus:StackStatus}") | ||
if [[ -z "$stack_exists" ]] ; then | ||
echo "Could find successful deployment, exit error..." | ||
exit 1 | ||
fi | ||
echo "Deployment successful" | ||
- name: Publish SAR | ||
if: ${{ inputs.stage == 'PROD' }} | ||
run: | | ||
# wait until SAR registers the app, otherwise it fails to make it public | ||
sleep 15 | ||
echo "Make SAR app public" | ||
aws serverlessrepo put-application-policy --application-id arn:aws:serverlessrepo:${{ env.AWS_REGION }}:${{ steps.aws-credentials-sar-role.outputs.aws-account-id }}:applications/${{ env.SAR_NAME }} --statements Principals='*',Actions=Deploy |
This file contains 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
Oops, something went wrong.