In order to use Bref efficiently, I’ve developed a Makefile so that I don’t have to remember all the various commands required. In particular, looking up the correct parameters to sam package & sam deploy is a pain and it’s much easier to type make deploy and it all works as I expect.

It looks like this:

Makefile:



# vim: noexpandtab tabstop=4 filetype=make .PHONY: list invoke invoke-local deploy outputs lastlog clean clean-all setup REGION := eu-west-2 PROJECT_NAME := hello-world UNIQUE_KEY := 1557903576 BUCKET_NAME := $(PROJECT_NAME)-$(UNIQUE_KEY)-brefapp STACK_NAME := $(PROJECT_NAME)-$(UNIQUE_KEY)-brefapp # default function to invoke. To override: make invoke FUNCTION=foo FUNCTION ?= my-function list: @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' invoke: vendor/bin/bref --region=$(REGION) invoke $(FUNCTION) invoke-local: sam local invoke $(FUNCTION) --no-event deploy: sam package \ --region $(REGION) \ --template-file template.yaml \ --output-template-file .stack-template.yaml \ --s3-bucket $(BUCKET_NAME) -sam deploy \ --region $(REGION) \ --template-file .stack-template.yaml \ --stack-name $(STACK_NAME) \ --capabilities CAPABILITY_IAM vendor/bin/bref deployment --region $(REGION) $(STACK_NAME) outputs: aws --region $(REGION) cloudformation describe-stacks --stack-name $(STACK_NAME) | jq '.Stacks[0]["Outputs"]' lastlog: sam logs --region $(REGION) --name $(FUNCTION) geterror: vendor/bin/bref deployment --region $(REGION) $(STACK_NAME) clean: aws --region $(REGION) cloudformation delete-stack --stack-name $(STACK_NAME) clean-all: clean aws --region $(REGION) s3 rb s3://$(BUCKET_NAME) --force setup: aws --region $(REGION) s3 mb s3://$(BUCKET_NAME) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 # vim: noexpandtab tabstop=4 filetype=make .PHONY: list invoke invoke-local deploy outputs lastlog clean clean-all setup REGION := eu-west-2 PROJECT_NAME := hello-world UNIQUE_KEY := 1557903576 BUCKET_NAME := $(PROJECT_NAME)-$(UNIQUE_KEY)-brefapp STACK_NAME := $(PROJECT_NAME)-$(UNIQUE_KEY)-brefapp # default function to invoke. To override: make invoke FUNCTION=foo FUNCTION ?= my-function list: @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2 > /dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' invoke: vendor/bin/bref --region=$(REGION) invoke $(FUNCTION) invoke-local: sam local invoke $(FUNCTION) --no-event deploy: sam package \ --region $(REGION) \ --template-file template.yaml \ --output-template-file .stack-template.yaml \ --s3-bucket $(BUCKET_NAME) -sam deploy \ --region $(REGION) \ --template-file .stack-template.yaml \ --stack-name $(STACK_NAME) \ --capabilities CAPABILITY_IAM vendor/bin/bref deployment --region $(REGION) $(STACK_NAME) outputs: aws --region $(REGION) cloudformation describe-stacks --stack-name $(STACK_NAME) | jq '.Stacks[0]["Outputs"]' lastlog: sam logs --region $(REGION) --name $(FUNCTION) geterror: vendor/bin/bref deployment --region $(REGION) $(STACK_NAME) clean: aws --region $(REGION) cloudformation delete-stack --stack-name $(STACK_NAME) clean-all: clean aws --region $(REGION) s3 rb s3://$(BUCKET_NAME) --force setup: aws --region $(REGION) s3 mb s3://$(BUCKET_NAME)

There’s three variables that I need to set at the top:

REGION – The AWS region. This has to match the Bref layer used in template.yaml .

– The AWS region. This has to match the Bref layer used in . PROJECT_NAME – The name of the project. This is used as part of the S3 bucket and CloudFormation stack names

– The name of the project. This is used as part of the S3 bucket and CloudFormation stack names UNIQUE_KEY – A random string to ensure uniqueness for bucket and stack names. I tend to use the current time to the ms, but any string.

I’ve included a full-cycle set of targets so make setup will create the initial S3 bucket that’s required for the project and then make deploy is used to deploy my project.

If I want to start again, make clean will remove the CloudFormation stack and make clean-all will remove the stack and the bucket.

I’ve also included a few utility targets:

make invoke FUNCTION=foo invokes the function foo on AWS.

invokes the function on AWS. make invoke-local FUNCTION=foo invokes the function foo on sam-local.

invokes the function on sam-local. make outputs displays the outputs of the CloudFormation stack. This is useful for picking up the API Gateway URL for instance, if you set it up in your template.yaml .

displays the outputs of the CloudFormation stack. This is useful for picking up the API Gateway URL for instance, if you set it up in your . make lastlog FUNCTION=foo displays the logs for the last invocation of the function foo .

Parameters for template.yaml

I pass the PROJECT_NAME and UNIQUE_KEY through to the template as the parameters ProjectName and UniqueKey respectively. These are then set in the Parameters section of the template:

template.yaml:



Parameters: ProjectName: Type: String UniqueKey: Type: String 1 2 3 4 5 Parameters : ProjectName : Type : String UniqueKey : Type : String

I then use them in the template when I need uniqueness, such as when creating an S3 bucket:

template.yaml:



Resources: ImagesBucket: Type: AWS::S3::Bucket Properties: BucketName: !Join [ '-', [!Ref "ProjectName", !Ref "UniqueKey", "files" ] ] 1 2 3 4 5 Resources : ImagesBucket : Type : AWS : :S3 : :Bucket Properties : BucketName : !Join [ '-' , [!Ref "ProjectName", !Ref "UniqueKey", "files" ] ]

Which creates a bucket named “hello-world-1557903576-files” which nicely complements “hello-world-1557903576-brefapp”.