Using Elastic IP to Identify Internal Instances on Amazon EC2


Elastic IP

Amazon EC2 supports Elastic IP Addresses to implement the effect of having a static IP address for public servers running on EC2. You can point the Elastic IP at any of your EC2 instances, changing the active instance at any time, without changing the IP address seen by the public outside of EC2.

This is a valuable feature for things like web and email servers, especially if you need to replace a failing server or upgrade or downgrade the hardware capabilities of the server, but read on for an insiders’ secret way to use Elastic IP addresses for non-public servers.

Internal Servers

Not all servers should be publicly accessible. For example, you may have an internal EC2 instance which hosts your database server accessed by other application instances inside EC2. You want to architect your installation so that you can replace the database server (instance failure, resizing, etc) but you want to make it easy to get all your application servers to start using the new instance.

There are a number of design approaches which people have used to accomplish this, including:

  1. Hard code the internal IP address into the applications and modify it whenever the internal server changes to a new instance (ugh and ouch).

  2. Run your own DNS server (or use an external DNS service) and change the IP address of the internal hostname to the new internal IP address (extra work and potentially extra failover time waiting for DNS propagation).

  3. Store the internal IP address in something like SimpleDB and change it when you want to point to a new EC2 instance (extra work and requires extra coding for clients to keep checking the SimpleDB mapping)

The following approach is the one I use and is the topic of the rest of this article:

  1. Assign an Elastic IP to the internal instance and use the external Elastic IP DNS name. To switch servers, simply re-assign the Elastic IP to a new EC2 instance

This last option uses a little-known feature of the Elastic IP Address system as implemented by Amazon EC2:

When an EC2 instance queries the external DNS name of an Elastic IP, the EC2 DNS server returns the internal IP address of the instance to which the Elastic IP address is currently assigned.

You may need to read that a couple times to grasp the implications as it is non-obvious that an “external” name will return an “internal” address.

Setting Up

You can create an Elastic IP address in an number of ways including the EC2 Console or the EC2 API command line tools. For example:

$ ec2-allocate-address 

The address returned at this point is the external Elastic IP address. You don’t want to use this external IP address directly for internal server access since you would be charged for network traffic.

The next step is to assign the Elastic IP address to an EC2 instance (which is going to be your internal server):

$ ec2-associate-address -i i-07612d6e
ADDRESS  i-07612d6e

Once the Elastic IP has been assigned to an instance, you can describe that instance to find the external DNS name (which will include the external Elastic IP address in it):

$ ec2-describe-instances i-07612d6e | egrep ^INSTANCE | cut -f4

This is the permanent external DNS name for that Elastic IP address no matter how many times you change the instance to which it is assigned. If you query this DNS name from outside of EC2, it will resolve to the external IP address as shown above:

$ dig +short

However, if you query this DNS name from inside an EC2 instance, it will resolve to the internal IP address for the instance to which it is currently assigned:

$ dig +short

You can now use this external DNS name in your applications on EC2 instances to communicate with the server over the internal EC2 network and you won’t be charged for the network traffic as long as you’re in the same EC2 availability zone.

Changing Servers

If you ever need to move the service to a new EC2 instance, simply reassign the Elastic IP address to the new EC2 instance:

$ ec2-associate-address -i i-3b783452
ADDRESS  i-3b783452

and the original external DNS name will immediately resolve to the internal IP address of the new instance:

$ dig +short

Existing connections will fail and new connections to the external DNS name will automatically be opened on the new instance, using either the public IP address or the private IP address depending on where the client is when requesting DNS resolution.


It is not entirely intuitive to have your application use names like but you can make it clearer by creating a permanent entry in your DNS which points to that name with a CNAME alias. For example, using bind:    CNAME

You can then use to refer to the server internally and still not have to update your DNS when you change instances.

Further Notes

Even though you are using an Elastic IP address, you don’t need (and often don’t want) to allow external users to be able to access your internal servers. For example, it is just asking for trouble to expose a MySQL server to the Internet. Keep the security groups tight so that the internal servers and services can only be accessed from your other EC2 instances.

