Learning Kubernetes part 1 - the Terraform Setup

Over the past months I have been working to level up my skills to gain some knowledge around Kubernetes. I have found it to be quite challenging, maybe because I am caught in my head and the landscape is vast in K8s, who knows.

Thus far, I have learned a lot and continue to work with Kubernetes in the lab while finding out what is next for me. I am excited about cloud architecture and building designs for what can run your “next big thing” in the cloud in the best way possible.

What Have I Learned?

Up until recently, I thought I was a slow learner, but I have found that I learn differently from others. Lot’s of reading, and some go do it, and sometime down the road, I will catch on.

In the last couple of weeks, I have been building AKS clusters to tinker with in Azure. Because I want to stay current (or as current as possible) with Azure, my lab is both on my laptop to play with standing up some docker images and in Azure. It gets built with Terraform when I am going to use it and torn down when I am done.

AKS is Azure’s managed Kubernetes service, as a consumer you worry about the worker nodes and putting your code there to run the next big thing. The management of the system happens inside the platform and the Microsoftees work it out.

Let’s step through my lab in Azure - comment’s appreciated to improve it or outline things I have not considered yet - I guarantee there are many.

The Resources

  • Azure Resource Group
  • Azure Container Registry
  • Azure Kubernetes Service
  • Key Vault
  • Azure Virtual Network
  • Gitlab Actions

Note: An Azure Subscription is needed to follow along and build these resources. You can get one for free for 30 days here

To build and remove resources I have chosen Terraform, Terraform Cloud, and GitHub Actions for these items. Code samples will be shown in Terraform.

Setting Up Terraform

You will need to install Terraform, and an editor - VSCode or JetBrains WebStorm work really well. There are plugins for both of these editors for Terraform which will help with formatting and code completion.

Because this post works with Azure, you will also likely want to install the AZ CLI and/or Azure PowerShell.

One more thing I found to be helpful in using GitHub Actions work with these resources is a service principal for use in logins and other access to Azure. Doing this moves the ownership to the service principal rather than a user account. Here is a bit of Terraform Documentation on this configuration.

In a large environment, it is possible to use Terraform to automate the creation of Service Principals and the assignment of Azure Policy and IAM roles/permissions, in conversations with Microsoft, this is not encouraged. Remember - some service principal has to be the “god mode” service principal which allows other items to create these resources. This will absolutely work, but please be mindful of the root level service principal and secure it.

Terraform Provider Configuration

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">=3.0.0"
  backend "remote" {
    organization = "derek2-training"
    workspaces {
      name = "tf-aks-2"

provider "azurerm" {
  features {
    key_vault {
      purge_soft_delete_on_destroy = true


A bit about Naming

Naming cloud resources is hard - or more challenging than it should be. Microsoft has created a Terraform module to help in naming Azure Resources, it helps to keep naming consistent within your environment. The Module is available on GitHub and is helpful for working with Azure resources.


module "naming" {
  source  = "Azure/naming/azurerm"
  version = "0.1.1"


Remote backends allow your Terraform state to be stored somewhere off of your laptop. This can be AWS S3, Azure Storage Accounts, or a service like Terraform Cloud.

Terraform cloud is a freemium service provided by HashiCorp that integrates with source control. This allows you to push your code to source control in the /dev branch and executes the plan and apply commands against the state stored in Terraform cloud.

More information about setting up organizations and all other things Terraform cloud can be found here.

Environment Variables Terraform leverages variables to improve reuse and Terraform Cloud can provide environment variables that bring values at run time to the terraform configuration. They can be stored as sensitive to ensure they are obfuscated within the state file. Within Terraform Cloud, setting details for your Azure Subscription, Tenant, and Service Principal login information, works well for automation and CICD deployments.

Note: Please read the Terraform Documentation about variables or environment variables to learn more about how they are used.

Local variables Locals are configured to bring variable values together to help in concatenation or Terraform function usage. Using something like local.tags is less typing than adding three different variables to add tags.

The local.tags setup brings all three variables for tags together, shown below:

locals {
  tags = {
    owner       = var.owner
    environment = var.environment
    namespace   = var.namespace

The overall goal is to put a layer between a resource and the variables that does not change much. Using local.name might really be var.name with a concatenation. You do not need to update the item within the resource as often because the local is a wrapper around variables and other text. There is just a bit of simplification when using locals.

Resource Group

resource "azurerm_resource_group" "this" {
  name     = "${module.naming.resource_group.name}-${var.location}-aks"
  location = var.location

  tags = local.tags

Notice in the resource group block that it is using the naming module called out before. The name value is using interpolation to mix string values and variable values to create a unique name for the resource.

Next Time

So far, I have outlined the resources that will be used in my lab environment and the the initial setup of the terraform resources to get started.

The only Azure resource created here is the Resource Group, everything else is Terraform prep.

Written on July 5, 2022