Automating infrastructure as code: Deploying Kubernetes with Digger and GitHub actions

Digger automates Terraform in CI pipelines, leveraging your existing infrastructure. Learn how to deploy a Civo Kubernetes cluster using Digger and GitHub Actions.

4 minutes reading time

Written by

Steve Miller
Steve Miller

Engineering Manager at Tuition.io

Terraform is a great tool for automating infrastructure configuration. As your configuration and environment grow larger, and additional team members come in to help manage infrastructure, a better model needs to be in place to help run your Terraform code in a collaborative manner.

Many solutions exist in both the open source (Atlantistf-controller) and commercial (Terraform CloudEnv0Spacelift) space. A solution that came to my attention recently is Digger.

Throughout this tutorial, we'll explore Digger, an open-source tool designed to run Terraform processes within your CI pipeline, leveraging your existing CI infrastructure.

What is Digger?

Digger is an open-source tool that allows you to run all Terraform processes using the same CI infrastructure you already use. It reuses your CI infrastructure with jobs, logs, compute, orchestration, etc., so you can benefit from your existing software deployment methodology.

Prerequisites

Before getting started with this tutorial, you will need to have a Civo account. Then, to launch a Civo Kubernetes cluster using Digger.dev, you can follow these steps:

  • In your Civo account, obtain an API token by going to Settings -> Profile and clicking the Security tab.
  • Create a new GitHub Repository.
  • In the new GitHub repository, go to Settings -> Secrets and Variables -> Actions. Create a CIVO_TOKEN secret with the API key above.
  • In the New Repository, ensure you enable GitHub Actions, as well as grant the pipeline read and write permissions.
 enable GitHub Actions

Configuring the Civo Provider in Terraform

In the repository, create the following files (links provided with example code):

Step 1: Specify required provider as maintained by Civo

terraform {
required_providers {
civo = {
source = "civo/civo"
}
}
}

Step 2: Configure the Civo Provider

Tip: This configuration sets up the Civo provider, allowing Terraform to interact with your Civo account. Ensure that the CIVO_TOKEN secret is set in your GitHub Actions pipeline to authenticate Terraform with Civo.

provider "civo" {
region = "LON1"
}

Step 3: Query xsmall instance size

data "civo_size" "xsmall" {
filter {
key = "type"
values = ["kubernetes"]
}
sort {
key = "ram"
direction = "asc"
}
}
data "civo_size" "small" {
filter {
key = "type"
values = ["kubernetes"]
}
filter {
key = "name"
values = ["g4s.kube.small"]
match_by = "re"
}
}

Step 4: Create a firewall

resource "civo_firewall" "core-firewall" {
name = "core"
create_default_rules = false
ingress_rule {
label = "k8s"
protocol = "tcp"
port_range = "6443"
cidr = ["0.0.0.0/0"]
action = "allow"
}
ingress_rule {
label = "k8s"
protocol = "tcp"
port_range = "80"
cidr = ["0.0.0.0/0"]
action = "allow"
}
ingress_rule {
label = "k8s"
protocol = "tcp"
port_range = "443"
cidr = ["0.0.0.0/0"]
action = "allow"
}
}

Step 5: Create a cluster without specific cluster type by default is K3s

resource "civo_kubernetes_cluster" "core-cluster" {
name = "core"
firewall_id = civo_firewall.core-firewall.id
applications = "cert-manager,traefik2-nodeport"
pools {
size = element(data.civo_size.small.sizes, 0).name
node_count = 3
}
}

Setting up the GitHub Actions pipeline

The next step is to sketch out the GitHub Actions pipeline and core Digger configurations. The main branch configuration needed for this is:

name: CI
on:
pull_request:
branches: [ "main" ]
types: [ closed, opened, synchronize, reopened ]
issue_comment:
types: [created]
if: contains(github.event.comment.body, 'digger')
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
# Based on https://github.com/diggerhq/digger/issues/395#issuecomment-1601257947
permissions: write-all
steps:
- name: digger run
uses: diggerhq/digger@v0.2.0
with:
# All current locking mechanisms require large-cloud resources
disable-locking: true
# AWS Setup Below
# setup-aws: true
# aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
# aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# aws-region: us-east-1
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CIVO_TOKEN: ${{ secrets.CIVO_TOKEN }}

How to configure Digger

auto_merge: false
projects:
- name: "core-cluster"
dir: core-cluster

Testing the pipeline

Once everything has been committed to the main branch, you'll need to make a PR to actually test the pipeline. Create a new branch, initial-commit. Make a minor change to any of the Terraform in the core-cluster directory. Push up that branch, then create a new PR.

In that PR, write a new comment to trigger a terraform plan to see the actions the Terraform code will perform.

write a new comment to trigger a terraform plan to see the actions the Terraform code will perform

Review the output of the terraform plan output. This will let you and any peer reviewers see what infrastructure changes will occur.

Review the output of the terraform plan output

Ensure all resources being created or modified are expected, then write a comment of digger apply.

digger apply

On the PR, you will see the results of the Terraform apply.

Terraform apply

Once the apply is complete, merge your PR into the main branch.

Once the pipeline has been completed successfully, you can log in to your Civo account and verify that the Kubernetes cluster has been created.

log in to your Civo account and verify that the Kubernetes cluster has been created

Now we have completed our first cluster, provisioned completely from Digger!

While this configuration will get you far, in Part 2, we will explore hardening our pipeline with better state and lock management, all within the Civo architecture!

Summary

Now that we have finished this tutorial, you should be able to use Digger to automate Terraform processes within a Civo Kubernetes cluster using GitHub Actions. You can read part 2, “Hardening our Infrastructure as Code Pipeline with Digger,” here.

If you are interested in learning more about the topics discussed in this tutorial, check out some of these resources:

Steve Miller
Steve Miller

Engineering Manager at Tuition.io

Steve Miller is a DevOps practitioner who enjoys creating robust architectures leveraging development and operational best practices. His twenty years of experience cover a wide variety of platforms in the public and private sectors. His background also covers a wide variety of cloud, virtualization, and enterprise datacenter technologies.

View author profile