Building a Cloud-Native Container Platform from Scratch - Part 4
Now that your infrastructure is live and Kubernetes is running in a secure VPC, it’s time to transform your EKS cluster into a real internal developer platform.
This phase is all about installing and configuring essential platform services — the kind that give your developers smooth deployments, visibility into their workloads, and a consistent operating model.
In this post, we’ll walk through the installation of:
- A GitOps engine (Argo CD)
- An ingress controller (AWS Load Balancer Controller)
- Certificate management (cert-manager)
- Observability stack (Prometheus, Grafana, Loki)
- Secrets integration
All components will be installed declaratively using Helm, and optionally managed via GitOps.
Full series
- Part 1: Why Build a Self-Service Container Platform
- Part 2: Choosing Your Platform’s Building Blocks
- Part 3: Bootstrapping Your Infrastructure with Terraform
- Part 4: Installing Core Platform Services (you are here)
- Part 5: Crafting the Developer Experience Layer
- Part 6: Scaling the Platform — Multi-Tenancy, Environments, and Governance
- Part 7: Day-2 Operations and Platform Maturity
- Part 8: The Future of Your Internal Platform
Pre-requisites
You will need these!
Helm
Before proceeding, ensure Helm is installed on your local machine.
Verify the installation:
helm version
I would recommend using a package manager like Homebrew (macOS/Linux) or Chocolatey (Windows), to install Helm:
-
Homebrew:
brew install helm
-
Chocolatey:
choco install kubernetes-helm
For more details, refer to the Helm installation guide.
Quick Helm Usage Guide
From this point on we will be making use of the helm repo add command. This command is used to add a new Helm chart repository. A chart repository is a location where packaged charts can be stored and shared.
Step 1: Bootstrap GitOps with Argo CD
Argo CD lets you define applications in Git and sync them into the cluster. It’s the cornerstone of a self-service platform.
Install it with Helm:
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd \
--namespace argocd --create-namespace
Expose the Argo UI with an ingress (we’ll get to that shortly), and store Git credentials securely using Kubernetes secrets or IRSA.
💡 Tip: You can even manage Argo CD with itself, by applying its own Application CRs via Git.
Step 2: Ingress Controller (AWS ALB)
To expose services like Argo CD, we’ll use the AWS Load Balancer Controller, which integrates with AWS ALB and uses Kubernetes ingress resources.
Install the controller:
helm repo add eks https://aws.github.io/eks-charts
helm upgrade --install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=my-platform-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
Don’t forget: the controller needs an IAM role with the correct policies, configured via IRSA.
Now your platform can expose HTTPS endpoints for workloads — and Argo CD’s UI — using annotated ingress manifests.
Step 3: SSL/TLS with cert-manager
You’ll want HTTPS by default for all services. cert-manager automates certificate issuance and renewal, supporting Let’s Encrypt and internal CAs.
Install with:
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace \
--set installCRDs=true
Then define a ClusterIssuer
with Let’s Encrypt or a corporate CA:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: platform@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: alb
Step 4: Observability (Prometheus, Grafana, Loki)
A modern platform isn’t complete without visibility.
Use the kube-prometheus-stack Helm chart for an integrated setup:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring --create-namespace
This gives you:
- Prometheus for metrics
- Grafana for dashboards
- Alertmanager for incident handling
Add Loki for logs (you can scrape container logs using Promtail or FluentBit):
helm repo add grafana https://grafana.github.io/helm-charts
helm install loki grafana/loki-stack --namespace monitoring
Dashboards and alerting rules can also be version-controlled; true platform hygiene.
Step 5: Secrets Integration
Avoid baking secrets into workloads or Helm charts. Instead, integrate with cloud-native tools:
- IRSA + AWS Secrets Manager or Parameter Store
- External Secrets Operator to map cloud secrets into Kubernetes
Install External Secrets:
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets \
--namespace external-secrets --create-namespace
This lets you define Kubernetes ExternalSecret
resources linked to AWS Secrets:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: my-api-keys
spec:
secretStoreRef:
name: aws-secrets
kind: ClusterSecretStore
target:
name: api-keys
data:
- secretKey: key
remoteRef:
key: prod/my-service/api-key
What You Have Now
With these building blocks, your cluster is no longer just compute — it’s a platform:
- Developers push to Git, Argo CD deploys
- Services are exposed securely via HTTPS
- Metrics, logs, and alerts are live
- Secrets are secure and auditable
And everything is modular, auditable, and replicable; ready to grow with your team.
Coming Up in Part 5
Next, we’ll focus on building the developer experience layer:
- Self-service namespaces and pipelines
- Templates for common workloads
- Internal developer portal options
Leave a comment