Adding CodePipeline support to the deployment repository

When you use CodePipeline to deploy your environments using CloudFormation, you need to ensure that you can supply a configuration file that includes input stack parameters, stack tags, and stack policy configuration. This file must be implemented in a JSON format, as defined at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-cfn-artifacts.html#w2ab2c13c15c15, so we need to modify the format of the input parameters file in the todobackend-aws repository, which is currently in a <parameter>=<value> format, located in a file called dev.cfg. As per the referenced document, all of your input parameters need to reside in a JSON file under a key called Parameters, which you can define in a new file called dev.json, located at the root of the todobackend-aws repository:

{ 
"Parameters": {
"ApplicationDesiredCount": "1",
"ApplicationImageId": "ami-ec957491",
"ApplicationImageTag": "latest",
"ApplicationSubnets": "subnet-a5d3ecee,subnet-324e246f",
"VpcId": "vpc-f8233a80"
}
}

In the preceding example, notice that I have updated the ApplicationImageTag value to latest. This is because our pipeline will actually obtain the value for the ApplicationImageTag input dynamically, from the build stage of our pipeline, and the latest value is a safer default value, in the event that you want to deploy your stack manually, from the command line.

At this point, the dev.cfg file is redundant, and can be deleted from your repository; however, note that you will need to modify the way you run deployments manually, from the command line, given that the aws cloudformation deploy command expects input parameters to be provided in a <parameter>=<value> format.

One way that you can solve this is to use the jq utility to transform your new dev.json configuration file into the required <parameter>=<value> format:

> aws cloudformation deploy --template-file stack.yml --stack-name todobackend \
--parameter-overrides $(cat dev.json | jq -r '.Parameters|to_entries[]|.key+"="+.value') \
--capabilities CAPABILITY_NAMED_IAM

This command is now quite a mouthful, so, in order to simplify running this command, you could add a simple Makefile to the todobackend-aws repository:

.PHONY: deploy

deploy/%:
aws cloudformation deploy --template-file stack.yml --stack-name todobackend-$* \
--parameter-overrides $$(cat $*.json | jq -r '.Parameters|to_entries[]|.key+"="+.value') \
--capabilities CAPABILITY_NAMED_IAM

In the preceding example, the % character in the task name captures a wildcard text value whenever you execute the make deploy command. For example, if you run make deploy/dev, then the % character would capture dev, and if you run make deploy/prod, then the captured value would be prod. You can then refer to the captured value by using the $* variable, which you can see that we have substituted in the stack name (todobackend-$*, which would expand to todobackend-dev and todobackend-prod, using the previous examples), and in the command to cat the dev.json or prod.json file. Note that because we have named our stack todobackend throughout this book, this command won't quite work for us, but if you rename your stack to todobackend-dev, this command will make it much easier to deploy to a given environment manually.

Before you continue, you need to add the new dev.json file, commit, and push your changes to the source Git repository, as we will soon add the todobackend-aws repository as another source in your CodePipeline pipeline.