Open ixti opened 1 week ago
@ixti thanks for creating this issue! After looking into this I think you may be running up against some default behavior of CloudFormation/CCAPI (which aws-native uses under the hood). By default when you create a security group via API a default egress-all rule will be created for you. For aws-native
the only way to prevent that from happening is to provide a different rule instead. As long as one rule is provided, the default egress-all rule will not be created.
Also, the securityGroupEgress
property on the SecurityGroup
resource does not work well with the separate SecurityGroupEgress
resource. Using both together can lead to unexpected rule deletion.
Below is an example of using securityGroupEgress
with a dummy rule (doesn't allow any traffic, but prevents the egress-alll rule from being created) along with ignoreChanges
. The ignoreChanges
is necessary in order to work with the SecurityGroupEgress
resource.
const albSecurityGroup = new awsNative.ec2.SecurityGroup(
'alb-sg',
{
groupDescription: 'Managed by Pulumi',
groupName: 'alb-sg',
vpcId: vpc.id,
securityGroupEgress: [
{
cidrIp: '255.255.255.255/32',
ipProtocol: 'icmp',
fromPort: 252,
toPort: 86,
description: 'Disallow all traffic',
},
],
},
{
provider: provider,
ignoreChanges: ['securityGroupEgress', 'securityGroupIngress'],
},
);
We should definitely document this, so I'll leave this issue open to track that progress.
@corymhall the problem is that I need to define some sort of DMZ where peers of the same SG can talk to each other freely, and additionally allow ingress from different SG.
I have:
const postgresSecurityGroup = new awsNative.ec2.SecurityGroup(name, {
groupDescription: "Managed by Pulumi",
groupName: "postgres-sg",
securityGroupEgress: [],
securityGroupIngress: [],
vpcId: vpc.id
}, {
parent: vpc,
provider: provider
});
new awsNative.ec2.SecurityGroupIngress("postgres-sg-svc-ingress", {
description: "Allow Postgres traffic from workers",
groupId: postgresSecurityGroup.id,
fromPort: 5432,
toPort: 5432,
ipProtocol: "tcp",
sourceSecurityGroupId: workerSecurityGroup.id
}, {
dependsOn: [postgresSecurityGroup, svcSecurityGroup],
parent: postgresSecurityGroup,
provider: provider
});
new awsNative.ec2.SecurityGroupIngress("postgres-sg-dmz-ingress", {
description: "Allow any traffic within the security group perimeter",
groupId: postgresSecurityGroup.id,
fromPort: 0,
toPort: 0,
ipProtocol: "-1",
sourceSecurityGroupId: postgresSecurityGroup.id
}, {
dependsOn: [postgresSecurityGroup],
parent: postgresSecurityGroup,
provider: provider
});
new awsNative.ec2.SecurityGroupEgress("postgres-sg-dmz-egress", {
description: "Allow any traffic within the security group perimeter",
groupId: postgresSecurityGroup.id,
fromPort: 0,
toPort: 0,
ipProtocol: "-1",
destinationSecurityGroupId: postgresSecurityGroup.id
}, {
dependsOn: [postgresSecurityGroup],
parent: postgresSecurityGroup,
provider: provider
});
And it randomly deletes rules :((
Probably, the problem that I'm having in Pulumi.yaml
:
options:
refresh: always
Frankly, pulumi refresh
on aws-native is really weird - constantly lots of warnings :((
I was able to make it stable by changing code to look like:
const postgresSecurityGroup = new awsNative.ec2.SecurityGroup(name, {
groupDescription: "Managed by Pulumi",
groupName: "postgres-sg",
securityGroupEgress: [],
securityGroupIngress: [],
vpcId: vpc.id
}, {
ignoreChanges: ["securityGroupIngress", "securityGroupEgress"],
parent: vpc,
provider: provider
});
new awsNative.ec2.SecurityGroupIngress("postgres-sg-svc-ingress", {
description: "Allow Postgres traffic from workers",
groupId: postgresSecurityGroup.id,
fromPort: 5432,
toPort: 5432,
ipProtocol: "tcp",
sourceSecurityGroupId: workerSecurityGroup.id
}, {
dependsOn: [postgresSecurityGroup, svcSecurityGroup],
parent: postgresSecurityGroup,
provider: provider,
replaceOnChanges: ["*"]
});
new awsNative.ec2.SecurityGroupIngress("postgres-sg-dmz-ingress", {
description: "Allow any traffic within the security group perimeter",
groupId: postgresSecurityGroup.id,
fromPort: 0,
toPort: 0,
ipProtocol: "-1",
sourceSecurityGroupId: postgresSecurityGroup.id
}, {
dependsOn: [postgresSecurityGroup],
parent: postgresSecurityGroup,
provider: provider,
replaceOnChanges: ["*"]
});
new awsNative.ec2.SecurityGroupEgress("postgres-sg-dmz-egress", {
description: "Allow any traffic within the security group perimeter",
groupId: postgresSecurityGroup.id,
fromPort: 0,
toPort: 0,
ipProtocol: "-1",
destinationSecurityGroupId: postgresSecurityGroup.id
}, {
dependsOn: [postgresSecurityGroup],
parent: postgresSecurityGroup,
provider: provider,
replaceOnChanges: ["*"]
});
UPDATE: But that creates default allow anywhere egress :((
UPDATE: But that creates default allow anywhere egress :((
@ixti Unfortunately the default allow-all egress rule is something AWS does by default (even if you use the CLI aws ec2 create-security-group
). You only have two options for preventing that.
aws ec2 revoke-security-group-egress
)securityGroupEgress
property. You can later add explicit egress rules via the SecurityGroupEgress
resource.So for your use case it would look like this
const postgresSecurityGroup = new awsNative.ec2.SecurityGroup(name, {
groupDescription: "Managed by Pulumi",
groupName: "postgres-sg",
securityGroupEgress: [
{
cidrIp: '255.255.255.255/32',
ipProtocol: 'icmp',
fromPort: 252,
toPort: 86,
description: 'Disallow all traffic',
},
],,
securityGroupIngress: [],
vpcId: vpc.id
}, {
ignoreChanges: ["securityGroupIngress", "securityGroupEgress"],
parent: vpc,
provider: provider
});
new awsNative.ec2.SecurityGroupIngress("postgres-sg-svc-ingress", {
description: "Allow Postgres traffic from workers",
groupId: postgresSecurityGroup.id,
fromPort: 5432,
toPort: 5432,
ipProtocol: "tcp",
sourceSecurityGroupId: workerSecurityGroup.id
}, {
dependsOn: [postgresSecurityGroup, svcSecurityGroup],
parent: postgresSecurityGroup,
provider: provider,
replaceOnChanges: ["*"]
});
new awsNative.ec2.SecurityGroupIngress("postgres-sg-dmz-ingress", {
description: "Allow any traffic within the security group perimeter",
groupId: postgresSecurityGroup.id,
fromPort: 0,
toPort: 0,
ipProtocol: "-1",
sourceSecurityGroupId: postgresSecurityGroup.id
}, {
dependsOn: [postgresSecurityGroup],
parent: postgresSecurityGroup,
provider: provider,
replaceOnChanges: ["*"]
});
new awsNative.ec2.SecurityGroupEgress("postgres-sg-dmz-egress", {
description: "Allow any traffic within the security group perimeter",
groupId: postgresSecurityGroup.id,
fromPort: 0,
toPort: 0,
ipProtocol: "-1",
destinationSecurityGroupId: postgresSecurityGroup.id
}, {
dependsOn: [postgresSecurityGroup],
parent: postgresSecurityGroup,
provider: provider,
replaceOnChanges: ["*"]
});
What happened?
Results are unpredictable, and may break the configuration with each run.
After running Pulumi application it may create some security group rules, may create some that are not even defined (egress to any IPv4), or delete some that were previously created - while thinking those resources are still in place.
Example
Output of
pulumi about
Additional context
No response
Contributing
Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).