Infrastructure as Code (IaC) tools are one of the crucial technologies in the cloud computing world. In the last few years, IaC has been proving to be beneficial to organizations in terms of efficiency in cloud resource management, less risk of human error, promoting automated deployment, consistency, etc.
Hashicorp’s Terraform has been a major IaC tool, and I have covered a lot of content about Terraform on this blog. I often get asked – what are the alternatives to Terraform? In this post, we discuss the same, in no particular order. We will not dive deep into Terraform, but it is assumed that the reader is already aware of its basics.
When we discuss IaC, we have to consider a generic set of features based on its usage. These are not tool-specific features, however, while making a choice of IaC tool we have to answer the below questions.
- Which language is used to write IaC?
- How are the relationships between the configuration and the cloud resources managed via these configurations maintained?
- Is it cloud agnostic or cloud adherent?
- What does a team development workflow look like?
- Is it open source or proprietary?
- What does the architecture of a particular IaC tool look like?
- What are the deployment requirements?
- Is there any plugin ecosystem or community support?
At every granular level, there are a lot of details to compare, discuss, and debate about. However, we will explore a few Terraform alternatives with respect to the above pointers and shed some light in the hope that it helps you decide on the choice of the IaC tool.
Here are some of the Terraform alternatives:
At a high level, Pulumi’s architecture consists of a language host, where the script files are developed. A CLI and deployment engine that create the cloud resources based on the scripts, and also make sure of the consistency. A state management mechanism where the last deployed state information is stored for future operational reference.
(image copied from the Pulumi docs here)
The state is usually managed in Pulumi Service – a service hosted online – which is a default choice for any operation performed. However, it is possible to self-host this service and use it internally. Additionally, Pulumi also supports state backends like AWS S3, Azure Blob Storage, and Google Cloud Storage. State management is also possible on the local filesystem with an explicit –local flag.
Infrastructure expressed using one of the languages in Pulumi is considered to be declarative. When Pulumi binary executes the program files, it feeds the information related to the desired existence of a cloud resource to the deployment engine. The deployment engine in turn checks against the state backend and decides whether to create, update, or delete the resource.
Pulumi SDK for the language of your choice makes use of provider plugins that consist of resources. A provider in Pulumi corresponds to the cloud platform like AWS, Azure, GCP, and so on. While a resource corresponds to the services, these cloud platforms provide. Providers use cloud platform APIs to perform the deployment operation as per the supplied program files.
Pulumi is a cloud-agnostic IaC tool with a growing community. It supports a range of cloud providers including AWS, Azure, and Google Cloud.
CloudFormation is a service provided by AWS to manage cloud resources in a more automated, reliable, consistent, and predictable manner. As the name suggests, AWS CloudFormation is a service provided by AWS, thus it is used to design, deploy, and manage AWS infrastructure.
Infrastructure is defined using CloudFormation templates, which use JSON or YAML syntax. Since this is a very familiar and user-friendly format, getting started with CloudFormation templates is quick. However, given the abundance of services and related attributes, it is not straightforward to define the infrastructure in CloudFormation templates from scratch.
This is where the CloudFormation Designer comes into the picture. CloudFormation designer is an editor which helps you build CloudFormation templates from scratch. The simple drag-and-drop interface helps developers design their infrastructure requirements by selecting the components they need in their architecture and also setting various attributes related to it. The CloudFormation designer simultaneously displays the output of the template on the same screen.
Once the CloudFormation template is created and validated to create the infrastructure as defined, the infrastructure thus created is stored as a Stack. A Stack is a set of infrastructure managed using a specific Template. The Stack also provides various parameter and attribute information.
For example, it keeps track of the events of creating and destroying the infrastructure, performs drift detection, protects from accidental termination, outputs the desired values from the infrastructure creation events, etc.
When we update an existing infrastructure managed by CloudFormation templates, Change sets are created. Change sets provide a way to preview the changes which will be applied. It highlights the creation, deletion, and update activities that will be performed due to the modified CloudFormation templates.
AWS CloudFormation templates help manage AWS infrastructure in a streamlined and consistent manner, with less possibility of human error. AWS also provides a number of quick-start templates with pre-defined solutions. All the actions performed using the AWS CloudFormation web console can also be performed using AWS CLI. AWS Also maintains a CloudFormation-specific CLI.
Azure ARM templates serve a similar purpose for Azure, as that by CloudFormation Templates for AWS but with few differences. To begin with, Azure ARM templates, aka Azure Resource Manager (ARM) Template is Azure native way to manage infrastructure as code.
ARM templates use JSON format to declare the desired state of infrastructure. A couple of ways to develop ARM templates are to use VS code extension developed by Microsoft to create ARM templates, and on the Azure portal as well.
Infrastructure in Azure is managed with respect to the subscription ID and resource group. ARM templates act as inputs to Azure Resource Manager, which interprets these templates and performs appropriate REST API calls to provision the resources. The resources thus created are always associated with a particular subscription and resource group.
There are a number of ways to work with ARM templates. After the portal, the most used options to deploy ARM templates are Azure CLI and PowerShell CLI. The verification of the deployment is done by visiting the Resource Group page. It provides details about the successful and failed deployments.
The ARM templates implement the function to accept input variables as well as generate the output variable values post successful deployment. They also support certain template functions, which help in querying the resources during runtime. This helps build dynamic and flexible ARM templates by not requiring to hardcode certain values.
Unlike AWS CloudFormation change sets, when the ARM templates are updated with new resources or by removing the older resources, there is no verification step before the action is triggered.
Google Deployment Manager is a service provided by Google Cloud Platform (GCP) to recreate compute environments in a predictable manner. Unlike AWS and Azure, the solution provided by Google Deployment Manager is not a full-fledged IaC solution but does assist in creating certain infrastructure components in GCP on a use-case basis.
Infrastructure is defined in YAML formatted configuration files. Every infrastructure component is represented as a resource in configuration files, and every resource has a type attribute that lets the deployment manager understand which REST APIs to use to provision the resource.
Each configuration file represents a single deployment. Every deployment has a user-defined name, which is used to access and analyze the status of deployment on the web console. To manage multiple resources in a single deployment, Templates are used as reusable building blocks. Templates are developed using Python or Jinja2 templating language.
To deploy the configuration using Google Deployment Manager, Google Cloud CLI is used. Google Cloud CLI comes bundled with deployment-manager function to process the configuration YAML files.
The information about the deployed components using the deployment manager is stored in a read-only object. This object is called manifest and is an equivalent of the state file in Terraform. However, there is not much to manage as it only provides the information of the currently deployed configuration. Any following update to the configuration deployment creates a new manifest.
There is no verification step involved when updating the deployment using configuration files. Instead, care has to be taken manually while making changes to the deployed configuration. For example, the existing dependencies of any resource being replaced have to be verified before deploying the configuration.
As mentioned earlier, Google Deployment Manager is a solution that is use-case specific and works well for managing deployments within GCP. However, it is not a complete IaC tool with all the bells and whistles we would expect in other IaC solutions.
If we want to deploy cloud applications on AWS, and at the same time develop the infrastructure as code using familiar programming languages then AWS CDK would be the right choice. With AWS CDK you can develop IaC on AWS in the same IDE, whilst leveraging the advantages offered by CloudFormation Templates.
However, AWS CDK offers much more than leveraging CloudFormation features in familiar programming languages. It is a way to develop the applications and the infrastructure these applications are hosted on, in the same IDE. Thus every iteration results in a fully deployed and functional application.
AWS CDK makes use of constructs, which define infrastructure components with proven defaults and flexibility to change them. The AWS Constructs library provides constructs for many AWS services that help in wrapping the complexity as well as taking care of interconnectivity between multiple services.
Multiple constructs are put together to form a Stack, which is analogous to CloudFormation Stacks. Similarly, multiple Stacks can be part of a single App, thus enabling the interconnectivity between services included in multiple stacks. It is also possible to import existing CloudFormation templates into AWS CDK, and vice versa.
AWS Constructs also correspond to the CloudFormation resource types. These constructs come in three flavors.
- L1 – with a 1:1 correspondence to the CloudFormation service. It is as good as using the AWS CDK version of the CloudFormation template defined for any service on AWS.
- L2 – also known as curated, is use-case specific construct that may employ one or more AWS services to satisfy a specific use case.
- L3 – these are pattern-level constructs that define the end-to-end architecture of an application.
AWS CDK comes with a developer-friendly CLI that helps in initializing a new application infrastructure, modifying existing infrastructure, analyzing the changes before deployment, and finally deploying the infrastructure.
Given its support for multiple programming languages, AWS CDK offers much more flexibility as compared to CloudFormation templates. However, since it synthesizes CloudFormation templates under the hood, it is adherent to the AWS cloud platform.
CDKTF is a cloud development kit by Hashicorp. Hashicorp is already known for its IaC tool – Terraform. Terraform uses the proprietary language known as Hashicorp Configuration Language – HCL as well as JSON. However, if we want to leverage the knowledge of familiar programming languages like Typescript, Python, Java, C#, and Go, to develop the infrastructure, then CDKTF is the choice.
It is similar to AWS CDK. However, with CDKTF we leverage the end-to-end infrastructure lifecycle management abilities offered by Terraform, and it is cloud agnostic. Unlike AWS CDK, CDKTF converts the script file written in the language of choice into Terraform configuration files in JSON format.
CDKTF has its own set of CLI commands which help in initializing the project, generating the Terraform config files, and deploying resources to the respective cloud platform. Even though Terraform is the underlying operational layer, we do not have to worry about the Terraform CLI commands.
Another important component in CDKTF is the cdktf package which contains the core libraries which help us in converting our scripts to Terraform configuration files. Using cdktf it is possible to convert the existing Terraform configuration defined in HCL to the preferred language in CDKTF. However, the configurations defined in CDKTF can only be translated to JSON formatted Terraform configuration.
CDKTF employs an application design architecture that is similar to AWS Constructs. Here the applications are wrapped into an App, which may contain multiple Stacks, and each Stack is a collection of multiple cloud resources. Resources defined in Stacks that are part of the same application can communicate with each other.
CDKTF is increasing in popularity as it allows developers to develop infrastructure by using the programming language familiar to them, at the same time leveraging the infrastructure lifecycle management capabilities of Terraform.
Microsoft Bicep is an open-source domain-specific language that provides a syntax to deploy Azure resources. Since this is a domain-specific language, it has its own set of syntax which might add a learning curve for developers. It is also not cloud-agnostic as it works with Azure Resource Manager to create and manage Azure cloud components.
As discussed in earlier sections, ARM templates use JSON format to express the IaC, which can become a bit cumbersome while developing large sets of infrastructure. Microsoft Bicep allows for a programming experience that results in an easily traceable IaC.
Under the hood, Bicep files are submitted to Azure Resource Manager which then provisions the resources on the Azure cloud.
Developing IaC using Microsoft Bicep supports modularity, where you can develop and reuse infrastructure components. It also implements a verification step where we can see the operations that would be performed before actually executing them.
As far as state management is concerned, all the state information is stored in Azure. There is not much that can be done with this information apart from querying.
Red Hat Ansible is primarily a configuration management tool. It has many product features, but for the sake of this post, we will limit our discussion to IaC and infrastructure lifecycle management capabilities offered by Ansible.
Ansible works on the concept of a playbook. It is a YAML formatted file that describes the sequence of activities that should be performed by the Ansible host. This principle also applies to public cloud provisioning.
Ansible is cloud-agnostic – it supports hundreds of modules for AWS, GCP, OpenStack, and Microsoft Azure, where it helps manage compute, databases, networks, containers, and related infrastructure.
Unlike other configuration management tools like Chef, Puppet, Salt Stack, Ansible is agentless. This eliminates the need for agent installation, which otherwise is a convenience to manage software patches and application versions on the target host machines. Instead, Ansible relies on SSH for Unix-based OS and WinRM for Windows OS to log into the resources and perform actions.
This ability allows Ansible to manage the resources which are also provisioned by it. There is no explicit state management with respect to the infrastructure itself and no provision of previewing the potential changes to the infrastructure.
As mentioned earlier, Ansible is geared toward configuration management, so it may not be the best choice for infrastructure management. However, using Ansible in conjunction with another IaC tool can be a great combination for any organization’s automation aspirations.
See the detailed comparison: Terraform vs. Ansible : Key Differences and Comparison of Tools
We encourage you to also explore how Spacelift makes it easy to work with Terraform. If you need any help managing your Terraform infrastructure, building more complex workflows based on Terraform, and managing AWS credentials per run, instead of using a static pair on your local machine, Spacelift is a fantastic tool for this. It supports Git workflows, policy as code, programmatic configuration, context sharing, drift detection, and many more great features right out of the box. You can check it for free, by creating a trial account.
Terraform Management Made Easy
Spacelift effectively manages Terraform state, more complex workflows, supports policy as code, programmatic configuration, context sharing, drift detection, resource visualization and includes many more features.