我有一个EC2实例运行来自AWS的旧AMI,我目前的设置来自WINDOWS_2016_BASE
。现在我知道了,但实例并不知道。
使用PowerShell我希望EC2实例创建更像自己,但不是来自我创建的AMI(因为它当然总是在旧版本中)而不是"直接"从它创建的实际AMI ImageId。由于AWS不允许,如果它不是它的最新版本(因此我需要间接路径来获取AMI ImageId,即使它结果是相同的......即如果它已经是最新版本)。
所以我需要使用PowerShell找到我已经知道的AMI的最新版本(我从元数据中得到)并且我不想指定AMI的名称,例如WINDOWS_2016_BASE
,因为我会就像机器创造更像自己,而不必硬编码脚本中的内容。
我不知道如何执行此操作,因为使用Get-EC2ImageByName -Names WINDOWS_2016_BASE
并不是我想要做的,因为我不想对该名称参数进行硬编码或通过userdata传递它。
Get-EC2Image -ImageId <an old imageid>
返回null,因为AMI不再是最新的。
答案 0 :(得分:2)
如果没有将此名称存放在您的脚本可以提示的位置(您已经声明过您不想这样做),或者依赖于名称/ amis之间的某些映射(这是Get- EC2ImageByName已经为你做了。)
AMI元数据的设计使得很容易检索相关AMI的“家族树”,假设它们的名称相似,除了版本或日期之类的微小差异。相关AMI的前缀是一致的常见模式,这使得它们更容易搜索和聚合。
这一点使您的方法变得困难,因为您的脚本将丢失那些数据 - AMI名称前缀。
您可以从metadata service动态检索实例的AMI ID,并将其传递到Get-EC2Image以获取AMI详细信息,但如果没有某种名称前缀来匹配和使用,您无法再远离它搜索更新的相关AMI。
也许重新考虑这种方法,并通过用户数据将名称前缀保存在标签或实例中?例如,我刚检查过,英文Windows Server 2016 Base AMI都共享此前缀:Windows_Server-2016-English-Full-Base
。如果您将其存储在您的实例上或作为其中一个标记,您的脚本可以检索它并运行以下PowerShell以获取最新的Windows Server 2016 AMI:
@(Get-EC2Image -Owner amazon -Filter @{ Name="name"; Values="Windows_Server-2016-English-Full-Base*" } | Sort CreationDate -Desc)[0].ImageId
答案 1 :(得分:1)
系统日志示例(我从aws控制台视图获取)
2016/12/26 14:36:12Z:AMI原产地名称:Windows_Server-2016-English-Full-Base
等效的powershell是:
Get-EC2ConsoleOutput
所以下面全部(我是PowerShell的新手,但我很确定有人可以将其包装成一个角色)
# read the system console log
$consoleLog = Get-EC2ConsoleOutput $currentInstanceObj.InstanceId
$consoleLogOutput = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($consoleLog.Output));
# extract the lines that contain AMI Origin in them (there should be 2) - sort them so name i first and version is second
$originLines = $consoleLogOutput -split '[\r\n]' | Where-Object {$_.Contains("AMI Origin")} | Sort-Object
# get the running name
$originLine = $originLines[0]
$originLineParts = $originLine.Split(':')
$originName = $originLineParts[$originLineParts.Length - 1].Trim()
"The origin name is $originName"
# get the running version (slighly pointless since the code below doesn't care as we want the latest - but it's for verbosity)
$originLine = $originLines[1]
$originLineParts = $originLine.Split(':')
$originVersion = $originLineParts[$originLineParts.Length - 1].Trim()
"The origin version is $originVersion"
# concatenate to get the original origin name (note: amazon have a naming pattern here - (name-version)
$amiName = $originName + "-" + $originVersion
"The original origin ami name is $amiName"
#find the latest of the same name and report the difference
$latestOriginObj = (Get-EC2Image -Filter @{ Name="name"; Values=($originName + "*")} | Sort-Object CreationDate -Descending | Select-Object -First 1)
if($latestOriginObj.ImageId -ne $currentInstanceObj.ImageId)
{
"The ami has been upgraded from " + ($currentInstanceObj.ImageId) + " to " + ($latestOriginObj.ImageId)
}
#....so go ahead and use the $latestOriginObj.ImageId when you create a new instance
其中的知识来源来自这些amazons docs
摘录如下:
AWS管理控制台提供有关用于创建Amazon EC2实例的AMI的详细信息。 “描述”选项卡上的“AMI ID”字段包含的信息包括Windows Server SKU,体系结构(32位或64位),AMI创建日期和AMI ID。
如果AMI已被设为私有或被更高版本替换且不再列在目录中,则AMI ID字段指出“无法加载ami-xxxxx的详细信息。您可能无法查看它。“要确定用于创建实例的AMI,您必须打开系统日志。在EC2控制台中,选择一个实例,然后从上下文菜单(右键单击)中选择“实例设置”,然后选择“获取系统日志”。 AMI创建日期和SKU列在AMI Origin Version和AMI Origin Name字段中。