Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automate layer releases #93

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ tests/testfunctions/bin/
tests/testfunctions/.serverless/
tests/testfunctions/.settings/
tests/testfunctions/build.gradle

.gitlab/build-pipeline.yaml
65 changes: 65 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
variables:
DOCKER_TARGET_IMAGE: registry.ddbuild.io/ci/datadog-lambda-java
DOCKER_TARGET_VERSION: latest
# Default version for development builds
# This will be overwritten by the tag version if it is a release.
VERSION: dev

stages:
- pre
- build

.go-cache: &go-cache
key: datadog-lambda-java-go-cache
policy: pull

ci image:
stage: build
image: registry.ddbuild.io/images/docker:20.10
tags: ["arch:arm64"]
rules:
- if: '$CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"'
changes:
- .gitlab/Dockerfile
when: on_success
variables:
DOCKER_TARGET: ${DOCKER_TARGET_IMAGE}:${DOCKER_TARGET_VERSION}
script:
- docker buildx build --platform linux/amd64,linux/arm64 --no-cache --pull --push --tag ${DOCKER_TARGET} -f .gitlab/Dockerfile .

generator:
stage: pre
image: registry.ddbuild.io/images/mirror/golang:alpine
tags: ["arch:amd64"]
cache: *go-cache
rules:
- if: '$CI_PIPELINE_SOURCE =~ /external_pull_request_event|merge_request_event|push/'
when: never
- when: always
script:
- if [[ "$CI_COMMIT_TAG" =~ ^v[0-9]+$ ]]; then echo "VERSION=${CI_COMMIT_TAG//[!0-9]/}" >> .env; fi
- apk add --no-cache gomplate
- gomplate --config .gitlab/config.yaml
artifacts:
paths:
- .gitlab/build-pipeline.yaml
reports:
dotenv: .env

build:
stage: build
needs: ["generator"]
trigger:
include:
- artifact: .gitlab/build-pipeline.yaml
job: generator
strategy: depend
needs:
- job: generator
artifacts: true
rules:
- if: '$CI_PIPELINE_SOURCE =~ /external_pull_request_event|merge_request_event|push/'
when: never
- when: always
variables:
VERSION: $VERSION
8 changes: 8 additions & 0 deletions .gitlab/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM registry.ddbuild.io/images/docker:24.0.5

RUN apt-get update && apt-get install -y --no-install-recommends \
curl gnupg unzip zip jq

# Install AWS CLI.
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip && ./aws/install
14 changes: 14 additions & 0 deletions .gitlab/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# gomplate template generation pipeline

inputFiles:
- .gitlab/template.yaml.tpl

outputFiles:
- .gitlab/build-pipeline.yaml

datasources:
environments:
url: .gitlab/datasources/environments.yaml

regions:
url: .gitlab/datasources/regions.yaml
9 changes: 9 additions & 0 deletions .gitlab/datasources/environments.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
environments:
- name: sandbox
external_id: sandbox-publish-externalid
role_to_assume: sandbox-layer-deployer
account: 425362996713
- name: prod
external_id: prod-publish-externalid
role_to_assume: dd-serverless-layer-deployer-role
account: 464622532012
31 changes: 31 additions & 0 deletions .gitlab/datasources/regions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
regions:
- code: "us-east-1"
- code: "us-east-2"
- code: "us-west-1"
- code: "us-west-2"
- code: "af-south-1"
- code: "ap-east-1"
- code: "ap-south-1"
- code: "ap-south-2"
- code: "ap-southeast-1"
- code: "ap-southeast-2"
- code: "ap-southeast-3"
- code: "ap-southeast-4"
- code: "ap-southeast-5"
- code: "ap-northeast-1"
- code: "ap-northeast-2"
- code: "ap-northeast-3"
- code: "ca-central-1"
- code: "ca-west-1"
- code: "eu-central-1"
- code: "eu-central-2"
- code: "eu-north-1"
- code: "eu-west-1"
- code: "eu-west-2"
- code: "eu-west-3"
- code: "eu-south-1"
- code: "eu-south-2"
- code: "il-central-1"
- code: "me-south-1"
- code: "me-central-1"
- code: "sa-east-1"
48 changes: 48 additions & 0 deletions .gitlab/scripts/get_secrets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash

# Unless explicitly stated otherwise all files in this repository are licensed
# under the Apache License Version 2.0.
# This product includes software developed at Datadog (https://www.datadoghq.com/).
# Copyright 2024 Datadog, Inc.

set -e

if [ -z "$EXTERNAL_ID_NAME" ]; then
printf "[Error] No EXTERNAL_ID_NAME found.\n"
printf "Exiting script...\n"
exit 1
fi

if [ -z "$ROLE_TO_ASSUME" ]; then
printf "[Error] No ROLE_TO_ASSUME found.\n"
printf "Exiting script...\n"
exit 1
fi

printf "Getting AWS External ID...\n"

EXTERNAL_ID=$(aws ssm get-parameter \
--region us-east-1 \
--name "ci.datadog-lambda-java.$EXTERNAL_ID_NAME" \
--with-decryption \
--query "Parameter.Value" \
--out text)

printf "Getting DD API KEY...\n"

export DD_API_KEY=$(aws ssm get-parameter \
--region us-east-1 \
--name ci.datadog-lambda-java.dd-api-key \
--with-decryption \
--query "Parameter.Value" \
--out text)

printf "Assuming role...\n"

export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" \
$(aws sts assume-role \
--role-arn "arn:aws:iam::$AWS_ACCOUNT:role/$ROLE_TO_ASSUME" \
--role-session-name "ci.datadog-lambda-java-$CI_JOB_ID-$CI_JOB_STAGE" \
--query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \
--external-id $EXTERNAL_ID \
--output text))
109 changes: 109 additions & 0 deletions .gitlab/scripts/publish_layers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/bin/bash

# Unless explicitly stated otherwise all files in this repository are licensed
# under the Apache License Version 2.0.
# This product includes software developed at Datadog (https://www.datadoghq.com/).
# Copyright 2024 Datadog, Inc.

set -e

LAYER_NAME="dd-trace-java"

publish_layer() {
region=$1

version_nbr=$(aws lambda publish-layer-version --layer-name $LAYER_NAME \
--description "Datadog Tracer Lambda Layer for Java" \
--compatible-runtimes "java8" "java11" "java17" "java21" \
--compatible-architectures "x86_64" "arm64" \
--zip-file "fileb://.layers/tracer.zip" \
--region $region \
| jq -r '.Version')

# Add permissions only for prod
if [ "$STAGE" == "prod" ]; then
permission=$(aws lambda add-layer-version-permission --layer-name $LAYER_NAME \
--version-number $version_nbr \
--statement-id "release-$version_nbr" \
--action lambda:GetLayerVersion \
--principal "*" \
--region $region
)
fi

echo $version_nbr
}


if [ ! -f ".layers/tracer.zip" ]; then
printf "[ERROR]: Could not find .layers/tracer.zip."
exit 1
fi

AVAILABLE_REGIONS=$(aws ec2 describe-regions | jq -r '.[] | .[] | .RegionName')

if [ -z "$REGION" ]; then
printf "[ERROR]: REGION not specified."
exit 1
else
printf "Region specified: $REGION\n"
if [[ ! "$AVAILABLE_REGIONS" == *"$REGION"* ]]; then
printf "Could not find $REGION in available regions: $AVAILABLE_REGIONS"
exit 1
fi
fi

if [ -z "$STAGE" ]; then
printf "[ERROR]: STAGE not specified.\n"
exit 1
fi

printf "[$REGION] Starting publishing layers...\n"

if [[ "$STAGE" =~ ^(staging|sandbox)$ ]]; then
# Deploy latest version
latest_version=$(aws lambda list-layer-versions --region $REGION --layer-name $LAYER_NAME --query 'LayerVersions[0].Version || `0`')
VERSION=$(($latest_version + 1))
else
# Running on prod
if [ -z "$CI_COMMIT_TAG" ]; then
printf "[ERROR]: No CI_COMMIT_TAG found.\n"
printf "Exiting script...\n"
exit 1
else
printf "Tag found in environment: $CI_COMMIT_TAG\n"
fi

VERSION="${CI_COMMIT_TAG//[!0-9]/}"
printf "Version: ${VERSION}\n"
fi

if [ -z "$VERSION" ]; then
printf "[ERROR]: Layer VERSION not specified"
exit 1
else
printf "Layer version parsed: $VERSION\n"
fi

latest_version=$(aws lambda list-layer-versions --region $REGION --layer-name $LAYER_NAME --query 'LayerVersions[0].Version || `0`')
if [ $latest_version -ge $VERSION ]; then
printf "[$REGION] Layer $LAYER_NAME version $VERSION already exists in region $REGION, skipping...\n"
exit 1
elif [ $latest_version -lt $((VERSION-1)) ]; then
printf "[$REGION][WARNING] The latest version of layer $LAYER_NAME in region $REGION is $latest_version, this will publish all the missing versions including $VERSION\n"
fi

while [ $latest_version -lt $VERSION ]; do
latest_version=$(publish_layer $REGION)
printf "[$REGION] Published version $latest_version of layer $LAYER_NAME in region $REGION\n"

# This shouldn't happen unless someone manually deleted the latest version, say 28, and
# then tries to republish 28 again. The published version would actually be 29, because
# Lambda layers are immutable and AWS will skip deleted version and use the next number.
if [ $latest_version -gt $VERSION ]; then
printf "[$REGION] Published version $latest_version is greater than the desired version $VERSION!"
exit 1
fi
done

printf "[$REGION] Finished publishing layer...\n\n"
23 changes: 23 additions & 0 deletions .gitlab/scripts/pull_and_zip_layers.sh

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible for us to update and use the pull_and_zip_layers.sh from the scripts/ directory? It will be nice to ensure that any local testing we do uses the same publishing methods as our releases.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking specifically publish_layers.sh, pull_and_zip_layers.sh and sign_layers.sh.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These scripts are different and tailored for GitLab, but after these changes we won't need the old scripts anymore -- we can remove them once I get automated releases working properly

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be nice to keep the others, for publishing to sandbox.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

# Unless explicitly stated otherwise all files in this repository are licensed
# under the Apache License Version 2.0.
# This product includes software developed at Datadog (https://www.datadoghq.com/).
# Copyright 2024 Datadog, Inc.

set -e

rm -f dd-java-agent.jar
wget -O dd-java-agent.jar https://dtdg.co/latest-java-tracer

rm -rf .layers
mkdir .layers

rm -rf layer-temp
mkdir -p layer-temp/java/lib

cp dd-java-agent.jar layer-temp/java/lib/dd-java-agent.jar
cd layer-temp
zip -r ../.layers/tracer.zip java
cd ..
rm -rf layer-temp
Loading
Loading