Advertisements
RSS

Tag Archives: VPC

How to configure AWS Lambda functions to use a outbound fixed ip

For our Serverless project running on AWS infrastructure we needed an outbound Lambda API call to a SaaS platform which demands a whitelist of the source IP addresses. Which is pretty hard since AWS has a whole range. Luckily there is a trick to target your Lambda function in a VPC which can be configured to use a elastic IP for outbound communication.

High Level Design

Steps to configure the VPC / Network

Step 1 – create/use a VPC

Our AWS Network configuration always start with an AWS VPC (Virtual Private Cloud). You can use an existing VPC and configure your subnets there, or create a new one. Network configuration on AWS can look simple with the GUI wizard, but the setup of your VPC had major impact on all your resources so for real production a thing to remember. In the example I use CIDR block 10.0.0.0/16 which gives me (way to much) options.

Step 2 – create a public and 1-n private subnets

We will need 1 public subnet to attach to a NAT Gateway and route our traffic to the Internet. The example can work with 1 private subnet which hosts your Lambda function. However for availability purposes you would want to have multiple private subnets in different availability zones for your lambda to run. In the example I use CIDR block 10.0.11.0/24 for the public subnet and 10.0.21.0/24, 10.0.22.0/24 and 10.0.23.0/24 for the 3 private subnets on each eu-west-1 availability zone.

Step 3 – Configure the Internet Gateway and the public subnet configuration

We need an Internet Gateway for our VPC, attach to our public subnet and a public route table configuration which targets all (0.0.0.0/0) outbound traffic from the public subnet.

Step 4 – Configure the NAT Gateway and the private subnet configuration

We need a NAT Gateway which uses an elastic IP address. By adding a private route table which we attach to our private subnet(s) we make sure that all functions in the VPC will use our elastic IP for outbound communication. At lease, if we make sure the private route table contains a (0.0.0.0/0) target to the NAT Gateway

Configure your Lambda function

Make sure your Lambda function(s) use the configured VPC by selecting it in the VPC pulldown and then select all the private subnet(s).

Notes:

  • Make sure your Lambda runs with the IAM AWSLambdaVPCAccessExecutionRole

CloudFormation source code

Template can be found in my aws-cloudformation Git repository as well:

