Testimonials
  • Nick was vital to creating and implementing a disaster recovery plan (DRP) for my business. We are extremely dependent on our network and database […] To be down or our security compromised would create a real financial hardship. We truly appreciated Nick’s professional and creative approach to our DRP […] Thanks Nick!
    Kimberly Dodd, CPA, Broker

Assign AWS Elastic IP (EIP) With Windows Powershell

After many Amazon Web Services Elastic Compute Cloud (AWS EC2) projects involving Linux, I’m finally working on a Windows EC2 project. With that we need a variety of maintenance scripts, such as assigning a static IP at boot (Elastic IP or EIP). Much to my surprise, there are very few examples for using native Windows scripting to perform this work (other than tired, old, cmd.exe, which is very limiting).

So, with a very basic understanding of PowerShell, I’ve setout to fill this gap… stay tuned for other AWS PS scripts soon, such as taking EBS Snapshots. Make sure you have the AWS .NET SDK installed before running this script.

Without further ado, here is the script (you may download it as well: AWS-EIP.ps1).

<#
    .SYNOPSIS
    Simple script to safely assign AWS Elastic IPs (EIPs) at Windows Boot.
    
    .DESCRIPTION
    Script first checks to see if the IP is already assigned, and if so aborts
    returning a non-zero code.  If assginement is successful, zero (0) is returned.
    
    NOTE:  Script must be updated to include instanceID, EIP, security credentials,
        and ServiceURL for your particular Region.
    
    .NOTES
        File Name :  AWS-EIP.ps1
        Author    :  Nick Webb - nickw at redwireservices dot com
        Version   :  0.2 - 02/21/2012
        
    .LINK
        http://www.redwireservices.com
    
    .EXAMPLE
    
    AWS-EIP.ps1
#>


# User modifyable items: #################################################

# Update to the AWS SDK Path on your system, if not default
Add-Type -Path "C:Program Files (x86)AWS SDK for .NETbinAWSSDK.dll"

# Update the following lines, as needed:
$accessKeyID="your access key ID"
$secretAccessKey="your secret access key"
$instanceID="i-your instance id"
$instanceEIP="x.x.x.x"

# Uncomment ONE of the following, which applies to your region
# US-West N. California:
$ServiceURL="https://ec2.us-west-1.amazonaws.com"

# US-West Oregon
#$ServiceURL="https://ec2.us-west-2.amazonaws.com"

# US-East (Standard)
#$ServiceURL="https://ec2.us-east-1.amazonaws.com"
# END User configurable options ##########################################

$config=New-Object Amazon.EC2.AmazonEC2Config
$config.ServiceURL = $ServiceURL
$client=[Amazon.AWSClientFactory]::CreateAmazonEC2Client($accessKeyID,$secretAccessKey,$config)

# See if the IP is already assigned somewhere
$request = New-Object -TypeName Amazon.EC2.Model.DescribeAddressesRequest
[void]$request.WithPublicIp($instanceEIP)

$result = New-Object -TypeName Amazon.EC2.Model.DescribeAddressesResponse
try {
    $result = $client.DescribeAddresses($request)
} 
catch {
    echo "Failed to validate EIP $instanceEIP, ensure that it is allocated and associated with your account.  Aborting."
    exit 2
}

# See if an instanceID is already assigned to this EIP
$xml=$result.ToXML()
$assignedInstanceID = [string]($xml.DescribeAddressesResponse.DescribeAddressesResult.Address.InstanceId)

# Run this block if an Instance already has this EIP associated to it... just in case changes would 
# result in downtime (i.e. if we are launching a test system from a cloned production one).
if ($assignedInstanceID) {
  echo "Address $instanceEIP already assigned to: $assignedInstanceID, aborting."
  exit 1
}

# If we get here, the IP is free and clear, go ahead and associate it.
$request = New-Object -TypeName Amazon.EC2.Model.AssociateAddressRequest
[void]$request.WithInstanceId($instanceID)
[void]$request.WithPublicIp($instanceEIP)

$result = $client.AssociateAddress($request)
if ($result) {
  echo "Address $instanceEIP assigned to $instanceID successfully."
  exit 0
}
else {
  echo "Failed to assign $instanceEIP to $instanceID."
  exit 3
}
This entry was posted in LinkedIn, Off The Wire, Tech Tips. Bookmark the permalink.

6 Responses to Assign AWS Elastic IP (EIP) With Windows Powershell

  1. For me, the $instanceID changes every time the instance is re-started. How do you make it a fixed $instanceID or how do you retrieve it in the script?

  2. Nick Webb says:

    Emmanuel,

    Great question.

    I’ve ran into that as well, and you can get the current instanceID from within the instance with a request to this URL:
    http://169.254.169.254/latest/meta-data/instance-id

    On Linux/bash I’ve put that in a variable like so:
    MY_INSTANCE=$(/usr/bin/wget -q -O – http://169.254.169.254/latest/meta-data/instance-id)

    Also note that this is pretty legacy stuff at this point. I wouldn’t update retiring applications that are using it, but I would (and have) slowly migrate over to VPC where this is not an issue (EIP assignments and local IPs are static across reboots and power-offs).

    Given your question, however, you may have a great use case for the old way (“EC2 Classic”).

  3. Dev says:

    Hi,

    I am new to Powershell programming and when i run this script i am getting following error.

    Add-Type : Could not load file or assembly ‘file:///C:\Program Files (x86)\AWS SDK for .NET\bin\Net45\AWSSDK.dll’ or one of its dependencies. This assembly is buil
    t by a runtime newer than the currently loaded runtime and cannot be loaded.
    At C:\AWS-EIP.ps1:4 char:9
    + Add-Type <<<< -Path "C:\Program Files (x86)\AWS SDK for .NET\bin\Net45\AWSSDK.dll" # Update the following lines, as

    Any help.

    Thanks,
    Dev

  4. Nick Webb says:

    Dev,

    Sounds like you do not have the AWS .NET toolkit installed.

    Nick

    • Dev says:

      Hi Nick,

      I have AWS.NET toolkit on that window instance. It seems that issue is realted to latest .net framework. But i figure out another way. I used bat file and after facing issue in order to run this bat file as a window service, i used task scheduler for that purpose. It work for me.

      Thanks for posting nice article.

      Thanks,
      Dev

Leave a Reply

Your email address will not be published. Required fields are marked *