'makefile evaluates $(eval...) first prior to multiline IF's condition in the target
My issue: Inline $(eval...) evaluated first, then "IF" is evaluated. What I expect from the SSM target is "IF condition is evaluated first and only then $(eval...)
➜ make staging ssm TARGET=i-0d334b9e3f763bfeb
if test "i-0d334b9e3f763bfeb" == "" ; then \
echo "OK"; \
\
\
echo "✔ Selected desired nodegroup staging-grafana-v1"; \
echo "✔ Selected desired instgance-id i-07cef18e93c64c795"; \
aws ssm start-session --target i-07cef18e93c64c795; \
else \
echo "✔ Selected desired instgance-id i-0d334b9e3f763bfeb"; \
aws ssm start-session --target i-0d334b9e3f763bfeb; \
fi
✔ Selected desired instgance-id i-0d334b9e3f763bfeb
Starting session with SessionId: master-admin-06c7c2b63ca2554c4
sh-4.2$
So I get "fzf" related functionality in the IF top block which should be skipped due to TARGET being non-null.
So essentially speaking:
- if TARGET is not defined - things are working as expected.
- if TARGET is defined, then I first get both fzf interfaces for fuzzy search, and only then the ELSE block's steps are executed.
.PHONY: all
.DEFAULT_GOAL := help
# ----------------------------------------------------------------------------
# Local Variables
#
# ============================================================================
help:
@grep -E '^[\.0-9a-zA-Z_-]+:.*?## .*$$' Makefile | awk 'BEGIN {FS = ":.*?## "}; {printf "⚡ \033[34m%-15s\033[0m %s\n", $$1, $$2}'
staging: ## setup staging env (use: make staging plan)
@echo -n
$(eval export ENVIRONMENT=staging)
prod: ## setup prod env (use: make prod plan)
@echo -n
$(eval export ENVIRONMENT=prod)
.ONESHELL:
ssm: ## start ssm sessione
if test "$(TARGET)" == "" ; then \
echo "OK"; \
$(eval NG = $(shell aws ec2 describe-instances \
--filter Name=tag:Name,Values=$(ENVIRONMENT)* \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[] | [0]]' \
--output text \
| fzf)) \
$(eval INSTANCE_ID = $(shell aws ec2 describe-instances \
--filter Name=tag:Name,Values=${NG} \
--query 'Reservations[].Instances[].{id: InstanceId}' \
--output text \
| fzf)) \
echo "✔ Selected desired nodegroup ${NG}"; \
echo "✔ Selected desired instgance-id ${INSTANCE_ID}"; \
aws ssm start-session --target ${INSTANCE_ID}; \
else \
echo "✔ Selected desired instgance-id ${TARGET}"; \
aws ssm start-session --target ${TARGET}; \
fi
Solution 1:[1]
Do not confuse Make syntax with the shell commands in a recipe. Yes, Make expands the $(eval ... function before passing the commands to the shell, even before deciding whether to run the ssm rule.
The solution is simple; there does not appear to be any reason to use eval here. The variables NG and INSTANCE_ID can be shell variables instead of Make variables.
ssm: ## start ssm sessione
if test "$(TARGET)" == "" ; then \
echo "OK"; \
NG=`aws ec2 describe-instances \
--filter Name=tag:Name,Values=$(ENVIRONMENT)* \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[] | [0]]' \
--output text \
| fzf`; \
INSTANCE_ID=`aws ec2 describe-instances \
--filter Name=tag:Name,Values=$$NG \
--query 'Reservations[].Instances[].{id: InstanceId}' \
--output text \
| fzf`; \
echo "? Selected desired nodegroup $$NG"; \
echo "? Selected desired instgance-id $$INSTANCE_ID"; \
aws ssm start-session --target $$INSTANCE_ID; \
else \
echo "? Selected desired instgance-id ${TARGET}"; \
aws ssm start-session --target ${TARGET}; \
fi
(P.S. If you were planning to use those variables later in other rules, then the if-then-else which assigns the values should be outside the rule and written in Make syntax.)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Beta |
