Skip to content
Merged
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
4 changes: 2 additions & 2 deletions ci/datasources/environments.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
environments:
- name: sandbox
sandbox:
external_id: sandbox-publish-externalid
role_to_assume: sandbox-layer-deployer
account: 425362996713
- name: prod
prod:
external_id: prod-publish-externalid
role_to_assume: dd-serverless-layer-deployer-role
account: 464622532012
66 changes: 56 additions & 10 deletions ci/input_files/build.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,6 @@ integration-test ({{ $runtime.name }}-{{ $runtime.arch }}):
script:
- RUNTIME_PARAM={{ $runtime.python_version }} ARCH={{ $runtime.arch }} ./scripts/run_integration_tests.sh

{{ range $environment := (ds "environments").environments }}

{{ if or (eq $environment.name "prod") }}
sign-layer ({{ $runtime.name }}-{{ $runtime.arch }}):
stage: sign
tags: ["arch:amd64"]
Expand All @@ -128,22 +125,25 @@ sign-layer ({{ $runtime.name }}-{{ $runtime.arch }}):
before_script:
- apt-get update
- apt-get install -y uuid-runtime
{{ with $environment := (ds "environments").environments.prod }}
- EXTERNAL_ID_NAME={{ $environment.external_id }} ROLE_TO_ASSUME={{ $environment.role_to_assume }} AWS_ACCOUNT={{ $environment.account }} source ./ci/get_secrets.sh
{{ end }}
script:
- LAYER_FILE=datadog_lambda_py-{{ $runtime.arch}}-{{ $runtime.python_version }}.zip ./scripts/sign_layers.sh {{ $environment.name }}
{{ end }}
- LAYER_FILE=datadog_lambda_py-{{ $runtime.arch}}-{{ $runtime.python_version }}.zip ./scripts/sign_layers.sh prod

{{ range $environment_name, $environment := (ds "environments").environments }}

publish-layer-{{ $environment.name }} ({{ $runtime.name }}-{{ $runtime.arch }}):
publish-layer-{{ $environment_name }} ({{ $runtime.name }}-{{ $runtime.arch }}):
stage: publish
tags: ["arch:amd64"]
image: registry.ddbuild.io/images/docker:20.10-py3
rules:
- if: '"{{ $environment.name }}" =~ /^(sandbox|staging)/'
- if: '"{{ $environment_name }}" == "sandbox"'
when: manual
allow_failure: true
- if: '$CI_COMMIT_TAG =~ /^v.*/'
needs:
{{ if or (eq $environment.name "prod") }}
{{ if or (eq $environment_name "prod") }}
- sign-layer ({{ $runtime.name }}-{{ $runtime.arch}})
{{ else }}
- build-layer ({{ $runtime.name }}-{{ $runtime.arch }})
Expand All @@ -153,7 +153,7 @@ publish-layer-{{ $environment.name }} ({{ $runtime.name }}-{{ $runtime.arch }}):
- integration-test ({{ $runtime.name }}-{{ $runtime.arch }})
{{ end }}
dependencies:
{{ if or (eq $environment.name "prod") }}
{{ if or (eq $environment_name "prod") }}
- sign-layer ({{ $runtime.name }}-{{ $runtime.arch}})
{{ else }}
- build-layer ({{ $runtime.name }}-{{ $runtime.arch }})
Expand All @@ -166,7 +166,7 @@ publish-layer-{{ $environment.name }} ({{ $runtime.name }}-{{ $runtime.arch }}):
before_script:
- EXTERNAL_ID_NAME={{ $environment.external_id }} ROLE_TO_ASSUME={{ $environment.role_to_assume }} AWS_ACCOUNT={{ $environment.account }} source ./ci/get_secrets.sh
script:
- STAGE={{ $environment.name }} PYTHON_VERSION={{ $runtime.python_version }} ARCH={{ $runtime.arch }} ./ci/publish_layers.sh
- STAGE={{ $environment_name }} PYTHON_VERSION={{ $runtime.python_version }} ARCH={{ $runtime.arch }} ./ci/publish_layers.sh

{{- end }}

