0

我有一个 EC2 实例运行来自 AWS 的旧 AMI,在我当前的设置中来自WINDOWS_2016_BASE. 现在我知道了,但实例不知道。

使用 PowerShell,我希望 EC2 实例创建更像它自己,但不是从我创建的 AMI(因为这当然总是在旧版本中),而不是“直接”从创建它的实际 AMI ImageId。由于 AWS 不允许这样做,如果它不是最新版本(因此我需要间接路由来获取该 AMI ImageId,即使结果是相同的......即如果它已经是最新版本)。

所以我需要使用 PowerShell 找到我已经知道的 AMI 的最新版本(我从元数据中获得)并且我不想指定 AMI 的名称,例如WINDOWS_2016_BASE因为我希望机器创建更像它自己无需我对脚本中的内容进行硬编码。

我不知道该怎么做,因为 usingGet-EC2ImageByName -Names WINDOWS_2016_BASE不是我想要做的,因为我不想硬编码该名称参数或通过 userdata 传递它。

Get-EC2Image -ImageId <an old imageid>返回 null,因为 AMI 不再是最新的。

4

2 回答 2

2

如果不将此名称存储在您的脚本可以提示的某个位置(您已声明您不想这样做),或者不依赖名称/amis 之间的某些映射(Get-EC2ImageByName 已经这样做),这将有些困难为你)。

AMI 元数据的设计使得可以轻松检索相关 AMI 的“家谱”,假设它们的名称相似,但版本或日期等可能存在细微差异。相关 AMI 的前缀保持一致是一种常见模式,这使得它们更易于搜索和聚合。

这一点使您的方法变得困难,因为您的脚本将丢失那部分数据——AMI 名称前缀。

您可以从元数据服务动态检索您的实例的 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
于 2017-04-21T03:27:36.077 回答
1

系统日志中的示例(我从 aws 控制台视图中获得)

2016/12/26 14:36:12Z:AMI 来源名称:Windows_Server-2016-English-Full-Base

等效的powershell是:

获取 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    


而这方面的知识来源来自这些亚马逊文档

摘录如下:

AWS 管理控制台提供有关您用于创建 Amazon EC2 实例的 AMI 的详细信息。描述选项卡上的 AMI ID 字段包含的信息包括 Windows Server SKU、架构(32 位或 64 位)、AMI 的创建日期和 AMI ID。

如果 AMI 已设为私有或被更高版本替换并且不再列在目录中,则 AMI ID 字段会显示“无法加载 ami-xxxxx 的详细信息。您可能无权查看它。” 要确定使用哪个 AMI 创建实例,您必须打开系统日志。在 EC2 控制台中,选择一个实例,然后从上下文菜单(右键单击)中选择实例设置,然后选择获取系统日志。AMI 的创建日期和 SKU 列在 AMI 原始版本和 AMI 原始名称字段中。

于 2017-04-21T04:56:15.517 回答