Where can I get the IP address of an elastic beanstalk load-balanced application?

Zhafri Shafiq
Geek Culture
Published in
5 min readJul 24, 2021

TL;DR: We managed to setup VPC with public and private subnets, created new EB environment in the new VPC with load balancer in public subnets and instances in private subnets.

This is my first article, so forgive me for the bad writing. I will try to get straight to the point.

This week, there was an issue with our mail service. Our mail service account was blocked, because it had reached monthly send limit of 25,000. It turned out that one of the API keys was compromised and was used for spamming.

One of the solutions is to restrict the API keys by whitelisting an IP address, and in this case, of an elastic beanstalk load-balanced application.

Now for your information, bear in mind that as of today, my experience dealing with AWS services is exactly one month. My ‘other’ solution was to whitelist all the IP addresses of the EC2 instances. I assumed that this might not be a good practice, as we need to keep track of all the instances spawned and destroyed over time. And I just had this thought that this is a common case where the elastic beanstalk application could have a static IP address. So the google-ing began.

From the google results, I read that we must configure the environment’s Network first in order to see it. But, when I went to check it in my application’s configuration, it was written that ‘This environment is not part of a VPC’. And there was no Edit button displayed, which was supposed to as mentioned from google results.

Elastic Beanstalk environment Network configuration

Basically, during environment creation, if we don’t select any subnet in Network configuration, the Elastic Beanstalk launches the instances in the default VPC of the environment but unfortunately it does not let us edit it at a later point.

The issue in existing environment is that:

  1. If we select no VPC during creation, Elastic Beanstalk does not let us edit any network configurations later.
  2. If we do select the VPC during creation (even default VPC), we can then modify the subnets of Elastic Beanstalk and EC2 at a later point, but not change the VPC itself.

A while after back and forth with my superior, we decided to contact AWS Support. Long story short, after the support session ended, to achieve the static IP address, we will need to roughly follow the below steps:

  1. Have a VPC with private and public subnets.
  2. Have a NAT Gateway in public subnet and in route table of private subnets, add a rule to NAT gateway (0.0.0.0/0 -> NAT Gateway).
  3. When creating elastic beanstalk environment, select this VPC and for instance subnets, check only the private subnets so EC2s are only in private subnets.
  4. This setup will route all the outgoing traffic from EC2s via NAT gateway. Now this NAT Gateway has a static elastic IP and this will be the outgoing IP of elastic beanstalk.

I will walkthrough the steps for VPC below.

  1. Go and create a new VPC. As for IPv4 CIDR block, you may set it as 10.0.0.0/16. There is an info button for more information.
VPC Creation

2. After creation, click the VPC id. Then, click action and Edit DNS hostnames. Check Enable for DNS hostnames.

3. Go to Subnets and create 4 subnets. You may name it public-subnet-1, private-subnet-1 for example, to differ between public and private subnets, which will be handy in the coming section. For Availability Zone, pick different zone for each type of subnets. For IPv4 CIDR, you may check below.

+-------------------+----------------------+-------------+
| Subnets | Availability Zone | IPv4 CIDR |
+-------------------+----------------------+-------------+
| public-subnet-1 | ap-southeast-1a | 10.0.1.0/24 |
| public-subnet-2 | ap-southeast-1b | 10.0.2.0/24 |
| private-subnet-1 | ap-southeast-1a | 10.0.3.0/24 |
| private-subnet-2 | ap-southeast-1b | 10.0.4.0/24 |
+-------------------+----------------------+-------------+

4. After subnets creation, you should see that there is only one record of route table in each subnets, which target to local. Now go to Internet Gateways and create a new one.

5. Inside the new internet gateway, you should see that the State is Detached. You have to attach it to the new VPC. Click Actions and Attach to VPC. Choose the new VPC. This action will add a route to internet gateways for all subnets in the VPC. You can verify it by looking at the route table from subnet’s Route tables.

6. Go to NAT Gateways and create NAT Gateway. For the subnet, pick any of the public subnet, if you followed my naming convention. Choose Public for Connectivity type. Allocate Elastic IP if you don’t have any. Elastic IP is required.

7. Now we need to create a new route table for private subnets that should target to NAT Gateway. Go to Route tables and create route table. You may name it private-route-table-1 for example.

8. Inside the new route table, add one more route by clicking Edit routes. Use the new NAT Gateway ID as the Target.

+-------------+--------+
| Destination | Target |
+-------------+--------+
| 0.0.0.0/0 | nat-id |
+-------------+--------+

9. After adding the new route, go to Subnet associations and Edit subnet associations. Check 2 private subnets and save. This should make the subnets private. You may verify it by looking at the route table from selected subnet’s Route tables, and you should see destination 0.0.0.0/0 -> nat-id.

This should conclude the minimum setup for VPC. Now for the elastic beanstalk part, we need to create a new environment.

Environment’s Network Configuration

  1. Upon creating the environment, in Network configuration, select the new VPC.
  2. For a load-balanced environment which is in my case, we should see a Load balancer settings and Instance settings. Choose Public for Visibility and check public subnets. In my case, we use Application Load Balancer, which requires at least 2 public subnets in different Availability Zone.
  3. For Instance settings, uncheck Public IP address and check all private subnets.
  4. Apply and continue the environment creation.

This should conclude the steps needed to achieve the static IP address for elastic beanstalk load-balance application.

As I mentioned, NAT Gateway has a static elastic IP and this is the IP address that I need for restricting API keys in mail service provider.

On extra notes, I did verified that the outgoing traffic is through the IP address.

Using bastion host, I ssh-ed into one of the private instances and run:

$ curl ifconfig.me

The IP address should be same as the NAT Gateway Elastic IP Address.

The end.

--

--