Skip to content

Instantly share code, notes, and snippets.

@hermannolafs
Last active October 18, 2024 11:45
Show Gist options
  • Save hermannolafs/ea2acfc328ce762777c6efa759b4a549 to your computer and use it in GitHub Desktop.
Save hermannolafs/ea2acfc328ce762777c6efa759b4a549 to your computer and use it in GitHub Desktop.
Terraform which bootstraps Cert Manager CRDs, Cert Manager helm chart and Traefik using the Kubernetes and Helm providers
##########################################
# Cert manager
##########################################
data "http" "cert_manager_crds" {
url = "https://github.com/cert-manager/cert-manager/releases/download/v${var.cert_manager_version}/cert-manager.crds.yaml"
}
locals {
cert_manager_crds = {
# We do this to avoid the whole manifest being the key in the resource list below, leading to
# insane output. This instead means the name of the crd becomes the key.
# This is absolutely not the most efficient way to do this, but neither is downloading the crd
# like we do above and splitting it up like we do here.
for crd in split("\n---\n", data.http.cert_manager_crds.response_body) : yamldecode(crd).metadata.name => yamldecode(crd)
}
}
resource "kubernetes_manifest" "cert_manager_crds" {
depends_on = [
azurerm_kubernetes_cluster.this,
data.http.cert_manager_crds
]
for_each = local.cert_manager_crds
lifecycle {
precondition {
condition = data.http.cert_manager_crds.status_code == 200
error_message = "Failed fetching Cert Manager CRDs at data.http.cert_manager_crds"
}
}
manifest = each.value
}
resource "kubernetes_namespace" "cert_manager" {
depends_on = [
data.http.cert_manager_crds,
kubernetes_manifest.cert_manager_crds
]
metadata {
name = "cert-manager"
}
}
resource "helm_release" "cert_manager" {
depends_on = [ kubernetes_namespace.cert_manager ]
name = "cert-manager"
repository = "https://charts.jetstack.io"
chart = "cert-manager"
version = var.cert_manager_version
namespace = resource.kubernetes_namespace.cert_manager.id
}
##########################################
# Traefik
##########################################
resource "helm_release" "traefik" {
depends_on = [ kubernetes_namespace.cert_manager ]
name = "traefik"
repository = "https://traefik.github.io/charts"
chart = "traefik"
version = var.traefik_version
namespace = "default"
set {
name = "ingressRoute.dashboard.enabled"
value = "true"
}
set {
name = "persistence.enabled"
value = "true"
}
}
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.0"
}
helm = {
source = "hashicorp/helm"
version = "~> 2.0"
}
http = {
source = "hashicorp/http"
version = "~> 3.0"
}
}
}
provider "azurerm" {
subscription_id = "beep boop bap"
features {}
}
provider "kubernetes" {
# This fails unless the kubernetes cluster is provisioned first
# https://github.com/hashicorp/terraform/issues/30937
# terraform terraform apply -target azurerm_kubernetes_cluster.this -auto-approve && terraform apply -auto-approve
# I was using AKS for this, but the helm.tf bits should be no different on any other k8s distribution
host = azurerm_kubernetes_cluster.this.kube_config[0].host
username = azurerm_kubernetes_cluster.this.kube_config[0].username
password = azurerm_kubernetes_cluster.this.kube_config[0].password
client_certificate = base64decode(azurerm_kubernetes_cluster.this.kube_config[0].client_certificate)
client_key = base64decode(azurerm_kubernetes_cluster.this.kube_config[0].client_key)
cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.this.kube_config[0].cluster_ca_certificate)
}
provider "helm" {
kubernetes {
host = azurerm_kubernetes_cluster.this.kube_config[0].host
client_certificate = base64decode(azurerm_kubernetes_cluster.this.kube_config[0].client_certificate)
client_key = base64decode(azurerm_kubernetes_cluster.this.kube_config[0].client_key)
cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.this.kube_config[0].cluster_ca_certificate)
}
}
variable "kubernetes_cluster_name" {
default = "mingus"
}
variable "location" {
default = "eastus"
}
variable "cert_manager_version" {
default = "1.16.1"
}
variable "traefik_version" {
default = "32.1.1"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment