-
Notifications
You must be signed in to change notification settings - Fork 421
139 lines (127 loc) · 6.52 KB
/
reusable_deploy_v2_sar.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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 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