AWS最新的ami imageId来自旧的imageid?

时间:2017-04-21 02:36:53

标签: powershell amazon-web-services ami aws-powershell

我有一个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不再是最新的。

2 个答案:

答案 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字段中。