Open TCP connections to the original server will not survive when the Elastic IP address is assigned to a new EC2 instance. Some applications and clients will automatically attempt to re-open a failed connection, getting through to the new server on the new internal IP address, but other applications may need to be kicked or signaled so they attempt a new connection to the server.

When using this approach, you need one Elastic IP address for each internal server which needs to be addressed. AWS accounts default to a limit of 5 Elastic IP addresses, but you can request an increased limit.

How do you solve the problem of connecting internal EC2 servers to each other?

Update 2009-07-20: Correct example host name.
Update 2012-03-06: Here’s the original forum post from Amazon that revealed this trick: Elastic internal IP address
Update 2012-04-02: Use different internal IP address for new instance example.


I've successfully used OpenVPN to manage a private cluster of servers behind a single public elastic IP.

You effectively build a private DNS service where each server coming online registers its internal IP with OpenVPN making it possible for all clients to use well known DNS names. (The OpenVPN package has a contrib script to acheive this)

It does however introduce the need to have a primary server to run the OpenVPN service - this is usually my NFS server.

On the server side, install DNSmasq and configure with the "addn-hosts" option pointing to the openvpn dynamically updated hosts file. This handles the auto update of the clients IP addresses.

On the clients, install resolvconf and ensure you run /sbin/dhclient on boot to rebuild the /etc/resolv.conf file

When you say "simply reassign" and "immediately", how immediate is this really? Assigning Elastic IP addresses to different instances used to take a couple of minutes, is that changed now?

If it has changed, this is great news, and we can stop relying on DNS for internal communications. But if not, waiting a couple of minutes for the Elastic IP change to occur is unacceptable in cases of failover.

I remember that delay back when Elastic IP first came out, but I know AWS was working to improve the performance and I have been happy with it since. I haven't seen any guarantees of speed, but try it yourself and see if it is acceptable for your needs.

This is a pretty neat idea, I wasn't aware of that external-internal translation!

In addition to the time it takes to update the IPs, my concern would be the limit. IP addresses are not a commodity and it's no surprise that Amazon limits you to 5, and even asks you for a use case in order to approve further IPs. When your use case is that you're not really going to use these externally, but only internally - it places Amazon in a difficult position.

Thanks, this was very helpful. It does put quite a strain on amazon as to how many IP's they will be allowing users to put into use but if they approve the use case then that's their call. I just hope that this doesn't pressure them into making it more difficult for users to get access to additional IP's

As for the time it takes to reassign an elastic IP I just reassigned an IP from one server over to another as written in the article above and it appeared to have taken at most a second or two. There was no perceived downtime. This is great to know for software updates or failover situations. I think the few minutes with possible downtime in between was how it originally worked but they have improved the reassign function greatly it appears.

You don't actually need elastic IPs for this to work; the IPs and DNS assigned at start-up do exactly the same and both work beautifully if you CNAME :)

Marius: Using the default internal IP address or DNS name with CNAME work for accessing an EC2 server instance from other client instances in the basic configuration. The point of this article, however, is to provide an approach for switching the server to a new instance (which will have a different internal IP address) without changing any configuration in the client instances or in your DNS configuration. Using elastic IPs as described above, you just assign the elastic IP to the new server instance and it flips over transparently.

Fantastic tip, thank you. Works like a charm.

There's still one more place where using the using the internal IP is not in principle totally avoidable: in the EC2 firewall rules. Imagine I want to give access to a specific machine to my instance's security group.

One option I've thought of is to create a security group per every machine and to give access not by IP but by security group.

How would you solve this?

jpabloae: I'm usually comfortable with all of my account's instances being on the same restricted VLAN, so I hadn't thought about the security group rules. The way we've set things up at our company we do give a specific security group to each machine (or machine role). It's mostly for tagging and documentation purposes, but as you point out it could also be used for protection. I'll add that to our list of things we can do to improve our architecture, thanks!

Eric: I've reached to a group based solution to avoid providing firewall access specifying the source IP and it works very well. There is only one detail one must take into account when using the ec2-authorize command:

