Terraform by Hashicorp is a pioneer in the area of IaC tooling which allows to define infrastructure in a declarative manner by using its own language (HCL – Hashicorp Configuration Language). That means:
- it takes definition of the infrastructure (simplistic example could be a couple of VMs running in AWS or OpenStack) found in the config file (can be a single .tf file) defined in HCL
- connects to the IaaS by using an appropriate provider – plugin/extension that allows to talk to AWS/Openstack etc.
- compares current state of the infrastructure against what is found in the definition file (.tf)
- tries to meet the desired state found definition file (using example below it means to deploy VMs)
Approach as above allows to have a deterministic state of your infrastructure and deployment is performed by calling API of the infrastructure provider rather than manually or using different methods already offered by them (e.g. HEAT templates for Openstack, python client vs CloudFormation for AWS, awscli tool). If a VM is deleted for any reason on the IaaS re-running the terraform apply (command to check current state of the infra, comparing against the definition file and trying to meet the desired state from the file) will just deploy the missing VM.
It allows to have a common language for defining the infrastructure on different infrastructure providers (bearing in mind that each of them use basic different building blocks to create the infrastructure e.g. aws_subnet resource vs openstack_networking_subnet_v2 resource).
Terraform allows for more than just creating resources on public/private cloud providers, it can deploy on kubernetes (more of a PaaS than IaaS), or interact with RESTAPI. People/companies create their custom providers.
However, anyone with some development background will see that that HCL language is limited – even writing a simple loop, while possible – it is somehow done indirectly (I admit I did not have time to check 0.12 option which was supposed to add some typical programming constructs like for loop). Immediately the feeling is that it should be done differently – you want to write a code and have appropriate programming libraries to wrap API calls to different providers. This is where Pulumi comes in – its tenets are the same:
- it is declarative
- it compares the current state against the definition (defined in the programming language of choice – at the moment of writing JS/TS/Python/Golang are supported)
- uses programming language libraries to connect to IaaS (e.g. pulumi_gcp in Python) which extend core pulumi framework
- tries to meet the desired state (pulumi up vs terraform apply)
What is new is that it’s SaaS by default and requires to setup an account on Pulumi website. Pulumi service keeps state on Amazon S3, but there is also an option to keep it locally (different backends). If it is kept on Pulumi then you can check your created infrastructure resources via their website (actually this is very cool, you can even click to connect to created VMs consoles’).
Rather than having a separate language to define the infrastructure you just import appropriate libraries and start defining the infrastructure directly in code. There is no better source of introduction to Pulumi than Joe Duffy’s blog post: http://joeduffyblog.com/2018/06/18/hello-pulumi/.
So which one should you choose? I would say it depends on the people who are going to use it:
- Developers, people with development skills should opt for Pulumi so as not to be constrained by HCL. That also means learning curve is steeper for Pulumi.
- People without such skills will feel more comfortable with HCL and might not feel constrained by it. They should go with Terraform. I just felt I had to create a lot of boilerplate with it.
- Terraform is more mature (older tool) but Pulumi’s people are quite helpful and available on Slack so it is just kicking off.
I have posted few examples with both tools in my gitlab repo: