Get a URL for each EC2 instance running under a load balancer
Posted by Philip Bulley | Filed under Amazon Web Services, Tips
I have to admit, that this was a task I wanted to accomplish quickly. The kind of ‘quickly’ where you just do a Google search and nice internet person tells you which APIs to use. But no such internet person seemed to exist, so I figured I’ll share my solution.
My problem was that I have a disk-based Codeigniter DB cache running on several EC2 instances. But when I make a change to my RDS database, I need to clear each cache on each individual running EC2 instance. These EC2 instances are within an auto-scaling group, so there’s no guarantee of how many caches will need to be cleared when I decide to purge.
The basic strategy involves calling (using the AWS PHP SDK):
- AmazonELB->describe_load_balancers() passing the name of your load balancer
- AmazonEC2->describe_instances() and parsing out the dnsName
Here’s a quick Codeigniter model that covers querying my live load balancer and then EC2 to get the public DNS names that I can later use to construct a URL to each running instance:
/models/aws_model.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | <?php require_once APPPATH . "/models/abstract_model.php"; require_once APPPATH . "/models/vo/AWSEC2InstanceVO.php"; require_once "application/libraries/aws_sdk/sdk.class.php"; class AWS_model extends Abstract_model { function __construct() { parent::__construct(); } /** * Query AWS to get a list of AWSEC2InstanceVO * for each instance in the ek_live load balancer group * * @return array */ public function getLiveAppInstanceList() { return $this->getInstances( $this->getLiveAppInstanceIDList() ); } /** * Gets the instance IDs currently running under the live * load balancer * * @return array */ public function getLiveAppInstanceIDList() { return $this->getELBInstanceIDList( 'ADD_YOUR_LIVE_LOAD_BALANCER_NAME_HERE' ); } /** * Query AWS to get the list of DNS names for specified instances. * Use getLiveAppDNSNameList() to get for all live instances * * @param $instanceIDList array An array of instance IDs * @return array */ public function getInstances( $instanceIDList ) { $ec2 = new AmazonEC2(); $response = $ec2->describe_instances( array( 'InstanceId' => $instanceIDList ) ); $instances = $response->body->reservationSet; $instanceList = array(); foreach( $instances->item as $instance ) { $item = $instance->instancesSet->item; $vo = new AWSEC2InstanceVO(); $vo->id = (string)$item->instanceId; $vo->imageID = (string)$item->imageId; $vo->state = (string)$item->instanceState->name; $vo->stateCode = (int)$item->instanceState->code; $vo->privateDnsName = (string)$item->privateDnsName; $vo->dnsName = (string)$item->dnsName; $vo->type = (string)$item->instanceType; $vo->launchTime = (string)$item->launchTime; $vo->availabilityZone = (string)$item->placement->availabilityZone; $vo->privateIpAddress = (string)$item->privateIpAddress; $vo->ipAddress = (string)$item->ipAddress; $instanceList[] = $vo; } // echo "<pre>"; // print_r( $instances ); // echo "</pre>"; return $instanceList; } /** * Gets a list of instance IDs under the specified load balancer * * @param $loadBalancerName string The name of the load balancer * @return array */ public function getELBInstanceIDList( $loadBalancerName ) { $elb = new AmazonELB(); $response = $elb->describe_load_balancers( array( 'LoadBalancerNames' => $loadBalancerName ) ); $instances = $response->body->DescribeLoadBalancersResult->LoadBalancerDescriptions->Instances(); $instanceIDList = array(); foreach( $instances[0] as $instanceID ) $instanceIDList[] = (string)$instanceID->InstanceId; // echo "<pre>"; // print_r( $instanceIDList ); // echo "</pre>"; return $instanceIDList; } } |
/models/vo/AWSEC2InstanceVO.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <?php class AWSEC2InstanceVO { /** @var string */ var $id; /** @var string */ var $imageID; /** @var string */ var $state; /** @var int */ var $stateCode; /** @var string */ var $privateDnsName; /** @var string */ var $dnsName; /** @var string */ var $type; /** @var string */ var $launchTime; /** @var string */ var $availabilityZone; /** @var string */ var $privateIpAddress; /** @var string */ var $ipAddress; } |
I can now call a URL/script on each EC2 instance like so:
1 2 3 4 5 6 7 8 9 10 11 12 | $instanceList = $this->AWS_model->getLiveAppInstanceList(); $message = "<ol>"; /** @var $instance AWSEC2InstanceVO */ foreach( $instanceList as $instance ) { $url = 'http://' . $instance->dnsName . '/path/to/script'; $result = file_get_contents( $url ); $message .= "<li>".$instance->id." - ".$instance->dnsName."<ul><li>Result: <strong>".$result."</strong></li></ul></li>"; } $message .= "</ol>"; echo $message; |
Hope this saves you a bit of time :)
Tags: aws, codeigniter, ec2, php