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.