Skip to content
This repository has been archived by the owner on Jun 26, 2023. It is now read-only.

Commit

Permalink
Add code to deploy AWS Lambda with Buildkite plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
denmat committed Nov 26, 2018
0 parents commit e83fc55
Show file tree
Hide file tree
Showing 8 changed files with 398 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
steps:
- label: "🤡 :hammer:"
plugins:
docker-compose#v2.5.1:
run: tests
- label: ":sparkles: lint"
plugins:
plugin-linter#v2.0.0:
id: artifacts
- label: ":shell: Shellcheck"
plugins:
shellcheck#v1.1.1:
files: hooks/**
40 changes: 40 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
FROM bats/bats:latest@sha256:97d91ee0aa9771e696cdf44c2b1672af484fd846eaf52ba2db6061f5c78a89d5

ENV LIBS_BATS_MOCK_VERSION="1.1.0" \
LIBS_BATS_SUPPORT_VERSION="0.3.0"

RUN apk --no-cache add ncurses curl

# Install bats-support
RUN mkdir -p /usr/local/lib/bats/bats-support \
&& curl -sSL https://github.com/ztombol/bats-support/archive/v0.3.0.tar.gz -o /tmp/bats-support.tgz \
&& tar -zxf /tmp/bats-support.tgz -C /usr/local/lib/bats/bats-support --strip 1 \
&& printf 'source "%s"\n' "/usr/local/lib/bats/bats-support/load.bash" >> /usr/local/lib/bats/load.bash \
&& rm -rf /tmp/bats-support.tgz

# Install bats-assert
RUN mkdir -p /usr/local/lib/bats/bats-assert \
&& curl -sSL https://github.com/ztombol/bats-assert/archive/v0.3.0.tar.gz -o /tmp/bats-assert.tgz \
&& tar -zxf /tmp/bats-assert.tgz -C /usr/local/lib/bats/bats-assert --strip 1 \
&& printf 'source "%s"\n' "/usr/local/lib/bats/bats-assert/load.bash" >> /usr/local/lib/bats/load.bash \
&& rm -rf /tmp/bats-assert.tgz

# Install lox's fork of bats-mock
RUN mkdir -p /usr/local/lib/bats/bats-mock \
&& curl -sSL https://github.com/lox/bats-mock/archive/master.tar.gz -o /tmp/bats-mock.tgz \
&& tar -zxf /tmp/bats-mock.tgz -C /usr/local/lib/bats/bats-mock --strip 1 \
&& printf 'source "%s"\n' "/usr/local/lib/bats/bats-mock/stub.bash" >> /usr/local/lib/bats/load.bash \
&& rm -rf /tmp/bats-mock.tgz

# Make sure /bin/bash is available, as bats/bats only has it at
# /usr/local/bin/bash and many plugin hooks (and shellscripts in general) use
# `#!/bin/bash` as their shebang
RUN if [[ -e /bin/bash ]]; then echo "/bin/bash already exists"; exit 1; else ln -s /usr/local/bin/bash /bin/bash; fi

# Expose BATS_PATH so people can easily use load.bash
ENV BATS_PATH=/usr/local/lib/bats

WORKDIR /plugin

ENTRYPOINT []
CMD ["bats", "tests/"]
22 changes: 22 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
The MIT License (MIT)

Copyright (c) 2017 Buildkite

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Lambda Deploy Buildkite Plugin

A [Buildkite plugin](https://buildkite.com/docs/agent/v3/plugins) for deploying AWS Lambda function code.

## Deploying Lambda Function Code

```yml
steps:
- plugins:
envato/lambda-deploy#v1.0.0:
function_name: myfunction
zip_file: deploy-version.zip
path: path/to/deploy/code
s3_bucket: deploybucket
s3_key: deploy/key/name
```
## Configuration
### `function_name` (required)

The name of the AWS Lambda function you wish to update

### `zip_file` (required)

The name of the zip file. If the zip file exists we deploy the file directly to AWS Lambda (via `aws lambda update-function-code --zip-file`).
If the file does not exist we use the `path` to create the zip file. If `s3_bucket` and `s3_key` are declared we will first push the file to S3.

### `path` (optional)

If the `path` is specified with the `zip_file` then the `path` is added to the `zip_file`. If no path is given then we default to the value
of `$PWD` which is added to the `zip_file`. If the path is given but the `zip_file` is not present, then the we `cd` into the `path` and
create a `zip` of the contents which is then uploaded.

### `s3_bucket` (optional)

The S3 bucket. The S3 bucket must already be created and have the correct permissions to copy an object to it.

### `s3_key`

The path to store the S3 key

## License

MIT (see [LICENSE](LICENSE))
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: '2'
services:
tests:
build: .
volumes:
- ".:/plugin:rw"
93 changes: 93 additions & 0 deletions hooks/command
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/bin/bash

set -euo pipefail

deploy_command=("aws" "lambda" "update-function-code")
aws_s3_copy_command=("aws" "s3" "cp" "--acl" "private")

BUILDKITE_PLUGIN_LAMBDA_DEPLOY_FUNCTION_NAME=${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_FUNCTION_NAME:-''}
BUILDKITE_PLUGIN_LAMBDA_DEPLOY_ZIP_FILE=${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_ZIP_FILE:-''}
BUILDKITE_PLUGIN_LAMBDA_DEPLOY_PATH=${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_PATH:-''}

if [[ "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_DEBUG:-false}" =~ (true|on|1) ]] ; then
echo "--- :hammer: Enabling debug mode"
set -x
fi

if [[ -n ${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_FUNCTION_NAME} ]] ; then
deploy_command+=("--function-name" "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_FUNCTION_NAME}")
else
echo "🚨: You must supply a function name" >&2
exit 1
fi

if [[ -n "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_ZIP_FILE}" ]] ; then
ZIP_FILE=${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_ZIP_FILE}
else
echo "🚨: You must supply a zip file name" >&2
exit 1
fi

if [[ -n "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_PATH}" ]] ; then
ZIP_PATH="${PWD}/${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_PATH}/"
else
ZIP_PATH="${PWD}/"
fi

DEPLOY_ZIP_FILE="${ZIP_PATH}${ZIP_FILE}"
echo "depf $DEPLOY_ZIP_FILE"
if [[ -n "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_REGION:-us-east-1}" ]] ; then
deploy_command+=("--region" "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_REGION}")
aws_s3_copy_command+=("--region" "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_REGION}")
fi

if [[ -n "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_S3_BUCKET:-}" ]] && [[ -n "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_S3_KEY:-}" ]] ; then
deploy_command+=("--s3-bucket" "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_S3_BUCKET}")
deploy_command+=("--s3-key" "${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_S3_KEY}")
aws_s3_copy_command+=("${DEPLOY_ZIP_FILE}" "s3://${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_S3_BUCKET}/${BUILDKITE_PLUGIN_LAMBDA_DEPLOY_S3_KEY}")
COPY_TO_S3=true
else
echo "S3 bucket or key not provided, copying up zip file direct to lambda"
deploy_command+=("--zip-file" "fileb://${DEPLOY_ZIP_FILE}")
COPY_TO_S3=false
fi

aws_s3_copy() {
${aws_s3_copy_command[@]}
}

aws_lambda_code_update() {
${deploy_command[@]} | jq '.CodeSha256'
}

# zip up paths if provided
make_zip() {
if [[ -e $ZIP_PATH ]] ; then
pushd $ZIP_PATH
zip -r ${DEPLOY_ZIP_FILE} .
popd
else
echo "🚨: Path for zip file not found" >&2
exit 1
fi
}

code_sha256() {
shasum -a 256 $DEPLOY_ZIP_FILE | base64
}

# If deploy zip file exists, don't zip.
[[ -e ${DEPLOY_ZIP_FILE} ]] || make_zip

LOCAL_CHECKSUM=$(code_sha256)

[[ $COPY_TO_S3 ]] && aws_s3_copy

RETURNED_CHECKSUM=$(aws_lambda_code_update)

if [[ $RETURNED_CHECKSUM == $LOCAL_CHECKSUM ]] ; then
echo "Successfully uploaded new function code with SHA ${RETURNED_CHECKSUM}"
else
echo "🚨:Checksum of local zip file ($LOCAL_CHECKSUM) does not match the returned checksum from AWS (${RETURNED_CHECKSUM})"
exit 1
fi
22 changes: 22 additions & 0 deletions plugin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: LambdaDeployer
description: Deploy Lambda Code
author: https://github.com/envato
requirements: []
configuration:
properties:
function_name:
type: string
zip_file:
type: string
path:
type: string
s3_bucket:
type: string
s3_key:
type: string
oneOf:
required:
- function_name
required:
- zip
additionalProperties: false
Loading

0 comments on commit e83fc55

Please sign in to comment.