Tag Archives: projMoveAws

Move mission critical services to Amazon Web Services

Summary

Summary here…

Description

Detailed Description…

Amazon EC2 Metadata

We use the following class to obtain Metadata from a running Amazon instance. This code also demonstrates a way set a timeout variable when using the WebClient object.

public class AwsHelper
{
private const string LOG_PREFIX = "AwsHelper/";
/* A class to return Metadata from a running Amazon instance.
Requires: using System.Net;
We call these methods in the startup routine of our windows service.
Here is an example:
// If called from a non AWS instance, each request would take 5 seconds (the timeout),
// so we wrap them to only be called when an AvailabilityZone is returned.
string avZone = AwsHelper.AvailabilityZone;
if (!string.IsNullOrEmpty(avZone))
{
Logging.LogInfo(logMsg + " Amazon Availability Zone: " + avZone);
Logging.LogInfo(logMsg + " AmiId: " + AwsHelper.AmiId);
Logging.LogInfo(logMsg + " PublicIpv4: " + AwsHelper.PublicIpv4);
Logging.LogInfo(logMsg + " InstanceId: " + AwsHelper.InstanceId);
Logging.LogInfo(logMsg + " InstanceType: " + AwsHelper.InstanceType);
Logging.LogInfo(logMsg + " SecurityGroups: " + AwsHelper.SecurityGroups);
}
Here is a list of other meta data that could be returned. This list is
obtained by calling: http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
hostname
instance-action
instance-id
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups
services/
*/
public static string AvailabilityZone
{
// Returns Region + AvailabilityZone, Example: eu-west-1c
get { return GetMetaData("placement/availability-zone"); }
}
public static string PublicIpv4
{
get { return GetMetaData("public-ipv4"); }
}
public static string AmiId
{
get { return GetMetaData("ami-id"); }
}
public static string InstanceId
{
get { return GetMetaData("instance-id"); }
}
public static string InstanceType
{
get { return GetMetaData("instance-type"); }
}
public static string SecurityGroups
{
get { return GetMetaData("security-groups"); }
}
public static string GetMetaData(string urlSuffix)
{
string logMsg = LOG_PREFIX + "GetMetaData";
string retVal = "";
const string URL_PREFIX = "http://169.254.169.254/latest/meta-data/";
const int WAIT_TIMEOUT_MILLISECONDS = 5000;
try
{
Logging.LogTrace(logMsg + string.Format(", for urlSuffix: {0}", urlSuffix));
// Create the Full Url we will need to find the data.
string fullUrl = URL_PREFIX;
if (!urlSuffix.StartsWith("/"))
{ fullUrl += "/"; }
fullUrl += urlSuffix;
WebClientWithTimeout webClient = new WebClientWithTimeout(WAIT_TIMEOUT_MILLISECONDS);
retVal = webClient.DownloadString(fullUrl);
}
catch (WebException ex)
{
if (ex.Message.Contains("The operation has timed out"))
{
// This "EXCEPTION" will normally be thrown when we try to use this
// method from a computer that is not running on an Amazon server.
Logging.LogTrace(logMsg + ", Property called from a non Amazon server.");
}
else
{ Logging.LogError(logMsg + ", WEBEXCEPTION: " + ex.Message, ex); }
}
catch (Exception ex)
{ Logging.LogError(logMsg + ", EXCEPTION: " + ex.Message, ex); }
return retVal;
}
private class WebClientWithTimeout : WebClient
{
// The reason we are not using the default WebClient class is because we need to specify
// a timeout. The default Timeout for the WebClient is at least 20 seconds (Some people
// say 100 seconds). When we are running on an Amazon server, the request returns almost
// instantaneously, so the timeout doesn't matter.
// However, when we call this from a non Amazon computer, the code will just "hang" until
// the timeout has elapsed.
// http://stackoverflow.com/questions/1789627/how-to-change-the-timeout-on-a-net-webclient-object
private int _timeoutMilliSeconds = 5000;
public WebClientWithTimeout() { }
public WebClientWithTimeout(int timeoutMilliSeconds)
{
_timeoutMilliSeconds = timeoutMilliSeconds;
}
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest webRequest = base.GetWebRequest(uri);
webRequest.Timeout = _timeoutMilliSeconds;
return webRequest;
}
}
}
Click the “view raw” link to view the entire code listing.

Technology

  • C#
  • WebClient (with timeout)