Aws-cdk: [Question]: Adding an existing Security Group to an ALB

Created on 5 Mar 2019  路  16Comments  路  Source: aws/aws-cdk

When I add an existing security group to elbv2.ApplicationLoadBalancer CFN still tries to create security group ingress resource. Is this by design? I thought that once you import the SG, ALB would just accept it as is (ISecurityGroup). Is this not the case or I鈥檓 doing something wrong? Do I need to use cfnLoadBalancer instead? Thanks!

 //Import existing VPC
    const vpc = ec2.VpcNetwork.importFromContext(this, "VPC", {
      vpcId: vpcId     
    });

    //Import existing Security Group
    const sg = ec2.SecurityGroup.import(this, "SecurityGroup", {
      securityGroupId: securityGroupId
    });

    //Create an instance of Elastic Load Blancer
    const alb = new elbv2.ApplicationLoadBalancer(this, "ALB", {
      vpc: vpc,
      securityGroup: sg,
      ipAddressType: elbv2.IpAddressType.Ipv4
    });
Resources:
  SecurityGroupfrom000004439CF506C4:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      IpProtocol: tcp
      CidrIp: 0.0.0.0/0
      Description: Allow from anyone on port 443
      FromPort: 443
      GroupId: sg-xxxxxxx
      ToPort: 443
    Metadata:
      aws:cdk:path: DlvEcsClustersStack/SecurityGroup/from 0.0.0.0_0:443
  ALBAEE750D2:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      IpAddressType: ipv4
      LoadBalancerAttributes: []
      Scheme: internal
      SecurityGroups:
        - sg-xxxxxxx
      Subnets:
        - subnet-xxxxxxxx
        - subnet-xxxxxxxx
        - subnet-xxxxxxxx
      Type: application
    Metadata:
      aws:cdk:path: DlvEcsClustersStack/ALB/Resource
@aws-cdaws-elasticloadbalancing feature-request

Most helpful comment

Same issue here. Any updates on this? Importing only creates new SGs and ignores the security group id passed into it

All 16 comments

Ah, good point. It's actually not 100% obvious what the "correct" behaviour should be here, and I suspect reasonable people may have different reasonable opinions.

Right now, passing a SecurityGroup will prevent a new SecurityGroup from being created, but new rules will still be added to allow traffic back and forth between constructs.

This behavior is consistent with, for example, how Roles are passed in. We won't create a Role, but we will add new policy statements to the roles in order to make interactions between resources work.

The feature is currently intended more to allow sharing of objects such as SGs and Roles between constructs, rather than a complete abdication of management responsibilities by the CDK.

I imagine you're asking this from the perspective of someone who works at a company where the creation of "security-related" resources such as IAM roles and security groups is only allowed by a select group of non-application developers?

Rico, is this a sub-set of #1546 ?

@rix0rrr That is correct. We cannot create or update any IAM roles, policies or security groups.

@Doug-AWS, no, don't worry about it.

I think the correct solution for this problem is going to be:

  • iam.ExternallyManagedRole, addToPolicy() will be a no-op.
  • ec2.ExternallyManagedSecurityGroup, addIngressRule() and addEgressRule() will be no-ops.

@rix0rrr Thanks for helping me out with this, but I can't seem to find iam.ExternallyManagedRole or ec2.ExternallyManagedSecurityGroup to test it out. Is this currently supported in v0.25.1?

I can see addToPolicy(), addIngressRule() and addEgressRule() in my imported roles and SGs, but I'm not sure how to make them no-op. Can you please elaborate on no-op?

    //Import existing VPC
    const vpc = ec2.VpcNetwork.importFromContext(this, "VPC", {
      vpcId: props.vpcId    
    });

    //Import existing Security Group
    const sg = ec2.SecurityGroup.import(this, "SecurityGroup", {
      securityGroupId: props.securityGroupId
    });

    //Import existing taskRole
    const taskRole = iam.Role.import(this, "TaskRole", {
      roleArn: `arn:aws:iam::${props.accountId}:role/csr-Task-Role`
    });

    //Import existing executionRole
    const executionRole = iam.Role.import(this, "ExecutionRole", {
      roleArn: `arn:aws:iam::${props.accountId}:role/csr-Executor-Role`
    });

EDIT: I think I figured it out on no-op (see #1957), but I still need iam.ExternallyManagedRole & ec2.ExternallyManagedSecurityGroup clarification.

    sg.addIngressRule = () => {};
    sg.addEgressRule = () => {};
    taskRole.addToPolicy = () => {};
    executionRole.addToPolicy = () => {};

@rix0rrr Btw #1948 and #1957 are two separate stacks I'm working on but there is some topic overlap (i.e. cdk trying to perform changes on resources I have no control of - SGs, roles, policies, etc). Just wanted to clarify that. Thanks again for helping out. 馃憤

You are right, the ExternallyManagedXxx classes I mentioned do not exist today.

You should be able to implement them yourself though.

class ExternallyManagedSomething extends cdk.Construct implements iam.IRole {
  public get roleArn(): string {
    return 'arn:aws:us-east-1:13245:role/my-role';
  }

  public addToPolicy(statement: iam.PolicyStatement) { 
    // do nothing
  } 
}

I've skipped over some details here so this code will not suffice for copy/pasting, but it should give you an idea on how to proceed.

The unfortunate truth is we don't support your scenario as of today, so you're kind of on your own.

image

J/K... I'm going to give it a try and see if that prevents ingress/egress changes. Thanks again for helping me out.

I'm seeing the same behavior when creating a Fargate service and passing a ref to an existing SG, it seems to create a new one.

Same issue here. Any updates on this? Importing only creates new SGs and ignores the security group id passed into it

Similar issue, we have need of restricting a public LB to a security group's rules, but it forces creation of open-to-the-world port 80/443 rules in that group.

Also interested to hear about this

Is there any progress on restricting public access on a load balancer with an already created security group? Not sure of a work around for this particular issue.

SecurityGroup.fromSecurityGroupId now takes an "options" struct which allows making imported security groups immutable.

Was this page helpful?
0 / 5 - 0 ratings