Resources:
  ######################
  ## VPC basics
  ######################
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
      - Key: Name
        Value: t10-fn-vpc-dev
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key: Name
        Value: t10-fn-internetgateway-dev
  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId:
        Ref: InternetGateway
      VpcId:
        Ref: VPC

  ######################
  ## Subnet Public
  ######################
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      AvailabilityZone: eu-west-2a
      CidrBlock: 10.0.11.0/24
      MapPublicIpOnLaunch: true
      Tags:
      - Key: Name
        Value: t10-fn-public-subnet-az1-dev
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:
        Ref: VPC
      Tags:
      - Key: Name
        Value: t10-fn-public-rt-dev
  PublicRouteTableRoute1:
    Type: AWS::EC2::Route
    DependsOn: InternetGateway
    Properties:
      RouteTableId:
        Ref: PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId:
        Ref: InternetGateway
  PublicRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: PublicSubnet1
      RouteTableId:
        Ref: PublicRouteTable
  PublicElasticIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain:
        Ref: VPC
  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId:
        Fn::GetAtt: PublicElasticIP.AllocationId
      SubnetId:
        Ref: PublicSubnet1
      Tags:
      - Key: Name
        Value: t10-fn-natgateway-dev

  ######################
  ## Subnet Private
  ######################
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      AvailabilityZone: eu-west-2a
      CidrBlock: 10.0.21.0/24
      MapPublicIpOnLaunch: false
      Tags:
      - Key: Name
        Value: t10-fn-private-subnet-az1-dev
  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      AvailabilityZone: eu-west-2b
      CidrBlock: 10.0.22.0/24
      MapPublicIpOnLaunch: false
      Tags:
      - Key: Name
        Value: t10-fn-private-subnet-az2-dev
  PrivateSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      AvailabilityZone: eu-west-2c
      CidrBlock: 10.0.23.0/24
      MapPublicIpOnLaunch: false
      Tags:
      - Key: Name
        Value: t10-fn-private-subnet-az3-dev
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:
        Ref: VPC
      Tags:
      - Key: Name
        Value: t10-fn-private-rt-dev
  PrivateRouteTableRoute1:
    Type: AWS::EC2::Route
    DependsOn: NatGateway
    Properties:
      RouteTableId:
        Ref: PrivateRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId:
        Ref: NatGateway
  PrivateRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: PrivateSubnet1
      RouteTableId:
        Ref: PrivateRouteTable
  PrivateRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: PrivateSubnet2
      RouteTableId:
        Ref: PrivateRouteTable
  PrivateRouteTableAssociation3:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: PrivateSubnet3
      RouteTableId:
        Ref: PrivateRouteTable

  ######################
  ## Security NACL
  ######################
  NetworkAcl:
    Type: AWS::EC2::NetworkAcl
    Properties:
      VpcId:
        Ref: VPC
      Tags:
      - Key: Name
        Value: t10-fn-nacl-dev
  NetworkAclEntryfn100:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      CidrBlock: 0.0.0.0/0
      Egress: 'false'
      NetworkAclId:
        Ref: NetworkAcl
      Protocol: "-1"
      RuleAction: allow
      RuleNumber: "100"
  NetworkAclEntryOutbound100:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      CidrBlock: 0.0.0.0/0
      Egress: 'true'
      NetworkAclId:
        Ref: NetworkAcl
      Protocol: "-1"
      RuleAction: allow
      RuleNumber: "100"
  PrivateSubnetNetworkAclAssociation1:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId:
        Ref: PrivateSubnet1
      NetworkAclId:
        Ref: NetworkAcl
  PrivateSubnetNetworkAclAssociation2:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId:
        Ref: PrivateSubnet2
      NetworkAclId:
        Ref: NetworkAcl
  PrivateSubnetNetworkAclAssociation3:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId:
        Ref: PrivateSubnet3
      NetworkAclId:
        Ref: NetworkAcl

  ######################
  ## Security Group(s)
  ######################
  LambdaSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: t10-fn-lambda-sg
      GroupDescription: t10-fn-lambda-sg
      SecurityGroupIngress:
      - IpProtocol: -1
        CidrIp: 0.0.0.0/0
      VpcId:
        Ref: VPC
      Tags:
      - Key: Name
        Value: t10-fn-lambda-sg-dev

  ######################
  ## OUTPUT
  ######################

  #Outputs:
  #  VPC:
  #    Description: A reference to the created VPC
  #    Value:
  #      Ref: VPC
  #    Export:
  #      Name: t10-fn-vpc-id$

References

Advertisements
 
Leave a comment

Posted by on 01-10-2018 in AWS

 

Tags: , , , , ,

AWS CloudFormation error “The parameter groupName cannot be used with the parameter subnet”

When trying to start some EC2 instance through CloudFormation I kept getting the error “The parameter groupName cannot be used with the parameter subnet”.  

The (YAML) AWS CloudFormation looks something like this:

Resources:
  KubernetesControllerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: t10-sg-k8s-controller
      GroupDescription: t10-sg-k8s-controller
      ......
      Tags:
        - Key: Name
          Value: t10-sg-k8s-controller
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-20ee5e5d
      InstanceType: t2.micro
      KeyName: t10_kubernetes
      PrivateIpAddress: 10.0.11.11
      SubnetId:
        Fn::ImportValue:
          !Sub "t10-vpc-k8s-subnet1-id"
      SecurityGroupIds: - !Ref KubernetesControllerSecurityGroup
      Tags:
        - Key: Name
          Value: t10-k8s-controller1

So the error ended in a Google search with many hits, many questions, many suggestions, but very few real answers.

Until I saw this answer from johnhunsley:
I believe you have created a Security Group without specifying a VPC ID. You have then attempted to create a launch config which launches instances into a subnet within a VPC. Therefore, when It attempts to assign the security group to those instances it fails because it expects the security group ID rather than the name.

So I think the response from AWS is in the running for the “Worst Error Message Ever” but the solution is very simple. Don’t make the mistake of not specifying your custom VPC ID when creating a new security group.

Resources:
  KubernetesControllerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: t10-sg-k8s-controller
      GroupDescription: t10-sg-k8s-controller
      ......
      VpcId: !ImportValue t10-vpc-id
      Tags:
        - Key: Name
          Value: t10-sg-k8s-controller

References

johnhunsley @ https://github.com/boto/boto/issues/350

 
Leave a comment

Posted by on 15-08-2018 in AWS, CloudFormation

 

Tags: , , ,