This is the default behavior of Make: each line in the "recipe" is executed by a separate shell, so nothing carries from one line to another.
GNU Make provides the .ONESHELL special target, which instructs Make to use a single shell for each recipe. The drawback of this is that it applies to the entire Makefile, so you don't have the option of individual execution.
You could use a backslash to combine multiple lines:
mytarget:
aws --version ; \
eval $(aws sts assume-role ... ) ; \
aws sts get-caller-identity
If you do this, it's important to put the semi-colon after every command. You could also use a conditional operation like &&
, to ensure that each line succeeds before invoking the next.
You could also as a variable to hold your access vars, and insert them in each line where you invoke an AWS operation:
ACCESS_VARS != aws sts assume-role --role-arn arn:aws:iam::123456789012:role/SomeRole --role-session-name test | jq -r '.Credentials | "AWS_ACCESS_KEY_ID=\(.AccessKeyId) AWS_SECRET_ACCESS_KEY=\(.SecretAccessKey) AWS_SESSION_TOKEN=\(.SessionToken)"'
test:
$(ACCESS_VARS) aws sts get-caller-identity
Note that the JQ command is different from the one in your quesion: if you set environment variables as part of a command, you don't use export
.
IMO, however, the best solution is to write a script to do your work, and invoke that script from the Makefile. This will let you test the script independently, and enable full shell features without the additional constraints applied by Make.