Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ec2): add helper method for creating intra-security-group traffic rules #5519

Closed
Closed
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions packages/@aws-cdk/aws-ec2/lib/security-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,19 @@ export class SecurityGroup extends SecurityGroupBase {
: new ImmutableImport(scope, id);
}

/**
* Allows traffic in the `from` security group to the `to` security group,
* creating an egress rule in the `from` security group and an ingress rule
* in the `to` security group. This does not override `allowAllOutbound` if
* it is set.
*/
public static allowTrafficBetweenSecurityGroups(fromSecurityGroup: ISecurityGroup,
toSecurityGroup: ISecurityGroup,
port: Port,
description?: string) {
fromSecurityGroup.connections.allowTo(toSecurityGroup, port, description);
}

/**
* An attribute that represents the security group name.
*
Expand Down Expand Up @@ -356,6 +369,22 @@ export class SecurityGroup extends SecurityGroupBase {
});
}

/**
* Creates a rule which allows members of the security group
* to connect with each other over the specified port.
*/
public allowIntraSecurityGroupTraffic(port: Port, description?: string) {
this.connections.allowInternally(port, description);
}

/**
* Creates a rule which allows members of the security group
* to connect with each other over the specified port.
*/
public allowTrafficFromSecurityGroup(fromSecurityGroup: ISecurityGroup, port: Port, description?: string) {
SecurityGroup.allowTrafficBetweenSecurityGroups(fromSecurityGroup, this, port, description);
}

public addEgressRule(peer: IPeer, connection: Port, description?: string, remoteRule?: boolean) {
if (this.allowAllOutbound) {
// In the case of "allowAllOutbound", we don't add any more rules. There
Expand Down
164 changes: 164 additions & 0 deletions packages/@aws-cdk/aws-ec2/test/test.security-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,170 @@ export = {

test.done();
},
'security group - test that an intra security group rule doesnt override `allowAllOutbound` egress'(test: Test) {
// GIVEN
const stack = new Stack();
const vpc = new Vpc(stack, 'VPC');

// WHEN
const sg = new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: true });
sg.allowIntraSecurityGroupTraffic(Port.tcp(443));
// THEN

expect(stack).to(haveResource('AWS::EC2::SecurityGroupIngress', {
IpProtocol: "tcp",
Description: "from SG1:443",
FromPort: 443,
GroupId: {
"Fn::GetAtt": [
"SG1BA065B6E",
"GroupId"
]
},
SourceSecurityGroupId: {
"Fn::GetAtt": [
"SG1BA065B6E",
"GroupId"
]
},
ToPort: 443
}));

expect(stack).to(haveResource('AWS::EC2::SecurityGroup', {
SecurityGroupEgress: [
{
CidrIp: "0.0.0.0/0",
Description: "Allow all outbound traffic by default",
IpProtocol: "-1"
}
],
}));

test.done();
},
'security group - test that a security group with intra rule and not `allowAllOutbound` has ingress and egress rules'(test: Test) {
// GIVEN
const stack = new Stack();
const vpc = new Vpc(stack, 'VPC');

// WHEN
const sg = new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: false });
sg.allowIntraSecurityGroupTraffic(Port.tcp(443));
// THEN

expect(stack).to(haveResource('AWS::EC2::SecurityGroupIngress', {
IpProtocol: "tcp",
Description: "from SG1:443",
FromPort: 443,
GroupId: {
"Fn::GetAtt": [
"SG1BA065B6E",
"GroupId"
]
},
SourceSecurityGroupId: {
"Fn::GetAtt": [
"SG1BA065B6E",
"GroupId"
]
},
ToPort: 443
}));

expect(stack).to(haveResource('AWS::EC2::SecurityGroupEgress', {
IpProtocol: "tcp",
Description: "to SG1:443",
FromPort: 443,
GroupId: {
"Fn::GetAtt": [
"SG1BA065B6E",
"GroupId"
]
},
DestinationSecurityGroupId: {
"Fn::GetAtt": [
"SG1BA065B6E",
"GroupId"
]
},
ToPort: 443
}));

expect(stack).notTo(haveResource('AWS::EC2::SecurityGroup', {
SecurityGroupEgress: [
{
CidrIp: "0.0.0.0/0",
Description: "Allow all outbound traffic by default",
IpProtocol: "-1"
}
],
}));

test.done();
},

'security group - test inter-security group rules'(test: Test) {
// GIVEN
const stack = new Stack();
const vpc = new Vpc(stack, 'VPC');

// WHEN
const sg1 = new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: false });
const sg2 = new SecurityGroup(stack, 'SG2', { vpc, allowAllOutbound: false });
sg1.allowTrafficFromSecurityGroup(sg2, Port.tcp(443));

// THEN

expect(stack).to(haveResource('AWS::EC2::SecurityGroupIngress', {
IpProtocol: "tcp",
Description: "from SG2:443",
FromPort: 443,
GroupId: {
"Fn::GetAtt": [
"SG1BA065B6E",
"GroupId"
]
},
SourceSecurityGroupId: {
"Fn::GetAtt": [
"SG20CE3219C",
"GroupId"
]
},
ToPort: 443
}));

expect(stack).to(haveResource('AWS::EC2::SecurityGroupEgress', {
IpProtocol: "tcp",
Description: "to SG1:443",
FromPort: 443,
GroupId: {
"Fn::GetAtt": [
"SG20CE3219C",
"GroupId"
]
},
DestinationSecurityGroupId: {
"Fn::GetAtt": [
"SG1BA065B6E",
"GroupId"
]
},
ToPort: 443
}));

expect(stack).notTo(haveResource('AWS::EC2::SecurityGroup', {
SecurityGroupEgress: [
{
CidrIp: "0.0.0.0/0",
Description: "Allow all outbound traffic by default",
IpProtocol: "-1"
}
],
}));

test.done();
},

'bogus outbound rule disappears if another rule is added'(test: Test) {
// GIVEN
Expand Down