With Hashicorp moving a bit away from their roots in the Open Source world and going into the more locked-in, don’t-compete-with-me kinda scenario, it’s hard not to start thinking whether you should be looking at jumping ship away from your massive Terraform setup. If you’re in that boat, where can you go? What are the alternatives to Terraform?
In this article, I’ll provide some of my recommendations as to where to go, with some pros and cons on each option. While your mileage might greatly vary depending on your technical requirements and conditions, there won’t be a one-size-fits-all solution, so I’ll try to cover as many options as possible.
Pulumi is a tool that allows you to write your infrastructure as code in your favorite programming language, and then it will take care of deploying it for you. It supports a wide range of languages, including TypeScript/JavaScript, Python, Go, C#, Java, and YAML.
While that sentence before might not get you hyped for it as a potential solution, think about the implications of it: you can write your infrastructure in any way you see fit, supported by some of the most used programming languages, without worrying about the limitations of something like HCL (Terraform’s language). If your team is already familiar with one of those languages, you can get started with Pulumi easily.
This is a huge plus and benefit, you avoid having to learn a new Domain-specific Language like HCL, including its quirks (I see you, dynamic
blocks! π€) and instead use the coding strategies you see fit. Just imagine having the ability to declare functions, ternary operators and even normal for-loops in your infrastructure code… Delicious!
What’s even more interesting, Pulumi offers a subcommand of their CLI that allows you to convert Terraform code to Pulumi, and while you would be correct to think it won’t cover every single case scenario out there, it will cover a wide amount of situations, leaving you at least with a head start. It’s like having a new coworker that knows Pulumi and can help you migrate away from Terraform!
pulumi.com/tf2pulumi/
, also allows you to use the conversion tool entirely online, for quick conversions or tests. Granted though, you might want to use the CLI to take full advantage of the rest of the tooling, but hey, it’s your choice! πHere’s a quick example to get you excited, taken straight from their website:
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_instance" "web" {
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.micro"
tags = {
Name = "HelloWorld"
}
}
And this is the converted code, in this case, to TypeScript – although their website allows you to convert to Python, Go and C#, while the rest of the languages are available via the CLI:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const ubuntu = aws.ec2.getAmi({
mostRecent: true,
filters: [{
name: "name",
values: ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"],
}, {
name: "virtualization-type",
values: ["hvm"],
}],
owners: ["099720109477"],
});
const web = new aws.ec2.Instance("web", {
ami: ubuntu.then(ubuntu => ubuntu.id),
instanceType: "t2.micro",
tags: { name: "HelloWorld" }
});
And again, think about things like for loops, if-else statements, and all of the other things you’re used to from your favourite programming language (which hopefully it’s among the ones supported by Pulumi π). Neat, no?
Engin Diri mentioned to me via Twitter (ehm, π?) two things:
In this article from his own blog, Engin explains how to launch a Minecraft server on Exoscale using Pulumi and YAML, and if you want to learn more about how to use Pulumi with YAML, their official blog post has you covered: Using Pulumi with YAML.
Thank you, Engin!
The good things:
The bad things:
While this is heavily Cloud-dependant, vendor-locked-in, it is still an option I’ve already heard teams considering moving to. Amazon CloudFormation is a service that allows you to write your infrastructure as code in JSON or YAML, and then it will take care of deploying it for you.
I have to admit as a personal note that it is not very user friendly unless you really grasp all the concepts behind it, and it’s not very easy to get started with. It’s also very opinionated (thanks to the tight dependency on Amazon), and it’s not easy to get out of the AWS ecosystem once you’re in. But hey, it’s an option!
On the bright side, CloudFormation is well integrated and in some (emphasis in “some”) situations, it would take less tinkering than what you could potentially achieve with Terraform and the cherry on top is that Cloud Administrators can configure CloudFormation templates that other can use as a self-serve mechanism, which is a nice touch.
Following the idea above of deploying an EC2 instance, the code would look similar to:
AWSTemplateFormatVersion: 2010-09-09
Description: A simple EC2 instance
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0ff8a91507f77f867
InstanceType: t2.micro
Tags:
- Key: Name
Value: MyEC2Instance
Google has a similar service called Google Cloud Deployment Manager, which is also worth checking out if you’re in the Google Cloud Platform ecosystem. It looks similar, but doesn’t strictly use the same domain-specific language as CloudFormation.
The good things:
The bad things:
Ah, the old King. Ansible is a configuration management tool that allows you to write your infrastructure as code in YAML, which will then take care of deploying it for you. IaaC veterans might recognize it as one of the early players in this game, and it still remains a very valid option, where I’ve personally seen it surpass others from the same era like Chef, Puppet or SaltStack (now “Salt Project”).
Ansible has personally served me well in the past, especially when you have to do more than just provision infrastructure but also get down to configuring nodes and services. Due to how long it’s been in the game, documentation is very good, and there’s a lot of community support around it.
Now granted, the process to get it working is somewhat different than the rest of the other tools in this space, as you need to install Ansible in your machine, and then use it to provision your infrastructure. Ansible is also agentless, meaning you don’t need to install anything in the nodes you’re provisioning, which is a nice touch.
For example, launching an EC2 instance would look like this (taken from the Ansible documentation):
- name: start an instance with a public IP address
amazon.aws.ec2_instance:
name: "public-compute-instance"
key_name: "prod-ssh-key"
vpc_subnet_id: subnet-5ca1ab1e
instance_type: c5.large
security_group: default
network:
assign_public_ip: true
image_id: ami-123456
tags:
Environment: Testing
But then you would also have to work off that key_name
parameter, and even before that, install and configure the AWS CLI and Ansible in your machine. It’s not as straightforward as the rest of the tools in this list, but it’s still a valid option since it can be configured as a repeatable process if needed if you’re willing to go through the hoops of making it happen.
The good things:
The bad things:
If you’re in the Kubernetes hype wagon, then you might want to check out Crossplane. Crossplane is a Kubernetes add-on that allows you to write your infrastructure as code in YAML, and then it will deploy it for you.
It does this by using a Kubernetes Operator that you have to install in a cluster to apply your YAML then manifests, coded very similarly to any of the other Kubernetes resources you’re familiar with, like Pods
, Deployments
or Services
, for example. For teams that understand what the words CRD
and Admission Controller
imply, Crossplane is an excellent choice.
Crossplane is leveraging what’s called the “Kubernetes Resource Model” by teaching Kubernetes about new resources that the Kubernetes API can manage. This is a compelling concept, and it’s what makes Crossplane so interesting!
Another super useful thing is that you can use the tooling around Kubernetes to simplify certain operations. For example, your deployments can automatically fetch credentials from Kubernetes Secrets
and inject them into your infrastructure. The usual tools that work with your Kubernetes deployments will also work with Crossplane. If you’re already leveraging tools around these concepts, Crossplane can play quite nicely with them.
The model is so popular, in fact, that even Cloud Providers like Google are replicating it. Google provides a similar solution via their Anthos Config Connector (ACC) product – also worth checking out if your shop is Google Cloud heavy!
The major issue for me? The chicken and egg problem: Since you have to have Crossplane installed in a Kubernetes cluster, you need, well, a Kubernetes cluster to begin with! In the past, I’ve felt down to the Terraform realm first to create an empty cluster, install Crossplane in it, and then use Crossplane to provision the rest of the infrastructure, but that isn’t good if you’re trying to get away from Terraform! π
One of the convincing points here is that since Crossplane is nothing more than yet another Kubernetes manifest, you can use Kubernetes tools around it. Say, for example, you want to prevent certain users from being able to create costly resources. You can use Open Policy Agent or Kyverno to add rules to your cluster to prevent that from happening. Neat, huh?
Another suuuuuper neat thing from Crossplane are their “Compositions”. Basically, they’re a way to apply a single manifest and get instead a whole bunch of resources. For example, you can create a single Composition
that will generate a VPC, a subnet, a security group, and an EC2 Instance with a single YAML manifest, by simply referencing this composition by name. It’s a great way to remove the complexity of creating many resources simultaneously.
Going back to our original example of creating an EC2 instance, that would look similar to this:
# This file will configure the AWS provider credentials for
# Crossplane by reading the credentials from a Kubernetes Secret
apiVersion: aws.crossplane.io/v1beta1
kind: ProviderConfig
metadata:
name: aws-config
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: aws-creds
key: creds
---
# This would create an EC2 instance in AWS using the credentials
# from before since the "aws-config" name references them
apiVersion: ec2.aws.crossplane.io/v1alpha1
kind: Instance
metadata:
name: my-ec2-instance
spec:
forProvider:
region: us-east-2
imageId: ami-0a987df89798 # change to your AMI
instanceType: t2.micro
keyName: my-key-pair # change to your key pair
providerConfigRef:
name: aws-config
The good things:
The bad things:
docs.crds.dev
, see the Instance
CRD here, for exampleAfter those 4 options, with personal strong preferences towards Crossplane and Pulumi π you might be wondering though, is this really necessary? Is the change really that bad?
As a personal opinion, I have to agree with Spacelift’s strongly-worded e-mail they sent a few days ago, quoting a section of it, emphasis mine:
Competition in services on top of Terraform has recently driven much innovation as many of our own concepts eventually found their way to Terraform Cloud. Itβs also worth remembering that Terraform itself is built on top of multiple open source libraries and an open source ecosystem.
Without the volunteer work of hundreds of unpaid individuals, HashiCorp products would not be successful, there would be no ecosystem, and the company would not exist.
And look, I understand HashiCorp truly built a remarkable product, and they deserve to capitalize on that. But I also think the community that helped them get there deserves similar respect. This change is one of those ways to burn bridges with the community, and I’m wondering if there are better ways to go about this.
There are already talks about a potential fork before the end of the year, which might give us an exciting exit to the Terraform problem. Some well-known companies have signed this manifesto and even committed engineering hours to ensure it stays as a community-driven project, under the direction of a foundation. I’m still determining where this will lead and what will happen, but I’m definitely keeping an eye on it!
In terms of the alternatives above, my personal favourites in order are:
But what’s your take on it? Any other tool you’d like to recommend? Let me know in the comments below! π