Provisioning compute instances with Chef from Terraform
Jeroen Jacobs -
The problem
When Terraform 0.13.4 was released, various provisioners, including the Chef provisioner, were deprecated with no replacement. They were later removed in Terraform 0.15.
You’d get a warning about this such as this one:
Warning: The "chef" provisioner is deprecated
on example.tf line 52, in resource "google_compute_instance" "example":
42: provisioner "chef" {
The "chef" provisioner is deprecated and will be removed from future versions of Terraform. Visit https://learn.hashicorp.com/collections/terraform/provision for alternatives to using provisioners that are a better fit for the Terraform workflow.
As we had hundreds of VMs set up already using this provisioner, we’d needed a drop-in replacement that would not hinder the current workflow and pipelines.
The solution
We decided to replace the Chef provisioner with a custom remote-exec provisioner. One of the requirements for us was that development machines and mostly our CI setup would not need to have any of the Chef tooling installed locally. In “the old days”, one would have used knife bootstrap to provision a VM. We no longer want this cumbersome dependency and require our VMs to be able to fully bootstrap themselves.
We ended up writing a custom shell script that gets run through a remote-exec provisioner during the creation of the instance.
Hence we cooked up the following:
The legacy
There are valid reasons why provisioning is something that should not be part of Terraform’s work. We’re not only looking at moving the provisioning out of the code, we’re looking at eliminating the need to provision software with Chef at all. For this we’re looking at a possibility to move some of the provisioned software to a Kubernetes cluster, or a managed service, to eliminate the overhead that comes with configuration management. In the same breath, we’re also looking at moving away from Chef as a whole, but that’ll be a story for another blogpost.