Skip to content

Commit

Permalink
First pass at adding Honeycomb beeline (#1)
Browse files Browse the repository at this point in the history
* First pass at adding Honeycomb beeline

* Remove refrences to the API Key

* feat: adding ability to source secrets from vault

* feat: makes the wrapper authenticate to vault

The wrapper will now try to loginto vault with the default vault role of
hc, get a token and if it can, export the token to the ENV, and start a
version of envconsul that will look into vault for the honeycomb api
secret.

If we aren't running on AWS or the VAULT_TOKEN isn't passed in, start a
version that tries to get it's configs from Consul and don't send events
to Honeycomb (becasue don't have a API Token)
  • Loading branch information
tfhartmann authored Mar 6, 2019
1 parent 9a669e7 commit 75b4ccb
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 15 deletions.
39 changes: 39 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# shellcheck shell=bash

dotenv

# auth against Vault if configured
if has vault; then
if [[ "$VAULT_ADDR" && "$VAULT_AUTH_GITHUB_TOKEN" ]]; then
# are we already authenticated?
TOKEN_LOOKUP=$(vault token-lookup -format=json 2>/dev/null)

if [ "$?" -eq 0 ]; then
# renew if possible
TOKEN_RENEW=$(vault token-renew -format=json 2>/dev/null)
else
# authenticate
vault login -method=github
fi
fi
fi

function get_vault_kv {
vault_path=$1
vault_key=${2:-value}
if [[ "$VAULT_ADDR" ]]; then
VAULT_KV=$(curl -s -H "X-Vault-Token: $(cat ~/.vault-token )" -X GET $VAULT_ADDR/v1/${vault_path} | jq -r .data.${vault_key})
fi
}

if get_vault_kv "secret/consul" "http_auth"; then
#echo "consul_http_auth = \"${VAULT_KV}\"" > _consul_http_auth.auto.tfvars
export CONSUL_HTTP_AUTH="${VAULT_KV}"
fi

if get_vault_kv "secret/consul" "http_addr"; then
#echo "consul_http_auth = \"${VAULT_KV}\"" > _consul_http_auth.auto.tfvars
export CONSUL_HTTP_ADDR="${VAULT_KV}"
fi

# vim: set et fenc=utf-8 ff=unix ft=sh sts=2 sw=2 ts=2 :
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
### https://raw.github.com/github/gitignore/90f149de451a5433aebd94d02d11b0e28843a1af/Go.gitignore
.env

healthcheck
vendor/
Expand Down
15 changes: 14 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,32 @@ RUN go get -d -v ./...
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
RUN CGO_ENABLED=0 GOOS=linux go get -v github.com/asicsdigital/dudewheresmy

# Download and verify the integrity of the download first
FROM sethvargo/hashicorp-installer:0.1.3 AS installer
ARG CONSUL_VERSION='1.4.0'
ARG VAULT_VERSION='1.0.2'
RUN /install-hashicorp-tool "vault" "$VAULT_VERSION"

FROM hashicorp/envconsul:alpine
RUN apk --no-cache add ca-certificates
RUN apk --no-cache add ca-certificates bind-tools
WORKDIR /root/
COPY --from=0 /go/src/github.com/asicsdigital/healthcheck/app .
RUN mkdir -p static
COPY --from=0 /go/src/github.com/asicsdigital/healthcheck/static ./static
COPY --from=0 /go/bin/dudewheresmy .
COPY --from=installer /software/vault /usr/local/bin/vault

ENV PORT=8080
ENV CONSUL_PREFIX=healthcheck
ENV CONSUL_HTTP_ADDR=""
ENV CONSUL_HTTP_AUTH=""
ENV EXTRA_ARGS=""
ENV HONEYCOMB_API_KEY=""
ENV HONEYCOMB_DATASET="healthcheck"
ENV VAULT_ADDR=""
ENV VAULT_TOKEN=""
ENV VAULT_PATH="secret/healthcheck"

EXPOSE $PORT
COPY ./scripts/envconsul_wrapper.sh wrapper.sh
CMD ["./wrapper.sh"]
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ In one shell:
```sh
$ docker pull asicsdigital/healthcheck:latest
$ docker run --rm -it \
-p 8080 \
-p 8080:8080 \
-e CONSUL_HTTP_ADDR="https://asics-services.us-east-1.staging.asics.digital" \
-e CONSUL_HTTP_AUTH="consul:GET_THIS_FROM_1PASSWORD" \
asicsdigital/healthcheck:latest
Expand All @@ -59,6 +59,20 @@ In another shell:
curl http://localhost:8080/healthcheck | jq .
```

You can also pass in a VAULT_TOKEN and a VAULT_ADDR to this example to read secrets from Vault.

( Someone will have had to have run `vault write secret/healthcheck HONEYCOMB_API_KEY=<KEY` at some point, check your vault )

```sh
docker run --rm -it \
-p 8080:8080 \
-e CONSUL_HTTP_ADDR="https://asics-services.us-east-1.staging.asics.digital" \
-e CONSUL_HTTP_AUTH="consul:GET_THIS_FROM_1PASSWORD" \
-e VAULT_ADDR="https://vault.us-east-1.staging.asics.digital" \
-e VAULT_TOKEN='<A VAULT TOKEN>' \
asicsdigital/healthcheck:latest
```

### Build from source

If you want to entirely avoid the dependency on Consul, build the application from source. You'll need a Golang development environment installed locally.
Expand Down
27 changes: 21 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,24 @@ import (

"github.com/caarlos0/env"
"github.com/urfave/negroni"

beeline "github.com/honeycombio/beeline-go"
"github.com/honeycombio/beeline-go/wrappers/hnynethttp"
)

const GitHubURI string = "https://github.com/asicsdigital/healthcheck"
const HealthCheckPath string = "/healthcheck"

type config struct {
Port int `env:"PORT"`
Application string `env:"HEALTHCHECK_APP" envDefault:"healthcheck"`
Status int `env:"HEALTHCHECK_STATUS" envDefault:"200"`
Metrics string `env:"HEALTHCHECK_METRICS" envDefault:"{}"`
Port int `env:"PORT"`
Application string `env:"HEALTHCHECK_APP" envDefault:"healthcheck"`
Status int `env:"HEALTHCHECK_STATUS" envDefault:"200"`
Metrics string `env:"HEALTHCHECK_METRICS" envDefault:"{}"`
HoneyKey string `env:"HONEYCOMB_API_KEY"`
HoneyDataset string `env:"HONEYCOMB_DATASET" envDefault:"healthcheck"`
}


type healthcheck struct {
Application string `json:"application"`
Status int `json:"status"`
Expand All @@ -27,10 +33,19 @@ type healthcheck struct {

func main() {
cfg := config{}
env.Parse(&cfg)

hc := healthcheck{}

// default config for our own healthcheck
defcfg := config{Application: "healthcheck", Status: 200, Metrics: "{}"}
defcfg := config{Application: "healthcheck", Status: 200, Metrics: "{}" }

beeline.Init(beeline.Config{
WriteKey: cfg.HoneyKey,
Dataset: cfg.HoneyDataset,
})
defer beeline.Close()


mux := http.NewServeMux()

Expand All @@ -54,7 +69,7 @@ func main() {
// middleware - redirect / to /healthcheck
mux.HandleFunc("/", redirectHandler(HealthCheckPath, http.StatusMovedPermanently))

n.UseHandler(mux)
n.UseHandler(hnynethttp.WrapHandler(mux))

n.Run()
}
Expand Down
54 changes: 47 additions & 7 deletions scripts/envconsul_wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,57 @@ set -u
DUDEWHERESMY=$(PATH=$PATH:. which dudewheresmy)
DUMB_INIT=$(which dumb-init)
ENVCONSUL=$(which envconsul)
VAULT_ROLE="${VAULT_ROLE:-hc}"

if [[ -z "$CONSUL_HTTP_ADDR" ]]; then
CONSUL_IP=$($DUDEWHERESMY hostip)
CONSUL_HTTP_ADDR="http://${CONSUL_IP}:8500"
export CONSUL_HTTP_ADDR
fi

$DUMB_INIT \
$ENVCONSUL \
$EXTRA_ARGS \
-prefix "$CONSUL_PREFIX" \
-upcase \
-sanitize \
-exec=./app
if [[ -z "$VAULT_ADDR" ]]; then
CONSUL_IP=$($DUDEWHERESMY hostip)
VAULT_IP=$(dig +short active.vault.service.consul @${CONSUL_IP} -p 8600)
VAULT_PORT=$(dig -t srv +short active.vault.service.consul @${CONSUL_IP} -p 8600 | cut -d' ' -f3)
VAULT_ADDR="http://${VAULT_IP}:${VAULT_PORT}"
export VAULT_ADDR
fi

if curl -fs -m 1 http://169.254.169.254/latest/meta-data/ -o /dev/null ; then
echo "Logging into Vault with role: ${VAULT_ROLE}"
vault login -no-print=true -method=aws role=${VAULT_ROLE}

if [ -f .vault-token ]; then
VAULT_TOKEN=$(cat .vault-token)
export VAULT_TOKEN
fi
fi

_HCL_CONFIG=$(cat<<EOT
secret {
no_prefix = true
path = "${VAULT_PATH}"
}
EOT
)
echo "${_HCL_CONFIG}" > config.hcl

if [ -z "$VAULT_TOKEN" ]; then
$DUMB_INIT \
$ENVCONSUL \
$EXTRA_ARGS \
-prefix "$CONSUL_PREFIX" \
-upcase \
-sanitize \
-exec=./app
else
$DUMB_INIT \
$ENVCONSUL \
$EXTRA_ARGS \
-prefix "$CONSUL_PREFIX" \
-upcase \
-sanitize \
-config config.hcl \
-exec=./app
fi
# CONSUL_IP=$(./dudewheresmy ip) ; VAULT_IP=$(dig +short active.vault.service.consul @${CONSUL_IP} -p 8600); VAULT_PORT=$(dig -t srv +short active.vault.service.consul @${CONSUL_IP} -p 8600 | cut -d' ' -f3) ; VAULT_ADDR="http://${VAULT_IP}:${VAULT_PORT}"

0 comments on commit 75b4ccb

Please sign in to comment.