Reputation: 8904
I have a makefile
with this goal:
setup:
@GHE_TOKEN=$(shell vault read -field=value is/cloud/eng/ghe_token)
@GHE_TOKEN=${GHE_TOKEN} pipenv install --dev
What I'm doing here is getting a secret from HashiCorp vault and passing it on to the next command. This works fine if I'm already logged in to vault properly.
However if I'm not logged in the pipenv install command proceeds even though there was an error in vault read
.
So what I'm looking for is the make goal to abort and display the error message if there is an error on the vault read
call and also be able to capture the output of a successful shell command to read. I know how to do one or the other, but not both.
Thanks for any help!
Upvotes: 0
Views: 812
Reputation: 101051
It isn't working because what you're doing is not at all what you think you're doing :).
When make processes a recipe it works like this: first all make variables and functions in all commands in the recipe are expanded, then each command line in the recipe is invoked one at a time, in its own shell.
So, in your situation note that ${GHE_TOKEN}
is a reference to a make variable named GHE_TOKEN
, which I assume is not set in your makefile, so it's the empty string. Also the make $(shell ...)
function is expanded before any command is run, and note that make doesn't care about the exit code of this; if it fails it won't cause the command to fail.
If we assume that the vault read -field=value is/cloud/engine/ghe_token
returns the value mysecret
, then make will substitute in that value and run these commands (basically):
/bin/sh -c 'GHE_TOKEN=mysecret'
/bin/sh -c 'GHE_TOKEN= pipenv install --dev'
This clearly isn't going to do what you want.
You need to do all the work in the shell; it's almost always a sign of something wrong if you are using make's shell
function in a recipe; a recipe is already running in the shell, so using $(shell ...)
just adds confusion.
You probably want this:
setup:
@export GHE_TOKEN=$$(vault read -field=value is/cloud/eng/ghe_token) \
&& pipenv install --dev
so that pipenv
is not run if the vault read
command fails.
Upvotes: 1