I have a number of EC2 instances in 3 availability zones. The application that I'm running on these instances are communicating with multiple third party applications that have a whitelist mechanism. I know that I'm able to communicate to those third party applications by using static IP addresses (Elastic IP) by using a NAT gateway. If I do that then I need to specify a specific route for each third party application to make it work. What I would like to achieve is a static outgoing IP without defining all those routes. So basically by default routing all traffic through the NAT gateway. I tried the following but than I can not access my application anymore. (By the way all those EC2 instances are behind an application LoadBalancer)

subnet routing table:     ->  local       ->  NAT Gateway

NAT Gateway subnet routing table     ->  local       ->  Internet Gateway

It will work if I setup the following routing tables but then I have to setup specific routes for each third party application that my application is communicating with.

subnet routing table:                 ->  local                   ->  Internet Gateway
ThirdPartyApplicationIp/32  ->  NAT Gateway

NAT Gateway subnet routing table     ->  local       ->  Internet Gateway

By defining these route specifically we can have issues when, for example, DNS records get updated and ip addresses change. I know that this will occur because I know some third party applications are using AWS with ELB's as well and IP's of ELB's will changes over time. Besides that is just not very convenient when we have to manage all of these third party applications like this.

Is there a way to solve this so I don't have to define specific routes for each third party application and still are able to access my application through a Application LoadBalancer and respects DNS changes?

Additional problem:
Solving this could also solve the following problem that I'm not having yet but will have in the near future: In the future when our application is communicating with a third party application and that application is connecting the our application as well, then the traffic is routed through the NAT Gateway. Because that is the routing I set up but then it will not work once the third party applications is trying to connection through the application LoadBalancer to our applications because then the traffic should be routed through the Internet Gateway directly instead of routing it through the NAT gateway. But if I do that then I will lose my static IP. Is there way of solving this?

Results from Matt's suggestion: Matt suggestion works but I don't really understand why. So I started played around with that setup to try to find out what the difference is. Because the routing tables are the same, as I did before, and that seemed odd to me. It turns out that if I add one EC2 instance to the private subnet that has a assigned public ip (Making it a public subnet again) the whole routing fails and my ELB would not respond anymore to requests. After deleting that new EC2 instance(with that assigned public ip) it still failed. Only after deleting the Availability Zones in my ELB and adding my private subnets again it works. Now what I don't understand is why just be simply adding a new EC2 instance with a public IP breaks all the routing? (That new EC2 instance is not in de Target Group of the ELB, just sitting idle in the subnet)

  • 1
    Did you move ec2 instances to a private subnet?
    – ALex_hha
    Feb 10, 2018 at 19:23
  • No i did not. All EC2 instances are in a public subnet. The reason i have them in a public subnet is because i want to be able to access then through ssh directly as i am using Ansible to manage the AWS infrastructure
    – Kevin
    Feb 10, 2018 at 19:26
  • @Kevin Google "bastion host" for that. Makes SSH in that scenario trivially easy, and it's helpful for security as well.
    – ceejayoz
    Feb 11, 2018 at 2:45
  • Okay that is nice but i'm working on AWS, and yes i could setup something similar there but i don't see how that would solve my main problem
    – Kevin
    Feb 11, 2018 at 9:29
  • A public subnet is a subnet with an Internet Gateway attached. Adding an EC2 instance with a public IP address won't make the subnet public and won't have any negative effect itself. Likely, there was something else afoot. Feb 11, 2018 at 15:23

1 Answer 1


In order to efficiently use a NAT gateway/instance, your EC2 instances should be in private subnets. This way, you simply have a default route for all outbound traffic to go through the NAT.

Move your EC2 instances from your public subnets to private subnets. Your load balancer will still be able to access them since the ELB resides inside your VPC.

Also, by moving your EC2 instances into private subnets, you'll improve security since the outside world cannot access them directly. If you need to access them, setup a bastion EC2 instance which you can either:

  • Tunnel through using SSH to get to your internal EC2 instances, or
  • SSH two-times to get to your internal EC2 instances.

I'm not an Ansible know-it-all, but I'm sure there's a way to use Ansible and keep your EC2 instances private.

  • I'm going try your solution right now. Thx Matt for your suggestion.
    – Kevin
    Feb 11, 2018 at 9:26
  • Your suggestion works but i really don't understand why. I updated my original post with more details. Maybe you can enlighten me and explain why this makes difference. Also your point of security is helpful and a better way of securing the platform then just only using Security Groups. I did not get around to testing with Ansible yet but I found this post that would solve it (Just posting it here for other people who are looking for a solution for that): stackoverflow.com/questions/31408017/…
    – Kevin
    Feb 11, 2018 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.