How to Deploy an AWS Elastic Beanstalk App in a Private Subnet?

Praveen NG
9 min readJul 2, 2024

--

Elastic Beanstalk is an AWS service with which you can easily deploy and manage web applications. With Elastic Beanstalk (EB) , AWS takes care of updates, monitoring, scaling and much more.

Any web app typically requires access from anywhere on the internet, but we may want to keep the web app server in a private subnet for security reasons. In this post, I explain how to deploy an EB app in a private subnet.

Please note that this project may not be free-tier eligible for everyone. However, if you complete this project and immediately delete the resources as described below, it shouldn’t cost more than a few cents.

  1. Create a new VPC

Login to AWS console and look for VPC (or search VPC). On the VPC console, click “Your VPCs” on the left panel. Click “Create VPC” button.

Create VPC

Enter a name for the new VPC. In the “IPv4 CIDR” field, type a valid private CIDR block range. Typically, 10.0.0.0/16 should be good (unless you have to peer with another VPC with the same CIDR block range). Keep the default values for the rest. Click “Create VPC”.

2. Create Subnets

We will create 4 subnets — 2 private and 2 public. The private subnets will be used to place the EB instance (and database and other resources, if applicable). The private and public subnets should be in the same availability zones. For example, if the two private subnets are in us-west-2a and us-west-2b zones, the two public subnets should also be in those zones (they cannot be, us-west-2c, for instance).

Click “Subnets” on the left panel. Then, click “Create subnet”. In the VPC dropdown, choose the newly created VPC.

Under “Subnet settings”, type a subnet name, e.g., “Public-subnet-1”. For “Availability zone” choose a zone. Under “IPv4 subnet CIDR block”, choose a subset of the vpc CIDR block. For example, 10.0.0.0/24.

Notice that VPC has “/16”, which as a capacity 65,536 distinct IP addresses. The subnet has a “/24”, which means there are only a capacity of 256 IP addresses. If these do not make sense to you, you can ignore it for now — it is not that important for this exercise.

Now let’s click “Add new subnet” button to add one more subnet. This time, choose the “Public-subnet-2” for the name field and 10.0.1.0/24 for the subnet CIDR block. Notice that, the first subnet had 10.0.0.0/24 and the second one has 10.0.1.0/24. This makes sure that the subnet IP addresses do not overlap. Again, if you don’t understand, you don’t have to worry about it now — just make sure you choose different values as described above. Also, choose a different availability zone (us-east-2b, for instance)

Now let’s repeat the process two more times to add “Private-subnet-1” and “Private-subnet-2” with subnet CIDR blocks “10.0.2.0/24” and 10.0.3.0/24". Make sure, the availability zones for “Public-subnet-1” and “Private-subnet-1” are the same. Similarly, those of “Public-subnet-2" and “Private-subnet-2” are the same.

Click “Create subnet” button to create 4 subnets.

3. Create an Internet Gateway

Next, we need to create an internet gateway to allow connections to the internet. To do that, click on “Internet gateways” on the left panel, and then click on “Create internet gateway” button. On the next page, give the internet gateway a name and click “Create internet gateway”.

Now, click on the newly created internet gateway, click on “Actions” dropdown, and then “Attach to VPC”. On the next page, select the newly created VPC and click on “Attach internet gateway”.

4. Create NAT gateway

Click on “NAT gateways” on the left panel, click on “Create NAT gateway” button. On the next page, enter a name for the NAT gateway and select one of the public subnets.

Select “Public” for the connectivity type (this allows instances in this subnet to access the internet, but parties from public internet cannot make a connection to these instances). Click on “Allocate Elastic IP”. Click “Create NAT gateway” button. Please note down the Elastic IP address. We will need to release it after completing this project. Otherwise, it will incur costs.

5. Create Route Tables

Route tables (RTs) has a set of rules. These rules determine how network traffic is redirected. For example, if an instance or service within the VPC needs to connect to an IP address, RT rules “tells” or “redirects” the traffic to the appropriate destination. We need to create a private RT and a public RT.

On the left panel, click “Route tables” and then on “Create route table” button. Type “Public-RT” in the “Name” field. Choose the newly created VPC in the VPC dropdown menu. Click “Create route table” button. Similarly, create a “Private-RT” route table.

Now, go back to the main “Route tables” page and click one of the “Public-RT” ID. Click the “Actions” dropdown and click “edit subnet associations”.

The next page will display all availability zones within the VPC. Select the two public availability zones. Click “Save associations” button.

We also need to add routes. Click on “Edit routes” button, and then “Add route” button. For “Destination”, add “0.0.0.0/0” and for “Target” select “Internet Gateway”, and then the name of the recently created internet gateway (see below).

