Security Enhancements to EKS Clusters

Raphael Ndonga | Sep 12, 2025 min read

I was reading this insightful article by Akhilesh Mishra to understand his approach on deploying a production-ready 3-tier application on AWS EKS. As I was following the steps, I noticed an issue:

Source Group Image

The postgres-security-group belonging to the postgres db instance was being set to allow all inbound traffic.

I wondered why that was the case, and yet it seemed to me that we had specifically allowed the cluster security group in the inbound rules set for the postgres-security-group as below:

Source Group Image

(SIDE-NOTE: the group-id set above should be changed to the SG_ID created)

It seemed like a concession because the below command failed; which was meant to test whether the cluster can connect to the postgress db instance through the security groups:

Source Group Image

When you run the command above you get a Timeout Error; the pod is unable to access the mentioned service

Taking a deeper look into the NODE_SG security group; I noticed it was created using the below query:

NODE_SG=$(aws eks describe-cluster --name Akhilesh-cluster --region eu-west-1 \
  --query "cluster.resourcesVpcConfig.securityGroupIds[0]" --output text)

Is the query cluster.resourcesVpcConfig.securityGroupIds[0] picking the correct security group ?

So I inquired for the full output with the below command:

aws eks describe-cluster --name Akhilesh-cluster --output text

I got the output below:

    "cluster": {
        "resourcesVpcConfig": {
            "subnetIds": [
            ],
            "securityGroupIds": [
                "<security-group-id>"
            ],
            "clusterSecurityGroupId": "<cluster-security-group-id>",
            "vpcId": "...",
            "endpointPublicAccess": true,
            "endpointPrivateAccess": false,
            "publicAccessCidrs": [
                "0.0.0.0/0"
            ]
        },
    }

From the above output, I you can see there are 2 security group IDs.

  • The securityGroupId above connects to the Elastic Network Interface that allows for connection between EKS control plane and the worker nodes
  • The cluster-security-group-id above connects to the Cluster itself.

The cluster-security-group-id is the best one to use as the source-group for inbound traffic to the postgres-security-group. This is because we want to make sure the cluster connects to postgress, not just the Elastic Network Interface.

To implement the above, change the NODE_SG variable, add its ingress inbound rule and run the dns-test pod

NODE_SG=$(aws eks describe-cluster --name Akhilesh-cluster --region eu-west-1 \
--query "cluster.resourcesVpcConfig.clusterSecurityGroupId" --output text)

aws ec2 authorize-security-group-ingress \
--group-id $SG_ID \
--protocol tcp \
--port 5432 \
--source-group $NODE_SG \
--region eu-west-1

kubectl run -it --rm --restart=Never dns-test --image=tutum/dnsutils \
 -- dig postgres-db.3-tier-app-eks.svc.cluster.local

You get the below output:

; <<>> DiG 9.9.5-3ubuntu0.2-Ubuntu <<>> postgres-db.3-tier-app-eks.svc.cluster.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62927
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;postgres-db.3-tier-app-eks.svc.cluster.local. IN A

;; ANSWER SECTION:
postgres-db.3-tier-app-eks.svc.cluster.local. 5 IN CNAME ndonga-postgres.c902m022grz3.eu-west-1.rds.amazonaws.com.        
ndonga-postgres.c902m022grz3.eu-west-1.rds.amazonaws.com. 5 IN A 192.168.143.150

;; Query time: 2 msec
;; SERVER: 10.100.0.10#53(10.100.0.10)
;; WHEN: Thu Sep 11 09:01:37 UTC 2025
;; MSG SIZE  rcvd: 259

pod "dns-test" deleted

SUCCESS