Elastic IP on application deployed using Elastic Beanstalk

26,125

Solution 1

Elastic Load Balancing (ELB) does not work with Amazon EC2 Elastic IP addresses, in fact the two concepts do not go together at all.

Elasticity via Elastic Load Balancing

Rather, ELB is usually used via CNAME records (but see below), and this provides the first level of elasticity/availability by allowing the aliased DNS address to change the IP of the ELB(s) in use, if need be. The second level of elasticity/availability is performed by the load balancer when distributing the traffic between the EC2 instances you have registered.

Think of it this way: The CNAME never changes (just like the Elastic IP address) and the replacement of EC2 instances is handled via the load balancer, Auto Scaling, or yourself (by registering/unregistering instances).

This is explained in more detail within Shlomo Swidler's excellent analysis The “Elastic” in “Elastic Load Balancing”: ELB Elasticity and How to Test it, which in turn refers to the recently provided Best Practices in Evaluating Elastic Load Balancing by AWS, which confirm his analysis and provide a good overall read regarding the Architecture of the Elastic Load Balancing Service and How It Works in itself (but lacks the illustrative step by step samples Shlomo provides).

Domain Names

Please note that the former limitation requiring a CNAME has meanwhile been addressed by respective additions to Amazon Route 53 to allow the root domain (or Zone Apex) being used as well, see section Aliases and the Zone Apex within Moving Ahead With Amazon Route 53 for a quick overview and Using Domain Names with Elastic Load Balancing for details.

Elasticity via Elastic Beanstalk

First and foremost, AWS Elastic Beanstalk uses Elastic Load Balancing in turn as described above. On top if that, it adds application lifecycle management:

AWS Elastic Beanstalk is an even easier way for you to quickly deploy and manage applications in the AWS cloud. You simply upload your application, and Elastic Beanstalk automatically handles the deployment details of capacity provisioning, load balancing, auto-scaling, and application health monitoring. [...] [emphasis mine]

This is achieved by adding the concept of an Environment into the mix, which is explained in the Architectural Overview:

The environment is the heart of the application. [...] When you create an environment, AWS Elastic Beanstalk provisions the resources required to run your application. AWS resources created for an environment include one elastic load balancer (ELB in the diagram), an Auto Scaling group, and one or more Amazon EC2 instances.

Please note that Every environment has a CNAME (URL) that points to a load balancer, i.e. just like using an ELB on its own.

All this comes together in Managing and Configuring Applications and Environments, which discusses some of the most important features of AWS Elastic Beanstalk in detail, including usage examples using the AWS Management Console, CLI, and the APIs.

Zero Downtime

Its hard to identify the most relevant part for illustration purposes, but Deploying Versions With Zero Downtime precisely addresses your use case and implies all required preceding steps (e.g. Creating New Application Versions and Launching New Environments), so reading section AWS Management Console might give you the best overall picture how this platform works.

Good luck!

Solution 2

In addition to the options described in Steffen's awesome answer, Elastic Beanstalk seems to have very recently enabled Elastic IP as an option if you don't need the full features of an Elastic Load Balancer (like auto-scaling beyond one instance).

I describe the option in my answer to a similar question. Elastic Beanstalk now allows you to choose between two Environment Types, and the Single-instance option creates an Elastic IP.

Dropdown with options "Single instance" and "Load balancing, autoscaling".


I think using an ELB will be the preferable option in most cases, but e.g. for a staging server it is nice to have an alternative that is less complex (and cheaper).

Solution 3

Apologies for answering a post a few years later, however for those that do actually need a set of static IP addresses on an ELB, it is possible to ask AWS nicely to add what they call 'Stable IP' addresses to an ELB, and thereby give it that static IP address feature.

They don't like doing this at all of course - but will if you can justify it (the main justification is when you have clients that have IP whitelist restrictions on outbound connections via their firewalls and are completely unwilling to budge on that stance).

Just be aware that the 'auto scaling' based on traffic option isn't straight forward any more - AWS would be unable to dynamically add more ELB endpoints to your ELB as they do with the out of the box solution and you have to go through the pain of opening up new IP addresses with your customers over time.

For the original question though, EB using an ELB to front EC2 instances where static IP addresses are not actually required (no client outbound firewall issues) is the best way as per the accepted answer.

Solution 4

In the case that none of the above solutions works, one alternative is to attach a NAT gateway to a private subnet and associate an EIP with the NAT gateway. In this case you’re able to use the ELB, use auto-scaling, and have a reserved EIP.

This is a bit more expensive though, especially for large throughput use cases. Also, SSHing into the instance to debug becomes a bit more complex.