That is, if you have one security group per instance or group of instances, you can avoid specifying IPs this way. However when doing this, if you want to specify a specific port with "-p" you must also specify the protocol (tcp or udp) or the command will fail. This silly little detail has stopped me from using this for months.

Eric....To echo what others have said, your articles are awesome! I am finding them very useful.

This tip on using the external dns name associated with the elastic ip is great! I was concerned that we would be charged for public network access....But your approach makes perfect sense!

Thanks for your great work!

Eric...One question. I have deployed the solution of using the public dns associated with the instance that is atached to the elastic ip as you outlined.

Any ideas on how durable this strategy is? That is, what would prevent amazon from suddenly changing their algorithm so that when an internal query is made for this public dns, it responds with the (public) elastic ip address? Then, we'd suddenly be on the hook for the additional public network bandwidth....

Not a big concern now, but just wanted to understand this better...


William: Though it's not in the documentation, Amazon employees have publicly stated that it works this way. If it matters to you, set up a monitor that will alert you if things change.

Hi Eric, thanks for another great article.

I'm just wondering, have you applied for an increase to your elastic IP limit?

I'm working on a fairly modest 3-tier setup which probably won't grow much beyond 10 small instances, at least initially, and would like to use the elastic IP switching technique to handle any node failing. However, the page for requesting a limit increase says, "We strongly encourage customers to use Elastic IPs primarily for load balancing use cases, and private IP addresses for all other internode communication." I'm not going to be doing much (if any) load balancing, and so I get the impression that a request saying "I've got 10 small instances and want more elastic IPs because it makes my life much easier if any of them fails" would be denied.

So is it realistic to rely on elastic IPs for anything more than a few instances, or should we be looking for other (ideally equally quick and simple) ways to manage failures etc. so that if we need to scale up, we won't get bitten by a refused limit increase request from AWS?

Thanks in advance.

Hi Eric, just a thought, if what you want is to be able to switch all references to a given instance quickly and easily in the case that the instance has failed and needs to be replaced, how about using /etc/hosts in all of the referencing instances to manage the mapping between a domain name and an internal IP address? In that case, if an instance fails and you replace it with a new one, you just have to update /etc/hosts in all the referencing instances to point to the new internal IP address. This is obviously more overhead than using an elastic IP address, but if you don't have too many instances all referencing the same instance, then the maintenance overhead is comparable, and means you can use elastic IPs sparingly on the instances you need to reference from outside EC2. What do you reckon?

If you need more elastic IPs, ask for them, ideally a while before the need becomes an emergency. If Amazon cares to save public IP addresses, they could implement elastic internal IPs for those of us who need this ability.

AItOawnwTuAM1PCinRzDL463629nC-JnyIwTISo: If you can keep all your /etc/hosts files accurate across all your instances then, sure, you don't need elastic IP addresses to tell the instances the current IP address of the host. However, I think you may have just proposed solving the square root of 2 by suggesting we simply use an "X" which when multiplied by itself equals 2 :-) If you know where all your instances are and can communicate the IP address to all new instances, then you've solved the problem, but you need to do that first. There are ways to do this other than using elastic IP addresses, but this is a simple and reliable method.

Does anyone know if AWS has or is considering the concept of an internal Elastic IP? This would work like a public ElasticIP but for an internal (10.x.x.x) address. Once assigned, you could associate it with any instance.

It would seem that this would solve most of the problems of connecting multiple EC2 servers without having to futz around with DNS names or chewing up the increasingly scarce public IPv4 addresses.

Example: The common case of a back-end (internal) database server and N front-end (public) Web server instances. If an InternalElasticIP was acquired by the manager of the account, he would assign it to the internal database server, and then configure all the Web instances to use this IP to connect to the DB. In the event of failure of the DB server, or migration to a larger configuration, it would only be necessary to re-assign the Internal Elastic IP to the new DB instance -- all the front end Web servers would not have to be reconfigured.


John: I've seen requests for this, but have not seen any commitment from Amazon. I think a suitable DNS service by Amazon would solve this and other problems related to Elastic Load Balancer.

Should this work also with mysql grant users?

