如何从ec2实例中获取实例ID?


Answers:


533

请参阅有关此主题的EC2文档

跑:

wget -q -O - http://169.254.169.254/latest/meta-data/instance-id

如果您需要从脚本中以编程方式访问实例ID,

die() { status=$1; shift; echo "FATAL: $*"; exit $status; }
EC2_INSTANCE_ID="`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id || die \"wget instance-id has failed: $?\"`"

更高级的用法示例(检索实例ID以及可用性区域和区域等):

EC2_INSTANCE_ID="`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id || die \"wget instance-id has failed: $?\"`"
test -n "$EC2_INSTANCE_ID" || die 'cannot obtain instance-id'
EC2_AVAIL_ZONE="`wget -q -O - http://169.254.169.254/latest/meta-data/placement/availability-zone || die \"wget availability-zone has failed: $?\"`"
test -n "$EC2_AVAIL_ZONE" || die 'cannot obtain availability-zone'
EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed -e 's:\([0-9][0-9]*\)[a-z]*\$:\\1:'`"

您还可以使用curl代替wget,具体取决于平台上安装的内容。


@Leopd,您显然比在Amazon实施EC2并编写文档的人员了解得更多。顺便说一句,如果您……应该注意,没有人会阻止您为169.254.169.254in 创建别名,/etc/hosts如果这样会使您感到更安全。
vladr

2
在Java SDK中呢?有什么方法可以不必在该URL上执行GET来获取此信息的吗?如果不在SDK中,这似乎很奇怪
Kevin M,

1
非常有帮助,谢谢。对于其他试图弄清最后一行中的正则表达式的人,这是我想到的:在行($)的末尾,找到一个或多个数字,后跟一个或多个小写字母。仅用数字代替。(反斜杠+括号告诉sed记住一个子字符串,用调用\1。)我发现这更容易阅读-唯一的反斜杠是sed所需的 EC2_REGION="$(echo "$EC2_AVAIL_ZONE" | sed -e 's:\([0-9][0-9]*\)[a-z]*$:\1:')"
马克·贝里

66
您可以使用http://instance-data/代替169.254.169.254
Jay P

20
我在2016-02-04上进行了检查。我发现“实例数据”主机名(a)没有在该文档中列出,并且(b)在新的EC2主机上不起作用(对我而言)。文档(docs.aws.amazon.com/AWSEC2/latest/UserGuide/…)仅提及169.254地址,而未提及“实例数据”主机名。即使用169.254.169.254/latest/meta-data/instance-id
JDS

138

在Amazon Linux AMI上,您可以执行以下操作:

$ ec2-metadata -i
instance-id: i-1234567890abcdef0

或者,在Ubuntu和其他一些Linux操作系统上,ec2metadata --instance-id(默认情况下,该命令可能未在ubuntu上安装,但是您可以使用添加它sudo apt-get install cloud-utils

顾名思义,您也可以使用该命令来获取其他有用的元数据。


3
如果您正在考虑使用此工具,那么这篇文章值得一读(tldr:命令行工具是Java,而Java的启动时间却很长)
James

最好的答案
Chuck Le Butt,

@马克·诺普 -以后没有ec2。它是ec2metadata --instance-id
Dawny33 '18

5
该命令在不同的Linux上是不同的:在Amazon Linux上ec2-metadata,在Ubuntu上似乎是ec2metadata
詹姆斯

对了,詹姆斯,我发现相同的ec2metadata也可以在Ubuntu上使用。
pyAddict

69

在Ubuntu上,您可以:

sudo apt-get install cloud-utils

然后您可以:

EC2_INSTANCE_ID=$(ec2metadata --instance-id)

您可以通过以下方式获取与实例关联的大多数元数据:

ec2metadata-帮助
语法:/ usr / bin / ec2metadata [选项]

查询和显示EC2元数据。

如果未提供任何选项,则将显示所有选项

选项:
    -h --help显示此帮助

    --kernel-id显示内核ID
    --ramdisk-id显示ramdisk ID
    --reservation-id显示预订ID

    --ami-id显示ami id
    --ami-launch-index显示AMI启动索引
    --ami-manifest-path显示ami清单路径
    --ancestor-ami-ids显示ami祖先ID
    --product-codes显示与ami相关的产品代码
    --availability-zone显示AMI放置区域

    --instance-id显示实例ID
    --instance-type显示实例类型

    --local-hostname显示本地主机名
    --public-hostname显示公共主机名

    --local-ipv4显示本地ipv4 ip地址
    --public-ipv4显示公共ipv4 ip地址

    --block-device-mapping显示块设备ID
    --security-groups显示安全组

    --mac显示实例的mac地址
    --profile显示实例配置文件
    --instance-action显示实例动作

    --public-keys显示openssh公共密钥
    --user-data显示用户数据(实际上不是元数据)

在Ubuntu下,lucid apt-get install检索不包含该实用程序的版本0.11-0ubuntu1。此后才将其添加到程序包中。
Aryeh Leib Taurog 2012年

7
默认情况下,Ubuntu 12.04.1 LTS Cluster Compute AMI包含cloud-utils软件包。
安德鲁

2
云utils的似乎是在RHEL / CentOS的太
克雷格·林格

50

/dynamic/instance-identity/document如果您不仅需要查询实例ID,还可以使用URL。

wget -q -O - http://169.254.169.254/latest/dynamic/instance-identity/document

这将让你JSON数据,如这一点-只有一个单一的请求

{
    "devpayProductCodes" : null,
    "privateIp" : "10.1.2.3",
    "region" : "us-east-1",
    "kernelId" : "aki-12345678",
    "ramdiskId" : null,
    "availabilityZone" : "us-east-1a",
    "accountId" : "123456789abc",
    "version" : "2010-08-31",
    "instanceId" : "i-12345678",
    "billingProducts" : null,
    "architecture" : "x86_64",
    "imageId" : "ami-12345678",
    "pendingTime" : "2014-01-23T45:01:23Z",
    "instanceType" : "m1.small"
}

1
+1用于显示所有详细信息,包括在一个简单调用中的instanceType
Luksurious 2014年

1
+1表示具有相当标准的权限(仅适用于wget)和工作行(在Amazon linux上,instance-data url对我不起作用),而无需为此目的安装其他软件包。
tishma'1

27

对于.NET人:

string instanceId = new StreamReader(
      HttpWebRequest.Create("http://169.254.169.254/latest/meta-data/instance-id")
      .GetResponse().GetResponseStream())
    .ReadToEnd();

24

在AWS Linux上:

ec2-metadata --instance-id | cut -d " " -f 2

输出:

i-33400429

使用in变量:

ec2InstanceId=$(ec2-metadata --instance-id | cut -d " " -f 2);
ls "log/${ec2InstanceId}/";

干净简洁的方式。使用Ubuntu 14开箱即用的工作
。– berbt

22

对于Powershell用户:

(New-Object System.Net.WebClient).DownloadString("http://169.254.169.254/latest/meta-data/instance-id")

4
只是不同的突击队:$instanceId=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id').Content
Sumit Murari

当使用ssm send-command(或Send-SSMCommand)在所述EC2实例上运行脚本时,Invoke-WebRequest并不总是有效。它在文档中并没有真正说出来。可能不是异步的...这很奇怪。但是,到目前为止,stefancaunter的选择没有问题。
J-Roel

22

对于Python:

import boto.utils
region=boto.utils.get_instance_metadata()['local-hostname'].split('.')[1]

归结为一线:

python -c "import boto.utils; print boto.utils.get_instance_metadata()['local-hostname'].split('.')[1]"

除了local_hostname之外,您还可以使用public_hostname,或者:

boto.utils.get_instance_metadata()['placement']['availability-zone'][:-1]

我看到的所有较新版本的boto都可以让您直接调用键“ instance_id”。我做了相关的建议修改。
saccharine

8
inst_id = boto.utils.get_instance_metadata()['instance-id']
atisman 2014年

您确实意识到这获得了实例所在的区域,而不是问题所要求的instance-id,对吗?
LukeGT 2015年

2
对于任何想知道的人,它都在boto中,但尚未在boto3中。有关使用urllib的解决方法,请参见stackoverflow.com/a/33733852github.com/boto/boto3/issues/313 FWIW上有一个开放的功能请求,JS SDK也具有以下功能:docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/… 使用new AWS.MetadataService().request('instance-id',function(error,data) { myInstanceId = data; })
Armadillo Jim

20

对于所有ec2机器,可以在文件中找到instance-id:

    /var/lib/cloud/data/instance-id

您还可以通过运行以下命令来获取实例ID:

    ec2metadata --instance-id

2
这是一个非常干净的解决方案,不需要HTTP请求。
尤里(Yuri)

实际上,可能的最佳答案
Shlublu

1
很好的答案,但是我在文档中找不到参考。请问您的参考是什么?令人担心的是,如果我们要在生产中运行此代码,我们怎么知道它将来不会更改?
shaya ajzner

可能是所有linux ec2机器,但绝对不是所有 ec2机器。Windows上没有这样的文件。 C:\ProgramData\Amazon\EC2-Windows\Launch\Log\Ec2Launch.log包含实例ID,但还包含很多其他垃圾。
詹姆斯

14

请参阅此帖子 -请注意,给定URL中的IP地址是常量(起初我很困惑),但是返回的数据特定于您的实例。


链接对我来说是404级
重新浏览

在下面查看@DEtDev的答案;我的答案很旧,看起来链接已被删除。
gareth_bowles

10

对于Ruby:

require 'rubygems'
require 'aws-sdk'
require 'net/http'

metadata_endpoint = 'http://169.254.169.254/latest/meta-data/'
instance_id = Net::HTTP.get( URI.parse( metadata_endpoint + 'instance-id' ) )

ec2 = AWS::EC2.new()
instance = ec2.instances[instance_id]

1
WTF家伙?!你偷了我的编辑!stackoverflow.com/review/suggested-edits/4035074
kixorz 2014年

3
抱歉。不知道怎么说“这是一个很好的编辑。我是OP。接受这一点”。
凯文·迈尔

10

更现代的解决方案。

从Amazon Linux,已经安装了ec2-metadata命令。

从终端

ec2-metadata -help

会给你可用的选择

ec2-metadata -i

将返回

instance-id: yourid

1
比依靠伪IP好得多
Mike D

ec2-metadata与您的motd文档结合在这里:coderwall.com/p/hr_9pw/motds-on-amazon-amis
Mike D

2
在Ubuntu映像中,命令为“ ec2metadata --instance-id”,将仅返回实例ID值
AlbertoMegía16


9

您可以尝试以下方法:

#!/bin/bash
aws_instance=$(wget -q -O- http://169.254.169.254/latest/meta-data/instance-id)
aws_region=$(wget -q -O- http://169.254.169.254/latest/meta-data/hostname)
aws_region=${aws_region#*.}
aws_region=${aws_region%%.*}
aws_zone=`ec2-describe-instances $aws_instance --region $aws_region`
aws_zone=`expr match "$aws_zone" ".*\($aws_region[a-z]\)"`

8

我为http api中的EC2元数据编写的c#.net类。我将根据需要使用功能进行构建。如果愿意,可以运行它。

using Amazon;
using System.Net;

namespace AT.AWS
{
    public static class HttpMetaDataAPI
    {
        public static bool TryGetPublicIP(out string publicIP)
        {
            return TryGetMetaData("public-ipv4", out publicIP);
        }
        public static bool TryGetPrivateIP(out string privateIP)
        {
            return TryGetMetaData("local-ipv4", out privateIP);
        }
        public static bool TryGetAvailabilityZone(out string availabilityZone)
        {
            return TryGetMetaData("placement/availability-zone", out availabilityZone);
        }

        /// <summary>
        /// Gets the url of a given AWS service, according to the name of the required service and the AWS Region that this machine is in
        /// </summary>
        /// <param name="serviceName">The service we are seeking (such as ec2, rds etc)</param>
        /// <remarks>Each AWS service has a different endpoint url for each region</remarks>
        /// <returns>True if the operation was succesful, otherwise false</returns>
        public static bool TryGetServiceEndpointUrl(string serviceName, out string serviceEndpointStringUrl)
        {
            // start by figuring out what region this instance is in.
            RegionEndpoint endpoint;
            if (TryGetRegionEndpoint(out endpoint))
            {
                // now that we know the region, we can get details about the requested service in that region
                var details = endpoint.GetEndpointForService(serviceName);
                serviceEndpointStringUrl = (details.HTTPS ? "https://" : "http://") + details.Hostname;
                return true;
            }
            // satisfy the compiler by assigning a value to serviceEndpointStringUrl
            serviceEndpointStringUrl = null;
            return false;
        }
        public static bool TryGetRegionEndpoint(out RegionEndpoint endpoint)
        {
            // we can get figure out the region end point from the availability zone
            // that this instance is in, so we start by getting the availability zone:
            string availabilityZone;
            if (TryGetAvailabilityZone(out availabilityZone))
            {
                // name of the availability zone is <nameOfRegionEndpoint>[a|b|c etc]
                // so just take the name of the availability zone and chop off the last letter
                var nameOfRegionEndpoint = availabilityZone.Substring(0, availabilityZone.Length - 1);
                endpoint = RegionEndpoint.GetBySystemName(nameOfRegionEndpoint);
                return true;
            }
            // satisfy the compiler by assigning a value to endpoint
            endpoint = RegionEndpoint.USWest2;
            return false;
        }
        /// <summary>
        /// Downloads instance metadata
        /// </summary>
        /// <returns>True if the operation was successful, false otherwise</returns>
        /// <remarks>The operation will be unsuccessful if the machine running this code is not an AWS EC2 machine.</remarks>
        static bool TryGetMetaData(string name, out string result)
        {
            result = null;
            try { result = new WebClient().DownloadString("http://169.254.169.254/latest/meta-data/" + name); return true; }
            catch { return false; }
        }

/************************************************************
 * MetaData keys.
 *   Use these keys to write more functions as you need them
 * **********************************************************
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
hostname
instance-action
instance-id
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups
*************************************************************/
    }
}

7

最新的Java SDK具有EC2MetadataUtils

在Java中:

import com.amazonaws.util.EC2MetadataUtils;
String myId = EC2MetadataUtils.getInstanceId();

在Scala中:

import com.amazonaws.util.EC2MetadataUtils
val myid = EC2MetadataUtils.getInstanceId

5

对于C ++(使用cURL):

    #include <curl/curl.h>

    //// cURL to string
    size_t curl_to_str(void *contents, size_t size, size_t nmemb, void *userp) {
        ((std::string*)userp)->append((char*)contents, size * nmemb);
        return size * nmemb;
    };

    //// Read Instance-id 
    curl_global_init(CURL_GLOBAL_ALL); // Initialize cURL
    CURL *curl; // cURL handler
    CURLcode res_code; // Result
    string response;
    curl = curl_easy_init(); // Initialize handler
    curl_easy_setopt(curl, CURLOPT_URL, "http://169.254.169.254/latest/meta-data/instance-id");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_to_str);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    res_code = curl_easy_perform(curl); // Perform cURL
    if (res_code != CURLE_OK) { }; // Error
    curl_easy_cleanup(curl); // Cleanup handler
    curl_global_cleanup(); // Cleanup cURL

3

只需检查var/lib/cloud/instance符号链接,它应该指向您的实例ID /var/lib/cloud/instances/{instance-id}在哪里{instance_id}


1
我不会用这个。您最好使用批准的HTTP请求来获取元数据。
荒木大辅(Daisuke Aramaki)

3

如果您希望在python中获取所有实例ID列表,请使用以下代码:

import boto3

ec2=boto3.client('ec2')
instance_information = ec2.describe_instances()

for reservation in instance_information['Reservations']:
   for instance in reservation['Instances']:
      print(instance['InstanceId'])

2

FWIW我编写了一个FUSE文件系统来提供对EC2元数据服务的访问:https : //bitbucket.org/dgc/ec2mdfs。我在所有自定义AMI上运行此命令。它允许我使用以下成语:cat / ec2 / meta-data / ami-id


2

在Go中,您可以使用goamz包

import (
    "github.com/mitchellh/goamz/aws"
    "log"
)

func getId() (id string) {
    idBytes, err := aws.GetMetaData("instance-id")
    if err != nil {
        log.Fatalf("Error getting instance-id: %v.", err)
    }

    id = string(idBytes)

    return id
}

这是 GetMetaData源。


1

在您提到用户为root的问题中,我应该提到的一件事是实例ID不依赖于用户。

对于Node开发人员,

var meta  = new AWS.MetadataService();

meta.request("/latest/meta-data/instance-id", function(err, data){
    console.log(data);
});


0

您可以通过传递元数据参数来发出HTTP请求以获取任何元数据。

curl http://169.254.169.254/latest/meta-data/instance-id

要么

wget -q -O - http://169.254.169.254/latest/meta-data/instance-id

您无需为获取元数据和用户数据的HTTP请求付费。

其他

您可以使用EC2实例元数据查询工具,这是一个简单的bash脚本,使用curl可以从正在运行的EC2实例中查询EC2实例元数据,如文档中所述。

下载工具:

$ wget http://s3.amazonaws.com/ec2metadata/ec2-metadata

现在运行命令以获取所需的数据。

$ec2metadata -i

参考:

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

https://aws.amazon.com/items/1825?externalID=1825

乐意效劳.. :)


0

PHP的替代方法:

$instance = json_decode(file_get_contents('http://169.254.169.254/latest/dynamic/instance-identity/document'),true);
$id = $instance['instanceId'];
print_r($instance);

这将提供有关实例的大量数据,所有数据都很好地打包在一个数组中,没有外部依赖性。因为这对我来说从来没有失败或延迟过,所以这样做应该是安全的,否则我会选择curl()


0

对于PHP:

$instance = json_decode(file_get_contents('http://169.254.169.254/latest/dynamic/instance-identity/document));
$id = $instance['instanceId'];

根据@John编辑


但是,如果您在PHP中具有curl和本机函数,为什么还要为此目的使用GuzzeHttp?
约翰

这是我的偏爱。我在许多其他事情上都使用了guzzle,这也是许多其他软件包的常见先决条件。
海滩小屋

$ instance = json_decode(file_get_contents(' 169.254.169.254/latest/dynamic/instance-identity / ...); $ id = $ instance ['instanceId'];我知道Guzzle广泛存在,我自己从未碰过它。一个简单的任务,我会提供最简单的方法
约翰·约翰·


0

通过执行以下命令,EC2实例本身可以访问与EC2资源相关的所有元数据:

网址:

http://169.254.169.254/<api-version>/meta-data/<metadata-requested>

对于您的情况:“ 请求元数据 ”应为instance-id,“ api-version ”通常是可以使用的最新版本

附加说明:您还可以使用上述命令获取与以下EC2属性相关的信息。

ami-id,ami-launch-index,ami-manifest-path,block-device-mapping /,主机名,iam /,实例操作,instance-id,instance-type,local-hostname,local-ipv4,mac,指标/,网络/,放置位置/,配置文件,公共主机名,公共IPV4,公共密钥/,预留ID,安全组,服务/,

有关更多详细信息,请单击以下链接:https : //docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html


0

对于Windows实例:

(wget http://169.254.169.254/latest/meta-data/instance-id).Content

要么

(ConvertFrom-Json (wget http://169.254.169.254/latest/dynamic/instance-identity/document).Content).instanceId

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.