Infrastructure is one of the core tenets of a software development process—it is directly responsible for the stable operation of a software application. This infrastructure can range from servers, load balancers, firewalls, and databases all the way to complex container clusters.
Infrastructure considerations are valid beyond production environments, as they spread across the entire development process. They include tools and platforms such as CI/CD platforms, staging environments, and testing tools. These infrastructure considerations increase as the level of complexity of the software product increases. Very quickly, the traditional approach for manually managing infrastructure becomes an unscalable solution to meet the demands of DevOps' modern rapid software development cycles. And that’s how Infrastructure as Code (IaC) has become the de facto solution in development today.
What is Infrastructure as Code?
Infrastructure as Code is the process of provisioning and managing infrastructure defined through code, instead of doing so with a manual process. IaC takes away the majority of provisioning work from developers, who can execute a script to have their infrastructure ready to go. That way, application deployments aren’t held up waiting for the infrastructure, and sysadmins aren’t managing time-consuming manual processes.
Here is a step-by-step explanation of how creating an IaC environment works:
- A developer defines the configuration parameters in a domain-specific language (DSL).
- The instruction files are sent to a master server, a management API, or a code repository.
- The IaC platform follows the developer’s instructions to create and configure the infrastructure.
With Infrastructure as Code, users don’t need to configure an environment every time they want to develop, test, or deploy software. All infrastructure parameters are saved in the form of files called manifests.
As with all code files, manifests are easy to reuse, edit, copy, and share. Manifests make building, testing, staging, and deploying infrastructure quicker and more consistent.
Developers codify the configuration files and store them in version control. If someone edits a file, pull requests and code review workflows can check the correctness of the changes.
Infrastructure as Code Best Practices
Infrastructure automation implementation will require numerous changes and refactoring, thus making this process pretty much strenuous for your organization. If you want to avoid most of the constraints and make it less severe - follow infrastructure as code best practices below!
Utilize CI/CD and quality control for repository with your IaC
This will help you to maintain good quality of the code and get fast feedback loops from your DevOps teammates or developers (after the changes were applied). Luckily, there are test frameworks like
terratest for terraform that allow us to write the actual tests, the earlier you try to cover everything with it - the more you benefit from it and fewer unexpected problems will happen with infrastructure. For sure you can't cover the application errors here, but at least you can be more confident in your infrastructure.
Make your infrastructure as code modular
Microservices architecture, where software is built by developing smaller, modular units of code that can be deployed independently of the rest of a product’s components, is a popular trend in the software development world.
The same concept can be applied to IaC. You can break down your infrastructure into separate modules or stacks and then combine them in an automated fashion.
There are a few benefits to this approach:
First, you can have greater control over who has access to which parts of your infrastructure code. For example, you may have junior engineers who aren’t familiar with or don’t have expertise in certain parts of your infrastructure configuration. By modularizing your infrastructure code, you can deny access to these components until the junior engineers get up to speed.
Also, modular infrastructure naturally limits the number of changes that can be made to the configuration. Smaller changes make bugs easier to detect and allow your team to be more agile.
And if you're using IaC to support a microservices architecture, a configuration template should be used to ensure consistency as your infrastructure scales to become a large cluster of servers. This will eventually be highly valuable for configuring the servers and specifying how they should interact.
Continuously test, integrate, and deploy
Continuous testing, integration, and deployment processes are a great way to manage all the changes that may be made to your infrastructure code.
Testing should be rigorously applied to your infrastructure configurations to ensure that there are no post-deployment issues. Depending on your needs, an array of tests should be performed. Automated tests can be set up to run each time a change is made to your configuration code.
The security of your infrastructure should also be continuously monitored and tested. DevSecOps is an emerging practice where security professionals work alongside developers to continuously incorporate threat detection and security testing throughout the software development life cycle instead of just throwing it in at the end.
To that end, you can use ggshield, the GitGuardian CLI, for IaC security scanning. This tool allows you to manage large-scale IaC misconfiguration from the comfort of the command line:
#Create a token to authenticate your GitGuardian workspace ggshield auth login #Scan your local repositories ggshield iac scan REPO
It can be adopted on local workstations (as a pre-commit check) to scan your IaC before each commit, or integrated into your CI pipelines to prevent serious misconfigurations from being deployed. Learn more here:
By increasing collaboration between testing, security, and development, bugs and threats can be identified earlier in the development life cycle.
We always encourage you to prevent security issues as early as possible in the software development life cycle. This will minimize the potential cost and impact of security misconfiguration.
With a sound continuous integration process, these configuration templates can be provisioned multiple times in different environments such as Dev, Test, and QA. Developers can then work within each of these environments with consistent infrastructure configurations. This continuous integration will mitigate the risk of errors being present that may be detrimental to your application when the infrastructure is deployed to production.
Maintain version control
These configuration files will be version-controlled. Because all configuration details are written in code, any changes to the codebase can be managed, tracked, and reconciled.
Just like with application code, source control tools like Git, Mercurial, Subversion, or others should be used to maintain versions of your IaC codebase. Not only will this provide an audit trail for code changes, it will also provide the ability to collaborate, peer-review, and test IaC code before it goes live.
Code branching and merging best practices should also be used to further increase developer collaboration and ensure that updates to your IaC code are properly managed.
I highly recommend that if you are just getting started with IaC, do not try to automate everything at the outset. The reason for this is a high pace of changes. Once your platform becomes more or less stable, you will be able to automate its provisioning and maintenance.
As organizations are aggressively embracing the IaC revolution, the market is getting flooded with infrastructure as code tools. So, choosing the right cloud infrastructure automation tool for your organization is the key.
One of the most embraced tools is Terraform that is extensively explained in this article.
Another well-renowned tool in the DevOps world is Ansible. It is a configuration management tool that lets you automate the provisioning of infrastructure. In the early days of network infrastructure, Linux servers dominated the network landscape. Ansible began providing infrastructure automation solutions to Linux environments but now has evolved to support Windows, IBM OSS, virtualization platforms, containers, etc.
Ansible uses Python-based YAML syntax. It uses procedural style language to manage the infrastructure wherein step-by-step procedures for the desired state are coded. The tool stores the desired state configuration by mapping corresponding tasks with the defined group of hosts and stores them in ‘Plays’. A list of ‘plays’ is called a Playbook.
Ansible uses push mode to deliver change instructions to nodes in the network and deployments are instantly done. The agentless master architecture makes it simple to install and use. When compared with Puppet and other CM tools, the Ansible community is smaller but offers good support. It best suits short-lived environments.
The third IaC tool is Pulumi. It is a new multi-language and multi-cloud development platform founded in 2017 and is quickly evolving to become one of the best Infrastructure as Code tools. Pulumi is more or less similar to Terraform, allowing you to create and deploy infrastructure as code to every type of cloud environment. It is open-source and free to use and is available on Github.
Pulumi supports all cloud providers such as AWS, Azure, GCP as well as other cloud services and is highly flexible. However, it is not easy to use but has a short learning curve. It offers deep support for Kubernetes. With reusable components and stacks, it makes your infrastructure management job simpler.
The fourth tool is AWS CloudFormation. It is a popular cloud infrastructure automation tool coming from the IaaS giant AWS. It enables organizations to easily create, deploy and manage the AWS resource stack using a template or a text file that acts as a single source of truth.
CloudFormation uses YAML or JSON. As it runs on the AWS infrastructure, you don’t have to worry about how it stores the infrastructure configuration. Templates are used to customize AWS stack, replicate and deploy apps in multiple environments.
Change Sets is an important feature that enables you to check what changes before instantiating a template. Nested Stacks is another important feature that enables you to easily manage complex stacks by encapsulating functional logic, groups, databases, etc. in the template. It means you don’t have to compare and check old and new templates before making any changes.
Coming from Amazon AWS, CloudFormation enjoys certain benefits. AWS keeps updating its features and services and CloudFormation gets these updates as well. Moreover, AWS keeps improving CloudFormation which means users will get the latest features and best services.
Infrastructure as Code Challenges
The IaC benefits are numerous, but this model does have certain challenges that need to be addressed so you can properly tackle them prior to the implementation process.
Regardless of how consistently or frequently you configure your servers, drifts in configuration may occur in the long run. This is why you should make sure there is no outside interference after you’ve established your IaC workflow. Every time you need to modify your infrastructure, you must ensure it is done according to your pre-established maintenance workflow. We refer to this principle as infrastructure immutability - the idea that your infrastructure should stay exactly as specified and that if a change is required, then a whole new set is provisioned and completely replaces the outdated one.
Should you still end up making some non-uniform changes to a similar system group, some of them will inevitably be different from the others, potentially resulting in a shift in configurations.
Potential duplication of errors
Though the IaC implementation process and machine creation rely heavily on automation, there are still certain segments of the entire process that need to be done manually. Writing the parent code is one of those processes, and – naturally – there’s always potential for error when there’s human work involved. Even within an environment where QA checks are regular and consistent.
These errors could occur in multiple machines as a side-effect of automation and can potentially represent as many security breaches. Remember that almost every cloud vulnerability comes from a misconfiguration. To make sure you are always on the safe side, we highly recommend double-checking the code that generates your IaC architecture. This can be done through strict and extremely consistent testing and thorough auditing processes. However, these additional efforts often lead to increased overheads.
Infrastructure as Code is slowly but surely becoming the norm for organizations that seek automation and faster delivery. Developing applications at a faster rate is only possible through a streamlined workflow and an improved development environment.
However, coming up with optimal IaC solutions for your unique IT architecture isn’t something that should be approached lightly, with insufficient resources, or the lack of guidance. But once you’ve set up your IaC environment the right way, your development process will immediately start yielding results.
You can learn more about Infrastructure as code by visiting the links below: