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:
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:
(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:
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