Created
August 6, 2020 00:57
-
-
Save dazza-codes/409c0ae953c83d50e5a5c42a68bbf8b4 to your computer and use it in GitHub Desktop.
Create or update an AWS lambda layer from zip files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Copyright 2020 Darren Weber | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"). You may not | |
| # use this file except in compliance with the License. A copy of the License is | |
| # located at | |
| # | |
| # http://aws.amazon.com/apache2.0/ | |
| # | |
| # or in the "license" file accompanying this file. This file is distributed on | |
| # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | |
| # or implied. See the License for the specific language governing permissions | |
| # and limitations under the License. | |
| SCRIPT_PATH=$(dirname "$0") | |
| SCRIPT_PATH=$(readlink -f "$SCRIPT_PATH") | |
| PY_VERSION=$(python --version | grep -o -E '[0-9]+[.][0-9]+') | |
| LAMBDA_REGION=${AWS_DEFAULT_REGION:-'us-west-2'} | |
| LAMBDA_ACCOUNT=${AWS_ACCOUNT} | |
| LAMBDA_BUCKET=${LAMBDA_BUCKET:-'serverless-deploys'} | |
| S3_PREFIX=${S3_PREFIX:-'lambda-layers'} | |
| S3_ROOT=s3://${LAMBDA_BUCKET}/${S3_PREFIX} | |
| crash () { | |
| echo "OOPS - something went wrong!" | |
| exit 1 | |
| } | |
| create_or_update_layer () { | |
| zip_file=$1 | |
| file_name=$(basename "$f") | |
| layer_name=$(echo "${file_name}" | sed -e 's/.zip//' -e 's/\./-/g') | |
| layer_arn="arn:aws:lambda:${LAMBDA_REGION}:${LAMBDA_ACCOUNT}:layer:${layer_name}" | |
| echo | |
| printf "CHECK LAYER VERSIONS %-40s -> %s\n" "${file_name}" "${layer_arn}" | |
| # To be smarter at detecting whether an update is required or not | |
| # - check some sha256 hashes and the zip archive file size | |
| # - see also https://stackoverflow.com/questions/9714139/why-does-zipping-the-same-content-twice-gives-two-files-with-different-sha1 | |
| # - use the right options on zip to get the same archive for the same content | |
| ver_json='/tmp/layer_versions.json' | |
| rm -f "${ver_json}" | |
| aws lambda list-layer-versions \ | |
| --layer-name "${layer_arn}" \ | |
| --compatible-runtime "python${PY_VERSION}" \ | |
| --no-paginate --output json > "${ver_json}" | |
| if [ -f "${ver_json}" ] && [ -s "${ver_json}" ]; then | |
| layer_ver_arn=$(jq '.LayerVersions | sort_by(.Version)[].LayerVersionArn' "${ver_json}" | tail -n1 | sed 's/"//g') | |
| if [ "${layer_ver_arn}" != "" ]; then | |
| printf "LATEST LAYER VERSION %-40s -> %s\n" "${file_name}" "${layer_ver_arn}" | |
| aws lambda get-layer-version-by-arn --arn "${layer_ver_arn}" > "${ver_json}" | |
| layer_hash=$(jq '.Content.CodeSha256' "${ver_json}" | tail -n1 | sed 's/"//g') | |
| layer_size=$(jq '.Content.CodeSize' "${ver_json}" | tail -n1 | sed 's/"//g') | |
| # https://stackoverflow.com/questions/33825815/how-to-calculate-the-codesha256-of-aws-lambda-deployment-package-before-uploadin | |
| zip_size=$(stat --format '%s' "${zip_file}") | |
| zip_hash=$(openssl dgst -sha256 -binary "${zip_file}" | openssl enc -base64) | |
| echo -e "lambda size: ${layer_size}" | |
| echo -e "zip file size: ${zip_size}" | |
| echo -e "lambda sha256: ${layer_hash}" | |
| echo -e "zip file sha256: ${zip_hash}" | |
| [ "${zip_size}" == "${layer_size}" ] \ | |
| && [ "${zip_hash}" == "${layer_hash}" ] \ | |
| && echo -e "SKIP layer publication\n\n" \ | |
| && return | |
| else | |
| echo "There is no lambda layer published" | |
| fi | |
| else | |
| echo "There is no lambda layer published" | |
| fi | |
| echo | |
| printf "CREATE or UPDATE LAYER %-40s -> %s\n" "${file_name}" "${layer_arn}" | |
| aws s3 ls "${S3_ROOT}/${file_name}" > /dev/null || crash | |
| # shellcheck disable=SC2140 | |
| aws lambda publish-layer-version \ | |
| --region "${LAMBDA_REGION}" \ | |
| --layer-name "${layer_arn}" \ | |
| --description "${layer_name}" \ | |
| --license-info "PRIVATE" \ | |
| --content S3Bucket="${LAMBDA_BUCKET}",S3Key="${S3_PREFIX}/${file_name}" \ | |
| --compatible-runtimes "python${PY_VERSION}" | |
| echo | |
| } | |
| if ! command -v jq > /dev/null; then | |
| curl -o jq-linux64 -sSL https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 \ | |
| && mv jq-linux64 ${HOME}/bin/jq \ | |
| && chmod a+x ${HOME}/bin/jq \ | |
| && jq --version | |
| fi | |
| aws s3 sync "${SCRIPT_PATH}" "${S3_ROOT}"/ --exclude '*' --include '*.zip' | |
| for f in "${SCRIPT_PATH}"/*.zip; do | |
| zip_file=$(basename "$f") | |
| create_or_update_layer "${zip_file}" | |
| done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment