Get rid of old habits- Use CloudFormation for infrastructure set up -01
Tags: aws, cloudformation, cloudskills, infrastructure
Published: 2021-03-06 18:40:05

Yes, I too had the habit of creating the required infrastructure manually. Yes, we gave up the idea of changing databases manually a long time ago for good reasons and switched to migrations. With so many resources, policies, roles getting added and having to replicate them in three to four environments, why still stuck with the same old habits when it is as easy as writing a DB migration script. In case you haven't tried yet, I want to share a common scenario, where I'll guide you through setting up the infrastructure to host a service-based application running in multiple availability zones in secure subnets with auto-scaling enabled to provide high availability and scalability. In case you are wondering why I am writing this, I saw some really bad practices recently, and I think they should change and I am doing my bit to help anyone in need.

### Sample Setup
I'll base my experience to write about an ideal setup. If you want to host a business application that you've written, most probably it will consist of two different sections namely applications for internal staff to run the business and client-facing applications / APIs which enable customer interaction.
Let's assume that the application for the internal staff is developed using a framework such as asp.net zero, serenity.io, or Laravel. Every bounded context can be hosted separately in the InternalApp Subnet with a public application load balancer handling the traffic.
The APIs that will be consumed by the web applications and the mobile applications better be secured using Cognito user pools and identity pools. When security for the APIs are provided using Cognito at API Gateway level it is not possible to use a public application load balancer, instead, it will have to be a private application load balancer. When the load balancer is private it will have to be connected to the API Gateway using a VPC link, so that the APIs you developed can be exposed in a secure manner. The deployment architecture diagram is as follows.

![Deployment Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hfx6ylmh6w3kph6x2ydo.png)
 
Our goal is to use CloudFormation templates to automate the deployment of the above infrastructure. I am not hoping to explain what CloudFormation templates are and their basics, hence providing the link to Amazon documentation.[Link](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)

The first step would be to create the VPC and it can be done with the following code. You may decide how many private IPs you need, here I am going for the maximum with a CIDR block of 10.0.0.0/16.

{% gist https://gist.github.com/mgsf/36fc436b86d3a20f8f5c5a8c391b76dd %}

The next step would be the creation of subnets in the two availability zones. The expected outcome can be shown diagrammatically as follows.
![Deployment Diagram 01](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s98822ksilcju6thwd10.png)
 
{% gist https://gist.github.com/mgsf/399f1795bcf291ff9311b0057105c80f %}

As the next step, we can create other resources such as internet gateway, nat gateway and etc. We could also do the route table configuration. Once the route table configuration is done we may create the associations between subnets and route tables. The code for the above tasks is as follows,

{% gist https://gist.github.com/mgsf/f4998d50a849ebc4d3a462eae18e03f8 %}

In the future stacks, we'll be needing the resources we created above and for that purpose, we'll have to output these resources with names that could be referenced later.

{% gist https://gist.github.com/mgsf/f808c2ada8cf03b609db9053353e8035 %}

We are done creating the resources but there is some more to be done such as security groups configuration, adding IAM roles, adding compute resources and etc. Due to the length of the article, I'll keep them for another day but you can expect them to arrive soon. Thanks for reading.