Comment obtenir l'ID d'instance à partir d'une instance ec2?


Réponses:


534

Voir la documentation EC2 sur le sujet .

Courir:

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

Si vous avez besoin d'un accès programmatique à l'ID d'instance à partir d'un script,

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: $?\"`"

Un exemple d'une utilisation plus avancée (récupérer l'ID d'instance ainsi que la zone et la région de disponibilité, etc.):

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:'`"

Vous pouvez également utiliser curlau lieu de wget, selon ce qui est installé sur votre plate-forme.


@Leopd, vous savez évidemment mieux que les gens d'Amazon qui ont implémenté EC2 et écrit les documents. Soit dit en passant, personne ne vous empêche de créer un alias pour 169.254.169.254dans /etc/hostssi cela vous fait sentir plus en sécurité, si vous ... soins.
vladr

2
Et dans le SDK Java? Y a-t-il un moyen d'obtenir cela sans avoir à faire un GET sur cette URL? Semble étrange si ce n'est pas dans le SDK
Kevin M

1
Très utile, merci. Pour ceux qui tentent de trouver l'expression régulière dans la dernière ligne, voici ce que j'ai trouvé: à la fin de la ligne ( $), trouvez un ou plusieurs chiffres suivis par une ou plusieurs lettres minuscules. Remplacez par les chiffres uniquement. ( Entre parenthèses Backslash + DITES sed de se rappeler une sous - chaîne, qui est rappelée avec \1.) Je trouve cela un peu plus facile à lire - les seuls antislashs sont celles requises par sed: EC2_REGION="$(echo "$EC2_AVAIL_ZONE" | sed -e 's:\([0-9][0-9]*\)[a-z]*$:\1:')".
Mark Berry

66
Vous pouvez éliminer les nombres magiques en utilisant http://instance-data/au lieu de169.254.169.254
Jay P.

20
J'ai vérifié cela le 2016-02-04. J'ai trouvé que le nom d'hôte "instance-data" n'est (a) pas répertorié dans cette documentation, et (b) ne fonctionne pas (pour moi) sur un nouvel hôte EC2. La documentation - docs.aws.amazon.com/AWSEC2/latest/UserGuide/… - ne mentionne que l'adresse 169.254 et ne fait aucune mention du nom d'hôte "instance-data". c'est à dire utiliser 169.254.169.254/latest/meta-data/instance-id
JDS

138

Sur les AMI Amazon Linux, vous pouvez faire:

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

