Looking at what we are Building
DEV Community

Looking at what we are Building

Never Use Your AWS Root User!

The root user (the email/password you signed up to AWS with) can do anything, including closing the account. It should basically never be used day-to-day. Instead, create a dedicated IAM user just for this project. In real life you would create a dedicated IAM user for your CI/CD pipeline to automate deployments:

  • AWS Console → IAM → Users → Create user (e.g. terraform-voting-app).
  • Do not enable AWS Console access; this user only needs programmatic access, i.e. an API key pair.
  • The AWS managed policy AdministratorAccess is the path of least friction, and is what you should use for the IAM user to test things out. But in real life you would go with a least‑privilege approach; learn more about it in AWS EKS IAM policy examples.
  • On the user's Security credentials tab → Create access key → choose "Command Line Interface (CLI)". You'll get an Access Key ID and a Secret Access Key; store them somewhere safe, we will be needing them later.

Give Terraform Those Credentials

The rule: credentials never go inside a .tf file, and never inside terraform.tfvars. So in your local machine or CI/CD pipeline you need to export AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_REGION as environment variables in the shell.

export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=us-east-1

Then you won't be needing aws configure or aws login step anywhere; the AWS provider has no access_key / secret_key arguments of its own, so it falls back to the AWS SDK's standard credential chain, which checks these exact environment variables first. The AWS CLI and, later, kubectl read the same variables.

In my local machine I do export an env variable file using a shell script. The export only lasts for the current shell session; re‑run it in any new terminal before running terraform / aws / kubectl.

What You Are About to Build

This is the part most beginner Terraform/EKS tutorials skip, and it's the part that makes the actual .tf files make sense at a glance instead of feeling like a wall of unfamiliar arguments.

flowchart TB
    subgraph AWS["AWS Account / Region"]
        subgraph VPC["VPC - 10.0.0.0/16"]
            IGW["Internet Gateway"]
            subgraph AZ1["Availability Zone A"]
                PubA["Public subnet\n10.0.100.0/24"]
                PrivA["Private subnet\n10.0.0.0/24"]
            end
            subgraph AZ2["Availability Zone B"]
                PubB["Public subnet\n10.0.101.0/24"]
                PrivB["Private subnet\n10.0.1.0/24"]
            end
            NAT["NAT Gateway\n(in a public subnet)"]
            CP["EKS Control Plane\n(managed by AWS,\nnot inside your subnets)"]
            PrivA --- Node1["EC2 worker node"]
            PrivB --- Node2["EC2 worker node"]
        end
        NLB["Network Load Balancer\n(public, one per exposed Service)"]
    end
    Internet(("Internet")) --> IGW
    IGW --> PubA
    IGW --> PubB
    PubA --> NAT
    NAT -.outbound only.-> Node1
    NAT -.outbound only.-> Node2
    CP <-. manages .-> Node1
    CP <-. manages .-> Node2
    Internet --> NLB
    NLB --> Node1
    NLB --> Node2
    Node1 -- runs --> Pods1["voting / result / worker\nredis / postgres pods"]
    Node2 -- runs --> Pods2["voting / result / worker\nredis / postgres pods"]

Reading it top to bottom:

  • VPC: a private network inside AWS, 10.0.0.0/16 here (65k addresses is just the conventional default and more than what we need).
  • Two Availability Zones: EKS requires subnets in at least 2 AZs, so a single AZ failure can't take the whole cluster down.
  • Public subnets have a route to the Internet Gateway. Their only job is hosting the NAT Gateway and, later, the public‑facing Load Balancers.
  • Private subnets is where the actual EC2 worker nodes live. They have no direct route in from the internet, and no public IP at all.
  • NAT Gateway lets the private‑subnet nodes reach out to the internet (to pull container images, talk to the EKS API, etc.) without allowing anything in from the internet. One‑way door.
  • EKS Control Plane is a managed AWS service which is the Kubernetes API server, scheduler, etc. It doesn't live "in" your subnets the way an EC2 instance does, though it does attach elastic network interfaces into them to talk to your nodes.
  • Worker nodes are plain EC2 instances, sitting in the private subnets, that the EKS control plane schedules your pods onto. This is the "data plane", as opposed to the control plane above.
  • Network Load Balancer is created later, by Kubernetes (not Terraform) when you expose a Service as type: LoadBalancer. This is how traffic actually reaches your app from a browser.

EKS Costs

We have two separate charges, both starting the moment terraform apply finishes:

  • The EKS control plane itself has a flat hourly rate. Check current EKS pricing and this is regardless of whether any pods are running.
  • The EC2 worker nodes: ordinary EC2 billing, because they're ordinary EC2 instances. Two t3.medium nodes, in this project. Plus a NAT Gateway (hourly + per‑GB processed) and small EBS volumes for each node's disk. None of it is free‑tier.

Reference Links

Top comments (0)

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.