Skip to content

Lessons Learned: When Helm Charts Aren’t Enough

So you’ve got your beautiful Helm chart. It’s packaged, versioned, templated, and ready to go. All you need now is… …a Kubernetes cluster that doesn’t look like it just woke up.

Surprise! Helm doesn’t provision servers. Helm doesn’t install Docker. Helm doesn’t configure your firewall or set up your DNS or drop in your SSH keys.

That’s where Ansible comes in. Because when you’re setting up a brand-new environment—a totally clean VM, a blank EC2, a freshly deployed node—Helm’s still sitting on the bench while Ansible boots the whole stadium.


The Context: Standing Up New Dev Environments Shouldn't Be an Expedition

Our team moves fast. We sometimes need to spin up new environments for:

  • Feature testing
  • Isolated bug triage
  • Scaling QA load
  • Dedicated agency demo instances
  • "Something broke and we need a fresh one" moments™

And while Kubernetes is great, it assumes a lot of things are already there. Before Helm can even install your app, the environment needs to have:

  • Docker installed and running
  • Your Kubernetes cluster configured (Minikube, K3s, or full-blown kubeadm)
  • kubectl and config contexts ready
  • Helm installed
  • Basic security rules in place
  • Git, Node.js, Java, Python (depending on your stack)
  • Directories and user permissions set up

Doing this by hand every time? That's how you build character. Or burn out.


The Fix: Use Ansible to Bootstrap the World

So I wrote an Ansible playbook that could turn any clean VM into a Kubernetes-ready, Helm-ready deployment target.

🧱 Base Setup

- name: Base system setup
  hosts: new_envs
  become: yes
  tasks:
    - name: Update APT cache
      apt:
        update_cache: yes

    - name: Install base packages
      apt:
        name:
          - git
          - curl
          - vim
          - unzip
          - python3-pip
        state: present

    - name: Install Docker
      shell: |
        curl -fsSL https://get.docker.com -o get-docker.sh
        sh get-docker.sh

    - name: Add user to docker group
      user:
        name: "{{ ansible_user }}"
        groups: docker
        append: yes

⚙️ Kubernetes + Helm Setup

- name: Kubernetes tools and cluster setup
  hosts: new_envs
  become: yes
  tasks:
    - name: Install K3s (lightweight Kubernetes)
      shell: curl -sfL https://get.k3s.io | sh -

    - name: Install Helm
      shell: |
        curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

    - name: Ensure helm repo is added
      shell: |
        helm repo add mychartrepo https://charts.example.com
        helm repo update

Now, after a clean VM spin-up, I could run:

ansible-playbook setup-k8s-env.yml -i inventory/dev.ini

And within minutes, I’d have:

✅ Docker ✅ K3s or kubeadm installed ✅ Helm 3 installed ✅ Git + Nginx + monitoring tools ✅ Ready for helm upgrade --install my-app ./charts/my-app


The Bonus: Now You Can Actually Use Your Helm Charts

People forget this: Helm is not a setup tool. It’s a deployer—for when your environment is already in shape.

Ansible bridges that gap by:

  • Installing all the dependencies you forgot you need
  • Making the environment consistent across Dev/QA/Stage
  • Letting you automate credentials, config files, and secrets (with Ansible Vault if needed)
  • Avoiding 20 steps of tribal knowledge and broken shell scripts

Final Thoughts: Use Helm to Deploy, Use Ansible to Prepare the Battlefield

If you’re setting up a new environment and your first steps involve SSHing into a VM and Googling “install Docker Ubuntu,” please stop.

Use Ansible.

Because when you run:

ansible-playbook provision-env.yml

… and then run your helm install

… and it works on the first try?

That’s when you know you’re doing DevOps right.