I'm writing a Makefile to wrap the deployment of an elastic beanstalk app to multiple environments. This is my first time writing an "advanced" makefile and I'm having a bit of trouble.
My goals are as follows:
make deploy
by itself should deploy withENVIRONMENT=$(USER)
andENV_TYPE=staging
.- The environment to deploy to can be set via an environment variable. If
ENVIRONMENT=production
thenENV_TYPE=production
, otherwiseENV_TYPE=staging
. - As a shorthand for setting the environment variable, one can suffix the
deploy
target with a-
and the name of the environment. For example:make deploy-production
.
It's number 3 that is giving me the most trouble. Since any environment not named production is of type staging, I tried to use pattern matching to define the target for deploying to staging environments. Here's what I have currently:
ENVIRONMENT = $(USER)
ifeq ($ENVIRONMENT, production)
ENV_TYPE=production
else
ENV_TYPE=staging
endif
DOCKER_TAG ?= $(USER)
CONTAINER_PORT ?= 8000
ES_HOST = logging-ingest.$(ENV_TYPE).internal:80
.PHONY: deploy
deploy:
-pip install --upgrade awsebcli
sed "s/<<ES_HOST>>/$(ES_HOST)/" < 01-filebeat.template > .ebextensions/01-filebeat.config
sed "s/<<DOCKER_TAG>>/$(DOCKER_TAG)/" < Dockerrun.template | sed "s/<<CONTAINER_PORT>>/$(CONTAINER_PORT)/" > Dockerrun.aws.json
eb labs cleanup-versions --num-to-leave 10 --older-than 5 --force -v --region us-west-2
eb deploy -v coolapp-$(ENVIRONMENT)
.PHONY: deploy-%
deploy-%: ENVIRONMENT=$*
deploy-%: deploy
@echo # Noop required
.PHONY: deploy-production
deploy-production: ENVIRONMENT=production
deploy-production: ENV_TYPE=production
deploy-production: deploy
@echo # Noop required
The problem is in the last step of the deploy
target. Namely, $(ENVIRONMENT)
appears to be unset.
Example Output:
18:42 $ make -n deploy-staging
pip install --upgrade awsebcli
sed "s/<<ES_HOST>>/logging-ingest.staging.internal:80/" < 01-filebeat.template > .ebextensions/01-filebeat.config
sed "s/<<DOCKER_TAG>>/schultjo/" < Dockerrun.template | sed "s/<<CONTAINER_PORT>>/8000/" > Dockerrun.aws.json
eb labs cleanup-versions --num-to-leave 10 --older-than 5 --force -v --region us-west-2
eb deploy -v coolapp-
echo # Noop required
Desired Output:
18:42 $ make -n deploy-staging
pip install --upgrade awsebcli
sed "s/<<ES_HOST>>/logging-ingest.staging.internal:80/" < 01-filebeat.template > .ebextensions/01-filebeat.config
sed "s/<<DOCKER_TAG>>/schultjo/" < Dockerrun.template | sed "s/<<CONTAINER_PORT>>/8000/" > Dockerrun.aws.json
eb labs cleanup-versions --num-to-leave 10 --older-than 5 --force -v --region us-west-2
eb deploy -v coolapp-staging
echo # Noop required
So I have tried to implement Renaud's recursive Make solution, but have run into a minor hiccup. Here's a simplified Makefile that I'm using:
ENVIRONMENT ?= $(USER)
ifeq ($ENVIRONMENT, production)
ENV_TYPE = production
else
ENV_TYPE = staging
endif
ES_HOST = logging-ingest.$(ENV_TYPE).internal:80
.PHONY: deploy
deploy:
@echo $(ENVIRONMENT)
@echo $(ENV_TYPE)
@echo $(ES_HOST)
.PHONY: deploy-%
deploy-%:
@$(MAKE) --no-print-directory ENVIRONMENT=$* deploy
When I run make production
, it looks like the if
statements surrounding the ENV_TYPE
definition are not run again. Here's my actual output:
12:50 $ make -n deploy-production
/Applications/Xcode.app/Contents/Developer/usr/bin/make --no-print-directory ENVIRONMENT=production deploy
echo production
echo staging
echo logging-ingest.staging.internal:80
The last two lines should say production
rather than staging
, implying there is something wrong with my conditional, but I haven't edited that conditional from earlier versions when it worked, so I'm a but confused. The same error happens if I invoke make with ENVIRONMENT
set manually (e.g. ENVIRONMENT=production make deploy
).
$(ENVIRONMENT)
in yourifeq
. Tryifeq ($(ENVIRONMENT), production)
– lockcmpxchg8bdeploy-
, otherwise it produces some truly baffling output if you typo the suffix (likemake deploy- production
). – lockcmpxchg8bdeploy-
target as suggested. – JohnS