Ou, sur Ubuntu et quelques autres versions de Linux, ec2metadata --instance-id(Cette commande peut ne pas être installée par défaut sur Ubuntu, mais vous pouvez l'ajouter avec sudo apt-get install cloud-utils)

Comme son nom l'indique, vous pouvez également utiliser la commande pour obtenir d'autres métadonnées utiles.


3
Si vous songez à l'utiliser, cet article vaut la peine d'être lu (tldr: les outils de ligne de commande sont-ils java, et java a un long temps de démarrage)
James

La meilleure réponse
Chuck Le Butt

@Marc Nope. Non -après ec2. Il estec2metadata --instance-id
Dawny33

5
La commande est différente sur différents Linux: sur Amazon Linux c'est ec2-metadata, sur Ubuntu cela semble être le cas ec2metadata.
James

James, j'ai trouvé les mêmes ec2metadata pour travailler sur Ubuntu.
pyAddict

69

Sur Ubuntu, vous pouvez:

sudo apt-get install cloud-utils

Et puis vous pouvez:

EC2_INSTANCE_ID=$(ec2metadata --instance-id)

Vous pouvez obtenir la plupart des métadonnées associées à l'instance de cette façon:

ec2metadata --help
Syntaxe: / usr / bin / ec2metadata [options]

Recherchez et affichez les métadonnées EC2.

Si aucune option n'est fournie, toutes les options seront affichées

Options:
    -h --help afficher cette aide

    --kernel-id affiche l'id du noyau
    --ramdisk-id affiche l'id du ramdisk
    --reservation-id affiche l'id de réservation

    --ami-id affiche l'identifiant de l'ami
    --ami-launch-index afficher l'index de lancement ami
    --ami-manifest-path affiche le chemin du manifeste ami
    --ancestor-ami-ids affiche l'identifiant de l'ancêtre ami
    --product-codes afficher les codes de produit associés ami
    - zone de disponibilité afficher la zone de placement ami

    --instance-id affiche l'identifiant de l'instance
    --instance-type affiche le type d'instance

    --local-hostname affiche le nom d'hôte local
    --public-hostname affiche le nom d'hôte public

    --local-ipv4 affiche l'adresse ip locale ipv4
    --public-ipv4 affiche l'adresse IP publique ipv4

    --block-device-mapping affiche l'ID de périphérique de bloc
    --security-groups affiche les groupes de sécurité

    --mac affiche l'adresse mac de l'instance
    --profile affiche le profil d'instance
    --instance-action affiche l'instance-action

    --public-keys affiche les clés publiques openssh
    --user-data affiche les données utilisateur (pas réellement les métadonnées)

Sous Ubuntu, lucid apt-get installrécupère la version 0.11-0ubuntu1 qui ne contient pas cet utilitaire. Il a été ajouté au package juste après .
Aryeh Leib Taurog

7
Le package cloud-utils est inclus par défaut sur l'AMI Ubuntu 12.04.1 LTS Cluster Compute.
Andrew

2
cloud-utils semble aussi être dans RHEL / CentOS
Craig Ringer

50

Utilisez l' /dynamic/instance-identity/documentURL si vous devez également interroger plus que votre ID d'instance.

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

Cela vous donnera des données JSON comme celle-ci - avec une seule demande .

{
    "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 pour afficher tous les détails, y compris instanceType en un seul appel
Luksurious

1
+1 pour avoir une ligne assez standard (wget uniquement) et de travail (l'URL de données d'instance ne fonctionnait pas pour moi sur amazon linux), sans installer de packages supplémentaires juste pour cette tâche simple.
tishma

27

Pour les .NETpersonnes:

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

24

sur AWS Linux:

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

Production:

i-33400429

Utilisation de variables:

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

Manière propre et concise. Travail
prêt à l'emploi

22

Pour les personnes PowerShell:

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

4
Commandet juste différent:$instanceId=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id').Content
Sumit Murari

Invoke-WebRequest ne fonctionne pas toujours lors de l'exécution d'un script sur ladite instance EC2 avec une commande d'envoi ssm (ou Send-SSMCommand). Cela ne dit pas vraiment dans les documents . Peut-être que ce n'est pas asynchrone ... ce qui serait bizarre. Mais l'option de stefancaunter fonctionne jusqu'à présent sans problème.
J-Roel

22

Pour Python:

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

qui se résume au one-liner:

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

Au lieu de local_hostname, vous pouvez également utiliser public_hostname, ou:

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

Toutes les nouvelles versions de boto que je vois vous permettent d'appeler directement la clé "instance_id". J'ai apporté les modifications suggérées pertinentes.
saccharine

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

Vous vous rendez compte que cela obtient la région dans laquelle l'instance se trouve, pas l'ID d'instance comme la question posée, non?
LukeGT

2
Pour tous ceux qui se demandent, c'est en boto mais pas encore en boto3. Voir stackoverflow.com/a/33733852 pour une solution de contournement utilisant urllib. Il y a une demande de fonctionnalité ouverte sur github.com/boto/boto3/issues/313 FWIW, le SDK JS a également ceci: docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/… Utilisationnew AWS.MetadataService().request('instance-id',function(error,data) { myInstanceId = data; })
Armadillo Jim

20

Pour toutes les machines ec2, l'ID-instance peut être trouvé dans le fichier:

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

Vous pouvez également obtenir l'ID d'instance en exécutant la commande suivante:

    ec2metadata --instance-id

2
Il s'agit d'une solution très propre, ne nécessitant pas de requête HTTP.
Yuri

La meilleure réponse possible en fait
Shlublu

1
Excellente réponse mais je n'ai pas trouvé de référence pour cela dans la documentation. puis-je vous demander quelle est votre référence? Le souci est que si nous allons exécuter ce code en production, comment savons-nous qu'il ne changera pas à l'avenir?
shaya ajzner

Toutes les machines linux ec2, peut-être, mais certainement pas toutes les machines ec2. Aucun fichier de ce type sous Windows. C:\ProgramData\Amazon\EC2-Windows\Launch\Log\Ec2Launch.logcontient l'ID d'instance, mais a également beaucoup d'autres ordures.
James

14

Voir cet article - notez que l'adresse IP dans l'URL donnée est constante (ce qui m'a dérouté au début), mais les données retournées sont spécifiques à votre instance.


Link est 404ing pour moi
repalviglator

Consultez la réponse de @ DEtDev ci-dessous; ma réponse est assez ancienne et il semble que le lien ait été supprimé.
gareth_bowles

10

Pour 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
Les gars de la WTF?! Tu as volé mon montage! stackoverflow.com/review/suggested-edits/4035074
kixorz

3
Désolé. Je ne savais pas comment dire "C'est un bon montage. Je suis l'OP. Acceptez ceci".
Kevin Meyer

10

Une solution plus contemporaine.

Depuis Amazon Linux, la commande ec2-metadata est déjà installée.

Depuis le terminal

ec2-metadata -help

Vous donnera les options disponibles

ec2-metadata -i

reviendra

instance-id: yourid

1
bien mieux que selon la pseudo ip
Mike D

combinez ec2-metadataavec vos motddocuments ici: coderwall.com/p/hr_9pw/motds-on-amazon-amis
Mike D

2
Dans l'image Ubuntu, la commande est "ec2metadata --instance-id" et ne renverra que la valeur d'ID d'instance
Alberto Megía


9

Vous pouvez essayer ceci:

#!/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

Une classe c # .net que j'ai écrite pour les métadonnées EC2 à partir de l'API http. Je vais le construire avec des fonctionnalités au besoin. Vous pouvez courir avec si vous l'aimez.

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

Le dernier SDK Java a EC2MetadataUtils:

En Java:

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

À Scala:

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

5

Pour C ++ (en utilisant 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

Vérifiez simplement le var/lib/cloud/instancelien symbolique, il devrait indiquer /var/lib/cloud/instances/{instance-id}où se {instance_id}trouve votre ID d'instance.


1
Je n'utiliserais pas ça. Il vaut mieux utiliser la demande HTTP approuvée pour obtenir les métadonnées.
Daisuke Aramaki

3

Si vous souhaitez obtenir la liste des identifiants de toutes les instances en python, voici le code:

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 J'ai écrit un système de fichiers FUSE pour donner accès au service de métadonnées EC2: https://bitbucket.org/dgc/ec2mdfs . Je l'exécute sur toutes les AMI personnalisées; cela me permet d'utiliser cet idiome: cat / ec2 / meta-data / ami-id


2

Dans Go, vous pouvez utiliser le package 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
}

Voici la source GetMetaData.


1

Dans la question que vous avez mentionnée en tant qu'utilisateur root, une chose que je dois mentionner est que l'ID d'instance ne dépend pas de l'utilisateur.

Pour les développeurs de nœuds ,

var meta  = new AWS.MetadataService();

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

1

Pour obtenir les métadonnées d'instance, utilisez

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

0

Vous pouvez simplement faire une requête HTTP pour obtenir des métadonnées en passant les paramètres de vos métadonnées.

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

ou

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

Vous ne serez pas facturé pour les demandes HTTP pour obtenir les métadonnées et les données utilisateur.

Autre

Vous pouvez utiliser l'outil de requête de métadonnées d'instance EC2 qui est un simple script bash qui utilise curl pour interroger les métadonnées d'instance EC2 à partir d'une instance EC2 en cours d'exécution, comme indiqué dans la documentation.

Téléchargez l'outil:

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

exécutez maintenant la commande pour obtenir les données requises.

$ec2metadata -i

Référer:

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

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

Heureux d'aider.. :)


0

Approche alternative pour PHP:

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

Cela fournira beaucoup de données sur l'instance, toutes joliment emballées dans un tableau, sans dépendances externes. Comme c'est une demande qui n'a jamais échoué ou retardé pour moi, il devrait être prudent de le faire de cette façon, sinon j'irais pour curl ()


0

Pour PHP:

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

Modifier par @John


Mais pourquoi utiliseriez-vous GuzzeHttp à cette fin si vous avez des fonctions curl et natives en PHP?
John

C'est ma préférence. J'utilise guzzle pour beaucoup d'autres choses, c'est un prérequis commun pour de nombreux autres packages.
Beachhouse

$ instance = json_decode (file_get_contents (' 169.254.169.254/latest/dynamic/instance-identity/… ); $ id = $ instance [' instanceId ']; je sais que Guzzle est répandu, je ne l'ai jamais touché moi-même. une tâche simple, je fournirais l'approche la plus légère.
John


0

Toutes les métadonnées liées à la ressource EC2 sont accessibles par l'instance EC2 elle-même à l'aide de la commande suivante en cours d'exécution:

CURL:

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

Pour votre cas: " métadonnées demandées " doit être id-instance , " api-version " est généralement le dernier qui peut être utilisé.

Remarque supplémentaire: vous pouvez également obtenir des informations sur les attributs EC2 ci-dessous à l'aide de la commande ci-dessus.

ami-id, ami-launch-index, ami-manifest-path, block-device-mapping /, hostname, iam /, instance-action, instance-id, instance-type, local-hostname, local-ipv4, mac, métriques /, réseau /, emplacement /, profil, public-hostname, public-ipv4, public-keys /, reservation-id, security-groups, services /,

Pour plus de détails, veuillez suivre ce lien: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html


0

Pour une instance Windows:

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

ou

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.