diff --git a/README.md b/README.md index 4d9e189..d0a80a9 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,17 @@ Load values from Consul and Vault as environment variables. ## Installing -Run `install.sh` in your Docker image. This will copy over _entrypoint.sh_, Consul -template files, and install dependencies needed to run the entrypoint. Then set -your `ENTRYPOINT`. +Download the [latest release](https://github.com/articulate/docker-consul-template-bootstrap/releases/latest), +add it to your image, and set it as your `ENTRYPOINT`. -```docker -ADD https://raw.githubusercontent.com/articulate/docker-consul-template-bootstrap/master/install.sh /tmp/consul_template_install.sh +If you are using Buildkit you can use the `TARGETARCH` arg to `ADD` the correct +architecture. -RUN bash /tmp/consul_template_install.sh && rm /tmp/consul_template_install.sh +```docker +ARG TARGETARCH +ADD --chmod=755 https://github.com/articulate/docker-consul-template-bootstrap/releases/latest/download/docker-consul-template-bootstrap_linux_${TARGETARCH} /entrypoint -ENTRYPOINT [ "/entrypoint.sh" ] +ENTRYPOINT [ "/entrypoint" ] ``` ## Usage @@ -42,58 +43,23 @@ ways: * If running on AWS ECS or Lambda, use the AWS IAM auth method * If Vault role does not match IAM role, set with `VAULT_ROLE` -## Circumventing Docker Caching - -With Docker cache, if you make any changes outside of `install.sh` (e.g. the `ctmpl` -files), you also need to update `install.sh`. Update the `CACHE_VERSION` to the -current datetime. - -## Development Usage - -To test this locally you will need to edit the `docker-compose.override.yml` and -add the following: - -```yaml -environment: - SERVICE_NAME: "your-service" - SERVICE_ENV: "dev|stage|prod|peer" - VAULT_ADDR: "https://myarticulatetest.localtunnel.me" - VAULT_TOKEN: "your-token" -``` +## Development -You can run vault locally with `vault server -dev`. This command will output the -VAULT_TOKEN you need and listen on port 8200. I use [localtunnel](https://localtunnel.me) -to grab a url to use as the VAULT_ADDR. `lt --port 8200 -s myarticulatetest` +You'll need to install the following: -## Test Suite +* Go 1.19 +* [golangci-lint](https://golangci-lint.run/) (`brew install golangci-lint`) +* [pre-commit](https://pre-commit.com/) (`brew install pre-commit`) +* [GoReleaser](https://goreleaser.com/) (_optional_) -The test suite is written in rspec and creates a series of containers (both vault -& consul) and runs a series of tests against those. The module used within rspec -is `https://github.com/zuazo/dockerspec` and uses serverspec behind the scenes. +Setup the build environment with `make init`. Run tests with `make test` and lint +code with `make lint`. -The tests included run through the normal cascade pattern of Global -> Product -> -Service and at the end provides output. These comprehensive tests could take 10 -minutes. +When committing, you'll need to follow the [Conventional Commits](https://www.conventionalcommits.org) +format. You can install a tool like [git-cz](https://github.com/commitizen/cz-cli#conventional-commit-messages-as-a-global-utility) +or [commitizen](https://github.com/commitizen-tools/commitizen#installation). -To kick off the tests: +## Creating a Release -1. Create a branch and push that branch to GitHub. -2. Run something similar to `cp docker-compose.override.example.yml docker-compose.override.yml` - -Then run: - -`docker-compose run app` - -If your changes are not committed and pushed it will not be picked up when the test -images build (rspec pulls in details from the git branch to create the tests). - -There may be a chance that the containers created by the test suite contain cached -content. If needed you can run: - -```bash -docker-compose down -docker rmi --force docker-consul-template-bootstrap_app -docker rmi --force consul_template_bootstrap_alpine -docker rmi --force consul_template_bootstrap_centos -docker rmi --force consul_template_bootstrap_debian -``` +To create a release, create a tag that follows [semver](https://semver.org/) and +a GitHub Action workflow will take care of creating the release. diff --git a/install.sh b/install.sh deleted file mode 100755 index 1baa940..0000000 --- a/install.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env bash - -# NOTE: Update if changes are made to this repo that need to be included in the images -# CACHE VERSION: 202209121400 - -set -eo pipefail - -CONSUL_TEMPLATE_BOOTSTRAP_REF="${1:-master}" - -if command -v apt-get; then - apt-get update - apt-get -y install --no-install-recommends unzip sudo jq wget curl ca-certificates - apt-get clean && apt-get autoclean && apt-get -y autoremove --purge - rm -rf /var/lib/apt/lists/* /usr/share/doc /root/.cache/ -elif command -v yum; then - grep "Amazon Linux" /etc/os-release &>/dev/null || yum -y install epel-release - yum -y update - yum -y install unzip jq sudo wget curl which - yum clean all - rm -rf /var/cache/yum -elif command -v apk; then - apk add --no-cache --update unzip sudo python3 jq wget ca-certificates curl which py3-pip bash - update-ca-certificates - rm -rf /var/cache/apk/* - - # Use the Python version of AWS CLI since they don't provide a musl compatible build - pip3 --no-cache-dir install awscli - SKIP_AWS_INSTALL=1 -else - echo "Could not find a supported package manager (apt-get, yum, apk)." - exit 1 -fi - -if [ -z "$SKIP_AWS_INSTALL" ]; then - curl -s "https://awscli.amazonaws.com/awscli-exe-linux-$(uname -m).zip" -o /tmp/awscliv2.zip - unzip -d /tmp /tmp/awscliv2.zip - /tmp/aws/install - rm -rf /tmp/aws /tmp/awscliv2 /tmp/awscliv2.zip -fi - -arch="linux_amd64" -[ "$(uname -m)" == "aarch64" ] && arch="linux_arm64" - -# Install Consul template -CONSUL_TEMPLATE_VERSION="${CONSUL_TEMPLATE_VERSION:-0.28.1}" -curl -s "https://releases.hashicorp.com/consul-template/${CONSUL_TEMPLATE_VERSION}/consul-template_${CONSUL_TEMPLATE_VERSION}_${arch}.zip" -o /tmp/consul-template.zip -unzip /tmp/consul-template.zip consul-template -d /usr/local/bin -rm /tmp/consul-template.zip - -# Install Vault CLI -VAULT_VERSION="${VAULT_VERSION:-1.10.0}" -curl -s "https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_${arch}.zip" -o /tmp/vault.zip -unzip /tmp/vault.zip vault -d /usr/local/bin -rm /tmp/vault.zip - -# Install consul-bootstrap -curl -Ls "https://github.com/articulate/docker-consul-template-bootstrap/archive/${CONSUL_TEMPLATE_BOOTSTRAP_REF}.zip" -o /tmp/docker-consul-template-bootstrap.zip -unzip /tmp/docker-consul-template-bootstrap.zip -d /tmp -mkdir -p /consul-template/ -mv "/tmp/docker-consul-template-bootstrap-${CONSUL_TEMPLATE_BOOTSTRAP_REF}"/{dev,peer,prod,stage} /consul-template/ -mv "/tmp/docker-consul-template-bootstrap-${CONSUL_TEMPLATE_BOOTSTRAP_REF}/entrypoint.sh" /entrypoint.sh -rm -rf /tmp/docker-consul-template-bootstrap* - -for package in wget jq curl which aws consul-template vault; do - if ! command -v "$package"; then - echo "$package is not installed" - exit 1 - fi -done diff --git a/wait-for-it.sh b/wait-for-it.sh deleted file mode 100644 index 5aa4633..0000000 --- a/wait-for-it.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env bash -# Use this script to test if a given TCP host/port are available -# Borrowed from https://github.com/vishnubob/wait-for-it/ - -cmdname=$(basename $0) - -echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } - -usage() -{ - cat << USAGE >&2 -Usage: - $cmdname host:port [-s] [-t timeout] [-- command args] - -h HOST | --host=HOST Host or IP under test - -p PORT | --port=PORT TCP port under test - Alternatively, you specify the host and port as host:port - -s | --strict Only execute subcommand if the test succeeds - -q | --quiet Don't output any status messages - -t TIMEOUT | --timeout=TIMEOUT - Timeout in seconds, zero for no timeout - -- COMMAND ARGS Execute command with args after the test finishes -USAGE - exit 1 -} - -wait_for() -{ - if [[ $TIMEOUT -gt 0 ]]; then - echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT" - else - echoerr "$cmdname: waiting for $HOST:$PORT without a timeout" - fi - start_ts=$(date +%s) - while : - do - if [[ $ISBUSY -eq 1 ]]; then - nc -z $HOST $PORT - result=$? - else - (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1 - result=$? - fi - if [[ $result -eq 0 ]]; then - end_ts=$(date +%s) - echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds" - break - fi - sleep 1 - done - return $result -} - -wait_for_wrapper() -{ - # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 - if [[ $QUIET -eq 1 ]]; then - timeout $BUSYTIMEFLAG $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & - else - timeout $BUSYTIMEFLAG $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & - fi - PID=$! - trap "kill -INT -$PID" INT - wait $PID - RESULT=$? - if [[ $RESULT -ne 0 ]]; then - echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT" - fi - return $RESULT -} - -# process arguments -while [[ $# -gt 0 ]] -do - case "$1" in - *:* ) - hostport=(${1//:/ }) - HOST=${hostport[0]} - PORT=${hostport[1]} - shift 1 - ;; - --child) - CHILD=1 - shift 1 - ;; - -q | --quiet) - QUIET=1 - shift 1 - ;; - -s | --strict) - STRICT=1 - shift 1 - ;; - -h) - HOST="$2" - if [[ $HOST == "" ]]; then break; fi - shift 2 - ;; - --host=*) - HOST="${1#*=}" - shift 1 - ;; - -p) - PORT="$2" - if [[ $PORT == "" ]]; then break; fi - shift 2 - ;; - --port=*) - PORT="${1#*=}" - shift 1 - ;; - -t) - TIMEOUT="$2" - if [[ $TIMEOUT == "" ]]; then break; fi - shift 2 - ;; - --timeout=*) - TIMEOUT="${1#*=}" - shift 1 - ;; - --) - shift - CLI=("$@") - break - ;; - --help) - usage - ;; - *) - echoerr "Unknown argument: $1" - usage - ;; - esac -done - -if [[ "$HOST" == "" || "$PORT" == "" ]]; then - echoerr "Error: you need to provide a host and port to test." - usage -fi - -TIMEOUT=${TIMEOUT:-15} -STRICT=${STRICT:-0} -CHILD=${CHILD:-0} -QUIET=${QUIET:-0} - -# check to see if timeout is from busybox? -# check to see if timeout is from busybox? -TIMEOUT_PATH=$(realpath $(which timeout)) -if [[ $TIMEOUT_PATH =~ "busybox" ]]; then - ISBUSY=1 - BUSYTIMEFLAG="-t" -else - ISBUSY=0 - BUSYTIMEFLAG="" -fi - -if [[ $CHILD -gt 0 ]]; then - wait_for - RESULT=$? - exit $RESULT -else - if [[ $TIMEOUT -gt 0 ]]; then - wait_for_wrapper - RESULT=$? - else - wait_for - RESULT=$? - fi -fi - -if [[ $CLI != "" ]]; then - if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then - echoerr "$cmdname: strict mode, refusing to execute subprocess" - exit $RESULT - fi - exec "${CLI[@]}" -else - exit $RESULT -fi