Cloud Formation good practices
Tags: iac, devops, aws, cloud
Published: 2022-06-07 22:11:57

Using AWS Cloud formation templates to deploy our infrastructure such that it can be easily reproduced consistently and it can also be incorporated in an automation scripts is increasingly becoming the default. There are lots of positives to Infrastructure as a code. However, when deploying huge infrastructures, the templates can become unreadable or even lead to security leaks. In these article we will be looking at some practices we can incorporate in our templates to help us mitigate these issues and facilitate readability.

**Using Parameters:**
This means we will not be hard-coding values in the templates. Declaration of Parameters facilitates re-usability of our template. 
Parameters are declared at the beginning of the template under the "Parameters" section to be referenced in the "Resources" section. They are stored in a parameter file usually in a JSON format where there are called during the creation or update of our infrastructures. 
Parameters can also be grouped based on resource types i.e server-group, network-group e.t.c which aids readability.

**Using Dynamic Reference:**
It is usually a good practice to store values in external services for reasons such as version control, security, etc.
We can reference external values that are stored in services like secrets in AWS Secrets Manager or plain-text values from AWS Parameter store with dynamic reference. A maximum of 60 dynamic references can be used in each templates. Dynamic reference are used with the following pattern: 
`{{resolve:service-name:reference-key}}`
Where service names are ssm, ssm-secure and secretsmanager.
_Note that it is not advisable not to use dynamic referencing for values that are part of the resource primary identifier as this would lead to secret leak when the resource is refernced._ 
You can read more on dynamic reference in the [AWS documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html).

**Using Mappings and Conditions:**
There are several region dependent values or pipeline-stage dependent resource properties, it can be a hassle trying to get the right value for the different regions the templates will be used or the different deployment stage such as development or production stage. The Mappings section of the template consists of key-value pairs declarations such that values can be called by referencing the key.

The conditions section of the template contains statements that defines entity configuration or creation. The statements are then attached to the concerned resources with the use of the optional "Condition" property.

Mappings and Conditions can also be combined such that if a condition is satisfied we might configure the resource by referencing a value based on a key from the satisfied condition. This one condition can be used to influence more resources in the template since we can have the same key name in different mapping declaration.

**Cross-stack Referencing**
We might decide to create different templates for different resource groups or different resource level. These resource will somehow still need to refer to each other. i.e we will need to reference the _VpcId_ created in our network-stack when we are creating the security group of a server. This is where cross stack reference comes to play. We are able to reference the resource created in a stack in another stack.
We can export these values in the Outputs section of our template. These values can then be referenced using the intrinsic _ImportValue_ fucntion. 

We have now discussed several Cloud formation tricks and practices. These can only be useful when they are used in the right contexts else we would have a lot of redundant parts in our template which will not produce the desired result.
I attempted to incorporate some of these practices [here](https://github.com/speedygamer12/Udacity-devops-highly-available-app-infrastructure/blob/main/README.md).

Happy learning and building.🛠️