Now, in a similar fashion, go back to “Route tables” page, click the “Private-RT” route table and add subnet associations. Make sure you choose the two private subnets.

Click on “Edit routes” and “Add route”. Type “0.0.0.0/0” for “Target” and “NAT gateway” for Target. Then choose the recently created NAT gateway name.

With that, we complete the VPC creation and related tasks. Next task is to create the actual EB app.

6. Creating an Elastic Beanstalk App

In the AWS console search Beanstalk and navigate to the main Beanstalk console. On the left panel (if you don’t see the panel, click on the hamburger menu on the top left corner), click “Applications”.

Click “Create application” button. On the next page, type a name for the app and click “Create” button.

Click “Environments” on the left panel and then click “Create environment”. On the next page, type a name for the application.

Under the “Platform” section, choose “Python” for platform.

For Application code, choose “Sample application”. Here, we will use sample code provided by AWS to create an app. If you have your own code for a web app, you can choose “Upload your code” and then either upload local files or read files uploaded to S3. For simplicity, I am using the Sample application.

For Presets, choose “Custom configuration”. This is because we will host the application in our custom-built VPC. Click “Next”.

On the next page, if you have an existing service role for Beanstalk applications, use it. Else, create a new service role (select it from the dropdown menu).

Choose an EC2 key pair, if you would want to connect to Elastic Beanstalk instances in the future. Else, leave it blank. Add an EC2 instance profile to add permissions to the EC2 instance. Click “Next”.

On the next page, choose the VPC we created earlier. Under “Instance settings”, choose the two private subnets we created. This is because, we want to keep the EC2 instance within a private subnet. If you want to add a database instance, you can add its configuration under “Database”. For the sample app, we don’t need a database, so we don’t have to make any changes. Click “Next”.

On the next page, we can configure root volume configuration. However, for the sample app, this is not necessary, so let’s not change anything.

Under “Capacity”, choose “Load balanced”. For instances, we can keep “1” for both “Min” and “Max”.

Under “Load balancer network settings”, choose the visibility “Public” and for subnets, choose the two public subnets. Click “Next”.

On the next page, for monitoring, choose “Basic”.

Under “Managed platform updates”, untick the “Activated” checkbox.

Click “Next”.

On the next page, review everything and click “Submit”

It will take a few minutes for Beanstalk to provision resources. You can see the updates under “Events” section at the bottom.

If everything was done correctly, after a few minutes, the health status in the “Environment overview” section (at the top of the page), should indicate “Green”. You will also see a domain name below the health status.

Click on the domain name, and it should open a sample app like below.

Congrats on successful launching of your Beanstalk app.

If you got the EC2 instance console page (search EC2 in the search field), you will see that a newly provisioned EC2 instance. Since Beanstalk manages resources, it manages EC2 instance running the web app. If you click the instance ID, you will be able to see instance details.

You can see that the instance has only a private IP address and does not have a public IP. This is because it is under the private subnet and no public IP is assigned to it. However, you are able to access the web app from the browser. This is because, Beanstalk provisioned a load balancer which directs the traffic to the EC2 instance running the web application.

If you go to the Load balancer console (EC2 console > Load Balancers), you will see an active load balancer.

7. Deleting Resources.

Even though VPC and Elastic Beanstalk do not cost money, the resources Beanstalk created has cost associated with them (EC2 instance, load balancers and Elastic IP addresses). So, we need to clean up resources if you don’t want to incur costs.

First, go to Elastic Beanstalk console. Click “Applications” on the left panel. Select the application we created. From “actions” dropdown select “Delete application”. In the popup window, confirm deletion by clicking the name of the app and then clicking “Delete” button. It may take several minutes for Beanstalk to delete resources.

After you make sure the app has been deleted, we can delete the VPC and the related resources we created. Go to VPC console and click “NAT gateways” on the left panel. Select the NAT gateway we created. From “Actions” dropdown, select “Delete NAT gateway”. In the popup window confirm deletion by typing “delete” and clicking “Delete” button. Wait for a few minutes to ensure that the NAT gateway is deleted.

Now we can delete the VPC. Go to VPC console, click “Your VPCs” on the left panel. Select the VPC we created. From the “actions” dropdown, select “Delete VPC”. Confirm deletion on the popup window.

Now the last thing to do is to release the elastic IP address. For that, click on “Elastic IPs” on the left panel of VPC console. Select the Elastic IP we created for this project. From “Actions” dropdown, click “Release Elastic IP Addresses”. On the popup window confirm it by clicking “Release”.

--

--

Praveen NG
Praveen NG

Written by Praveen NG

A data science professional with a research background.

No responses yet