In this newsletter, I wanted to include a few thoughts on the development of infrastructure as code, and challenges I have run into a few times. Also, I am not a fan of CloudFormation, but it is something that one sometimes has to work with. Tools like rain can improve the experience, which I write briefly about as well.
Enjoy! ## Messy code is always messy
Regular programming languages for infrastructure as code offer more expressive power, better testing and development tools, and more efficient organization than domain specific languages.
This is for the most part true. These are useful properties.
Drawbacks, however, are that you also have much more power to shoot yourself in the foot. It requires more discipline to write good code, even though you may write less code.
Still, messy code is always messy.
I have seen big chunks of AWS CDK code, several hundred or thousand lines in a single function - often the constructor of a stack object. If it had been in CloudFormation or Terraform, it would have been many more lines. But at least for Terraform, there is often more structure to what is defined, in my experience.
I have also seen very nicely structured code in AWS CDK. Also, I have seen well structured code that is very hard to change. It is harder to write nicely structured code with AWS CDK than regular application code, which has to do with what you are actually doing - building a dependency graph of resources, which might have a state that must be preserved.
You cannot refactor your code as you like, since that could break your (stateful) infrastructure.
Having state may be databases, or simply resources with a name which has to be preserved. Or there may be resources which other depend on being there all the time (e.g. networks).
So you have to balance the way you structure your code with the needs to not break your infrastructure. Especially if you use AWS CDK. This is something to keep in mind, which is CloudFormation under the hood. CloudFormation is not good with refactoring. You are better off with Terraform (CDKTF) and Pulumi, though.
_You can think of your infrastructure-as-code code as something to generate both the structure and content of a database.__
So a few points I think may be good to have in mind when building infrastructure-as-code, and in particular with programming languages:
- Separate stateful and stateless infrastructure, and infrastructure with different life cycles and organisational ownership.
- Keep inheritance hierarchies (if using object-oriented languages) to a minimum, especially with stateful resources. Group by functions instead.
- Think declarative and modular when designing interfaces to be used in the code, even with imperative languages. You, or someone else which are not intimately familiar with the infrastructure, may need to make changes a year from now - without touching it in between.
Infrastructure as code with programming languages, is powerful, but also requires discipline and to be mindful.
More rain, less pain (with CloudFormation)
CloudFormation is one of the earliest tools for creating cloud infrastructure among declarative infrastructure-as-code tools. It is also a tool that has pretty bad user experience with the default tools provided by AWS, such as the AWS CLI.
There are some external tools like Sceptre, that can improve your experience and offer extra capabilities. Others have also used the AWS CDK CLI tool to get a better command-line experience.
However, there is an unofficial tool from the AWS CloudFormation team called rain, which provides a nicer user experience than the official AWS tools. It is an open source command-line tool written in Go. The features it provides are more what you would expect from a tool like this.
There are the basics, of course: deploy stacks, list stacks, get stack diffs, remove stacks, watch stack updates as they happen. Get the template from an existing stack. There are also options to work with stacksets, and to merge stacks.
On top of that, you can generate CloudFormation templates from specified resource types, and it can try to check and warn of potential issues at actual deployment, e.g. service limits, collisions with existing resources, etc.
It can also create S3 buckets for use with the deployment.
Rain also understands a few extensions to CloudFormation of its own. You can include definitions from other files, generate S3 URLs, and also have a simple local filesystem-based module system.
All in all, rain is more like what a useful command-line tool for CloudFormation should be, and it is created by people at AWS. I am not sure why this is not part of the official toolset for CloudFormation?
You can find the contents of this bulletin and older ones, and more at Cloudgnosis.org. You will also find other useful articles around AWS automation and infrastructure-as-software.
Until next time,
/Erik