Je voudrais exécuter des scripts sur des hôtes qui sont des instances EC2 mais je ne sais pas comment être sûr que l'hôte est vraiment une instance EC2.
J'ai fait quelques tests, mais ce n'est pas suffisant:
Eh bien, en fait, il existe un moyen très simple de détecter si l'hôte est une instance EC2: vérifiez la recherche inversée de votre adresse IP publique. Les revers EC2 sont assez difficiles à manquer.
De plus, si vous ne l'avez pas modifié, le nom d'hôte devrait être votre inverse, ce qui le rend encore plus facile à repérer.
Vous pouvez également utiliser l '"IP magique" dont vous avez parlé, car c'est en effet la manière standard d'obtenir des balises d'instance EC2, cependant, si vous n'êtes pas sur un réseau EC2, vous devrez attendre un délai d'attente, ce qui n'est généralement pas le cas. souhaitable...
Si ces méthodes ne suffisent pas, faites simplement un whois de votre IP et vérifiez si vous êtes à l'intérieur et le bloc IP Amazon EC2.
EDIT: Vous pouvez utiliser ce petit bit Shell:
#!/bin/bash
LOCAL_HOSTNAME=$(hostname -d)
if [[ ${LOCAL_HOSTNAME} =~ .*\.amazonaws\.com ]]
then
echo "This is an EC2 instance"
else
echo "This is not an EC2 instance, or a reverse-customized one"
fi
Attention cependant, [[est un bashisme. Vous pouvez également utiliser un Python ou Perl uniline, YMMV.
Changement de la réponse de Hannes pour éviter les messages d'erreur et inclure un exemple d'utilisation dans le script:
if [ -f /sys/hypervisor/uuid ] && [ `head -c 3 /sys/hypervisor/uuid` == ec2 ]; then
echo yes
else
echo no
fi
Cela ne fonctionne pas dans les instances Windows. L'avantage par rapport à la boucle est qu'elle est presque instantanée sur EC2 et non EC2.
pdate: Pour les nouvelles instances C5/M5, utilisez le fichier /sys/devices/virtual/dmi/id/product_uuid
à la place et vérifiez EC2
au lieu de ec2
. (Merci à Josh et Saumitra dans les commentaires pour avoir mentionné cela)
Tout d'abord, j'ai ressenti le besoin de poster une nouvelle réponse en raison des problèmes subtils suivants avec les réponses existantes, et après avoir reçu une question sur mon commentaire sur la réponse de @ qwertzguy . Voici les problèmes avec les réponses actuelles:
hostname -d
, Qui est utilisé pour le DNS interne, rien avec "amazonaws.com" dedans.)instance-data.ec2.internal
Peut ne pas fonctionner. Sur une instance Ubuntu EC2 VPC sur laquelle je viens de tester, je vois: $ curl http://instance-data.ec2.internal curl: (6) Could not resolve Host: instance-data.ec2.internal
ce qui ferait que le code s'appuyant sur cette méthode conclurait à tort qu'il n'est pas sur EC2!dmidecode
de @tamale peut fonctionner, mais dépend de vous a.) Ayant dmidecode
disponible sur votre instance, et b.) Ayant root ou Sudo
capacité sans mot de passe à partir de votre code.bios_version
De 1.0
. Ce fichier n'est pas du tout documenté sur le document d'Amazon , donc je ne m'y fierais vraiment pas.whois
sur le résultat est problématique à plusieurs niveaux. Notez que l'URL suggérée dans cette réponse est une page 404 en ce moment! Même si vous avez trouvé un service tiers qui a fonctionné, il serait relativement très lent (par rapport à la vérification locale d'un fichier) et éventuellement des problèmes de limitation de débit ou des problèmes de réseau, ou peut-être que votre instance EC2 n'a même pas accès au réseau extérieur.-m
Ou --max-time
Pour boucler pour éviter qu'il ne se bloque pendant très longtemps, en particulier sur une instance non EC2 où cette adresse peut conduire à nulle part et se bloquer (comme dans @ réponse algal ).De plus, je ne vois pas que quelqu'un ait mentionné documenté par Amazon repli de la vérification du fichier (possible) /sys/devices/virtual/dmi/id/product_uuid
.
Qui savait que déterminer si vous utilisez EC2 pouvait être si compliqué?! OK, maintenant que nous avons (la plupart) des problèmes avec les approches répertoriées, voici un extrait de bash suggéré pour vérifier si vous exécutez sur EC2. Je pense que cela devrait fonctionner généralement sur presque toutes les instances Linux, les instances Windows sont un exercice pour le lecteur.
#!/bin/bash
# This first, simple check will work for many older instance types.
if [ -f /sys/hypervisor/uuid ]; then
# File should be readable by non-root users.
if [ `head -c 3 /sys/hypervisor/uuid` == "ec2" ]; then
echo yes
else
echo no
fi
# This check will work on newer m5/c5 instances, but only if you have root!
Elif [ -r /sys/devices/virtual/dmi/id/product_uuid ]; then
# If the file exists AND is readable by us, we can rely on it.
if [ `head -c 3 /sys/devices/virtual/dmi/id/product_uuid` == "EC2" ]; then
echo yes
else
echo no
fi
else
# Fallback check of http://169.254.169.254/. If we wanted to be REALLY
# authoritative, we could follow Amazon's suggestions for cryptographically
# verifying their signature, see here:
# https://docs.aws.Amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
# but this is almost certainly overkill for this purpose (and the above
# checks of "EC2" prefixes have a higher false positive potential, anyway).
if $(curl -s -m 5 http://169.254.169.254/latest/dynamic/instance-identity/document | grep -q availabilityZone) ; then
echo yes
else
echo no
fi
fi
De toute évidence, vous pouvez étendre cela avec encore plus de contrôles de secours, et inclure la paranoïa sur la gestion, par exemple. un faux positif de /sys/hypervisor/uuid
se produisant pour commencer par "ec2" par hasard et ainsi de suite. Mais c'est une bonne solution à des fins d'illustration et probablement presque tous les cas d'utilisation non pathologiques.
[†] Récupéré cette explication du support AWS concernant la modification des instances c5/m5:
Les instances C5 et M5 utilisent un nouvelle pile d'hyperviseur et les pilotes de noyau associés ne créent pas de fichiers dans sysfs (qui est monté sur/sys) comme les pilotes Xen tilisés par l'autre/ancien) les types d'instances le font . La meilleure façon de détecter si le système d'exploitation s'exécute sur une instance EC2 est de prendre en compte les différentes possibilités répertoriées dans la documentation que vous avez liée .
Recherchez les métadonnées par le nom de domaine interne EC2 au lieu d'IP, ce qui retournera un échec DNS rapide si vous n'êtes pas sur EC2, et évite les conflits IP ou les problèmes de routage:
curl -s http://instance-data.ec2.internal && echo "EC2 instance!" || echo "Non EC2 instance!"
Sur certaines distributions, les systèmes très basiques ou très tôt aux étapes d'installation curl n'est pas disponible. En utilisant wget à la place:
wget -q http://instance-data.ec2.internal && echo "EC2 instance!" || echo "Non EC2 instance!"
Si le but est de dire s'il s'agit d'une instance EC2 OR un autre type d'instance cloud, comme google, alors dmidecode
fonctionne très bien et aucun réseau n'est requis. J'aime ça vs certaines des autres approches, car le chemin de l'URL des métadonnées est différent pour EC2 et GCE.
# From a google compute VM
$ Sudo dmidecode -s bios-version
Google
# From an Amazon ec2 VM
$ Sudo dmidecode -s bios-version
4.2.Amazon
Les noms d'hôtes sont susceptibles de changer, exécutez un whois contre votre IP publique:
if [[ ! -z $(whois $(curl -s shtuff.it/myip/short) | grep -i Amazon) ]]; then
echo "I'm Amazon"
else
echo "I'm not Amazon"
fi
ou appuyez sur l'URL des métadonnées AWS
if [[ ! -z $(curl -s http://169.254.169.254/1.0/) ]]; then
echo "I'm Amazon"
else
echo "I'm not Amazon"
fi
Cela fonctionne également bien pour les hôtes Linux dans ec2 et ne nécessite pas le réseau et les délais d'attente associés:
grep -q Amazon /sys/devices/virtual/dmi/id/bios_version
Cela fonctionne, car Amazon définit cette entrée comme suit:
$ cat /sys/devices/virtual/dmi/id/bios_version 4.2.Amazon
Réponse rapide:
if [[ -f /sys/devices/virtual/dmi/id/product_uuid ]] && \
grep -q "^EC2" /sys/devices/virtual/dmi/id/product_uuid
then
echo "IS EC2"
else
echo "NOT EC2"
fi
J'utilisais l'une des réponses publiées ici depuis plus d'un an - mais cela ne fonctionne pas sur les nouveaux types d'instances "c5" (je travaille actuellement sur la mise à niveau à partir de "c4").
J'aime cette solution car elle semble la moins susceptible de se casser à l'avenir.
Sur les types d'instances plus anciens et les plus récents, ce fichier est présent et commence par "EC2". J'ai vérifié sur Ubuntu fonctionnant sur VirtualBox (que je dois également prendre en charge) et il contient la chaîne "VirtualBox".
Comme l'a noté une affiche précédente (mais c'était facile à manquer) - il existe une documentation Amazon sur les façons de le faire - qui comprend ma réponse.
https://docs.aws.Amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
test -f /sys/hypervisor/uuid -a `head -c 3 /sys/hypervisor/uuid` == ec2 && echo yes
mais je ne sais pas comment c'est portable à travers les distributions.
Vous pouvez peut-être utiliser "facter":
"Facter est une bibliothèque multiplateforme permettant de récupérer des faits simples sur le système d'exploitation, comme le système d'exploitation, la distribution Linux ou l'adresse MAC."
http://www.puppetlabs.com/puppet/related-projects/facter/
Par exemple, si nous regardons le fait ec2 (facter-1.6.12/lib/facter/ec2.rb):
require 'facter/util/ec2'
require 'open-uri'
def metadata(id = "")
open("http://169.254.169.254/2008-02-01/meta-data/#{id||=''}").read.
split("\n").each do |o|
key = "#{id}#{o.gsub(/\=.*$/, '/')}"
if key[-1..-1] != '/'
value = open("http://169.254.169.254/2008-02-01/meta-data/#{key}").read.
split("\n")
symbol = "ec2_#{key.gsub(/\-|\//, '_')}".to_sym
Facter.add(symbol) { setcode { value.join(',') } }
else
metadata(key)
end
end
end
def userdata()
begin
value = open("http://169.254.169.254/2008-02-01/user-data/").read.split
Facter.add(:ec2_userdata) { setcode { value } }
rescue OpenURI::HTTPError
end
end
if (Facter::Util::EC2.has_euca_mac? || Facter::Util::EC2.has_openstack_mac? ||
Facter::Util::EC2.has_ec2_arp?) && Facter::Util::EC2.can_connect?
metadata
userdata
else
Facter.debug "Not an EC2 Host"
end
Si vous avez installé curl, cette commande retournera 0 si vous exécutez dans EC2 et non nulle si vous n'êtes pas:
curl --max-time 3 http://169.254.169.254/latest/meta-data/AMI-id 2>/dev/null 1>/dev/null`
Il essaie d'extraire les métadonnées EC2 déclarant l'AMI-ID. Si cela ne réussit pas après 3 secondes, il suppose qu'il ne fonctionne pas dans EC2.
Un peu tard pour cette fête, cependant je suis tombé sur ce post et j'ai trouvé cette documentation AWS:
Pour une méthode définitive et cryptographiquement vérifiée d'identification d'une instance EC2, vérifiez le document d'identité d'instance, y compris sa signature. Ces documents sont disponibles sur chaque instance EC2 à l'adresse locale non routable http://169.254.169.254/latest/dynamic/instance-identity/
https://docs.aws.Amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
Bien sûr, cela nécessite la surcharge du réseau, bien que vous puissiez définir le délai d'expiration de la boucle comme suit:
curl -s --connect-timeout 5 http://169.254.169.254/latest/dynamic/instance-identity/
Cela définit le délai d'attente à 5 secondes.