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

feat: Automate Layer Releases with R2R artifacts #6

Merged
merged 67 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
c334483
add `.gitlab-ci.yml`
duncanista Sep 3, 2024
69fc509
modify pipeline
duncanista Sep 3, 2024
fe89e36
add runner
duncanista Sep 3, 2024
fc255ba
update pipeline with `artifacts: true`
duncanista Sep 3, 2024
34b4bf8
comment out to test upstream pipeline id
duncanista Sep 3, 2024
8de6b7b
add `needs:project` instead of `needs:pipeline`
duncanista Sep 3, 2024
e32f320
see if we can download artifacts manually
duncanista Sep 3, 2024
147ee0d
typo
duncanista Sep 3, 2024
d681415
use `serverless-tools` ci image
duncanista Sep 3, 2024
b7549e9
unzip and log binaries
duncanista Sep 3, 2024
dfd920a
typo
duncanista Sep 3, 2024
6df5d5b
improve script
duncanista Sep 3, 2024
d39eb5c
add `Dockerfile.r2r`
duncanista Sep 3, 2024
270892d
update `build` script to account for `r2r`
duncanista Sep 3, 2024
8fd8a54
update pipeline
duncanista Sep 3, 2024
b479efb
typo
duncanista Sep 3, 2024
89fd4af
remove force
duncanista Sep 3, 2024
6c61391
change variable name
duncanista Sep 3, 2024
97894c6
add casing
duncanista Sep 3, 2024
2a26c19
update how path is calculated
duncanista Sep 3, 2024
5131965
modify how artifacts are copied into datadog
duncanista Sep 3, 2024
868117d
forgot to create directory
duncanista Sep 3, 2024
7493949
try again
duncanista Sep 3, 2024
516058b
remove `linux-`
duncanista Sep 3, 2024
1d62aba
add tons of scripts
duncanista Sep 4, 2024
4a124b2
add `datasources`
duncanista Sep 4, 2024
828af82
add template and configuration
duncanista Sep 4, 2024
0cdef12
update pipeline
duncanista Sep 4, 2024
b368d59
update pipeline and rules
duncanista Sep 4, 2024
ab2b568
add needs for `build`
duncanista Sep 4, 2024
0245330
update rules
duncanista Sep 4, 2024
10656f4
update pipeline path
duncanista Sep 4, 2024
76b139d
use same image for publish
duncanista Sep 4, 2024
f895338
update secret key
duncanista Sep 4, 2024
eedb5f7
add gitlab runner image
duncanista Sep 4, 2024
5ccd03d
comment out so we can build runners image
duncanista Sep 4, 2024
9160446
replace job images with internal
duncanista Sep 4, 2024
f03955d
add compatible runtimes
duncanista Sep 4, 2024
76089ab
typo
duncanista Sep 4, 2024
720ba84
change the runners image to be the correct one
duncanista Sep 4, 2024
c672101
see if this fixes compatible runtimes list
duncanista Sep 4, 2024
a09c839
allow artifacts script to use `TRACER_BRANCH`
duncanista Sep 4, 2024
e289043
remove default `TRACER_BRANCH`
duncanista Sep 4, 2024
f5d169b
add debugging for artifacts script
duncanista Sep 4, 2024
4fe491c
add a placeholder value, or else the `TRACER_BRANCH` doesnt get passed
duncanista Sep 4, 2024
1127ec8
update placeholder removal again
duncanista Sep 4, 2024
6ca6c1c
maybe pass `.env`?
duncanista Sep 4, 2024
fbf8fbd
test how variables come as
duncanista Sep 4, 2024
6708479
try different approach
duncanista Sep 4, 2024
ccfa1d9
set placeholder value again
duncanista Sep 4, 2024
b836614
yaap
duncanista Sep 4, 2024
ad84d89
clean `LAYER_SUFFIX` if not set from incoming pipeline
duncanista Sep 4, 2024
cd2d430
make it production ready with repo tags
duncanista Sep 4, 2024
aa58856
use correct building script
duncanista Sep 4, 2024
7d59b7c
use correct root directory
duncanista Sep 4, 2024
724247f
see if this works for `TRACER_VERSION`
duncanista Sep 4, 2024
0fe19db
propagate `.env`
duncanista Sep 4, 2024
3fed352
see if this fixes propagation
duncanista Sep 4, 2024
182a4c9
add debugging
duncanista Sep 4, 2024
7dbb567
remove default value for tracer version
duncanista Sep 4, 2024
d088ab4
remove testing job
duncanista Sep 4, 2024
7c78c85
change `prod` to `sandbox` in signing
duncanista Sep 4, 2024
e635203
remove prod datasources to not mess it up during testing
duncanista Sep 4, 2024
089112d
rollback to make it production ready
duncanista Sep 4, 2024
9ca472d
remove R2R from manual script
duncanista Sep 4, 2024
4242f72
remove unused action
duncanista Sep 4, 2024
7933fb5
add some comment docs on decisions made for native binaries
duncanista Sep 6, 2024
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
32 changes: 0 additions & 32 deletions .github/workflows/build-lambda-layers.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.layers
.DS_Store
Datadog.Trace.dll

