如何自动将弹性IP地址与AutoScale组中的Windows服务器关联?

时间:2016-06-25 05:24:51

标签: windows powershell amazon-web-services amazon-ec2

我正在尝试找到一种方法示例,将相同的弹性IP地址可靠地关联到属于AutoScale组的Windows Server。本质上,目标是处理服务器终止并通过AutoScale替换并保持相同的公共IP(远程提供的服务所需)的情况。

AutoScale组配置为仅允许最多1台服务器和最少1台服务器用于自动恢复方案。服务器位于VPC中,实际上是需要静态寻址的远程Web队列的工作者。

我还想利用IAM角色,这样我就不必在提供的UserData脚本中嵌入AWS凭据。目前我正在寻找一个示例PowerShell脚本,但如果有人知道更好的方法,我当然愿意接受建议。我已经看到了一些较旧的示例,但它们已经过时并使用了我想避免的嵌入式AWS凭据。

2 个答案:

答案 0 :(得分:2)

以下是我们使用的内容:

在Autoscaling组的启动配置中,指定以下用户数据:

<script>
PowerShell -ExecutionPolicy Bypass -NoProfile -File c:\tools\server_userdata.ps1 -instanceEIP eipalloc-abcdefg
</script>

将EIP标识符eipalloc-abcdefg传递给脚本。当然,将其更改为您的EIP。

我们在实例上预先烘焙userdata脚本,而不是将完整脚本传递给用户数据。我们通常在这个脚本中做很多配置;我已经将它简化为仅在此处进行EIP分配。使用预烘焙脚本,我们可以在各种实例函数和环境中共享相同的脚本,并通过仅通过用户数据传递参数来控制该实例的配置,在脚本中没有任何静态编码。

另请注意,我们使用脚本文件和Windows事件日志条目来简化故障排除。

<强> C:\工具\ server_userdata.ps1

<powershell>
Import-Module WebAdministration
Start-Transcript -Path C:\userscriptlog.txt
param (
    [string]$instanceEIP = $(throw "-instanceEIP is required."),
)
if ([System.Diagnostics.EventLog]::SourceExists("Userdata") -eq $False) {
    New-Eventlog -Logname Application -Source 'Userdata' 
}
Write-Eventlog -Logname Application -Source 'Userdata' -EventId 1 -EntryType Information -Message 'Begining post-deployment configuration script'

# get instance-id
try { 
    $InstanceId = (Invoke-WebRequest http://169.254.169.254/latest/meta-data/instance-id).content
} catch { 
    $_.Exception.message | out-file c:\InstanceId_error.log 
    Write-Host "FATAL: InstanceId exception"
    Exit 1
}

if (!$InstanceId) { 
    Write-Host "FATAL: InstanceId is null"
    Exit    
} else {
    $InstanceId | out-file C:\InstanceId.txt
    Write-Host "InstanceId: $InstanceId"    
}

Write-Host "EIP: $instanceEIP"

# assign EIP

$request = New-Object -TypeName Amazon.EC2.Model.AssociateAddressRequest
[void]$request.WithInstanceId($InstanceId)
[void]$request.WithPublicIp($instanceEIP)

$result = $client.AssociateAddress($request)
if ($result) {
  Write-Host  "Address $instanceEIP assigned to $instanceID successfully."
  exit 0
}
else {
  Write-Host  "Failed to assign $instanceEIP to $instanceID."
  exit 2
}

Write-Eventlog -Logname Application -Source 'Userdata' -EventId 1 -EntryType Information -Message 'Post-deployment configuration script complete'
Stop-Transcript
</powershell>

关于IAM角色,此脚本假定实例具有适当的角色和权限。以下是必需的权限:

{  
   "Version":"2012-10-17",
   "Statement":[  
      {  
         "Action":[  
            "ec2:AssociateAddress",
            "ec2:DescribeAddresses",
         ],
         "Sid":"Stmt1375723773000",
         "Resource":[  
            "*"
         ],
         "Effect":"Allow"
      }
   ]
}

答案 1 :(得分:0)

如果它有帮助我需要Auto Scaling Group来维护单个IP后面的单个实例(这样外部服务可以通过IP将来自我的服务器的请求列入白名单)。我通过分配弹性IP然后在创建启动配置中添加启动脚本来解决它 - &gt;配置详细信息 - &gt;高级详细信息 - &gt;用户数据:

#!/bin/bash

# configure AWS
aws configure set aws_access_key_id {MY_ACCESS_KEY}
aws configure set aws_secret_access_key {MY_SECRET_KEY}
aws configure set region {MY_REGION}

# associate Elastic IP
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
ALLOCATION_ID={MY_EIP_ALLOC_ID}
aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOCATION_ID --allow-reassociation

如果实例向南,则Auto Scale Group会旋转一个新实例,该实例回收相同的弹性IP,白名单仍然有效。 (这基本上是Shlomo Swidler和Bless @ AWS建议的方法,只是更详细一点。:-))

对于那些想要一个地址池的人,可以扩展这种方法以使用'aws ec2 describe-addresses'并选择一个未分配给实例的方法。