Infrastructure as code — for developers

As developers, we are fairly conversant with CI systems so I am going to scope it out of this post. This is a quick introduction to three tools that you really need to know if you are a developer looking to get into operations.

Terraform

Terraform is a tool for declaratively provisioning infrastructure on various cloud providers. While AWS has tools like CloudFormation, its very AWS specific. Terraform uses the Hashicorp Configuration Language to construct a graph of resources that you would like to create eg., EC2 instances, VPCs, Security groups and so on. There are providers for every possible cloud provider who has an API. Like kubernetes, it follows a state enforcement pattern where you declare the state you want to be and diffs it with the current state and effects the state change. You can either store the state locally (by default and not recommended) or you can store it on any of the backends like etcd, consul or S3. With support for S3, we can also use any S3 compatible service like DigitalOcean spaces by setting the endpoint URL. Terraform guides are quite good to get a quick overview of Terraform.

Ansible

While there are a lot of tools like Chef, Puppet, Salt, etc that compete in the same space as Ansible, I would recommend Ansible over those. My criteria for choosing Ansible was

  • It should not require an agent
  • It should be simple and extensible
  • It should be easy to integrate with other tools like Terraform and Packer.

Ansible uses YAML to declare the state of the machine. While terraform works at the level of cloud resources, Ansible uses modules for effecting chages on the machine like installing APT packages, copying files or running arbitrary commands. There is a digital ocean tutorial on creating a kubernetes cluster with ansible. It gives a good understanding of how a moderately complex Ansible script looks like.

Packer

While we can use Ansible to setup a blank VM, it would be even better to create an image that has most of the software setup. This allows us configure an autoscaling group to use this AMI instead a standard Ubuntu distro. This also ensures that the VM you create is ready for action as soon as it spins up. Packer uses JSON as its configuration language. It can build images for any cloud platform like AMIs or Google Cloud images or even DigitalOcean snapshots. Packer also has a templating engine that is very similar to Golang’s text/template package. You can use various provisioners to build the image using shell scripts or tools like ansible, puppet or chef-solo.

Workflow

Let us consider setting up a minimal Kubernetes cluster. We roughly have two roles.

  • Controller — This contains etcd, API server, controller manager and scheduler.
  • Node — This contains docker, kubelet and kubeproxy

We’ll initially use packer and ansible to create an image that has the binaries and packages installed. It will not have the services configured or the certificates or kubeconfig files.

We’ll then write a separate set of playbooks that will create certificates locally on the build machine and use terraform to launch nodes and then call ansible playbooks to setup the nodes it creates by passing in these configuration variables to ansible. Ansible will generate certificates locally for the IP addresses for the nodes and setup kubeconfig files that point to it. It would also setup systemd service definitions and start them. As a follow up post, we are create a Kubernetes cluster on DigitalOcean with Terraform, Ansible and Packer. Click on the follow button to get notified on our blog posts.

Follow up posts: