Skip to content

Instantly share code, notes, and snippets.

@duttonw
Created February 1, 2023 22:55
Show Gist options
  • Save duttonw/6b494b8d33d157a904f9817d91e2967b to your computer and use it in GitHub Desktop.
Save duttonw/6b494b8d33d157a904f9817d91e2967b to your computer and use it in GitHub Desktop.

Revisions

  1. duttonw created this gist Feb 1, 2023.
    99 changes: 99 additions & 0 deletions GetInternalNLBIp4List.cfn.yml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,99 @@
    #In this example we want to get the private ip4 address of a ELBv2 (network)
    #Full stack located here: https://github.com/qld-gov-au/quickstart-atlassian-bitbucket/blob/d6ebe59b5ccdd204a7edc72ab6f0f89d575ac6f8/templates/quickstart-bitbucket-dc.template.yaml


    #Network Load Balancer health checks, need internal ip to approve connectivity
    InternalNLBIp4List:
    DependsOn: NetworkLoadBalancerELB2
    Type: Custom::InternalNLBIp4ListCollector
    Version: 1.0
    Properties:
    ServiceToken: !GetAtt InternalNLBIp4ListCollector.Arn
    ELBv2Arn: !Ref NetworkLoadBalancerELB2
    StackName: !Ref 'AWS::StackName'
    InternalNLBIp4ListCollector:
    Type: "AWS::Lambda::Function"
    Properties:
    Handler: index.lambda_handler
    Role: !GetAtt InternalNLBIp4ListCollectorExecutionRole.Arn
    Runtime: python3.7
    Timeout: 120
    Code:
    ZipFile: |
    import cfnresponse
    import boto3
    def lambda_handler(event, context):
    elbv2 = boto3.client('elbv2')
    ec2 = boto3.client('ec2')
    elb2arn = event['ResourceProperties']['ELBv2Arn']
    response = elbv2.describe_load_balancers(LoadBalancerArns=[elb2arn])
    name = response['LoadBalancers'][0]['LoadBalancerName']
    elbtype = response['LoadBalancers'][0]['Type']
    filters = [{'Name': 'description', 'Values': ['ELB '+ elbtype[0:3] + '/' + name + '*']}]
    eni_response = ec2.describe_network_interfaces(Filters=filters)
    ip_addresses = [eni['PrivateIpAddress'] for eni in eni_response['NetworkInterfaces']]
    ip_addresses_cidr = [eni['PrivateIpAddress'] + '/32' for eni in eni_response['NetworkInterfaces']]
    print (ip_addresses)
    responseData = {}
    responseData['PrivateIpAddresses'] = ip_addresses
    responseData['PrivateIpCidrAddresses'] = ip_addresses_cidr
    cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
    InternalNLBIp4ListCollectorExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
    AssumeRolePolicyDocument:
    Version: '2012-10-17'
    Statement:
    - Effect: Allow
    Principal:
    Service:
    - lambda.amazonaws.com
    Action:
    - sts:AssumeRole
    Path: "/"
    Policies:
    - PolicyName: root
    PolicyDocument:
    Version: '2012-10-17'
    Statement:
    - Effect: Allow
    Action:
    - logs:CreateLogGroup
    - logs:CreateLogStream
    - logs:PutLogEvents
    Resource: !Sub "arn:${AWS::Partition}:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*InternalNLBIp4ListCollector*"
    - Effect: Allow
    Action:
    - "elasticloadbalancing:DescribeLoadBalancers"
    - "ec2:DescribeNetworkInterfaces"
    Resource: "*"





    #NLB ip's need to be whitelisted to allow health checks to pass
    SecurityGroupIngressNLB:
    DependsOn:
    - InternalNLBIp4List
    - SecurityGroup
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
    GroupId: !Ref SecurityGroup
    IpProtocol: "-1"
    FromPort: -1
    ToPort: -1
    CidrIp: !Select [ 0, !GetAtt InternalNLBIp4List.PrivateIpCidrAddresses ]
    SecurityGroupIngressNLB2: #ELB in 2 subnets, will have 2 ip's
    DependsOn:
    - InternalNLBIp4List
    - SecurityGroup
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
    GroupId: !Ref SecurityGroup
    IpProtocol: "-1"
    FromPort: -1
    ToPort: -1
    CidrIp: !Select [ 1, !GetAtt InternalNLBIp4List.PrivateIpCidrAddresses ]