Solution 5

You can set the environment as a Single Instance as stated in the already accepted answer, or if you want to use an Elastic IP that you have already created, you can do the following.

Inside of the .ebextensions folder at the root of your project, make a file called setup.config and paste in the following:

container_commands:
    00_setup_elastic_ip:
        command: |
            export AWS_ACCESS_KEY_ID={YOUR-ACCESS-KEY-ID}
            export AWS_SECRET_ACCESS_KEY={YOUR-SECRET-ACCESS-KEY}
            export AWS_DEFAULT_REGION=us-east-1    
            INSTANCE_ID=$(ec2-metadata -i)
            words=( $INSTANCE_ID )
            EC2_ID="${words[1]}"
            aws ec2 associate-address --instance-id $EC2_ID --allocation-id {eipalloc-ID-TO-THE-IP}

All you have to do is replace the 3 parts contained inside of the {} and you are good to go. This will replace the IP of your Elastic Beanstalk instance with the Elastic IP of your choosing.

The parts contained in {} are (get rid of the {} though, that is just there to show you which parts to replace with your info):

  1. Your AWS Access Key ID
  2. Your AWS Secret Access Key
  3. the allocation ID of the Elastic IP you want to assign to your Elastic Beanstalk environment's instance.
Share:
26,125

Related videos on Youtube

satoshi
Author by

satoshi

Updated on July 09, 2022

Comments

  • satoshi
    satoshi almost 2 years

    I'm a bit confused about the use of the Elastic IP service offered by Amazazon Web Services. I guess the main idea is that I can switch to a new version of the web application with no downtime following this simple procedure:

    1. Deploy the new version on a new EC2 instance
    2. Configure the new version properly and test it using a staging DB
    3. Once properly tested, make this new version use the live DB
    4. Associate the Elastic IP to this instance
    5. Terminate all the useless services (staging DB and old EC2 instance)

    Is this the common way to deploy a new version of a web application?

    Now, what if the application is scaled on more instances? I configured the auto scaling in the Elastic Beanstalk settings and this created a load balancer (I can it see in the EC2 section of the AWS Management Console). The problem is that I apparently cannot associate the Elastic IP with the load balancer, I have to associate it with an existing instance. To which instance should I associate it to? I'm confused...

    Sorry if some questions may sound stupid but I'm only a programmer and this is the first time I set up a cloud system.

    Thank you!

  • Tony Gutierrez
    Tony Gutierrez over 8 years
    Be warned that the EIP gets released and a new one assigned if you rebuild the Elastic Beanstalk environment...which is kind of dumb.
  • user1533481
    user1533481 over 7 years
    Did you have the same problem and got AWS added "stable IP" for you? (I just to make sure AWS has that kind of service if requested)
  • keba
    keba over 7 years
    Yes - we have ELBs with static (stable) IP addresses assigned.
  • ALex_hha
    ALex_hha over 6 years
    Starting with september 2017 you can use network load balancer (which support EIP) within Beanstalk - aws.amazon.com/elasticloadbalancing/details
  • Defozo
    Defozo about 6 years
    However, fortunately, it is the same EIP when we eg. change type of the instance.
  • devdanke
    devdanke about 6 years
    I found it much easier to setup HTTPS for a beanstalk app with the "Load Balancing, autoscaling" option.
  • TheSharpieOne
    TheSharpieOne over 5 years
    And even more crazy: if you want all of the features of the application load balancer with a EIP/static IP via the network load balancer, you can just run both plus a lambda to tie them together: aws.amazon.com/blogs/networking-and-content-delivery/…
  • Kamil Kwiaton
    Kamil Kwiaton about 2 years
    That is so amazing! WOW! Big thanks, I had to associate static IP with beanstalk due to outbound traffic and it works like magic!
  • Rami
    Rami about 2 years
    It did not work, any other ideas? I have a single instance environment other than going through the NAT
  • mastercooler6
    mastercooler6 about 2 years
    Id have to see your setup.config file. You have one right? You also could make the instance a single environment (not using load balancers) and then instance should get its own elastic IP
  • Rami
    Rami about 2 years
    it is a single instance and I want to attach a specific EIP to it. this is my setup.config the same as yours container_commands: 00_setup_elastic_ip: command: | export AWS_ACCESS_KEY_ID=1235 export AWS_SECRET_ACCESS_KEY=1234 export AWS_DEFAULT_REGION=us-east-1 INSTANCE_ID=$(ec2-metadata -i) words=( $INSTANCE_ID ) EC2_ID="${words[1]}" aws ec2 associate-address --instance-id $EC2_ID --allocation-id eipalloc-1234