tl;dr: What if we provided a Terraform “cloud” for Juju that allowed you to provide custom, templatized Terraform config files that Juju would use to spin up Juju infrastructure.
I’m going to go through the thought process that led to this idea and how it might be implemented.
Me and my partner were just discussing how one of the limitations of Juju is the fact that it can’t deploy highly specialized infrastructure because it focuses on simple abstractions over infrastructure so that it can be deployed similarly to multiple clouds without modifications.
Just to clarity what I mean, when you specify the servers you need as part of a Juju bundle, for example, you say that you need at least this much CPU, at least this much memory, and you need it to be a certain Linux distribution. By specifying only these relatively universal parameters, Juju can then spin up specific infrastructure that matches those requirements on almost any cloud.
This works really well to allow you to target multiple clouds, but want it doesn’t allow you to do is spin up specialized infrastructure that is specific to a certain cloud provider.
For example, in a certain enterprise infrastructure use-case, there was the requirement to spin up servers with specialized network configuration including a VPN tunnel. This needed to provision cloud-specific resources in a targeted configuration. Juju would not be suitable for this use-case because of its high-level abstractions. Instead Terraform was used because, instead of abstracting over clouds for portability, Terraform goes the route of allowing you to define the specific infrastructure you want provisioned in each cloud.
Both of the paradigms make sense and you can’t have specific control and high-level abstractions at the same time, so both tools have their place.
Still, me and my partner were thinking about how we might be able to marry the two ideas. What if I wanted to be able to use Juju to deploy my applications on infrastructure that I had customized for a specific cloud/use-case.
The first thought is that you can use Juju’s manual cloud to add infrastructure that was provisioned with Terraform to the Juju controller. You could probably even get terraform to automatically add the provisioned infrastructure to the Juju controller for you. The obvious disadvantage of the manual cloud is that Juju cannot automatically provision servers for you when you do something such as a
juju add-unit mysql or when you deploy Juju bundles.
Then I had an idea. What if you used a templating language such as the Go templating language, Mustaches, Liquid, etc. to write a Terraform file ( which I’m not going to call a Terraform template for the sake of confusing terminology ) where the inputs to the template were the requirements that Juju has for the machines, such as memory, CPU, and distro. So the workflow would be like this:
The user would create a template that uses the infrastructure requirements from Juju models and bundles and renders to a valid Terraform file that will provision the infrastructure.
When somebody does something like
juju add-unit, Juju would re-render the template with the updated list of servers required and then re-run
terraform apply to update the infrastructure.
This model allows the user to to create specific infrastructure tailored to the deployment that they need while still allowing them to get the first class user-experience of having Juju trigger the provisioning of the machines.
I think that this could be relatively feasible and open Juju up to a lot of situations where it might not otherwise be used.