Skip to content

Commit 3b291db

Browse files
viw-test1wangzlei
andauthored
feat: Add region build release workflow for Java Lambda layer (#1355)
*Issue #, if available:* N/A *Description of changes:* Add a standalone region-build-release.yml workflow for deploying the Java Lambda layer to specific regions. This is needed for region build releases where we need to build and publish the Lambda layer independently from the full SDK release. The workflow: 1. Takes a version and target regions as inputs (manual workflow_dispatch) 2. Builds the Java Lambda layer from source 3. Publishes the layer to each specified region in parallel 4. Generates release notes with layer ARN table, Terraform file, and CDK constants 5. Creates a draft GitHub release with the layer artifact 6. Uploads the layer artifact to the latest SDK release This was previously part of a separate Lambda release workflow before it was merged into release-build.yml in PR #461. Re-adding it as a dedicated workflow to support region-specific deployments without triggering a full SDK release. V2: Key difference from previous version: ey differences: 1. publish-layer-prod now has a Lambda layer "Upload to S3 and Sign" step that checks for a signing profile and signs the layer before publishing. The old version just uploaded and published directly. 2. publish-layer-prod uses LAYER_ARTIFACT_NAME env var instead of a hardcoded filename 3. publish-layer-prod outputs the SigningProfileVersionArn after publishing 4. generate-lambda-release-note outputs layer-note as a job output (for use by publish-github) 5. publish-github is a separate job (old version had everything in generate-release-note), and it doesn't upload to the upstream SDK release (removed that step since this is a region only build, not a full release anymore) 6. Uses the same action versions and pin hashes as the current release-build.yml By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. Co-authored-by: Lei Wang <66336933+wangzlei@users.noreply.github.com>
1 parent c3174c2 commit 3b291db

1 file changed

Lines changed: 258 additions & 0 deletions

File tree

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
name: Region Build Release
2+
on:
3+
workflow_dispatch:
4+
inputs:
5+
version:
6+
description: The version to tag the lambda release with, e.g., 1.2.0
7+
required: true
8+
aws_region:
9+
description: 'Deploy lambda layer to aws regions'
10+
required: true
11+
default: ''
12+
13+
env:
14+
LAYER_ARTIFACT_NAME: aws-opentelemetry-java-layer.zip
15+
# Legacy list of commercial regions to deploy to. New regions should NOT be added here, and instead should be added to the `aws_region` default input to the workflow.
16+
LEGACY_COMMERCIAL_REGIONS: us-east-1, us-east-2, us-west-1, us-west-2, ap-south-1, ap-northeast-3, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-northeast-1, ca-central-1, eu-central-1, eu-west-1, eu-west-2, eu-west-3, eu-north-1, sa-east-1
17+
LAYER_NAME: AWSOpenTelemetryDistroJava
18+
VERSION: ${{ github.event.inputs.version }}
19+
AWS_REGION: ${{ github.event.inputs.aws_region }}
20+
21+
permissions:
22+
id-token: write
23+
contents: write
24+
25+
jobs:
26+
build-layer:
27+
environment: Release
28+
runs-on: ubuntu-latest
29+
outputs:
30+
aws_regions_json: ${{ steps.set-matrix.outputs.aws_regions_json }}
31+
steps:
32+
- name: Set up regions matrix
33+
id: set-matrix
34+
env:
35+
AWS_REGIONS: ${{ env.AWS_REGION }}
36+
run: |
37+
IFS=',' read -ra REGIONS <<< "$AWS_REGIONS"
38+
MATRIX="["
39+
for region in "${REGIONS[@]}"; do
40+
trimmed_region=$(echo "$region" | xargs)
41+
MATRIX+="\"$trimmed_region\","
42+
done
43+
MATRIX="${MATRIX%,}]"
44+
echo ${MATRIX}
45+
echo "aws_regions_json=${MATRIX}" >> $GITHUB_OUTPUT
46+
47+
- name: Checkout Repo @ SHA - ${{ github.sha }}
48+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
49+
50+
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
51+
with:
52+
java-version-file: .java-version
53+
distribution: 'temurin'
54+
55+
- name: Build layers
56+
working-directory: lambda-layer
57+
run: |
58+
./build-layer.sh
59+
60+
- name: Upload layer
61+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2
62+
with:
63+
name: layer.zip
64+
path: lambda-layer/build/distributions/${{ env.LAYER_ARTIFACT_NAME }}
65+
66+
publish-layer-prod:
67+
runs-on: ubuntu-latest
68+
needs: build-layer
69+
strategy:
70+
matrix:
71+
aws_region: ${{ fromJson(needs.build-layer.outputs.aws_regions_json) }}
72+
steps:
73+
- name: role arn
74+
env:
75+
LEGACY_COMMERCIAL_REGIONS: ${{ env.LEGACY_COMMERCIAL_REGIONS }}
76+
run: |
77+
LEGACY_COMMERCIAL_REGIONS_ARRAY=(${LEGACY_COMMERCIAL_REGIONS//,/ })
78+
FOUND=false
79+
for REGION in "${LEGACY_COMMERCIAL_REGIONS_ARRAY[@]}"; do
80+
if [[ "$REGION" == "${{ matrix.aws_region }}" ]]; then
81+
FOUND=true
82+
break
83+
fi
84+
done
85+
if [ "$FOUND" = true ]; then
86+
echo "Found ${{ matrix.aws_region }} in LEGACY_COMMERCIAL_REGIONS"
87+
SECRET_KEY="LAMBDA_LAYER_RELEASE"
88+
else
89+
echo "Not found ${{ matrix.aws_region }} in LEGACY_COMMERCIAL_REGIONS"
90+
SECRET_KEY="${{ matrix.aws_region }}_LAMBDA_LAYER_RELEASE"
91+
fi
92+
SECRET_KEY=${SECRET_KEY//-/_}
93+
echo "SECRET_KEY=${SECRET_KEY}" >> $GITHUB_ENV
94+
95+
- uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0
96+
with:
97+
role-to-assume: ${{ secrets[env.SECRET_KEY] }}
98+
role-duration-seconds: 1200
99+
aws-region: ${{ matrix.aws_region }}
100+
101+
- name: Get s3 bucket name for release
102+
run: |
103+
echo BUCKET_NAME=java-lambda-layer-${{ github.run_id }}-${{ matrix.aws_region }} | tee --append $GITHUB_ENV
104+
105+
- name: download layer.zip
106+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
107+
with:
108+
name: layer.zip
109+
110+
- name: Upload to S3 and Sign
111+
continue-on-error: true
112+
run: |
113+
aws s3 mb s3://${{ env.BUCKET_NAME }}
114+
aws s3 cp ${{ env.LAYER_ARTIFACT_NAME }} s3://${{ env.BUCKET_NAME }}
115+
116+
# Sign the layer
117+
echo "Checking for signing profile..."
118+
PROFILE=$(aws signer list-signing-profiles --query "profiles[?profileName=='ADOTLambdaLayerSigningProfile'].arn" --output text 2>/dev/null)
119+
[ -z "$PROFILE" ] && echo "No signing profile found, skipping" && exit 0
120+
121+
echo "Starting signing job..."
122+
JOB_ID=$(aws signer start-signing-job \
123+
--source "s3={bucketName=${{ env.BUCKET_NAME }},key=${{ env.LAYER_ARTIFACT_NAME }},version=null}" \
124+
--destination "s3={bucketName=${{ env.BUCKET_NAME }},prefix=signed-}" \
125+
--profile-name ADOTLambdaLayerSigningProfile \
126+
--query 'jobId' --output text 2>/dev/null) || exit 0
127+
[ -z "$JOB_ID" ] && echo "No job ID returned" && exit 0
128+
echo "Job ID: $JOB_ID"
129+
130+
echo "Waiting for signing job to complete..."
131+
aws signer wait successful-signing-job --job-id "$JOB_ID" || exit 0
132+
echo "Signing completed"
133+
134+
echo "Moving signed layer..."
135+
SIGNED=$(aws signer describe-signing-job --job-id "$JOB_ID" --query 'signedObject.s3.key' --output text 2>/dev/null)
136+
echo "SIGNED value: '$SIGNED'"
137+
if [ -n "$SIGNED" ]; then
138+
aws s3 mv "s3://${{ env.BUCKET_NAME }}/$SIGNED" "s3://${{ env.BUCKET_NAME }}/${{ env.LAYER_ARTIFACT_NAME }} --clobber"
139+
echo "Signed layer moved successfully"
140+
else
141+
echo "No SIGNED value returned, skipping move"
142+
fi
143+
144+
- name: Publish Layer Version
145+
run: |
146+
layerARN=$(
147+
aws lambda publish-layer-version \
148+
--layer-name ${{ env.LAYER_NAME }} \
149+
--content S3Bucket=${{ env.BUCKET_NAME }},S3Key=${{ env.LAYER_ARTIFACT_NAME }} \
150+
--compatible-runtimes java11 java17 java21 \
151+
--compatible-architectures "arm64" "x86_64" \
152+
--license-info "Apache-2.0" \
153+
--description "AWS Distro of OpenTelemetry Lambda Layer for Java Runtime" \
154+
--query 'LayerVersionArn' \
155+
--output text
156+
)
157+
echo $layerARN
158+
echo "LAYER_ARN=${layerARN}" >> $GITHUB_ENV
159+
mkdir ${{ env.LAYER_NAME }}
160+
echo $layerARN > ${{ env.LAYER_NAME }}/${{ matrix.aws_region }}
161+
cat ${{ env.LAYER_NAME }}/${{ matrix.aws_region }}
162+
163+
# Output SigningProfileVersionArn
164+
aws lambda get-layer-version-by-arn \
165+
--arn $layerARN \
166+
--output json | jq -r '.Content.SigningProfileVersionArn'
167+
168+
- name: public layer
169+
run: |
170+
layerVersion=$(
171+
aws lambda list-layer-versions \
172+
--layer-name ${{ env.LAYER_NAME }} \
173+
--query 'max_by(LayerVersions, &Version).Version'
174+
)
175+
aws lambda add-layer-version-permission \
176+
--layer-name ${{ env.LAYER_NAME }} \
177+
--version-number $layerVersion \
178+
--principal "*" \
179+
--statement-id publish \
180+
--action lambda:GetLayerVersion
181+
182+
- name: upload layer arn artifact
183+
if: ${{ success() }}
184+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2
185+
with:
186+
name: ${{ env.LAYER_NAME }}-${{ matrix.aws_region }}
187+
path: ${{ env.LAYER_NAME }}/${{ matrix.aws_region }}
188+
189+
- name: clean s3
190+
if: always()
191+
run: |
192+
aws s3 rb --force s3://${{ env.BUCKET_NAME }}
193+
194+
generate-lambda-release-note:
195+
runs-on: ubuntu-latest
196+
needs: publish-layer-prod
197+
outputs:
198+
layer-note: ${{ steps.layer-note.outputs.layer-note }}
199+
steps:
200+
- name: Checkout Repo @ SHA - ${{ github.sha }}
201+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
202+
- uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd #v3.1.2
203+
- name: download layerARNs
204+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
205+
with:
206+
pattern: ${{ env.LAYER_NAME }}-*
207+
path: ${{ env.LAYER_NAME }}
208+
merge-multiple: true
209+
- name: show layerARNs
210+
run: |
211+
for file in ${{ env.LAYER_NAME }}/*
212+
do
213+
echo $file
214+
cat $file
215+
done
216+
- name: generate layer-note
217+
id: layer-note
218+
working-directory: ${{ env.LAYER_NAME }}
219+
run: |
220+
echo "| Region | Layer ARN |" >> ../layer-note
221+
echo "| ---- | ---- |" >> ../layer-note
222+
for file in *
223+
do
224+
read arn < $file
225+
echo "| " $file " | " $arn " |" >> ../layer-note
226+
done
227+
cd ..
228+
{
229+
echo "layer-note<<EOF"
230+
cat layer-note
231+
echo "EOF"
232+
} >> $GITHUB_OUTPUT
233+
cat layer-note
234+
- name: generate tf layer
235+
working-directory: ${{ env.LAYER_NAME }}
236+
run: |
237+
echo "locals {" >> ../layer_arns.tf
238+
echo " sdk_layer_arns = {" >> ../layer_arns.tf
239+
for file in *
240+
do
241+
read arn < $file
242+
echo " \""$file"\" = \""$arn"\"" >> ../layer_arns.tf
243+
done
244+
cd ..
245+
echo " }" >> layer_arns.tf
246+
echo "}" >> layer_arns.tf
247+
terraform fmt layer_arns.tf
248+
cat layer_arns.tf
249+
- name: generate layer ARN constants for CDK
250+
working-directory: ${{ env.LAYER_NAME }}
251+
run: |
252+
echo "{" > ../layer_cdk
253+
for file in *; do
254+
read arn < "$file"
255+
echo " \"$file\": \"$arn\"," >> ../layer_cdk
256+
done
257+
echo "}" >> ../layer_cdk
258+
cat ../layer_cdk

0 commit comments

Comments
 (0)