DEV Community

Amira Abidi
Amira Abidi

Posted on

How I Built My AWS EKS Infrastructure with Terraform

In my previous article, I shared how I moved my application from a local Docker environment to AWS EKS.

This time, I want to focus on one of the most important parts of the project: Infrastructure as Code with Terraform.

My goal was simple: I didn't want my AWS infrastructure to depend on resources created manually from the AWS Console.

I wanted it to be reproducible, structured, and easier to maintain.

Why Terraform?

My architecture includes several AWS components:

  • VPC and subnets
  • Internet and NAT Gateways
  • EKS
  • RDS PostgreSQL
  • Application Load Balancer
  • Route 53
  • ACM certificates
  • IAM roles and policies
  • ECR repositories

Creating everything manually would work, but reproducing the same architecture consistently would quickly become difficult.

That's where Terraform came in.

Instead of describing the infrastructure in documentation, I could describe it directly as code.

Structuring the Infrastructure

One thing I quickly learned is that putting every resource into a single main.tf file doesn't scale very well.

So I organized the infrastructure into reusable Terraform modules.

The structure looks roughly like this:

terraform/
├── modules/
│   ├── vpc/
│   ├── eks/
│   ├── rds/
│   ├── ecr/
│   └── security/
│
└── environments/
    ├── dev/
    └── prod/
Enter fullscreen mode Exit fullscreen mode

Each module has a specific responsibility.

The VPC module manages networking, the EKS module manages the Kubernetes infrastructure, and the RDS module manages the PostgreSQL database.

This made the code much easier to understand and maintain.

Networking First

Before deploying EKS, I needed the network.

I created a VPC distributed across three Availability Zones, with public and private subnets.

The public layer hosts internet-facing components such as the Application Load Balancer and NAT Gateways.

The EKS worker nodes run in private subnets, which means they aren't directly exposed to the internet.

The simplified architecture is:

Internet
   │
   ▼
Application Load Balancer
   │
   ▼
Private Subnets
   │
   ├── EKS Worker Nodes
   │
   └── RDS PostgreSQL
Enter fullscreen mode Exit fullscreen mode

This was an important lesson for me:

Using Kubernetes doesn't remove the need to understand networking.

You still need to think about routing, security groups, public/private subnets, DNS, and internet access.

Creating the EKS Cluster

Once the network was ready, Terraform could create the EKS cluster and its node groups.

The worker nodes are distributed across the three Availability Zones.

From there, Kubernetes manages the application workloads.

My application itself isn't defined directly in Terraform. Kubernetes resources are managed separately, allowing Terraform to focus primarily on the AWS infrastructure.

I found this separation useful:

Terraform manages the infrastructure. Kubernetes manages the workloads.

Managing Multiple Environments

Another requirement was separating development and production.

Instead of maintaining two completely different Terraform codebases, both environments reuse the same modules with different configurations.

Conceptually:

              ┌── dev
Terraform ────┤
              └── prod
                  │
                  ▼
             Shared Modules
Enter fullscreen mode Exit fullscreen mode

This means I can change the infrastructure logic once while keeping environment-specific values separate.

Each environment has its own EKS cluster and RDS database.

Remote Terraform State

Terraform state is critical because it maps the configuration to the resources that actually exist in AWS.

Keeping it only on my laptop wasn't something I wanted to rely on.

So I configured a remote backend using Amazon S3.

This makes the infrastructure state persistent and independent from my local machine.

It also reinforced an important point:

Terraform state is part of the infrastructure and needs to be protected accordingly.

What I Learned

Before this project, Terraform looked mostly like a way to automate AWS resource creation.

After building a complete environment with it, I see it differently.

The real value isn't just:

“I can create an EKS cluster with Terraform.”

It's being able to describe an architecture in a way that is repeatable, reviewable, and maintainable.

I also learned that the order of thinking matters.

Before writing Terraform code, I needed to understand the architecture:

networking → security → compute → database → application → observability

Terraform doesn't design the architecture for you.

It forces you to express the architecture you've designed.

What's Next?

Infrastructure is now reproducible and the application is running on Kubernetes.

But deploying a service isn't enough.

The next question is:

How do I know if my Kubernetes cluster and application are actually healthy?

In the next article, I'll look at how I added Prometheus and Grafana monitoring to AWS EKS and what I learned about observability along the way.

Top comments (0)