If I have web1 and db1, I can ping db1 via it's elastic IP external ec2 name. It's definitely resolving to an internal IP there. Also since the two servers are in the same security group, I can use the mysql client on web1 to attempt connection to db1:

On db1 I do this grant:
mysql> grant all on *.* to 'root'@'' identified by 'mypwd';

Then on web1:
$ mysql -u root --host=ec2-public-name
ERROR 1130 (HY000): Host 'ip-xxx.internal' is not allowed to connect to this MySQL server

If I do this on db1:
mysql> grant all on *.* to 'root'@'ip-xxx.internal' identified by 'mypwd';

Then on web1, I do the same mysql client connect, it works.

The only thing I can think, web1 is currently not an elastic IP. Don't know if that matters, but I'll try it.


Sean: Yes, it sounds like you need to use the internal DNS name for permissions, since that works. Elastic IP addresses will not help this situation. Or, just allow connections from any IP address in MySQL and trust your firewall (EC2 security groups) to protect you from connections outside of the instances you want to allow.

How do you handle the DNS to IP cache on your client machines (which are also in ec2)?

DB server current, external DNS:
DB server current, internal IP:
DB server NEW (the one ur gonna switch to), internal IP:

So all your database client servers connect to, and so they cache the DNS lookup to ip When you move the elastic ip to the new DB server - all those clients will still try to connect to, instead of correct? Because the OS has cached the DNS lookup?

How do you get around this?


I don't see any noticeable delay in getting the new internal IP address with the tools I use. You may need to track down what is caching the DNS and clear it.

Great article, thanks!

I've got bind set up on a box in EC2, forwarding everything except in my custom top-level domain (".tld") to the AWS internal DNS server. It seemed to be working for a while, but once in a while the public name ("") incorrectly resolves to the public IP address. Any idea why this might happen?

I notice I'm using short names without periods on the left hand sides of my CNAME entries... does this matter? For example:

blah CNAME

Instead of

blah.tld. CNAME

It's also worth noting that the CNAME trick does not work with dnsmasq.

Hi Eric,

Elastic IP have some limitation when it used for inter instance communication.

First, after instance stopped or rebooted you have to reattach Elastic IP to youre instance.

Second, you can get only five Elastic IP by default.

For me best solutions are Amazon VPN (but only if you like to manually configure all network configaration) or some utility like [...]


The Elastic IP limit can easily be increased by asking Amazon through the form linked to above.

Needing to reassociate an Elastic IP with an instance after a stop/start is an annoyance, but not a serious limitation. If you are stopping the instance with the Elastic IP, the other servers using it will not be able to contact it, and it isn't entirely clear that it is the one they should be contacting when it comes back up.

Amazon VPC works for some situations, especially with the new Elastic Network Interface. However, (1) it isn't trivial to set up VPC, and (2) some AWS features have historically not been released for VPC as soon as they are for normal EC2 use (e.g., RDS, ELB).

Followup on my earlier post: I fixed the problem by setting "forward only" in my bind config. Yay, serverfault!



Thanks for following up with the solution to your problem!

It looks like Amazon charges $0.01 per GB for using an elastic IP inside of the EC2 network.


Public and Elastic IP and Elastic Load Balancing Data Transfer

$0.01 per GB in/out – If you choose to communicate using your Public or Elastic IP address or Elastic Load Balancer inside of the Amazon EC2 network, you’ll pay Regional Data Transfer rates even if the instances are in the same Availability Zone. For data transfer within the same Availability Zone, you can easily avoid this charge (and get better network performance) by using your private IP whenever possible


It is true that you get charged a small fee per GB if you use the Elastic IP address for communication between EC2 instances. HOWEVER, the method described above does not use the Elastic IP address. It uses the public DNS name of the Elastic IP address to resolve to the private (internal) IP address of the instance. This way, all communication from within that availability zone is free.

Hi Eric,

Would this work in Route 53 console for ec2 instance?:

Thanks for your help.


Yes, you can use wildcard (*) hostnames in Route53 DNS CNAME entries.

Hi Eric,
"...if you ever need to move the service ... simply reassign... and the original external DNS name will immediately resolve to the internal IP address of the new instance:

$ dig +short
It still points to in your example.

Shouldn't in point to some other internal IP ? for the case?


Good catch. I've updated the second example to a different internal IP address.

Seems to work really nicely unless you stop and start and instance, then elastic IP losses its mind and previously associated IP to image mapping. While a reboot is fine. Odd.


I not sure there is a way to escape from regional data charges using the public dns (ie - of an elastic ip.

I downloaded a report from AWS that shows the regional data used by EC2 instances. It's a few GB over the past month.

I only have two EC2 instances in my AWS account. Both are in the same availability zone (including the EBS volumes). One is a DB server and the other is an app server. I've only been using the public dns of the elastic ip to communicate between the two instances.

Am I missing something? Pinging the public dns from an instance does return the private ip.


If your instances are in the same availability zone and you follow the instructions in this article, then all traffic between the two instances using this method will be free. If the instances are in the same region but different availability zones, there will be a minimal inter-zone network charge. If the instances are in different regions, then it will automatically use the public IP address and you will be charged full network charges on both sides of the connection.

Jeff, Alexey:

I agree that you wouldn't want to have to manually associate an elastic IP when stopping and then starting an instance. We handle this by adding a @reboot entry to our root crontab to automatically associate our elastic IP to our instance.

The @reboot crontab calls a script that

1. pulls the instance ID from EC2 metadata:

e.g. wget -q -O -

2. calls ec2-associate-address to complete the association for us.

ec2-associate-address -i $instance_id $ip


Thanks for adding this tip!

You'll need to be careful if you ever create an AMI from that instance and run other instances of the AMI as they will steal the Elastic IP from the original. And maybe that is desired behavior in some cases.

Leave a comment

Ubuntu AMIs

Ubuntu AMIs for EC2:

More Entries

When Are Your SSL Certificates Expiring on AWS?
If you uploaded SSL certificates to Amazon Web Services for ELB (Elastic Load Balancing) or CloudFront (CDN), then you will want to keep an eye on the expiration dates and…
Throw Away The Password To Your AWS Account
reduce the risk of losing control of your AWS account by not knowing the root account password As Amazon states, one of the best practices for using AWS is Don’t…
AWS Community Heroes Program
Amazon Web Services recently announced an AWS Community Heroes Program where they are starting to recognize publicly some of the many individuals around the world who contribute in so many…
EBS-SSD Boot AMIs For Ubuntu On Amazon EC2
With Amazon’s announcement that SSD is now available for EBS volumes, they have also declared this the recommended EBS volume type. The good folks at Canonical are now building Ubuntu…
EC2 create-image Does Not Fully "Stop" The Instance
The EC2 create-image API/command/console action is a convenient trigger to create an AMI from a running (or stopped) EBS boot instance. It takes a snapshot of the instance’s EBS volume(s)…
Finding the Region for an AWS Resource ID
use concurrent AWS command line requests to search the world for your instance, image, volume, snapshot, … Background Amazon EC2 and many other AWS services are divided up into various…
Changing The Default "ubuntu" Username On New EC2 Instances
configure your own ssh username in user-data The official Ubuntu AMIs create a default user with the username ubuntu which is used for the initial ssh access, i.e.: ssh ubuntu@<HOST>…
Default ssh Usernames For Connecting To EC2 Instances
Each AMI publisher on EC2 decides what user (or users) should have ssh access enabled by default and what ssh credentials should allow you to gain access as that user.…
New c3.* Instance Types on Amazon EC2 - Nice!
Worth switching. Amazon shared that the new c3.* instance types have been in high demand on EC2 since they were released. I finally had a minute to take a look…
Query EC2 Account Limits with AWS API
Here’s a useful tip mentioned in one of the sessions at AWS re:Invent this year. There is a little known API call that lets you query some of the EC2…
Using aws-cli --query Option To Simplify Output
My favorite session at AWS re:Invent was James Saryerwinnie’s clear, concise, and informative tour of the aws-cli (command line interface), which according to GitHub logs he is enhancing like crazy.…
Reset S3 Object Timestamp for Bucket Lifecycle Expiration
use aws-cli to extend expiration and restart the delete or archive countdown on objects in an S3 bucket Background S3 buckets allow you to specify lifecycle rules that tell AWS…
Installing aws-cli, the New AWS Command Line Tool
consistent control over more AWS services with aws-cli, a single, powerful command line tool from Amazon Readers of this tech blog know that I am a fan of the power…
Using An AWS CloudFormation Stack To Allow "-" Instead Of "+" In Gmail Email Addresses
Launch a CloudFormation template to set up a stack of AWS resources to fill a simple need: Supporting Gmail addresses with “-” instead of “+” separating the user name from…
New Options In ec2-expire-snapshots v0.11
The ec2-expire-snapshots program can be used to expire EBS snapshots in Amazon EC2 on a regular schedule that you define. It can be used as a companion to ec2-consistent-snapshot or…
Replacing a CloudFront Distribution to "Invalidate" All Objects
I was chatting with Kevin Boyd (aka Beryllium) on the ##aws Freenode IRC channel about the challenge of invalidating a large number of CloudFront objects (35,000) due to a problem…
Email Alerts for AWS Billing Alarms
using CloudWatch and SNS to send yourself email messages when AWS costs accrue past limits you define The Amazon documentation describes how to use the AWS console to monitor your…
Cost of Transitioning S3 Objects to Glacier
how I was surprised by a large AWS charge and how to calculate the break-even point Glacier Archival of S3 Objects Amazon recently introduced a fantastic new feature where S3…
Running Ubuntu on Amazon EC2 in Sydney, Australia
Amazon has announced a new AWS region in Sydney, Australia with the name ap-southeast-2. The official Ubuntu AMI lookup pages (1, 2) don’t seem to be showing the new location…
Save Money by Giving Away Unused Heavy Utilization Reserved Instances
You may be able to save on future EC2 expenses by selling an unused Reserved Instance for less than its true value or even $0.01, provided it is in the…
Installing AWS Command Line Tools from Amazon Downloads
This article describes how to install the old generation of AWS command line tools. For the most part, these have been replaced with the new AWS cli that is…
Convert Running EC2 Instance to EBS-Optimized Instance with Provisioned IOPS EBS Volumes
Amazon just announced two related features for getting super-fast, consistent performance with EBS volumes: (1) Provisioned IOPS EBS volumes, and (2) EBS-Optimized Instances. Starting new instances and EBS volumes with…
Which EC2 Availability Zone is Affected by an Outage?
Did you know that Amazon includes status messages about the health of availability zones in the output of the ec2-describe-availability-zones command, the associated API call, and the AWS console? Right…
Installing AWS Command Line Tools Using Ubuntu Packages
See also: Installing AWS Command Line Tools from Amazon Downloads Here are the steps for installing the AWS command line tools that are currently available as Ubuntu packages. These include:…
Ubuntu Developer Summit, May 2012 (Oakland)
I will be attending the Ubuntu Developer Summit (UDS) next week in Oakland, CA.  This event brings people from around the world together in one place every six months to…
Uploading Known ssh Host Key in EC2 user-data Script
The ssh protocol uses two different keys to keep you secure: The user ssh key is the one we normally think of. This authenticates us to the remote host, proving…
Seeding Torrents with Amazon S3 and s3cmd on Ubuntu
Amazon Web Services is such a huge, complex service with so many products and features that sometimes very simple but powerful features fall through the cracks when you’re reading the…
There are a number of CloudCamp events coming up in cities around the world. These are free events, organized around the various concepts, technologies, and services that fall under the…
Use the Same Architecture (64-bit) on All EC2 Instance Types
A few hours ago, Amazon AWS announced that all EC2 instance types can now run 64-bit AMIs. Though t1.micro, m1.small, and c1.medium will continue to also support 32-bit AMIs, it…
ec2-consistent-snapshot on GitHub and v0.43 Released
The source for ec2-conssitent-snapshot has historically been available here: ec2-consistent-snapshot on using Bazaar For your convenience, it is now also available here: ec2-consistent-snapshot on GitHub using Git You are…