Expand All @@ -186,3 +186,49 @@ publish-pypi-package:
{{- end }}
script:
- ./ci/publish_pypi.sh

layer bundle:
stage: build
tags: ["arch:amd64"]
image: registry.ddbuild.io/images/docker:20.10
needs:
{{ range (ds "runtimes").runtimes }}
- build-layer ({{ .name }}-{{ .arch }})
{{ end }}
dependencies:
{{ range (ds "runtimes").runtimes }}
- build-layer ({{ .name }}-{{ .arch }})
{{ end }}
artifacts:
expire_in: 1 hr
paths:
- datadog_lambda_py-bundle-${CI_JOB_ID}/
name: datadog_lambda_py-bundle-${CI_JOB_ID}
script:
- rm -rf datadog_lambda_py-bundle-${CI_JOB_ID}
- mkdir -p datadog_lambda_py-bundle-${CI_JOB_ID}
- cp .layers/datadog_lambda_py-*.zip datadog_lambda_py-bundle-${CI_JOB_ID}

signed layer bundle:
stage: sign
image: registry.ddbuild.io/images/docker:20.10-py3
tags: ["arch:amd64"]
rules:
- if: '$CI_COMMIT_TAG =~ /^v.*/'
needs:
{{ range (ds "runtimes").runtimes }}
- sign-layer ({{ .name }}-{{ .arch }})
{{ end }}
dependencies:
{{ range (ds "runtimes").runtimes }}
- sign-layer ({{ .name }}-{{ .arch }})
{{ end }}
artifacts:
expire_in: 1 day
paths:
- datadog_lambda_py-signed-bundle-${CI_JOB_ID}/
name: datadog_lambda_py-signed-bundle-${CI_JOB_ID}
script:
- rm -rf datadog_lambda_py-signed-bundle-${CI_JOB_ID}
- mkdir -p datadog_lambda_py-signed-bundle-${CI_JOB_ID}
- cp .layers/datadog_lambda_py-*.zip datadog_lambda_py-signed-bundle-${CI_JOB_ID}
36 changes: 30 additions & 6 deletions ci/publish_layers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,20 @@ AWS_CLI_PYTHON_VERSIONS=(
"python3.13"
"python3.13"
)
PYTHON_VERSIONS=("3.8-amd64" "3.8-arm64" "3.9-amd64" "3.9-arm64" "3.10-amd64" "3.10-arm64" "3.11-amd64" "3.11-arm64" "3.12-amd64" "3.12-arm64" "3.13-amd64" "3.13-arm64")
PYTHON_VERSIONS=(
"3.8-amd64"
"3.8-arm64"
"3.9-amd64"
"3.9-arm64"
"3.10-amd64"
"3.10-arm64"
"3.11-amd64"
"3.11-arm64"
"3.12-amd64"
"3.12-arm64"
"3.13-amd64"
"3.13-arm64"
)
LAYER_PATHS=(
".layers/datadog_lambda_py-amd64-3.8.zip"
".layers/datadog_lambda_py-arm64-3.8.zip"
Expand Down Expand Up @@ -53,11 +66,16 @@ LAYERS=(
"Datadog-Python313"
"Datadog-Python313-ARM"
)
STAGES=('prod', 'sandbox', 'staging')
STAGES=('prod', 'sandbox', 'staging', 'gov-staging', 'gov-prod')

printf "Starting script...\n\n"
printf "Installing dependencies\n"
pip install awscli

if [ -z "$SKIP_PIP_INSTALL" ]; then
echo "Installing dependencies"
pip install awscli
else
echo "Skipping pip install"
fi

publish_layer() {
region=$1
Expand Down Expand Up @@ -89,7 +107,7 @@ fi

printf "Python version specified: $PYTHON_VERSION\n"
if [[ ! ${PYTHON_VERSIONS[@]} =~ $PYTHON_VERSION ]]; then
printf "[Error] Unsupported PYTHON_VERSION found.\n"
printf "[Error] Unsupported PYTHON_VERSION found: $PYTHON_VERSION.\n"
exit 1
fi

Expand Down Expand Up @@ -133,8 +151,14 @@ if [[ ! ${STAGES[@]} =~ $STAGE ]]; then
fi

layer="${LAYERS[$index]}"
if [ -z "$LAYER_NAME_SUFFIX" ]; then
echo "No layer name suffix"
else
layer="${layer}-${LAYER_NAME_SUFFIX}"
fi
echo "layer name: $layer"

if [[ "$STAGE" =~ ^(staging|sandbox)$ ]]; then
if [[ "$STAGE" =~ ^(staging|sandbox|gov-staging)$ ]]; then
# Deploy latest version
latest_version=$(aws lambda list-layer-versions --region $REGION --layer-name $layer --query 'LayerVersions[0].Version || `0`')
VERSION=$(($latest_version + 1))
Expand Down
105 changes: 105 additions & 0 deletions scripts/publish_govcloud.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#! /usr/bin/env 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 2025 Datadog, Inc.
#
# USAGE: download the layer bundle from the build pipeline in gitlab. Use the
# Download button on the `layer bundle` job. This will be a zip file containing
# all of the required layers. Run this script as follows:
#
# ENVIRONMENT=[us1-staging-fed or us1-fed] [LAYER_NAME_SUFFIX=optional-layer-suffix] [REGIONS=us-gov-west-1] ./scripts/publish_govcloud.sh <layer-bundle.zip>
#
# protip: you can drag the zip file from finder into your terminal to insert
# its path.

set -e

LAYER_PACKAGE=$1

if [ -z "$LAYER_PACKAGE" ]; then
printf "[ERROR]: layer package not provided\n"
exit 1
fi

PACKAGE_NAME=$(basename "$LAYER_PACKAGE" .zip)

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

if [ "$ENVIRONMENT" = "us1-staging-fed" ]; then
AWS_VAULT_ROLE=sso-govcloud-us1-staging-fed-power-user

export STAGE=gov-staging

if [[ ! "$PACKAGE_NAME" =~ ^datadog_lambda_py-(signed-)?bundle-[0-9]+$ ]]; then
echo "[ERROR]: Unexpected package name: $PACKAGE_NAME"
exit 1
fi

elif [ $ENVIRONMENT = "us1-fed" ]; then
AWS_VAULT_ROLE=sso-govcloud-us1-fed-engineering

export STAGE=gov-prod

if [[ ! "$PACKAGE_NAME" =~ ^datadog_lambda_py-signed-bundle-[0-9]+$ ]]; then
echo "[ERROR]: Unexpected package name: $PACKAGE_NAME"
exit 1
fi

else
printf "[ERROR]: ENVIRONMENT not supported, must be us1-staging-fed or us1-fed.\n"
exit 1
fi

TEMP_DIR=$(mktemp -d)
unzip $LAYER_PACKAGE -d $TEMP_DIR
cp -v $TEMP_DIR/$PACKAGE_NAME/*.zip .layers/


AWS_VAULT_PREFIX="aws-vault exec $AWS_VAULT_ROLE --"

echo "Checking that you have access to the GovCloud AWS account"
$AWS_VAULT_PREFIX aws sts get-caller-identity


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

# Determine the target regions
if [ -z "$REGIONS" ]; then
echo "Region not specified, running for all available regions."
REGIONS=$AVAILABLE_REGIONS
else
echo "Region specified: $REGIONS"
if [[ ! "$AVAILABLE_REGIONS" == *"$REGIONS"* ]]; then
echo "Could not find $REGIONS in available regions: $AVAILABLE_REGIONS"
echo ""
echo "EXITING SCRIPT."
exit 1
fi
fi

for region in $REGIONS
do
echo "Starting publishing layers for region $region..."

export REGION=$region

for python_version in "3.8" "3.9" "3.10" "3.11" "3.12" "3.13"; do
for arch in "amd64" "arm64"; do
export PYTHON_VERSION=$python_version
export ARCH=$arch

export SKIP_PIP_INSTALL=true

echo "Publishing layer for $PYTHON_VERSION and $ARCH"

$AWS_VAULT_PREFIX ./ci/publish_layers.sh
done
done
done

echo "Done !"
Loading
Loading