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

Conversation

flemjame-at-amazon
Copy link
Contributor


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

Helper method part of a security group that abstracts this code:

        ISecurityGroup sg = new SecurityGroup(construct, id, SecurityGroupProps.builder()
                .vpc(vpc)
                .build());
        Connections cn = new Connections(ConnectionsProps.builder()
                .securityGroups(Arrays.asList(sg))
                .build());
        sg.getConnections().allowTo(cn, Port.tcp(443));

and makes it into:

        ISecurityGroup sg = new SecurityGroup(construct, id, SecurityGroupProps.builder()
                .vpc(vpc)
                .build());
        sg.allowIntraSecurityGroupTraffic(cn, Port.tcp(443));

I created this because I spent a lot of time looking through documentation trying to allow security group members to talk to each other. Having a method that abstracts away the Connections object would eliminate figuring out how to accomplish this.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@rix0rrr
Copy link
Contributor

rix0rrr commented Dec 24, 2019

@flemjame-at-amazon
Copy link
Contributor Author

Have you seen connections.allowInternally(port) ? https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.Connections.html#allow-wbr-internallyportrange-description

I actually made that change a few days ago, after checking out the Connections documentation.

@rix0rrr
Copy link
Contributor

rix0rrr commented Dec 27, 2019

I actually made that change a few days ago, after checking out the Connections documentation.

Okay, but you have to talk me through the value proposition that is being offered in this PR. As far as I can tell, it's wrapper methods to do what can already be achieved. Presumably you would like this merged because in your opinion will be easier to find/more discoverable.

Can you share some motivation/justification on why you think the current methods are not discoverable and the ones you've added will be better, AND better for the majority of users?

rix0rrr
rix0rrr previously requested changes Jan 2, 2020
Copy link
Contributor

@rix0rrr rix0rrr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this as "changes requested" so it will disappear from my TODO list. Please re-request a review using the GitHub interface when ready.

@flemjame-at-amazon
Copy link
Contributor Author

flemjame-at-amazon commented Jan 2, 2020

I actually made that change a few days ago, after checking out the Connections documentation.

Okay, but you have to talk me through the value proposition that is being offered in this PR. As far as I can tell, it's wrapper methods to do what can already be achieved. Presumably you would like this merged because in your opinion will be easier to find/more discoverable.

Can you share some motivation/justification on why you think the current methods are not discoverable and the ones you've added will be better, AND better for the majority of users?

Re: discoverability -- if I am looking to create rules for a Security Group, the first step is to go to the Security Group documentation. On that page, I see methods for "addIngressRule" and "addEgressRule", which sounds exactly like what I want.

public addEgressRule(peer: IPeer, connection: Port, description?: string, remoteRule?: boolean): void
public addIngressRule(peer: IPeer, connection: Port, description?: string, remoteRule?: boolean): void

I go to the Peer page to check the syntax for adding a Security Group, but there is no method for doing so. I only see options for ipv4/ipv6 CIDRs and prefix lists. At this point, I am not sure where to turn, so I start searching Google for the answer.

Ideally, there would be a Peer for a security group, however when I tried implementing such a thing I ran into an error:

Exception in thread "main" software.amazon.jsii.JsiiException: Cannot use tokens in construct ID: to ${Token[Default.PrefixListID.350]}:443
Error: Cannot use tokens in construct ID: to ${Token[Default.PrefixListID.350]}:443
    at new ConstructNode (/private/var/folders/h1/l30xn7q95cg89_8vtpbcx4nr06cc3p/T/jsii-kernel-2NdZz1/node_modules/@aws-cdk/core/lib/construct.js:39:19)
    at new Construct (/private/var/folders/h1/l30xn7q95cg89_8vtpbcx4nr06cc3p/T/jsii-kernel-2NdZz1/node_modules/@aws-cdk/core/lib/construct.js:435:21)
    at new CfnElement (/private/var/folders/h1/l30xn7q95cg89_8vtpbcx4nr06cc3p/T/jsii-kernel-2NdZz1/node_modules/@aws-cdk/core/lib/cfn-element.js:20:9)
    at new CfnRefElement (/private/var/folders/h1/l30xn7q95cg89_8vtpbcx4nr06cc3p/T/jsii-kernel-2NdZz1/node_modules/@aws-cdk/core/lib/cfn-element.js:95:1)
    at new CfnResource (/private/var/folders/h1/l30xn7q95cg89_8vtpbcx4nr06cc3p/T/jsii-kernel-2NdZz1/node_modules/@aws-cdk/core/lib/cfn-resource.js:21:9)
    at new CfnSecurityGroupEgress (/private/var/folders/h1/l30xn7q95cg89_8vtpbcx4nr06cc3p/T/jsii-kernel-2NdZz1/node_modules/@aws-cdk/aws-ec2/lib/ec2.generated.js:4729:9)
    at SecurityGroup.addEgressRule (/private/var/folders/h1/l30xn7q95cg89_8vtpbcx4nr06cc3p/T/jsii-kernel-2NdZz1/node_modules/@aws-cdk/aws-ec2/lib/security-group.js:43:13)
    at SecurityGroup.addEgressRule (/private/var/folders/h1/l30xn7q95cg89_8vtpbcx4nr06cc3p/T/jsii-kernel-2NdZz1/node_modules/@aws-cdk/aws-ec2/lib/security-group.js:199:19)

