1
+ # Partitioned Layer Publish
2
+ # ---
3
+ # This workflow publishes a specific layer version in an AWS account based on the environment input.
4
+ #
5
+ # We pull each the version of the layer and store them as artifacts, the we upload them to each of the Partitioned AWS accounts.
6
+ #
7
+ # A number of safety checks are performed to ensure safety.
8
+
9
+ on :
10
+ workflow_dispatch :
11
+ inputs :
12
+ environment :
13
+ description : Deployment environment
14
+ type : choice
15
+ options :
16
+ - Gamma
17
+ - Prod
18
+ required : true
19
+ version :
20
+ description : Layer version to duplicate
21
+ type : string
22
+ required : true
23
+ partition :
24
+ description : Partition to deploy to
25
+ type : choice
26
+ options :
27
+ - China
28
+ - GovCloud
29
+ workflow_call :
30
+ inputs :
31
+ environment :
32
+ description : Deployment environment
33
+ type : string
34
+ required : true
35
+ version :
36
+ description : Layer version to duplicate
37
+ type : string
38
+ required : true
39
+
40
+ name : Layer Deployment (Partitions)
41
+ run-name : Layer Deployment (${{ inputs.partition }}) - ${{ inputs.environment }} / Version - ${{ inputs.version }}
42
+
43
+ permissions :
44
+ contents : read
45
+
46
+ jobs :
47
+ setup :
48
+ runs-on : ubuntu-latest
49
+ outputs :
50
+ regions : ${{ format('{0}{1}', steps.regions_china.outputs.regions, steps.regions_govcloud.outputs.regions) }}
51
+ parition : ${{ format('{0}{1}', steps.regions_china.outputs.partition, steps.regions_govcloud.outputs.parition) }}
52
+ steps :
53
+ - id : regions_china
54
+ name : Parition (China)
55
+ if : ${{ inputs.partition == 'China' }}
56
+ run : |
57
+ echo regions='["cn-north-1", "cn-northwest-1"]'>> "$GITHUB_OUTPUT"
58
+ echo partition='aws-cn'>> "$GITHUB_OUTPUT"
59
+ - id : regions_govcloud
60
+ name : Partition (GovCloud)
61
+ if : ${{ inputs.partition == 'GovCloud' }}
62
+ run : |
63
+ echo regions='["us-gov-east-1", "us-gov-west-1"]'>> "$GITHUB_OUTPUT"
64
+ echo partition='aws-us-gov'>> "$GITHUB_OUTPUT"
65
+ download :
66
+ runs-on : ubuntu-latest
67
+ permissions :
68
+ id-token : write
69
+ contents : read
70
+ environment : Prod (Readonly)
71
+ steps :
72
+ - name : Configure AWS Credentials
73
+ uses : aws-actions/configure-aws-credentials@b47578312673ae6fa5b5096b330d9fbac3d116df # v4.2.1
74
+ with :
75
+ role-to-assume : ${{ secrets.AWS_IAM_ROLE }}
76
+ aws-region : us-east-1
77
+ mask-aws-account-id : true
78
+ - name : Grab Zip
79
+ run : |
80
+ aws --region us-east-1 lambda get-layer-version-by-arn --arn arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:${{ inputs.version }} --query 'Content.Location' | xargs curl -L -o AWSLambdaPowertoolsTypeScriptV2.zip
81
+ aws --region us-east-1 lambda get-layer-version-by-arn --arn arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:${{ inputs.version }} > AWSLambdaPowertoolsTypeScriptV2.json
82
+ - name : Store Zip
83
+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
84
+ with :
85
+ name : AWSLambdaPowertoolsTypeScriptV2.zip
86
+ path : AWSLambdaPowertoolsTypeScriptV2.zip
87
+ retention-days : 1
88
+ if-no-files-found : error
89
+ - name : Store Metadata
90
+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
91
+ with :
92
+ name : AWSLambdaPowertoolsTypeScriptV2.json
93
+ path : AWSLambdaPowertoolsTypeScriptV2.json
94
+ retention-days : 1
95
+ if-no-files-found : error
96
+
97
+ copy :
98
+ name : Copy
99
+ needs :
100
+ - setup
101
+ - download
102
+ runs-on : ubuntu-latest
103
+ permissions :
104
+ id-token : write
105
+ contents : read
106
+ # Environment should interperlate as "GovCloud Prod" or "China Beta"
107
+ environment : ${{ inputs.partition }} ${{ inputs.environment }}
108
+ strategy :
109
+ matrix :
110
+ region : ${{ fromJson(needs.setup.outputs.regions) }}
111
+ steps :
112
+ - name : Download Zip
113
+ uses : actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
114
+ with :
115
+ name : AWSLambdaPowertoolsTypeScriptV2.zip
116
+ - name : Download Metadata
117
+ uses : actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
118
+ with :
119
+ name : AWSLambdaPowertoolsTypeScriptV2.json
120
+ - name : Verify Layer Signature
121
+ run : |
122
+ SHA=$(jq -r '.Content.CodeSha256' 'AWSLambdaPowertoolsTypeScriptV2.json')
123
+ test "$(openssl dgst -sha256 -binary AWSLambdaPowertoolsTypeScriptV2.zip | openssl enc -base64)" == "$SHA" && echo "SHA OK: ${SHA}" || exit 1
124
+ - id : transform
125
+ run : |
126
+ echo 'CONVERTED_REGION=${{ matrix.region }}' | tr 'a-z\-' 'A-Z_' >> "$GITHUB_OUTPUT"
127
+ - name : Configure AWS Credentials
128
+ uses : aws-actions/configure-aws-credentials@b47578312673ae6fa5b5096b330d9fbac3d116df # v4.2.1
129
+ with :
130
+ role-to-assume : ${{ secrets[format('IAM_ROLE_{0}', steps.transform.outputs.CONVERTED_REGION)] }}
131
+ aws-region : ${{ matrix.region}}
132
+ mask-aws-account-id : true
133
+ - name : Create Layer
134
+ id : create-layer
135
+ run : |
136
+ cat AWSLambdaPowertoolsTypeScriptV2.json | jq '{"LayerName": "AWSLambdaPowertoolsTypeScriptV2", "Description": .Description, "CompatibleRuntimes": .CompatibleRuntimes, "LicenseInfo": .LicenseInfo}' > input.json
137
+
138
+ LAYER_VERSION=$(aws --region ${{ matrix.region}} lambda publish-layer-version \
139
+ --zip-file fileb://./AWSLambdaPowertoolsTypeScriptV2.zip \
140
+ --cli-input-json file://./input.json \
141
+ --query 'Version' \
142
+ --output text)
143
+
144
+ echo "LAYER_VERSION=$LAYER_VERSION" >> "$GITHUB_OUTPUT"
145
+
146
+ aws --region ${{ matrix.region}} lambda add-layer-version-permission \
147
+ --layer-name 'AWSLambdaPowertoolsTypeScriptV2' \
148
+ --statement-id 'PublicLayer' \
149
+ --action lambda:GetLayerVersion \
150
+ --principal '*' \
151
+ --version-number "$LAYER_VERSION"
152
+ - name : Verify Layer
153
+ env :
154
+ LAYER_VERSION : ${{ steps.create-layer.outputs.LAYER_VERSION }}
155
+ run : |
156
+ export layer_output='AWSLambdaPowertoolsTypeScriptV2-${{matrix.region}}.json'
157
+ aws --region ${{ matrix.region}} lambda get-layer-version-by-arn --arn 'arn:${{ needs.setup.outputs.parition }}:lambda:${{ matrix.region}}:${{ secrets[format('AWS_ACCOUNT_{0}', steps.transform.outputs.CONVERTED_REGION)] }}:layer:AWSLambdaPowertoolsTypeScriptV2:${{ env.LAYER_VERSION }}' > $layer_output
158
+ REMOTE_SHA=$(jq -r '.Content.CodeSha256' $layer_output)
159
+ LOCAL_SHA=$(jq -r '.Content.CodeSha256' AWSLambdaPowertoolsTypeScriptV2.json)
160
+ test "$REMOTE_SHA" == "$LOCAL_SHA" && echo "SHA OK: ${LOCAL_SHA}" || exit 1
161
+ jq -s -r '["Layer Arn", "Runtimes", "Version", "Description", "SHA256"], ([.[0], .[1]] | .[] | [.LayerArn, (.CompatibleRuntimes | join("/")), .Version, .Description, .Content.CodeSha256]) |@tsv' AWSLambdaPowertoolsTypeScriptV2.json $layer_output | column -t -s $'\t'
162
+
163
+ - name : Store Metadata - ${{ matrix.region }}
164
+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
165
+ with :
166
+ name : AWSLambdaPowertoolsTypeScriptV2-${{ matrix.region }}.json
167
+ path : AWSLambdaPowertoolsTypeScriptV2-${{ matrix.region }}.json
168
+ retention-days : 1
169
+ if-no-files-found : error
0 commit comments