Traditionally, the management of IT infrastructure is not a simple affair, with system administrators doing their best to manage the availability and resiliency of systems on a day-to-day basis. While the infrastructure keeps growing over time and becomes distributed, this tends to get even more difficult and needs a lot of manpower to manage the infrastructure's availability 24x7.
The advent of microservices and containerized infrastructure made it very complex. The DevOps culture also brought this paradigm shift since the developers now need more systems with lesser shelf life. The system administrator now needs to manage not a few monolithic systems hosting multiple services but, megalithic systems hosting microservices.
The traditional approach of managing IT infrastructure manually is also muddled with problems. These problems would only be augmented as the infrastructure grows.
I would like to share my experience with working on a program where we used a systemic approach to develop and deliver Infrastructure as Code (IaC) and a robust DevOps framework for one of our Clients. I will explain how some of the significant choices we made drove some exceptional accomplishments on the program.
Significant Feature Requirements
Time to Market
Time to Market is governed by the element of speed. Something that enables users to set up the infrastructure in the shortest time frame. Thereby keeping this consistent across environments, from development to quality, release, and production and bringing greater efficiency to the entire delivery life-cycle
Integrity of Infrastructure
Making configuration changes manually is prone to human errors and misses in documenting such changes. Integrity of Infrastructure would mean no inconsistencies, mistakes, discrepancies, or lapses in changes. If the changes are also version controlled, roll-back to previous functioning state can be achieved with the least effort, that reinforces integrity and also enables accountability.
Configuration Drift
This occurs when code that has deployed components in an infrastructure, becomes more and more different, as time goes by, due to required changes and updates, and general entropy. While this can be well documented and updated for some major changes, this may increase the burden of fairly trivial changes, such as tweaking a web server configuration. The choice of approach or method is crucial to accommodate both the types of changes.
Immutable Infrastructure
For a futuristic and resilient infrastructure, the environment should be immutable. Any change needs to be holistic and not to address very small configuration changes individually, that can lead to configuration drift. While this may seem like unnecessary accumulation of changes, it proves immensely effective in achieving uniformity and consistency in the Infrastructure. This becomes crucial in critical services or complex integration points of the infrastructure
Modularity
Advent of Microservices is crucial for businesses and having a method that can deploy infrastructure and can cater to the business requirement is necessary. Modularity in design and method which enables this plays a significant role. By applying this concept small stacks or modules of infrastructure, should be possible, which can later be combined to form a composite module. This also gives us control over management of these modules and makes it secure.
Code Everything
Infrastructure that can be codified as much as possible is the future. Modularity is crucial to enable this. To begin with every component of the infrastructure that can be deployed with code needs to be identified, analyzed to find the right Cloud Fit, designed so management with code is possible, and deploy using automation. This will enable the foundation for the seamless and rapid deployment of Infrastructure
The Approach
Some of the significant architectural decisions that are needed, for building a robust framework, are;
A decision of the approach to be taken for deploying the code and deciding if it was declarative or imperative.
A declarative approach defines the logic and the end result that the program would generate. The logic specifies what is to be done. This gives it the flexibility for easy extension. It is simple to learn since it triggers the abstraction part of the brain. It does not have mutable variables so there are no damaging side-effects.
An Imperative approach defines the procedure and the exact steps that are needed for the program to generate. The procedure specifies how it is to be done. This makes it an easier to read and understand. It is much simpler to learn since the steps are clearly articulated. It has both mutable and immutable variables so it has damaging side-effects if not properly written. The significant choices in infrastructure domain were Terraform and Ansible.
Terraform uses the declarative model which makes it more suitable for provisioning large deployments. Ansible on the other hand is imperative or procedural and can handle large deployment easily however, when architectures become complex, Terraform makes it simpler due to its logical nature of programming when compared to Ansible which is procedural in nature. There was another factor that drove my decision and that was the Cloud platform which was AWS.
Both Terraform and Ansible come with the significant features that can make a robust Infrastructure as Code framework.
-
On Time to Market, Ansible being procedural scores a little higher on Time to Market. It is something that enables users to set up the infrastructure in the shortest time frame. However, Terraform may score slightly on keeping this consistent across environments.
-
For Integrity of Infrastructure, this is primarily governed by the source control like Git or BitBucket so I would give them equal points but, integrations with Terraform Cloud or TFE may be a nudge easier when compared to Ansible Tower or AWX
-
Configuration Drift is something that may become unmanageable in case of Ansible when compared to Terraform. Due to descriptive model, Terraform recreates the entire infrastructure rather than creating deltas that Ansible is capable of.
-
Terraform only support Immutable Infrastructure while Ansible support both Immutable and Mutable infrastructure. For a futuristic and resilient infrastructure, the environment should be immutable. It proves immensely effective in achieving uniformity and consistency in Infrastructure.
-
Both Terraform and Ansible support modular code however, my experience has shown Ansible scoring significantly due to the procedural or imperative model.
-
Code Everything, both Terraform and Ansible support for a broad-spectrum of services and have modules and plugins for them. They are the two most important platforms of IaC.
Based on the constraints and the requirement to use AWS as the Cloud Provider, our assessment of the capabilities of both Terraform and Ansible, we decided to use both Declarative and Imperative approaches. Both types are needed to have a robust framework and all depends on the decision of where to use which one. We used Terraform for provisioning of Infrastructure components such as VPC, EC2, RDS, Security Groups etc. and used Ansible for installation of middleware and applications, configuration of EC2, domain join the EC2 etc.
The Architecture