How To Create An Internet-Facing Network Load Balancer With Static Public (Elastic) IP Address
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
In the last blog post, we have discussed Network Load Balancer target group’s health checks.
https://cloudaffaire.com/network-load-balancer-target-group-health-checks/
In this blog post, we will discuss how to create an internet-facing network load balancer with static public (elastic) ip address.
How To Create An Internet-Facing Network Load Balancer With Static Public (Elastic) IP Address:
By default, AWS assigns an private IPv4 address to each load balancer node from the subnet for its Availability Zone. Alternatively, if you create an internet-facing load balancer, you can select an Elastic IP address for each Availability Zone. This provides your load balancer with static IP addresses. If you create an internal load balancer, you can assign a private IP address from the IPv4 range of each subnet instead of letting AWS assign one.
internet-facing load balancer ip assignment:
- one public ip address assigned by AWS or one elastic ip address assigned by customer to each load balancer node in Availability Zone.
- one private address assigned by AWS to each load balancer node from the subnet for its Availability Zone.
Note: Customer can not specify the private ip address for internet-facing load balancer nodes.
How To Create An Internet-Facing Network Load Balancer With Static Public (Elastic) IP Address:
Step 1: Create a custom VPC with two Elastic IP addresses for your internet-facing network load balancer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
######################################################################### ## Internet-Facing Network Load Balancer With Static Public IP Address ## ######################################################################### ## Prerequisite: AWS CLI installed and configured with proper access ## https://cloudaffaire.com/category/aws/aws-cli/ ##---------------------------------- ## Create custom vpc for your nlb ## ##---------------------------------- ## Create a directory for this demo mkdir aws_internet_facing_nlb_demo && cd aws_internet_facing_nlb_demo ## Create a VPC with DNS hostname enabled AWS_VPC_ID=$(aws ec2 create-vpc \ --cidr-block 10.0.0.0/16 \ --query 'Vpc.{VpcId:VpcId}' \ --output text) && aws ec2 modify-vpc-attribute \ --vpc-id $AWS_VPC_ID \ --enable-dns-hostnames "{\"Value\":true}" ## Create two public subnets AWS_SUBNET_PUBLIC_ONE_ID=$(aws ec2 create-subnet \ --vpc-id $AWS_VPC_ID --cidr-block 10.0.1.0/24 \ --availability-zone ap-south-1a --query 'Subnet.{SubnetId:SubnetId}' \ --output text) && AWS_SUBNET_PUBLIC_TWO_ID=$(aws ec2 create-subnet \ --vpc-id $AWS_VPC_ID --cidr-block 10.0.2.0/24 \ --availability-zone ap-south-1b --query 'Subnet.{SubnetId:SubnetId}' \ --output text) && aws ec2 modify-subnet-attribute \ --subnet-id $AWS_SUBNET_PUBLIC_ONE_ID \ --map-public-ip-on-launch && aws ec2 modify-subnet-attribute \ --subnet-id $AWS_SUBNET_PUBLIC_TWO_ID \ --map-public-ip-on-launch ## Create an Internet Gateway AWS_INTERNET_GATEWAY_ID=$(aws ec2 create-internet-gateway \ --query 'InternetGateway.{InternetGatewayId:InternetGatewayId}' \ --output text) && aws ec2 attach-internet-gateway \ --vpc-id $AWS_VPC_ID \ --internet-gateway-id $AWS_INTERNET_GATEWAY_ID ## Create a route table AWS_CUSTOM_ROUTE_TABLE_ID=$(aws ec2 create-route-table \ --vpc-id $AWS_VPC_ID \ --query 'RouteTable.{RouteTableId:RouteTableId}' \ --output text ) && aws ec2 create-route \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID \ --destination-cidr-block 0.0.0.0/0 \ --gateway-id $AWS_INTERNET_GATEWAY_ID ## Associate the public subnet with route table AWS_ROUTE_TABLE_ASSOID_ONE=$(aws ec2 associate-route-table \ --subnet-id $AWS_SUBNET_PUBLIC_ONE_ID \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID \ --query 'AssociationId' \ --output text) && AWS_ROUTE_TABLE_ASSOID_TWO=$(aws ec2 associate-route-table \ --subnet-id $AWS_SUBNET_PUBLIC_TWO_ID \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID \ --query 'AssociationId' \ --output text) ## Create a security group aws ec2 create-security-group \ --vpc-id $AWS_VPC_ID \ --group-name myvpc-security-group \ --description 'My VPC non default security group' ## Get security group ID's AWS_DEFAULT_SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \ --filters "Name=vpc-id,Values=$AWS_VPC_ID" \ --query 'SecurityGroups[?GroupName == `default`].GroupId' \ --output text) && AWS_CUSTOM_SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \ --filters "Name=vpc-id,Values=$AWS_VPC_ID" \ --query 'SecurityGroups[?GroupName == `myvpc-security-group`].GroupId' \ --output text) ## Create security group ingress rules aws ec2 authorize-security-group-ingress \ --group-id $AWS_CUSTOM_SECURITY_GROUP_ID \ --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "Allow SSH"}]}]' && aws ec2 authorize-security-group-ingress \ --group-id $AWS_CUSTOM_SECURITY_GROUP_ID \ --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 0, "ToPort": 65535, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "Allow TCP"}]}]' ## Create two Elastic IP address for your NLB AWS_ELASTIC_IP_ONE_ALLOCID=$(aws ec2 allocate-address \ --domain vpc \ --query 'AllocationId' \ --output text) && AWS_ELASTIC_IP_TWO_ALLOCID=$(aws ec2 allocate-address \ --domain vpc \ --query 'AllocationId' \ --output text) |
Step 2: Create two EC2 instances as your Network Load Balancer target.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
##-------------------------------------------------- ## Create two ec2 instances your nlb target group ## ##-------------------------------------------------- ## Get Amazon Linux 2 latest AMI ID AWS_AMI_ID=$(aws ec2 describe-images \ --owners 'amazon' \ --filters 'Name=name,Values=amzn2-ami-hvm-2.0.????????-x86_64-gp2' 'Name=state,Values=available' \ --query 'sort_by(Images, &CreationDate)[-1].[ImageId]' \ --output 'text') ## Create a key-pair aws ec2 create-key-pair \ --key-name myvpc-keypair \ --query 'KeyMaterial' \ --output text > myvpc-keypair.pem && chmod 400 myvpc-keypair.pem ## Create user data to configure LAMP stack vi myuserdataone.txt ----------------------- #!/bin/bash sudo yum install -y httpd sudo systemctl start httpd sudo usermod -a -G apache ec2-user sudo chown -R ec2-user:apache /var/www sudo chmod 2775 /var/www sudo find /var/www -type d -exec chmod 2775 {} \; sudo find /var/www -type f -exec chmod 0664 {} \; sudo echo "hello from instance one" > /var/www/html/index.html ----------------------- :wq vi myuserdatatwo.txt ----------------------- #!/bin/bash sudo yum install -y httpd sudo systemctl start httpd sudo usermod -a -G apache ec2-user sudo chown -R ec2-user:apache /var/www sudo chmod 2775 /var/www sudo find /var/www -type d -exec chmod 2775 {} \; sudo find /var/www -type f -exec chmod 0664 {} \; sudo echo "hello from instance two" > /var/www/html/index.html ----------------------- :wq ## Create two EC2 instance in two public subnet AWS_EC2_INSTANCE_ONE_ID=$(aws ec2 run-instances \ --image-id $AWS_AMI_ID \ --instance-type t2.micro \ --key-name myvpc-keypair \ --monitoring "Enabled=false" \ --security-group-ids $AWS_CUSTOM_SECURITY_GROUP_ID \ --subnet-id $AWS_SUBNET_PUBLIC_ONE_ID \ --user-data file://myuserdataone.txt \ --private-ip-address 10.0.1.10 \ --query 'Instances[0].InstanceId' \ --output text) && AWS_EC2_INSTANCE_TWO_ID=$(aws ec2 run-instances \ --image-id $AWS_AMI_ID \ --instance-type t2.micro \ --key-name myvpc-keypair \ --monitoring "Enabled=false" \ --security-group-ids $AWS_CUSTOM_SECURITY_GROUP_ID \ --subnet-id $AWS_SUBNET_PUBLIC_TWO_ID \ --user-data file://myuserdatatwo.txt \ --private-ip-address 10.0.2.10 \ --query 'Instances[0].InstanceId' \ --output text) |
Step 3: Create an internet-facing network load balancer with static public (elastic) ip address.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
##----------------------------------------------------------------------- ## Create internet-facing network load balancer with static ip address ## ##----------------------------------------------------------------------- ## Create the network load balancer AWS_NLB_ARN=$(aws elbv2 create-load-balancer \ --name my-network-load-balancer \ --subnet-mappings SubnetId=$AWS_SUBNET_PUBLIC_ONE_ID,AllocationId=$AWS_ELASTIC_IP_ONE_ALLOCID \ SubnetId=$AWS_SUBNET_PUBLIC_TWO_ID,AllocationId=$AWS_ELASTIC_IP_TWO_ALLOCID \ --type network \ --query 'LoadBalancers[0].LoadBalancerArn' \ --output text) ## Check the status of load balancer aws elbv2 describe-load-balancers \ --load-balancer-arns $AWS_NLB_ARN \ --query 'LoadBalancers[0].State.Code' \ --output text ## Once the nlb status is active, get the DNS name for your nlb AWS_NLB_DNS=$(aws elbv2 describe-load-balancers \ --load-balancer-arns $AWS_NLB_ARN \ --query 'LoadBalancers[0].DNSName' \ --output text) && echo $AWS_NLB_DNS ## Create the target group for your nlb AWS_NLB_TARGET_GROUP_ARN=$(aws elbv2 create-target-group \ --name my-nlb-targets \ --protocol TCP --port 80 \ --vpc-id $AWS_VPC_ID \ --query 'TargetGroups[0].TargetGroupArn' \ --output text) ## Register both the instances in the target group aws elbv2 register-targets --target-group-arn $AWS_NLB_TARGET_GROUP_ARN \ --targets Id=$AWS_EC2_INSTANCE_ONE_ID Id=$AWS_EC2_INSTANCE_TWO_ID ## Create a listener for your load balancer with a default rule that forwards requests to your target group AWS_NLB_LISTNER_ARN=$(aws elbv2 create-listener --load-balancer-arn $AWS_NLB_ARN \ --protocol TCP --port 80 \ --default-actions Type=forward,TargetGroupArn=$AWS_NLB_TARGET_GROUP_ARN \ --query 'Listeners[0].ListenerArn' \ --output text) ## Verify the health of the registered targets for your target group aws elbv2 describe-target-health --target-group-arn $AWS_NLB_TARGET_GROUP_ARN ## Get the Elastic IP address from network interface AWS_ELASTIC_IP_ONE=$(aws ec2 describe-network-interfaces \ --filters Name=association.allocation-id,Values=$AWS_ELASTIC_IP_ONE_ALLOCID \ --query 'NetworkInterfaces[0].Association.PublicIp' \ --output text) && AWS_ELASTIC_IP_TWO=$(aws ec2 describe-network-interfaces \ --filters Name=association.allocation-id,Values=$AWS_ELASTIC_IP_TWO_ALLOCID \ --query 'NetworkInterfaces[0].Association.PublicIp' \ --output text) && echo $AWS_ELASTIC_IP_ONE && echo $AWS_ELASTIC_IP_TWO ## Check NLB DNS name for IP address ## Same as elastic ip address that you have assigned dig +short $AWS_NLB_DNS | tail -n2 ## Send request to your NLB using DNS and IP address curl $AWS_NLB_DNS curl $AWS_ELASTIC_IP_ONE curl $AWS_ELASTIC_IP_TWO ## Responce from both the instances |
Step 4: Cleanup.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
##----------- ## Cleanup ## ##----------- ## Delete the listener and Deregister targets aws elbv2 delete-listener \ --listener-arn $AWS_NLB_LISTNER_ARN && aws elbv2 deregister-targets \ --target-group-arn $AWS_NLB_TARGET_GROUP_ARN \ --targets Id=$AWS_EC2_INSTANCE_ONE_ID Id=$AWS_EC2_INSTANCE_TWO_ID ## Delete target group and nlb aws elbv2 delete-target-group \ --target-group-arn $AWS_NLB_TARGET_GROUP_ARN && aws elbv2 delete-load-balancer \ --load-balancer-arn $AWS_NLB_ARN ## Deallocate the Elastic IP address aws ec2 release-address \ --allocation-id $AWS_ELASTIC_IP_ONE_ALLOCID && aws ec2 release-address \ --allocation-id $AWS_ELASTIC_IP_TWO_ALLOCID ## Terminate the ec2 instances aws ec2 terminate-instances \ --instance-ids $AWS_EC2_INSTANCE_ONE_ID && aws ec2 terminate-instances \ --instance-ids $AWS_EC2_INSTANCE_TWO_ID ## Delete key pair aws ec2 delete-key-pair \ --key-name myvpc-keypair ## Delete custom security group (once instances are terminated) aws ec2 delete-security-group \ --group-id $AWS_CUSTOM_SECURITY_GROUP_ID ## Delete internet gateway aws ec2 detach-internet-gateway \ --internet-gateway-id $AWS_INTERNET_GATEWAY_ID \ --vpc-id $AWS_VPC_ID && aws ec2 delete-internet-gateway \ --internet-gateway-id $AWS_INTERNET_GATEWAY_ID ## Disassociate the subnets from custom route table aws ec2 disassociate-route-table \ --association-id $AWS_ROUTE_TABLE_ASSOID_ONE && aws ec2 disassociate-route-table \ --association-id $AWS_ROUTE_TABLE_ASSOID_TWO ## Delete custom route table aws ec2 delete-route-table \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID ## Delete the public subnets aws ec2 delete-subnet \ --subnet-id $AWS_SUBNET_PUBLIC_ONE_ID && aws ec2 delete-subnet \ --subnet-id $AWS_SUBNET_PUBLIC_TWO_ID ## Delete the vpc aws ec2 delete-vpc \ --vpc-id $AWS_VPC_ID ## Delete the directory used in this demo cd .. && rm -rf aws_internet_facing_nlb_demo |
Hope you have enjoyed this article, In the next blog post, we will discuss how to create an internal network load balancer with private ip address.
All the public cloud providers are changing the console user interface rapidly and due to this some of the screenshots used in our previous AWS blogs are no longer relevant. Hence, we have decided that from now onwards most of the demo will be done programmatically. Let us know your feedback on this in the comment section.
To get more details on AWS ELB, please refer below AWS documentation
https://docs.aws.amazon.com/elasticloadbalancing/index.html