Introducing Static IP for Application load balancers: Magic of layer4 and layer7 together
WHY THIS BLOG POST: As earlier we were having benefit of only Application load balancers at layer 7 level (HTTP/HTTPS).
Then AWS has introduced the Load balancer with layer 4 (static IP)i.e Network load balancers that gives static IPs at load balancer.
But we couldn’t have both together,It means we can use either Application load balancers: Layer 7 (HTTP/HTTPS) or Network load balancer: Layer 4(static IP).
Going forward with the revolutions,we can have both benefits together with some efforts. Thanks to AWS team for launching all this new features.
As it was asked by one of my customer also, so i have implemented this last week.
Lets dirty our hands with implementation:
- Create a ec2 instance and install nginx application for sample testing.
- Put the instance inside the Application load balancer.
- Create a Network load balancer internal/internet facing according to your application requirement.
- An internal Application Load Balancer. This is where your layer 7 magic happens, such as HTTPS termination fancy routing.
- Both your internal Application Load Balancer and Network Load Balancer need to be in the same Availability Zones.
- An IP-address-based target group for the NLB (target group protocol is TCP).
- An IAM role that has an IAM policy that allows AWS Lambda to create the resources for us.
- An Amazon S3 bucket where we will store information such as ALB IP addresses.
- Create AWS Lambda function to connect the ALB to the NLB.
- CloudWatch event to trigger your lambda.
Role of the Lambda function the gluing soul of this implementation:
- Query DNS for IP addresses in use by the ALB. Upload the results (NEW IP LIST) to the S3 bucket.
- Call the describe-target-health API action to get a list of the IP addresses that are currently registered to the NLB (REGISTERED LIST).
- Download previous IP address list (OLD LIST). If it is the first invocation of the Lambda function, this IP address list is empty.
- Publish the NEW LIST to the Lambda function CloudWatch Logs log stream. This can be used later to search for IP addresses that were used by the ALB.
- Update the CloudWatch metric that tracks the number of the internal ALB IP addresses (created on first invocation). This metric shows how many IP addresses changed since the last run. This is useful if you want to track how many IP addresses your load balancer had over time,disable it by setting CW_METRIC_FLAG_IP_COUNT to “false”.
- Register IP addresses to the NLB that are in NEW LIST but missing from the OLD LIST or REGISTERED LIST.
- Deregister IP addresses in the OLD LIST that are missing from the NEW LIST.
The Architecture:
- Create IAM policy as given below:
{“Version”: “2012–10–17”,“Statement”: [{“Action”: [“logs:CreateLogGroup”,“logs:CreateLogStream”,“logs:PutLogEvents”],“Resource”: [“arn:aws:logs:*:*:*”],“Effect”: “Allow”,“Sid”: “LambdaLogging”},{“Action”: [“s3:Get*”,“s3:PutObject”,“s3:CreateBucket”,“s3:ListBucket”,“s3:ListAllMyBuckets”],“Resource”: “*”,“Effect”: “Allow”,“Sid”: “S3”},{“Action”: [“elasticloadbalancing:Describe*”,“elasticloadbalancing:RegisterTargets”,“elasticloadbalancing:DeregisterTargets”],“Resource”: “*”,“Effect”: “Allow”,“Sid”: “ELB”},{“Action”: [“cloudwatch:putMetricData”],“Resource”: “*”,“Effect”: “Allow”,“Sid”: “CW”}]}
2.Create a IAM role and attach the policy to it.
3.Create a Lambda function:
- Change the handler name to “populate_NLB_TG_with_ALB.lambda_handler” so that AWS Lambda can pick up the Python file that contains the function code.
- Choose Python2.7 as Runtime.
- After that and upload the Lambda function zip file.
Put the environment variables:
Below is the description for all the Environment variables:
ALB_DNS_NAME — the full DNS name (FQDN) of the ALBALB_LISTENER — The traffic listener port of the ALBS3_BUCKET — Bucket to track changes between Lambda invocationsNLB_TG_ARN — The ARN of the NLBs target groupMAX_LOOKUP_PER_INVOCATION — The max times of DNS look per invocation. The default value is 50.INVOCATIONS_BEFORE_DEREGISTRATION — Then number of required Invocations before an IP address is deregistered. The default value is 3.CW_METRIC_FLAG_IP_COUNT — The controller flag that enables the CloudWatch metric of the IP address count. The default value is “true”.
Trigger the lambda manually to test it.
4. After we create the Lambda function, the next step is to create a CloudWatch Event, and configure it to trigger the Lambda function that we just created.
As implementation is done, it’s time to verify the magic now:
- Verify if your site like mine is nginx site works by using the DNS name of the NLB or the IP address on the listening port.
curl http://yourNLB-DNS.elb.us-east-1.amazonaws.com
Here,we will get the nginx html body text in output.
2.Registered targets from NLB:
3. Output from Cloudwatch log groups:
4. Output from Terminal:
Note:
- We will be getting the IPs per availability zone as we have mentioned in the load balancer.
- There will be extra charges for doing this implementation.
- Before implementing this blog in production, please try once in non-prod environment.
Happy APPLICATION LOAD BALANCING with static IP!