I’ve created ECS fargate connected to RDS postgresql. Load balancer is public facing, and RDS is ISOLATED. I want RDS database accessed through ECS container/load balancer and EC2. Once the RDS instance is created, I added ingress rule to allow security group for ecs.
props.dbInstance.connections.securityGroups[0].addIngressRule(
ecsSecurityGroup,
ec2.Port.tcp(5432),
'Allow ECS access to RDS Postgres'
);
However, I get a Circular Dependency Error.
❌ CdkStack failed: Error [ValidationError]: Circular dependency between resources: [RDSNestedStackRDSNestedStackResource4BEA771C, ECSNestedStackECSNestedStackResourceFF50F200]
There are two stacks: RDS and ECS.
RDSStack,
export class RDSStack extends NestedStack {
public readonly dbInstance: rds.DatabaseInstance;
constructor(scope: Construct, id: string, props: RDSStackProps) {
super(scope, id);
// RDS security group
const rdsSecurityGroup = new ec2.SecurityGroup(this, `RDSSecurityGroup`, {
vpc: props.vpc,
description: 'Security group for RDS instance',
});
// New private subnet group for RDS instance
const rdsSubnetGroup = new rds.SubnetGroup(this, `RDSInstanceSubnetGroup`, {
vpc: props.vpc,
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
description: 'Subnet group for RDS instance',
});
// RDS instance in the private subnet with no public access
this.dbInstance = new rds.DatabaseInstance(this, `RDSInstance`, {
publiclyAccessible: false,
subnetGroup: rdsSubnetGroup,
vpc: props.vpc,
port: 5432,
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
securityGroups: [rdsSecurityGroup],
// more
});
// EC2 security group
const ec2SecurityGroup = new ec2.SecurityGroup(this, `EC2SecurityGroup`, {
vpc: props.vpc,
description: 'Security group for EC2 instance',
});
// Allow SSM traffic (HTTPS)
ec2SecurityGroup.addEgressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(443), 'Allow HTTPS traffic for SSM');
// Allow all outbound connections for EC2 instance
ec2SecurityGroup.addEgressRule(ec2.Peer.anyIpv4(), ec2.Port.allTraffic());
// ingress rules to RDS security group to allow traffic from the EC2
rdsSecurityGroup.addIngressRule(
ec2.Peer.securityGroupId(ec2SecurityGroup.securityGroupId),
ec2.Port.tcp(5432),
'Allow DB access from EC2 instance'
);
and ECSStack
export class ECSStack extends NestedStack {
constructor(scope: Construct, id: string, props: ECSStackProps) {
super(scope, id, props);
const ecsSecurityGroup = new ec2.SecurityGroup(this, `ECSSecurityGroup`, {
vpc: props.vpc,
description: 'Security group for ECS',
});
const cluster = new ecs.Cluster(this, `ECSCluster`, { vpc });
const taskDefinition = //...
const container = //...
const albfs = new ecs_patterns.ApplicationLoadBalancedFargateService(this, `FargateService`,
{
publicLoadBalancer: true,
securityGroups: [ecsSecurityGroup],
assignPublicIp: true,
// more
}
);
const lbSecurityGroup = albfs.loadBalancer.connections.securityGroups[0];
lbSecurityGroup.addIngressRule(
ec2.Peer.anyIpv4(),
ec2.Port.tcp(80), // 443 for https
'Allow HTTP from anywhere'
);
----> Problem line of codes
// Grant permissions to ECS task to access RDS
props.dbInstance.connections.securityGroups[0].addIngressRule(
ecsSecurityGroup,
ec2.Port.tcp(5432),
'Allow ECS access to RDS Postgres'
);
}
If I comment out the problem lines, I can deploy but the ECS containers do not seem to be accessing database. Why am I getting a circular error? I want ECS containers to access RDS.