Does Helm provision aws infrastructure?
The short answer is no, Helm does not natively provision AWS cloud infrastructure.
Helm is a package manager designed specifically for Kubernetes. Its job is to template, package, and deploy Kubernetes-native YAML manifests (like Deployments, Services, ConfigMaps, and Ingresses) onto an already-running cluster. It does not natively understand or manage AWS resources like VPCs, EC2 instances, RDS databases, or S3 buckets. However, because the cloud native ecosystem is highly integrated, the line can sometimes look blurry. Here is how that boundary gets crossed and how the two worlds interact.
The "Grey Area": When Helm Indirectly Triggers AWS Provisioning
While Helm itself only talks to the Kubernetes API, certain Kubernetes operators and controllers can watch for Helm-deployed resources and provision AWS infrastructure in response:
1. Cloud-Provider Load Balancers
If your Helm chart deploys a Kubernetes Service of type: LoadBalancer:
- Helm simply submits that Service YAML to the EKS control plane.
- The cloud-controller-manager inside EKS sees this and automatically provisions an AWS Classic Load Balancer or Network Load Balancer (NLB) in your AWS account.
- Similarly, deploying an Ingress resource alongside the AWS Load Balancer Controller (often installed via Helm itself) triggers the creation of an AWS Application Load Balancer (ALB).
2. Custom Resource Definitions (CRDs) & Operators
You can use Kubernetes operators that are explicitly designed to manage cloud infrastructure through Kubernetes. If you install these operators (often using Helm), you can then use Helm to deploy manifests that provision AWS resources:
- AWS Controllers for Kubernetes (ACK): This framework allows you to define AWS resources (like an S3 bucket or an RDS instance) directly as Kubernetes custom resources. If you bundle an ACK custom resource inside a Helm chart, running helm install will tell the ACK operator to provision that infrastructure in AWS.
- Crossplane: Similar to ACK, Crossplane turns your cluster into a control plane. You can package Crossplane claims inside Helm charts to spin up databases, networks, and queues.
The Standard Best Practice: "Separation of Concerns"
Because managing cloud infrastructure via Kubernetes manifests can get complex quickly, the industry-standard pattern is to keep these layers strictly separated:
┌────────────────────────────────────────────────────────┐
│ App Layer (Helm) │
│ - Deployments, Services, Ingress, ConfigMaps, etc. |
└───────────────────────────┬────────────────────────────┘
│ Runs inside
┌───────────────────────────▼────────────────────────────┐
│ Kubernetes Cluster (EKS) │
└───────────────────────────┬────────────────────────────┘
│ Provisioned by
┌───────────────────────────▼────────────────────────────┐
│ Infra Layer (IaC - Terraform) │
│ - VPC, Subnets, EKS Cluster, IAM, RDS, S3, etc. │
└────────────────────────────────────────────────────────┘
- Infrastructure as Code (Terraform, OpenTofu, CloudFormation, Pulumi): Used to provision the underlying AWS infrastructure—the VPC, subnets, IAM roles, EKS cluster, and managed node groups.
- Helm: Used once the cluster is up and running to deploy and configure applications, ingress controllers, logging agents, and service meshes on top of that infrastructure.
How to use Terraform to install a Helm chart?
To bridge the gap between infrastructure and application deployment, you can use the HashiCorp Helm Provider directly inside your Terraform configuration.
This approach ensures strict ordering: Terraform first provisions the AWS network and EKS cluster, and only after the cluster is fully active does it initialize Helm to install your charts.
Here is a clean, production-ready example showing how to connect your AWS provider, configure the Kubernetes/Helm providers dynamically using the cluster's output token, and deploy a chart.
# 1. PROVIDERS CONFIGURATION
# We configure Kubernetes and Helm providers dynamically using tokens
# generated from the newly created AWS EKS cluster.
provider "aws" {
region = "eu-west-2" # London
}
provider "kubernetes" {
host = aws_eks_cluster.main.endpoint
cluster_ca_certificate = base64decode(aws_eks_cluster.main.certificate_authority[0].data)
token = data.aws_eks_cluster_auth.main.token
}
provider "helm" {
kubernetes {
host = aws_eks_cluster.main.endpoint
cluster_ca_certificate = base64decode(aws_eks_cluster.main.certificate_authority[0].data)
token = data.aws_eks_cluster_auth.main.token
}
}
# Data source to fetch authentication tokens for EKS dynamically
data "aws_eks_cluster_auth" "main" {
name = aws_eks_cluster.main.name
}
# 2. AWS EKS CLUSTER PROVISIONING (Simplified)
resource "aws_eks_cluster" "main" {
name = "production-core-cluster"
role_arn = aws_iam_role.eks_cluster.arn
vpc_config {
subnet_ids = ["subnet-12345678", "subnet-87654321"] # Replace with your VPC subnet IDs
}
}
# 3. HELM RELEASE PROVISIONING
# Terraform treats this Helm chart as a resource managed within its state file.
resource "helm_release" "ingress_nginx" {
name = "ingress-nginx"
repository = "https://kubernetes.github.io/ingress-nginx"
chart = "ingress-nginx"
version = "4.10.0"
namespace = "ingress-system"
create_namespace = true
# Explicit dependency guarantees the cluster exists before Helm tries to talk to it
depends_on = [aws_eks_cluster.main]
# Passing configuration values into the Helm chart
set {
name = "controller.replicaCount"
value = "3"
}
set {
name = "controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-type"
value = "nlb"
}
}
Why this pattern works so well:
- Token-Based Auth Lifecycle: By using the aws_eks_cluster_auth data source, Terraform fetches a short-lived administrative token on the fly during the apply phase, ensuring Helm can authenticate without storing static kubeconfig files on disk or in version control.
- Escaping Helm Keys: Note the double backslash (\\) in the annotation key. Helm uses dot notation to traverse nested values, so if an AWS annotation key contains a dot (like aws-load-balancer-type), you must escape it in Terraform so Helm interprets it as a single key string rather than a nested map.
- State Management: When you run terraform destroy, Terraform is smart enough to reverse the order: it calls Helm to cleanly uninstall the charts, deletes any cloud-provider resources (like NLBs) created by those charts, and then tears down the EKS cluster.

No comments:
Post a Comment