'How to add a security group to an existing RDS with CDK without cyclic-dependency
I have a multi-stack application where I want to deploy an RDS in one stack and then in a later stack deploy a Fargate cluster that connects to the RDS.
Here is how the rds gets defined:
this.rdsSG = new ec2.SecurityGroup(this, `ecsSG`, {
vpc: props.vpc,
allowAllOutbound: true,
});
this.rdsSG.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(5432), 'Ingress 5432');
this.aurora = new rds.ServerlessCluster(this, `rds`, {
engine: rds.DatabaseClusterEngine.AURORA_POSTGRESQL,
parameterGroup: rds.ParameterGroup.fromParameterGroupName(this, 'ParameterGroup', 'default.aurora-postgresql10'),
vpc: props.vpc,
securityGroups: [this.rdsSG],
// more properties below
});
With that add ingress rule everything is fine, since both the RDS and Fargate are in the same VPC, I can communicate fine. It worries me making that open the world even though its in its own VPC.
const ecsSG = new ec2.SecurityGroup(this, `ecsSG`, {
vpc: props.vpc,
allowAllOutbound: true,
});
const service = new ecs.FargateService(this, `service`, {
cluster,
desiredCount: 1,
taskDefinition,
securityGroups: [ecsSG],
assignPublicIp: true,
});
How can I remove the ingress rule and allow inbound connections to the RDS from that ecsSG since it gets deployed later? If I try to call the following command from the deploy stack, I get a cyclic dependency error:
props.rdsSG.connections.allowFrom(ecsSG, ec2.Port.allTcp(), 'Aurora RDS');
Thanks for your help!
Solution 1:[1]
This turned out to be easier than I thought- you can just flip the connection so that rather than trying to modify the rds to accept a security group of the ecs, you use the allowTo
to establish a connection to the rds instance.
ecsSG.connections.allowTo(props.rds, ec2.Port.tcp(5432), 'RDS Instance');
Solution 2:[2]
Also maybe the other way round the RDS security group might be better described by aws_rds module rather than aws_ec2 module https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_rds/CfnDBSecurityGroup.html (couldn't post a comment due to low rep)
Solution 3:[3]
Just as an additional possibility here. What works for me is that I don't need to define any security group. Just the service and the db, and connect the two:
const service = new ecsPatterns.ApplicationLoadBalancedEc2Service(
this,
'app-service',
{
cluster,
...
},
);
const dbCluster = new ServerlessCluster(this, 'DbCluster', {
engine: dbEngine,
...
});
dbCluster.connections.allowDefaultPortFrom(service.service);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Coherent |
Solution 2 | Dhruv |
Solution 3 | webjunkie |