One-liner#

Add the ECS task’s Security Group as an inbound source in the RDS Security Group. Reference the SG itself — not an IP address.


Why You Can’t Use IPs#

ECS Fargate assigns a new IP every time a task starts:

Task A: 10.0.1.23  → terminates
Task B: 10.0.2.87  → new task (different IP)
Task C: 10.0.1.45  → scale-out (yet another IP)

Because tasks scale in and out with auto-scaling, registering IPs in a Security Group is impractical.


Security Group Reference#

Instead of IPs, specify the SG itself as the source:

ECS Task Security Group: sg-ecs-app
  Outbound: 5432 → sg-rds (PostgreSQL)

RDS Security Group: sg-rds
  Inbound: 5432 ← sg-ecs-app    ← SG referenced as source!

With this setup, any resource belonging to sg-ecs-app can reach RDS regardless of its IP. Even if tasks scale to 100, the SG rule stays as a single line.

Terraform example#

# ECS Task SG
resource "aws_security_group" "ecs_app" {
  name   = "ecs-app"
  vpc_id = var.vpc_id
}

# RDS SG
resource "aws_security_group" "rds" {
  name   = "rds"
  vpc_id = var.vpc_id

  ingress {
    from_port       = 5432
    to_port         = 5432
    protocol        = "tcp"
    security_groups = [aws_security_group.ecs_app.id]  # SG reference, not an IP
  }
}

Full Network Flow#

[Public Subnet]
  ALB (sg-alb)
    ↓ port 80/443

[Private Subnet - App]
  ECS Fargate Task (sg-ecs-app)
    ↓ port 5432

[Private Subnet - Data]
  RDS (sg-rds)
    Inbound: 5432 ← sg-ecs-app
  • ALB → ECS: register sg-alb in the inbound rules of sg-ecs-app
  • ECS → RDS: register sg-ecs-app in the inbound rules of sg-rds
  • Each tier is linked via SG references, so IP changes have no impact

ECS vs EKS#

ECS FargateEKS Pod
IP assignmentENI per task, IP changesIP per Pod, IP changes
SG scopeTask-level SGPod-level SG (Security Groups for Pods)
DB accessSG referenceSG reference or IRSA + IAM Auth

The same SG reference approach works for controlling RDS access from EKS as well.


Real-world Experience#

In the PlayBall project, for EKS Pod → RDS access:

EKS Pod SG → registered in RDS SG inbound
  + IRSA for IAM authentication (no static passwords)
  + Credential injection via Secrets Manager (External Secrets)

SG handles network access control, IRSA handles authentication, Secrets Manager handles credential management — three layers of defense.