66# Copyright 2019 Datadog, Inc.
77
88# Publish the datadog python lambda layer across regions, using the AWS CLI
9- # Usage: publish_layer.sh [region] [layer]
10- # Specifying the region and layer arg will publish the specified layer to the specified region
9+ # Usage: VERSION=5 REGIONS=us-east-1 LAYERS=Datadog-Python27 publish_layers.sh
10+ # VERSION is required.
1111set -e
1212
1313# Makes sure any subprocesses will be terminated with this process
1414trap " pkill -P $$ ; exit 1;" INT
1515
1616PYTHON_VERSIONS_FOR_AWS_CLI=(" python2.7" " python3.6" " python3.7" " python3.8" )
1717LAYER_PATHS=(" .layers/datadog_lambda_py2.7.zip" " .layers/datadog_lambda_py3.6.zip" " .layers/datadog_lambda_py3.7.zip" " .layers/datadog_lambda_py3.8.zip" )
18- AVAILABLE_LAYER_NAMES =(" Datadog-Python27" " Datadog-Python36" " Datadog-Python37" " Datadog-Python38" )
18+ AVAILABLE_LAYERS =(" Datadog-Python27" " Datadog-Python36" " Datadog-Python37" " Datadog-Python38" )
1919AVAILABLE_REGIONS=$( aws ec2 describe-regions | jq -r ' .[] | .[] | .RegionName' )
2020
2121# Check that the layer files exist
2727 fi
2828done
2929
30- # Check region arg
31- if [ -z " $1 " ]; then
32- echo " Region parameter not specified, running for all available regions."
30+ # Determine the target regions
31+ if [ -z " $REGIONS " ]; then
32+ echo " Region not specified, running for all available regions."
3333 REGIONS=$AVAILABLE_REGIONS
3434else
35- echo " Region parameter specified: $1 "
36- if [[ ! " $AVAILABLE_REGIONS " == * " $1 " * ]]; then
37- echo " Could not find $1 in available regions: $AVAILABLE_REGIONS "
35+ echo " Region specified: $REGIONS "
36+ if [[ ! " $AVAILABLE_REGIONS " == * " $REGIONS " * ]]; then
37+ echo " Could not find $REGIONS in available regions: $AVAILABLE_REGIONS "
3838 echo " "
3939 echo " EXITING SCRIPT."
4040 exit 1
4141 fi
42- REGIONS=($1 )
4342fi
4443
45- echo " Starting publishing layers for regions: $REGIONS "
46-
47- # Check layer_name arg
48- if [ -z " $2 " ]; then
49- echo " Layer name parameter not specified, running for all layer names."
50- LAYER_NAMES=(" ${AVAILABLE_LAYER_NAMES[@]} " )
44+ # Determine the target layers
45+ if [ -z " $LAYERS " ]; then
46+ echo " Layer not specified, running for all layers."
47+ LAYERS=(" ${AVAILABLE_LAYERS[@]} " )
5148else
52- echo " Layer name parameter specified: $2 "
53- if [[ ! " ${AVAILABLE_LAYER_NAMES [@]} " =~ " ${2 } " ]]; then
54- echo " Could not find $2 in available layer names : ${AVAILABLE_LAYER_NAMES [@]} "
49+ echo " Layer specified: $LAYERS "
50+ if [[ ! " ${AVAILABLE_LAYERS [@]} " =~ " ${LAYERS } " ]]; then
51+ echo " Could not find $LAYERS in available layers : ${AVAILABLE_LAYERS [@]} "
5552 echo " "
5653 echo " EXITING SCRIPT."
5754 exit 1
5855 fi
59- LAYER_NAMES=($2 )
6056fi
6157
58+ # Determine the target layer version
59+ if [ -z " $VERSION " ]; then
60+ echo " Layer version not specified"
61+ echo " "
62+ echo " EXITING SCRIPT."
63+ exit 1
64+ else
65+ echo " Layer version specified: $VERSION "
66+ fi
6267
68+ read -p " Ready to publish version $VERSION of layers ${LAYERS[*]} to regions ${REGIONS[*]} (y/n)?" CONT
69+ if [ " $CONT " != " y" ]; then
70+ echo " Exiting"
71+ exit 1
72+ fi
6373
64-
65- echo " Publishing layers: ${LAYER_NAMES[*]} "
74+ index_of_layer () {
75+ layer_name=$1
76+ for i in " ${! AVAILABLE_LAYERS[@]} " ; do
77+ if [[ " ${AVAILABLE_LAYERS[$i]} " = " ${layer_name} " ]]; then
78+ echo " ${i} " ;
79+ fi
80+ done
81+ }
6682
6783publish_layer () {
6884 region=$1
@@ -76,46 +92,50 @@ publish_layer() {
7692 --compatible-runtimes $aws_version_key \
7793 | jq -r ' .Version' )
7894
79- aws lambda add-layer-version-permission --layer-name $layer_name \
95+ permission= $( aws lambda add-layer-version-permission --layer-name $layer_name \
8096 --version-number $version_nbr \
8197 --statement-id " release-$version_nbr " \
8298 --action lambda:GetLayerVersion --principal " *" \
83- --region $region
99+ --region $region )
84100
85- echo " Published layer for region $region , python version $aws_version_key , layer_name $layer_name , layer_version $version_nbr "
86- }
87-
88- BATCH_SIZE=1
89- PIDS=()
90-
91- wait_for_processes () {
92- for pid in " ${PIDS[@]} " ; do
93- wait $pid
94- done
95- PIDS=()
101+ echo $version_nbr
96102}
97103
98104for region in $REGIONS
99105do
100106 echo " Starting publishing layer for region $region ..."
101-
102107 # Publish the layers for each version of python
103- i=0
104- for layer_name in " ${LAYER_NAMES[@]} " ; do
105- aws_version_key=" ${PYTHON_VERSIONS_FOR_AWS_CLI[$i]} "
106- layer_path=" ${LAYER_PATHS[$i]} "
107-
108- publish_layer $region $layer_name $aws_version_key $layer_path &
109- PIDS+=($! )
110- if [ ${# PIDS[@]} -eq $BATCH_SIZE ]; then
111- wait_for_processes
108+ for layer_name in " ${LAYERS[@]} " ; do
109+ latest_version=$( aws lambda list-layer-versions --region $region --layer-name $layer_name --query ' LayerVersions[0].Version || `0`' )
110+ if [ $latest_version -ge $VERSION ]; then
111+ echo " Layer $layer_name version $VERSION already exists in region $region , skipping..."
112+ continue
113+ elif [ $latest_version -lt $(( VERSION- 1 )) ]; then
114+ read -p " WARNING: The latest version of layer $layer_name in region $region is $latest_version , publish all the missing versions including $VERSION or EXIT the script (y/n)?" CONT
115+ if [ " $CONT " != " y" ]; then
116+ echo " Exiting"
117+ exit 1
118+ fi
112119 fi
113120
114- i=$( expr $i + 1)
115-
121+ index=$( index_of_layer $layer_name )
122+ aws_version_key=" ${PYTHON_VERSIONS_FOR_AWS_CLI[$index]} "
123+ layer_path=" ${LAYER_PATHS[$index]} "
124+
125+ while [ $latest_version -lt $VERSION ]; do
126+ latest_version=$( publish_layer $region $layer_name $aws_version_key $layer_path )
127+ echo " Published version $latest_version for layer $layer_name in region $region "
128+
129+ # This shouldn't happen unless someone manually deleted the latest version, say 28
130+ # and then try to republish it again. The published version is actually be 29, because
131+ # Lambda layers are immutable and AWS will skip deleted version and use the next number.
132+ if [ $latest_version -gt $VERSION ]; then
133+ echo " ERROR: Published version $latest_version is greater than the desired version $VERSION !"
134+ echo " Exiting"
135+ exit 1
136+ fi
137+ done
116138 done
117139done
118140
119- wait_for_processes
120-
121141echo " Done !"
0 commit comments