.gitlab/build-pipeline.yaml
85 changes: 85 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
variables:
DOCKER_TARGET_IMAGE: registry.ddbuild.io/ci/dd-trace-dotnet-aws-lambda-layer
DOCKER_TARGET_VERSION: latest
# Default version for development builds
# This will be overwritten by the tag version if it is a release.
VERSION: dev
# Manual trigger variables
TRACER_BRANCH:
description: "Branch of the dd-trace-dotnet repository to use (default empty)."
value: ""
TRACER_VERSION:
description: "Latest release version of the dd-trace-dotnet to tag the build with (default empty)."
value: ""
LAYER_SUFFIX:
description: "Suffix to be appended to the layer name (default empty)."
value: ""

stages:
- pre
- build

.go-cache: &go-cache
key: dd-trace-dotnet-aws-lambda-layer-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
# These variables are used to trigger the build job manually, when the pipeline is triggered by an external source
# these are not set, so we reset them to a placeholder.
- if [ -z "$TRACER_BRANCH" ] || [ "$TRACER_BRANCH" = "placeholder" ]; then echo "TRACER_BRANCH=placeholder" >> .env; fi
- if [ -z "$TRACER_VERSION" ] || [ "$TRACER_VERSION" = "placeholder" ]; then echo "TRACER_VERSION=placeholder" >> .env; fi
- if [ -z "$UPSTREAM_PIPELINE_ID" ] || [ "$UPSTREAM_PIPELINE_ID" = "placeholder" ]; then echo "UPSTREAM_PIPELINE_ID=placeholder" >> .env; fi
- if [ -z "$LAYER_SUFFIX" ] || [ "$LAYER_SUFFIX" = "placeholder" ]; then echo "LAYER_SUFFIX=placeholder" >> .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:
UPSTREAM_PIPELINE_ID: $UPSTREAM_PIPELINE_ID
VERSION: $VERSION
TRACER_BRANCH: $TRACER_BRANCH
LAYER_SUFFIX: $LAYER_SUFFIX
TRACER_VERSION: $TRACER_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 --fix-missing --no-install-recommends \
curl gcc gnupg g++ make cmake unzip openssl g++ uuid-runtime

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

inputFiles:
- .gitlab/template.yaml.tpl

outputFiles:
- .gitlab/build-pipeline.yaml

datasources:
architectures:
url: .gitlab/datasources/architectures.yaml

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

regions:
url: .gitlab/datasources/regions.yaml
3 changes: 3 additions & 0 deletions .gitlab/datasources/architectures.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
architectures:
- name: amd64
- name: arm64
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
30 changes: 30 additions & 0 deletions .gitlab/datasources/regions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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-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"
67 changes: 67 additions & 0 deletions .gitlab/scripts/build_layer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/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 2021 Datadog, Inc.

# Usage examples :
# TRACER_VERSION=xxx ARCH=arm64 ./scripts/build_layer.sh
# ARCH is optional. Default is to build both arm and amd64 layers.

set -e

if [ "$TRACER_VERSION" = "placeholder" ]; then
TRACER_VERSION=""
fi

if [ -z "$TRACER_VERSION" ]; then
# Running on dev
echo "Running on dev environment"
TRACER_VERSION="dev"
else
echo "Found version tag in environment variables"
echo "Tracer version: ${TRACER_VERSION}"
fi

# Move into the root directory, so this script can be called from any directory
SCRIPTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
ROOT_DIR=$SCRIPTS_DIR/../..
cd $ROOT_DIR

LAYER_DIR=".layers"
TARGET_DIR=$(pwd)/$LAYER_DIR
DOCKERFILE="./scripts/Dockerfile.r2r"

# Build the image
function docker_build_zip {
arch=$1

tmp_dir=$(mktemp -d)
docker buildx build -t datadog/dd_trace_dotnet:$TRACER_VERSION . \
-f $DOCKERFILE \
--no-cache \
--platform linux/${arch} \
--build-arg TRACER_VERSION="${TRACER_VERSION}" \
--build-arg ARCH=${arch} \
-o $tmp_dir/datadog

cp $tmp_dir/datadog/dd_trace_dotnet.zip $TARGET_DIR/dd_trace_dotnet_${arch}.zip
unzip $tmp_dir/datadog/dd_trace_dotnet.zip -d $TARGET_DIR/dd_trace_dotnet_${arch}

rm -rf $tmp_dir
}

# Clean and make directories in ./layers
function clean_layer_directory {
arch=$1

rm -rf $LAYER_DIR/dd_trace_dotnet_${arch} 2>/dev/null
mkdir -p $LAYER_DIR/dd_trace_dotnet_${arch}
}

