Skip to main content

Command Palette

Search for a command to run...

End-to-end GitOps With Terraform and ArgoCD For EKS

Published
3 min read

Architecture Diagram

We will be designing a production grade GitOps architecture to automate both infrastructure provisioning and application delivery on AWS using Terraform.

Overview

We will use Terraform to build the foundation. It will provision the VPC and networking components, deploy the Amazon EKS cluster, and use the Terraform Helm Provider to install ArgoCD directly into the cluster. The Git Repository contains all Kubernetes manifests, Helm charts, and configurations, and ArgoCD sits inside the EKS cluster, watching this repository, detecting any update status and automatically applying changes to EKS if a developer pushes a change to the repo. DevOps team access the ArgoCD UI/API through a dedicated Load Balancer to monitor deployment health. End-users on the other hand hit the actual deployed application, through a separate Load Balancer. This will help us manage traffic and access to the system in a controlled and organized manner.

Drift Detection

Because ArgoCD constantly compares the live state (EKS) with the desired state (Git), it provides automatic drift detection. If someone manually deletes a deployment in the cluster using kubectl, ArgoCD will see the discrepancy and immediately recreate it to match Git.

Code Overview

The main.tf file sets up a complete AWS environment for EKS (Elastic Kubernetes Service) with ArgoCD pre-installed.

  • VPC & Networking: Uses the terraform-aws-modules/vpc/aws module to create a secure network with public and private subnets across two Availability Zones. It includes a NAT Gateway to allow private instances to access the internet.

  • EKS Cluster: Provisions a managed Kubernetes cluster (v1.30) with a node group of t3.medium

    instances.

  • Storage Support: Configures the EBS CSI Driver via IRSA (IAM Roles for Service Accounts), which allows Kubernetes to manage AWS Elastic Block Store volumes (needed for the Postgres database).

  • ArgoCD Bootstrapping:

    • Creates the argocd namespace.

    • Fetches the official ArgoCD manifests directly via an HTTP data source and applies them using the kubectl_manifest resource.

    • Patches the argocd-server service to be a LoadBalancer so you can access the ArgoCD UI from your browser.

    • Automated App Deployment: Finally, it deploys the application defined in manifests/argocd-app.yaml using ArgoCD itself.

The manifests define a 3-tier web application:

  • argocd-app.yaml: This is the "App of Apps" or root configuration. It tells ArgoCD to watch a specific Git repository (gitops-manifest-awstf.git) and sync the configurations to the 3tirewebapp-dev namespace.

  • frontend.yaml & backend.yaml: Define the application layers. The frontend talks to the backend via a BACKEND_URL environment variable. Both use ConfigMaps for non-sensitive configuration.

  • postgres.yaml: Sets up a PostgreSQL database with a PersistentVolumeClaim(PVC), ensuring data persists even if the pod restarts.

  • secret.yaml: Contains the database credentials. Note that these are currently stored in plaintext (Base64 encoded by K8s), which leads into the security discussion.

Some concerns in Setup

Some configurations prioritize ease of use over strict production security. Here are the key issues and why they exist:

Security IssueLearning Use CaseProduction Alternative
Plaintext Secrets in secret.yamlMakes it easy to see how K8s Secrets work without external dependencies.Use AWS Secrets Manager, HashiCorp Vault, or Sealed Secrets.
Public EKS Endpoint (cluster_endpoint_public_access = true)Allows to run kubectl from their local machine without setting up a VPN or Bastion host.Disable public access and use a Private Endpoint with a VPN.
Remote Manifest FetchingRapidly installs ArgoCD without keeping large YAML files in the repo.Use Helm charts with pinned versions or local, audited manifests.
LoadBalancer for ArgoCD UIProvides immediate access to the UI to see the GitOps magic in action.Use an Ingress Controller with TLS and OAuth/OIDC for authentication.

After deployment, I got the argocd url:

The Argo CD is running on the default http port. The web application is running on custom 3000 port. So we open it:


Video reference:


Arigato!