Deploying a Kubernetes cluster on Proxmox using Terraform and Ansible: Part 2 - Setting up k8s

In part 1 of this article, I showed how to use Terraform to deploy two virtual machines on Proxmox and provision them with cloud-init. In this part, I will show how to integrate Ansible with Terraform and use Ansible to install and set up a Kubernetes cluster on the virtual machines.

Integrating Ansible with Terraform

Terraform does not have native integration with Ansible, but we can leverage the local-exec provisioner to make our own integration. The local-exec provisioner runs a command locally (on the machine running Terraform) after a resource is created. In our case we would like to run Ansible after both virtual machines have been created and provisioned. To do this we need a resource that is always created last. One way to do this that meshes well with Ansible is to use a Terraform resource to manage the Ansible Inventory. Since the inventory depends on the IP-addresses of the virtual machines, it will always be created last. We can then use the local-exec provisioner on this resource to launch Ansible.

To do this, create a new file called ansible.tf with the following content:

Note: This file refers to a directory called ansible and a file called playbook.yml. We will create them in the next step.

Deploying a Kubernetes cluster using kubespray

There are several ways to install Kuberentes using Ansible. I decided to use kubespray, because it is well maintained and supports several different container runtimes and network plugins. To use kubespray we will add it as a git submodule. Create a new directory called ansible and run the following commands:

$ cd ansible
$ git submodule add https://github.com/kubernetes-sigs/kubespray

To use kubespray we need to add it to ansible's search path. To do this, create a file called ansible.cfg and add it to the ansible directory:

We can then use kubespray by creating a playbook and importing it. Create a file called playbook.yml and add it to the ansible directory:

The final directory structure should look like this:

.
├── ansible
│   ├── ansible.cfg
│   ├── kubespray
│   └── playbook.yml
├── ansible.tf
├── cloud-init
│   └── user-data.yml
├── files.tf
├── main.tf
└── virtual_machines.tf

That's it! You can now run the following command in the root directory to bring up the virtual machines and deploy the Kuberentes cluster:

$ terraform apply