Skip to content
Go back

Bootstrapping ArgoCD With Terraform

3 min readEdit page

Overview

Kubernetes has lot of flexibility and features. But, in order to make use of it to the full potential, it requires us to install some essentials tools in it. One of the example of the most used tools in industry right now is ArgoCD. ArgoCD allows us to manage the applications inside the Kubernetes cluster. This post written to help you on how to bootstrapping the Kubernetes cluster.

What is Bootstrapping?

Why Bootstrapping?

How to Bootstrapping Kubernetes Cluster?

See below Terraform snippet to bootstrapping the ArgoCD with the cluster. The snippet assuming that the kubeconfig is there locally. So if you want to have it together with your cluster definition, you might need to adjust the kubernetes and helm provider in order to authenticate to the cluster.

terraform {
  required_providers {
    helm = {
      source  = "hashicorp/helm"
      version = "2.12.1"
    }

    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "2.25.2"
    }
  }
}

provider "helm" {
  kubernetes {
    config_path = "~/.kube/config"
  }
}

provider "kubernetes" {
  config_path = "~/.kube/config"
}

resource "kubernetes_namespace" "infrastructure" {
  metadata {
    name = "infrastructure"
  }
}

resource "helm_release" "argocd" {
  name       = "argocd"
  chart      = "argo-cd"
  repository = "https://argoproj.github.io/argo-helm"
  version    = "6.0.12"
  namespace  = kubernetes_namespace.infrastructure.metadata[0].name

  values = ["${file("argocd-values.yml")}"]
}

resource "helm_release" "nginx_ingress" {
  name       = "ingress-nginx"
  chart      = "ingress-nginx"
  repository = "https://kubernetes.github.io/ingress-nginx"
  version    = "4.9.1"
  namespace  = kubernetes_namespace.infrastructure.metadata[0].name

  set {
    name  = "controller.ingressClassResource.name"
    value = "nginx"
  }
}

How it Works?

Assumptions:

Below is the explanation for the above snippets.

  1. We configure the providers for both kubernetes and helm
     terraform {
         required_providers {
             helm = {
                 source  = "hashicorp/helm"
                 version = "2.12.1"
             }
    
             kubernetes = {
                 source  = "hashicorp/kubernetes"
                 version = "2.25.2"
             }
         }
     }
    
     provider "helm" {
         kubernetes {
             config_path = "~/.kube/config"
         }
     }
    
     provider "kubernetes" {
         config_path = "~/.kube/config"
     }
  2. Creating the targeted namespace
    resource "kubernetes_namespace" "infrastructure" {
        metadata {
            name = "infrastructure"
        }
    }
  3. Deploy the ingress controller and ArgoCD
    resource "helm_release" "argocd" {
        name       = "argocd"
        chart      = "argo-cd"
        repository = "https://argoproj.github.io/argo-helm"
        version    = "6.0.12"
        namespace  = kubernetes_namespace.infrastructure.metadata[0].name
    
        values = ["${file("argocd-values.yml")}"]
    }
    
    resource "helm_release" "nginx_ingress" {
        name       = "ingress-nginx"
        chart      = "ingress-nginx"
        repository = "https://kubernetes.github.io/ingress-nginx"
        version    = "4.9.1"
        namespace  = kubernetes_namespace.infrastructure.metadata[0].name
    
        set {
            name  = "controller.ingressClassResource.name"
            value = "nginx"
        }
    }
  4. The helm applications will be installed in the cluster and your ArgoCD and ingress controller will be installed after some times.

As you can see in the above, there is argocd-values.yml, this is basically the parameters of the helm chart. See below example for references that I used for my local Kubernetes:

controller:
  resources:
    limits:
      cpu: "100m"
      memory: "128Mi"
dex:
  resources:
    limits:
      cpu: "10m"
      memory: "32Mi"
redis:
  resources:
    limits:
      cpu: "10m"
      memory: "32Mi"
repoServer:
  resources:
    limits:
      cpu: "1000m"
      memory: "512Mi"
server:
  resources:
    limits:
      cpu: "100m"
      memory: "128Mi"
  ingress:
    enabled: true
    ingressClassName: nginx
    hostname: argocd.rizkidoank.local

configs:
  params:
    server.insecure: true

Given the values parameters above, after everything installed, the ArgoCD will be accessible with argocd.rizkidoank.local

What to Do Next?

I might write the guide to create or manage base infra applications or creating ArgoCD application for our own service in another posts. For more in depth about ArgoCD, you may refer to the docs argo-cd.readthedos


Edit page
Share this post:

Previous Post
Use Terraform to Deploy Hugo to Vercel
Next Post
Cache Terraform Provider Plugins