echo "Building layers for ${ARCH}"
clean_layer_directory $ARCH
docker_build_zip $ARCH

echo "Finished building layers for ${ARCH}"
82 changes: 82 additions & 0 deletions .gitlab/scripts/download_tracer_artifacts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/bin/bash

set -e

GITLAB_TOKEN=$(aws ssm get-parameter \
--region us-east-1 \
--name "ci.$CI_PROJECT_NAME.serverless-gitlab-token" \
--with-decryption \
--query "Parameter.Value" \
--out text)

TRACER_PROJECT_ID=348

# Clean environment variables if they are set as 'placeholder'

Choose a reason for hiding this comment

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

it would be great to wrap some of this code in functions for maintainability!

if [ "$UPSTREAM_PIPELINE_ID" = "placeholder" ]; then
UPSTREAM_PIPELINE_ID=""
fi

if [ "$TRACER_BRANCH" = "placeholder" ]; then
TRACER_BRANCH=""
fi

echo "Running with the following configuration:"
echo "UPSTREAM_PIPELINE_ID: $UPSTREAM_PIPELINE_ID"
echo "TRACER_BRANCH: $TRACER_BRANCH"

# If 'UPSTREAM_PIPELINE_ID' or 'TRACER_BRANCH' are not set, exit
if [ -z "$UPSTREAM_PIPELINE_ID" ] && [ -z "$TRACER_BRANCH" ]; then
echo "None of UPSTREAM_PIPELINE_ID or TRACER_BRANCH is set. Exiting..."
exit 1
fi

# If 'UPSTREAM_PIPELINE_ID' is not set, calculate the latest based on the 'TRACER_BRANCH' or,
# if 'TRACER_BRANCH' is set, prioritize it over 'UPSTREAM_PIPELINE_ID' even if it's set
#
# This might happen when doing a manual trigger of the pipeline, normally done for Production deployments with tags.
if [ -z "$UPSTREAM_PIPELINE_ID" ] || [ -n "$TRACER_BRANCH" ]; then
echo "UPSTREAM_PIPELINE_ID is not set, or TRACER_BRANCH is set. Calculating the latest pipeline ID..."

URL="$CI_API_V4_URL/projects/$TRACER_PROJECT_ID/pipelines?ref=$TRACER_BRANCH&per_page=1&order_by=id&sort=desc"
echo "Getting pipelines for '$TRACER_BRANCH' from: $URL"
PIPELINES=$(curl $URL --header "PRIVATE-TOKEN: $GITLAB_TOKEN")

# Get the latest pipeline ID
UPSTREAM_PIPELINE_ID=$(echo "${PIPELINES}" | jq -r '.[0] | @base64' | base64 --decode | jq -r '.id')
fi

echo "UPSTREAM_PIPELINE_ID: $UPSTREAM_PIPELINE_ID"

# Get the jobs of the upstream pipeline
URL="$CI_API_V4_URL/projects/$TRACER_PROJECT_ID/pipelines/$UPSTREAM_PIPELINE_ID/jobs"
echo "Looking for the artifacts job 'download-serverless-artifacts' for pipeline ID '$UPSTREAM_PIPELINE_ID' in '$URL'"
PIPELINE_JOBS=$(curl $URL --header "PRIVATE-TOKEN: $GITLAB_TOKEN")

FOUND_ARTIFACTS_JOB=false
# Iterate over pipeline trigger jobs
for pipeline_job in $(echo "${PIPELINE_JOBS}" | jq -r '.[] | @base64'); do
# Only check the 'download-serverless-artifacts' job
pipeline_job_name=$(echo "${pipeline_job}" | base64 --decode | jq -r '.name')
if [ "${pipeline_job_name}" = "download-serverless-artifacts" ]; then
FOUND_ARTIFACTS_JOB=true
pipeline_job_id=$(echo ${pipeline_job} | base64 --decode | jq -r '.id')

ARTIFACTS_URL="$CI_API_V4_URL/projects/348/jobs/$pipeline_job_id/artifacts"
echo "Downloading artifacts from: $ARTIFACTS_URL"
ARTIFACTS=$(curl $ARTIFACTS_URL --header "PRIVATE-TOKEN: $GITLAB_TOKEN" --location --output artifacts.zip)
fi
done

if [ "$FOUND_ARTIFACTS_JOB" = false ]; then
echo "No artifacts job found in the pipeline. Exiting..."
exit 1
fi

target_dir=artifacts

mkdir -p $target_dir
unzip artifacts.zip -d $target_dir
mv $target_dir/artifacts/* $target_dir
rmdir $target_dir/artifacts

ls -R $target_dir
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.dd-trace-dotnet-aws-lambda-layer.$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.dd-trace-dotnet-aws-lambda-layer.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.dd-trace-dotnet-aws-lambda-layer-$CI_JOB_ID-$CI_JOB_STAGE" \
--query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \
--external-id $EXTERNAL_ID \
--output text))
Loading