开发者

Using AWS API/SDK to Register new EC2 Instances with Existing Elastic Load Balancer - is it possible?

I'm working on using the .Net SDK to help automate the deployment of an application into Windows EC2 instances. The process I want to achieve is:

  1. Create a new EC2 instance - this "bootstraps" itself by loading in the new application version using a service.
  2. Ensure the new instance is in the 'running' state
  3. Run some simple acceptance tests on the new instance.
  4. Register the new instance with an existing Elastic Load balancer that has an instance running the old version of the application.
  5. When the new instance is registered with the load balancer, de-register the old instance.
  6. Stop the old EC2 instance.

I've managed to get steps 1 and 2 working, and I'm pretty confident about 3 and 6.

To do this I've been writing a simple C# console app that uses the AWS .Net SDK v1.3.2 to make the various API calls.

However, when I get to step 4 I cannot get the new instance registered with the load balancer. Here is my code:

public IList<Instance> PointToNewInstance(string newInstanceId)
{
    var allInstances = new List<Instance>();

    using (var elbClient = ClientUtilities.GetElbClient())
    {
        try
        {
            var newInstances = new List<Instance> {new Instance(newInstanceId)};
            var registInstancesRequest = new RegisterInstancesWithLoadBalancerRequest
                                             {
                                                 LoadBalancerName = LoadBalancerName,
                                                 Instances = newInstances
                                             };

            var registerReponse = elbClient.RegisterInstancesWithLoadBalancer(registInstancesRequest);
            allInstances = registerReponse.RegisterInstancesWithLoadBalancerResult.Instances;

            var describeInstanceHealthRequest = new DescribeInstanceHealthRequest
                                                    {
                                                        Instances = newInstances
   开发者_开发技巧                                                 };
            DescribeInstanceHealthResponse describeInstanceHealthResponse;

            do
            {
                describeInstanceHealthResponse = elbClient.DescribeInstanceHealth(describeInstanceHealthRequest);
            } while (describeInstanceHealthResponse.DescribeInstanceHealthResult.InstanceStates[0].State == "OutOfService");

            _log.DebugFormat("New instance [{0}] now in service - about to stop remove old instance", newInstanceId);

            if (allInstances.Any(i => i.InstanceId != newInstanceId))
            {
                elbClient.DeregisterInstancesFromLoadBalancer(new DeregisterInstancesFromLoadBalancerRequest
                                                                  {
                                                                      Instances = allInstances.Where(i => i.InstanceId != newInstanceId).ToList(),
                                                                      LoadBalancerName = LoadBalancerName
                                                                  });
                foreach (var instance in allInstances.Where(i => i.InstanceId != newInstanceId).ToList())
                {
                    _log.DebugFormat("Instance [{0}] has now been de-registered from load-balancer [{1}]", instance.InstanceId, LoadBalancerName);
                }
            }
        }
        catch (Exception exception)
        {
            _log.Error(exception);
        }
    }

    return allInstances.Where(i => i.InstanceId != newInstanceId).ToList();
}

The code just freezes at this line:

var registerReponse = elbClient.RegisterInstancesWithLoadBalancer(registInstancesRequest);

When I looked in more detail at the documention (relevant documentation here) I noticed this line:

NOTE: In order for this call to be successful, the client must have created the LoadBalancer. The client must provide the same account credentials as those that were used to create the LoadBalancer.

Is it actually possible to use the API to register new instances with an existing load balancer?


All of that is easy to implement. Use Auto Scaling. Use API.


As Roman mentions, it sounds like Auto Scaling is a good way for you to go, it may not solve all of your problems but its certainly a good starting point:

-an auto scaling group can be tied to a load balancer, e.g. ill have x healthy instances

-new instances are automatically added to the load balancer (no traffic will be sent until it passed the health check)

-you can define custom health checks, such as ping http://hostname/isalive just have your instance respond to these requests once its passes step 3

-you can define scaling policies but by default if you're over capacity the oldest instances will be killed

-you don't mention the use case of the app but if you don't want a public facing address you can use an internal load balancer that doesn't take any traffic, just looks after the health check

-where possible you should always use least privilege principles for security, with your method you're going to have to give every instance a lot of power to control other instances, whether through mistake or abuse this can go wrong very easily

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