Search code examples
amazon-web-servicesamazon-ec2sysprep

Call to 169.254.169.254/latest/meta-data/instance-id fails in AWS deployment script


I'm using some scripts based on http://blog.brianbeach.com/2014/07/setting-hostname-in-syspreped-ami.html to set the Host Name of a new windows instance created from an AMI to be the Name tag of the instance. Instead of HKLM:\System\Setup pointing to windeploy.exe, it runs a script which runs this:

$InstanceName = 'WebServerNew'

Try 
{
    Start-Transcript -Path D:\WebServerUtility\SysPrep\Windeploy.log -Append
    Write-Host "Discovering instance identity from meta-data web service"
    $InstanceId = (Invoke-RestMethod 'http://169.254.169.254/latest/meta-data/instance-id').ToString()
    $AvailabilityZone = (Invoke-RestMethod 'http://169.254.169.254/latest/meta-data/placement/availability-zone').ToString()
    $Region = $AvailabilityZone.Substring(0,$AvailabilityZone.Length-1)

    Write-Host "Getting Tags for the instance"
    $Tags = Get-EC2Tag -Filters @{Name='resource-id';Value=$InstanceId} -Region $Region
    $InstanceName = ($Tags | Where-Object {$_.Key -eq 'Name'}).Value
    Write-Host "`tFound Instance Name: $InstanceName"    
}
Catch
{
    Write-Host $_
    $InstanceName = 'WebServerError'
}

try
{ 
    If($InstanceName -ne $null) {
          Write-Host "Setting the machine name to $InstanceName"
          $AnswerFilePath = "C:\Windows\Panther\unattend.xml"
          $AnswerFile = [xml](Get-Content -Path $AnswerFilePath) 
          $ns = New-Object System.Xml.XmlNamespaceManager($AnswerFile.NameTable)
          $ns.AddNamespace("ns", $AnswerFile.DocumentElement.NamespaceURI)
          $ComputerName = $AnswerFile.SelectSingleNode('/ns:unattend/ns:settings[@pass="specialize"]/ns:component[@name="Microsoft-Windows-Shell-Setup"]/ns:ComputerName', $ns)
          $ComputerName.InnerText = $InstanceName
          $AnswerFile.Save($AnswerFilePath)
    }
}
Catch
{
    Write-Host $_
}
Finally
{
    Stop-Transcript
}

and THEN it calls WinDeploy.exe to finish the specialization.

The problem is that the line

    Write-Host "Discovering instance identity from meta-data web service"
    $InstanceId = (Invoke-RestMethod 'http://169.254.169.254/latest/meta-data/instance-id').ToString()

fails with "Unable to connect to the remote server".

Any idea why it would be unable to connect to that?

enter image description here


Solution

  • You need to add this to the top of the script:

    Start-Service -Name 'Dhcp'
    route add 169.254.169.254 MASK 255.255.255.255 0.0.0.0
    

    The DHCP Client is stopped when the script is triggered. That why you don't have IP.

    And you also need to add a route to the meta-data service. Sysprep remove those routes.