Looking at the implementation of SecurityGroup, it looks like it uses the Peer as an input to compute the construct id for ingress/egress rules. And since the construct id is used to compute the logical resource name, that can’t depend on a ref. Changing this is definitely NOT backwards compatible, so I scrapped that idea.

The right way to add an inter or intra-SG rule is to use the SecurityGroupIngress and SecurityGroupEgress resources, per AWS documentation. Connections will do this for you, but it isn't advertised at all on the Security Group documentation. Searching for "Connections" on the Security Group documentation brings up the property "connections" but there is no documentation on what it is or does.

I saw two options: to increase the visibility of the Connections class and how to use it for common cases, or abstract it away in the Security Group class. I prefer the abstraction because it provides a quick method for a CDK user to add an intra-security group rule, which in my experience is a common use case, and which is visible from the Security Group page, which is where I would expect to find it.

rix0rrr added a commit that referenced this pull request Jan 6, 2020
For people already familiar with the inner workings of Security Groups,
our `.connections` pattern is a little confusing.

Add some more verbiage to the documentation which points people in
the right direction with respect to security group manipulation.

Closes #5519.
@rix0rrr
Copy link
Contributor

rix0rrr commented Jan 6, 2020

I tried improving the docs you searched in this PR: #5662 to hopefully make it easier for you and others to find the right methods.

I hope to explain the philosophy using these sentences:

Like IAM Roles, Security Groups need to exist to control access between AWS resources, but CDK will automatically generate and populate them with least-privilege permissions for you so you can concentrate on your business logic.

After construction, you can selectively allow connections to and between constructs via--for example-- the instance.connections object. Think of it as "allowing connections to your instance", rather than "adding ingress rules a security group".

@flemjame-at-amazon
Copy link
Contributor Author

I tried improving the docs you searched in this PR: #5662 to hopefully make it easier for you and others to find the right methods.

I hope to explain the philosophy using these sentences:

Like IAM Roles, Security Groups need to exist to control access between AWS resources, but CDK will automatically generate and populate them with least-privilege permissions for you so you can concentrate on your business logic.

After construction, you can selectively allow connections to and between constructs via--for example-- the instance.connections object. Think of it as "allowing connections to your instance", rather than "adding ingress rules a security group".

OH! It makes so much more sense after reading PR #5662. That's a really nice way to abstract security groups from CDK users.

@flemjame-at-amazon
Copy link
Contributor Author

I tried improving the docs you searched in this PR: #5662 to hopefully make it easier for you and others to find the right methods.

I hope to explain the philosophy using these sentences:

Like IAM Roles, Security Groups need to exist to control access between AWS resources, but CDK will automatically generate and populate them with least-privilege permissions for you so you can concentrate on your business logic.

After construction, you can selectively allow connections to and between constructs via--for example-- the instance.connections object. Think of it as "allowing connections to your instance", rather than "adding ingress rules a security group".

How does this work for things not managed with a security group, like Network Load Balancers? I only see options like "allowFromAnyIpv4", which isn't ideal, and a better would be something like "allowFromVpcIpv4"

@mergify mergify bot dismissed rix0rrr’s stale review January 6, 2020 19:33

Pull request has been modified.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@rix0rrr
Copy link
Contributor

rix0rrr commented Jan 7, 2020

How does this work for things not managed with a security group, like Network Load Balancers? I only see options like "allowFromAnyIpv4", which isn't ideal, and a better would be something like "allowFromVpcIpv4"

You can always make a Peer.ipv4(vpc.cidrRange) if you need that. We need to think about the right way to do this. The problem is that if you say instance.connections.allowFrom(vpc), we can create the ingress rule with the CIDR, but we can't update all SGs of instances in the VPC to allow outbound connections. For default SGs (allowAllOutbound=true) that doesn't matter, but I don't really like that it won't work for locked-down SGs.

@mergify mergify bot closed this in #5662 Jan 7, 2020
mergify bot added a commit that referenced this pull request Jan 7, 2020
For people already familiar with the inner workings of Security Groups,
our `.connections` pattern is a little confusing.

Add some more verbiage to the documentation which points people in
the right direction with respect to security group manipulation.

Closes #5519.

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
@flemjame-at-amazon flemjame-at-amazon deleted the add-intra-sg-method branch September 2, 2020 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants