5

I have a simple 2-tier arrangement - one web server (Websphere hosted on windows), and one oracle db server. The web server needs to connect the oracle database server.

I am trying to write a script that

  1. Brings up a EC2 instance with the Oracle database
  2. Brings up a EC2 instance with Websphere
  3. Configures the Websphere instance to communicate to the database

I am stuck at #3. Every time I run the script, the DB server gets a different ip address. How do I tell my Websphere instance "Use this ip address for the DB"?

Some solutions I have considered -

  1. Configure Websphere to connect to a host name. When the DB server comes up and is assigned an IP Address, update the DNS record (probably Route 53)
  2. Pass the DB server ip address as user data when launching the websphere instance, and run a startup script to update the configuration
  3. Use Elastic IP Addresses - but that would require routing db traffic over the internet, right?

Each of these solutions seem more work than usual. Is there something I am missing? What is the standard way to solve this problem?

EDIT for Bounty Elastic IP Address solution works, but I don't like using wasting public ip addresses on servers that should never connect to the internet. I am curious to hear any other solution you have employed to solve this problem.

9 Answers 9

8
+100

You can use an Elastic IP, but connect via its domain name, and it will resolve to the internal address. So obviously you derive the DNS name from the elastic IP, e.g. ec2-46-147-161-187.eu-west-1.compute.amazonaws.com corresponds to 46.147.161.187 in eu-west-1. The domain will be fixed so you can hardcode it if you wish.

See https://forums.aws.amazon.com/message.jspa?messageID=299889.

5
  • 1
    That's a good solution. But there is a restriction on the number of public elastic ip addresses, and I think we will soon run out of them. Is there an equivalent of "Private Elastic IP Addresses"? Feb 9, 2012 at 11:15
  • There's no private elastic IP equivalent. You could use tags to filter, rather than user data. So you call your DB server 'DB1', and then on the webserver, you can run a filtered describe-instances api call, e.g. --filter tag:name=DB1 and the private IP address will be among the data returned. More here: docs.amazonwebservices.com/AWSEC2/latest/CommandLineReference/… Feb 9, 2012 at 11:32
  • 1
    You can easily ask for more Elastic IP addresses: aws.amazon.com/contact-us/eip_limit_request Feb 9, 2012 at 18:59
  • 1
    For your reference, I talk in length about using Elastic IP addresses with internal EC2 instance communication in this article: alestic.com/2009/06/ec2-elastic-ip-internal Feb 9, 2012 at 19:03
  • @JamesLittle and Eric Hammond - thanks for your notes. This solution works, but I don't like wasting public IP addresses for servers that shouldn't need them. I will wait a couple of days, start a bounty and see if there are any other solutions. If nothing comes up, I'll accept this answer. Thanks! Feb 10, 2012 at 18:28
4

You have to assume that you can't use a broadcast-response mechanism like DHCP for this job, which means that the only option left is to update and query some directory somewhere.

Dynamic DNS (e.g. DNS UPDATE; RFC 2136) is an obvious solution. If you already have a nameserver, this solution takes about 5 minutes to set up. See http://linux.yyz.us/nsupdate/ for a quick-start tutorial on setting up bind for dynamic updates and using the nsupdate command. See this blog entry for information on using DDNS with Route 53.

Alternately, you can roll your own solution using something like a simple private PHP script on a webserver somewhere to handle IP registration updates and query-response mechanics. Obviously this solution is a bit more flexible, but it lacks the simple elegance of DDNS.

4

I'd suggest that one solution is to use Amazon's Virtual Private Cloud (VPC) - this sounds like a good use case for it. (Additionally, VPC has no additional cost, in this scenario).

Essentially, you could create a new VPC and a public subnet (typically 10.0.0.0/24) within that VPC. Then launch both instances into the subnet.

  • Launch the websphere instance into the subnet and then associate an elastic IP with it
    • Note: you need special VPC Elastic IPs - the regular ones don't work in VPC - when allocating them, specify the domain as 'vpc'.
  • Launch the Oracle instance, and pass the PrivateIpAddress parameter with a valid IP address from your subnet.
    • This will assign the requested private IP to your instance, it will be available to other instances in the VPC (but no internet access without an elastic IP in VPC) and you will not waste public IP addresses. It is worth noting that VPC addresses are retained for the life of the instance - even if the instance is stopped, the address is not dissociated. Also, you cannot route traffic between instances in a VPC using an elastic IP.

Of course, in this setup or any setup not using NAT each instance that has any sort of internet access will be assigned a public IP (even if it is not an elastic IP address). Only by using both private and public subnets with a NAT instance configured for routing, can you allow an instance to have no public IP at all, but still be able to access the internet. (The downside of course, being that for a small setup - e.g. 2 instances - you require a 3rd instance to perform NAT, which isn't practical).

Further Reading:

1

You can have the database server register a dynamic DNS CNAME record upon startup.

I do something similar for a server we'll call mydb. (hostnames and IPs were changed to protect identities.)

output from 'dig mydb.example.net' from outside AWS

mydb.example.net.       108     IN      CNAME   ec2-123-45-6-7.compute-1.amazonaws.com.
ec2-123-45-6-7.compute-1.amazonaws.com. 258 IN A 123.45.6.7

output from 'dig mydb.example.net' from inside AWS

mydb.example.net.       108     IN      CNAME   ec2-123-45-6-7.compute-1.amazonaws.com.
ec2-123-45-6-7.compute-1.amazonaws.com. 258 IN A 10.2.2.2

Note the relatively low timeout (108s) for that CNAME record.

When the mydb server comes up, it CHANGES the CNAME record to point to the NEW dynamic AWS name.

Another thing that's nice is that depending on if you're outside or inside AWS, you'll get a different response. (the most cost effective response)

Using an Elastic IP forgoes the need to wait for the DNS TTL timeout, so that's nice, but if you can live with a DNS TTL timeout to bring up a new DB server (you should have a failover DB server at mydb2.example.net ready all the time anyway, right?) , then this solution might work for you.

1

There are only three possible solutions (when EIP is not an option) and you seem to have a general handle on them already:

  1. Use dynamic dns. You can have your database update a zone hosted in Route53 with it's private IP address. Route53 will allow very low TTLs. Your websphere servers should always know to connect to your designated route53 A record, for e.g. mydb.internal.mydomain.com

  2. Use tags to tag your database instance role and ip address. Then have your websphere server query for instances tagged as a database server and discover it's IP address

  3. Use a VPC and specify the private IP for your DB instance on launch. Your websphere instances always connect to the same designated ip.

I'd avoid a VPC if it is not necessary and given your description above, it doesn't seem warranted from what I understand.

1

The standard way is to use a configuration Management tools like Chef, Puppet.

Since, I have lots of experience in using Chef., I will talk about using Chef here.

In your case, this is how it should be. 1) Upon server startup, each server ( otherwise called as node ) should register itself with chef server. 2) Each node will be assigned a run list. A run list contains many roles ( eg: db, web, etc ) and/or recipes. 3) Each role will have recipes to bootstrap and configure that software component.

It is more or less similar in Puppet world too.

Links: Chef Puppet

Note, all these are OpenSource. Opcode offers a hosted version of Chef Server too. You could try that.

0

One simple thing that i like to do is add a tag to the server

ec2-create-tags <instance-id> --tag Purpose=DB

Then you can query the server based on the tag in a powershell script using the AWSSDKforNET. The New-GenericList method i have just creates a new list in powershell using reflection.

$client = Create-EC2-Client

# Request a list of all the current AmazonEC2 Instances
$request = New-Object -TypeName Amazon.EC2.Model.DescribeInstancesRequest
$filterList = New-GenericList Amazon.EC2.Model.Filter

# Create a new filter to only get servers with a purpose of webserver
$filter = New-Object -TypeName Amazon.EC2.Model.Filter
$filter = $filter.WithName("tag:Purpose");
$filter = $filter.WithValue("DB");
$filterList.Add($filter);

# Add the filter to the request
$request = $request.WithFilter($filter);
$response = $client.DescribeInstances($request)

$servers = @()
foreach ($instance in $response.DescribeInstancesResult.Reservation)
{
    if($instance.RunningInstance[0].InstanceState.Name -eq "running")
    {
        $servers += $instance.RunningInstance[0].PrivateIpAddress.ToString()
    }
}

$servers
0

Look at http://www.exapark.com/product.html This tool updates hosts file with current internal IPs of running instances

-1

You could use vCider, which gives you virtual private networks, even across cloud providers (so you can have a layer 2 broadcast domain across your data center, EC2 or Rackspace, for example). You also have full control over IP address assignment, which means that you will have a fixed address for your host. Basically, it allows you to create your own VPC (virtual private cloud), but keeps you independent of particular providers and give you full layer 2 functionality.

You can signup here. The use of up to 8 hosts is for free. vCider also offers some security features you may be interested in.

Ah, and regarding your bounty: You can use private IP addresses in your virtual network, so you won't have to waste public addresses or even expose your servers via a public address. Be aware that an EC2 machine will always have a public IP address, but with vCider you can actually do something called 'cloud cloaking', which completely shuts down all traffic on that public address, essentially making your host disappear from the public Internet.

I should mention here that I work for vCider, but please don't let this stop you from considering vCider. If you have any questions, please let me know.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .