Найти регион в экземпляре EC2

131

Есть ли способ найти регион экземпляра внутри экземпляра?

Ищу что-то похожее на метод поиска идентификатора экземпляра .

Гэри Ричардсон
источник
8
Краткий ответ для тех, кому наплевать на все сценарии оболочки: получить зону доступности http://169.254.169.254/latest/meta-data/placement/availability-zoneи удалить последний символ.
Sarsaparilla
Для тех, кто читает пост в середине 2020 года, теперь вы можете использоватьhttp://169.254.169.254/latest/meta-data/placement/region
d4nyll

Ответы:

148

Этот URL-адрес ( http://169.254.169.254/latest/dynamic/instance-identity/document ), похоже, больше не работает. Я получаю 404, когда пытался его использовать. У меня есть следующий код, который, похоже, работает:

EC2_AVAIL_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed 's/[a-z]$//'`"

Надеюсь это поможет.

РЕДАКТИРОВАТЬ: улучшено sedна основе комментариев

dannosaur
источник
4
Это должно выполняться внутри инстанса EC2 и питаться от серверной части AWS. Он не будет работать больше нигде (в основном потому, что этот IP-адрес является APIPA). Также нет возможности получить эту информацию непосредственно из экземпляра без подключения к источнику метаданных. Это предполагает, что API 169.254.169.254 доступен, и ваш сценарий должен соответствующим образом обрабатывать сетевые сбои. ec2-metadataэто просто оболочка для этого API, но, по сути, делает то же самое.
dannosaur
1
Это что-то задокументировано? Вы можете объяснить, как вы это нашли?
meawoppl
2
Честно говоря, когда я придумал этот двухстрочный лайнер, я просто копался в API в поисках чего-нибудь, что можно было бы использовать для определения правильного региона. API метаданных AWS полностью задокументирован здесь: docs.aws.amazon.com/AWSEC2/latest/UserGuide/…
dannosaur
12
Гораздо более простая команда sed replace, чем та, которая предусмотрена для EC2_REGION:sed 's/[a-z]$//
threejeez
2
Если это в сценарии начальной загрузки, возможно, служба метаданных еще не создана - если это так, подождите и повторите попытку. Я видел, что после загрузки требуется 10-15 секунд, чтобы расположение метаданных стало доступным.
Vacri
81

Есть еще один способ добиться этого:

REGION=`curl http://169.254.169.254/latest/dynamic/instance-identity/document|grep region|awk -F\" '{print $4}'`

echo $REGION

us-east-1
mgarman
источник
Должно ли это работать в любом регионе / аз (и на любом AMI)? Я 404 - Not Foundпытаюсь перейти по GETэтому URL-адресу с компьютера в домене us-east-1a.
Adam Monsen
@AdamMonsen, возможно, это временная ошибка. Я на нас-восток-1а и отлично работает.
Флорин Андрей
Спасибо @FlorinAndrei. У меня тоже работает.
Adam Monsen
3
С jq:curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region
Yaron
4
С awk:curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | awk -F\" '/region/ {print $4}'
Ярон
39

Если вы согласны с использованием jq, вы можете запустить следующее:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq .region -r

Думаю, это самый чистый способ.

Илья Шер
источник
31
ec2-metadata --availability-zone | sed 's/.$//'

Для систем на базе Debian команда не должна содержать тире.

ec2metadata --availability-zone | sed 's/.$//'
Хосе Альбан
источник
6
Получить чистую строку только с названием региона:ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
nahsh 06
ec2-metadataпохоже, что это не то, что доступно по умолчанию - можете ли вы включить инструкции по установке?
Тим Мэлоун
23

Если вы хотите избежать регулярных выражений, вот однострочник, который вы можете сделать с помощью Python:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | python -c "import json,sys; print json.loads(sys.stdin.read())['region']"
Джэён Чун
источник
Этот ответ должен быть выше!
Костас Демирис
@KostasDemiris Я согласен, лучше читать значение из структуры JSON, чем из регулярного выражения.
lasec0203
1
Я согласен, что это лучший способ сделать это, если у вас не установлен jq. Вы действительно ожидаете, что AWS представит это как что-то вроде 169.254.169.254/latest/meta-data/placement/region ...
Krenair
17

Вы можете использовать метаданные ec2:

ec2-metadata -z | grep -Po "(us|sa|eu|ap)-(north|south|central)?(east|west)?-[0-9]+"
Даниэль Куппиц
источник
2
С этим, если вы в деле, eu-central-1вы облажались.
dannosaur
2
centralне существовало, когда я изначально написал свой ответ. Это добавлено сейчас.
Дэниел Куппиц
22
Сценарий, который ломается каждый раз, когда AWS добавляет новый регион, мне не кажется особенно сильным решением.
Райан Б. Линч
1
Вместо grep awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}'сохранятся только первые два компонента имени AZ.
dskrvk
@dskrvk Если вы просто сохраните первые два компонента, как вы распределите между ними eu-west-1, eu-west-2и eu-west-3(Также us-west-1и us-west-2) @OP: простое сопоставление '[a-z][a-z]-[a-z]*-[0-9][0-9]*'кажется более безопасным (это базовое регулярное выражение, его можно сделать короче с помощью расширенного RE). (Текущее регулярное выражение разбивается на caрегион, afрегионы и meрегион)
Герт ван ден Берг,
15

Самый простой, который я нашел до сих пор

 curl -s 169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/.$//'
Франческо Гуалацци
источник
1
Преимущество этого заключается в отсутствии зависимостей, отличных от значений по умолчанию, и это всего лишь одна строка.
Марк Стосберг
14

очень простой однострочник

export AVAILABILITY_ZONE=`wget -qO- http://instance-data/latest/meta-data/placement/availability-zone`
export REGION_ID=${AVAILABILITY_ZONE:0:${#AVAILABILITY_ZONE} - 1}
Рави Кумар
источник
4
Это две строчки
Christian
1
Но это не работает в регионе США-Запад-1. Возвращает curl: (6) Could not resolve host: instance-data; Name or service not knownошибку.
SK Venkat
1
@SKVenkat Это, вероятно, связано с настройками DNS вашего VPC ... Использование IP для метаданных-api кажется более безопасным (половина других ответов делает это)
Герт ван ден Берг,
@GertvandenBerg, я второй ..
СК Венкат
9

Если у вас установлен jq , вы также можете сделать это (вероятно, самый «изящный» метод) следующим образом:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -c -r .region

Это просто возвращает исходное значение «региона» без какой-либо красивой печати или другого форматирования. Ссылка: AWS Forum

Арбаб Назар
источник
7

Достать регион из зоны доступности, убрать последнюю букву из него.

ec2-metadata -z | awk '{print $2}' | sed 's/[a-z]$//'
mohrt
источник
6

Используйте JQ:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region
Spanky
источник
4

Это самое чистое решение, которое я нашел:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document |sed -n 's/  "region" : "\(.*\)"/\1/p'

Например,

export REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document |sed -n 's/  "region" : "\(.*\)"/\1/p')

  • Не выполняет вызов API, использует метаданные экземпляра EC2
  • Использует только curl и базовый sed, поэтому никакие зависимости от SDK или инструментов вряд ли будут установлены.
  • Не пытается проанализировать имя зоны доступности, поэтому не беспокойтесь, если AWS изменит формат имени AZ / региона
Келли Сетзер
источник
Да отлично, спасибо. Этот результат можно легко десериализовать в объект json.
dynamiclynk
Я получаю запятую в конце.
Craig
4

Благодаря https://unix.stackexchange.com/a/144330/135640 , с bash 4.2+ мы можем просто удалить последний символ из зоны доступности:

$ region=`curl -s 169.254.169.254/latest/meta-data/placement/availability-zone`
$ region=${region::-1}
$ echo $region
us-east-1

Это предполагает, что AWS продолжает использовать один символ для зон доступности, добавленных к региону.

Стив Янсен
источник
5
Нам всегда удавалось удалить последний символ в оболочке:region=${region%?}
Дэвид Джонс,
4

2, который работает, пока вы используете ec2.internal в качестве поискового домена:

az=$(curl -s http://instance-data/latest/meta-data/placement/availability-zone)
region=${az:0:${#az} - 1}
Гил Зеллнер
источник
4

Для всех, кто хочет сделать это с помощью старого доброго PowerShell

$var = (curl http://169.254.169.254/latest/dynamic/instance-identity/document | Select-String-Pattern "Zone" | ConvertFrom-Json | Select-Object -ExpandProperty "region")
echo $var
промозглый
источник
3

Или не делайте Ubuntu или этот инструмент обязательными, а просто выполните:

: "${EBS_VOLUME_AVAILABILITY_ZONE:=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)}"
: ${EBS_VOLUME_REGION:="${EBS_VOLUME_AVAILABILITY_ZONE%%*([![:digit:]])}"}
вялый
источник
2
Обратите внимание, что это работает только потому, что в настоящее время зона доступности - это всегда имя региона с добавленной к нему строчной буквой (например, регион - «us-west-1», зона - «us-west-1a»). Если Amazon когда-нибудь нарушит этот шаблон, приведенная выше логика перестанет работать.
Мэтт Сольнит
3

Если вы работаете с json - используйте правильные инструменты. jq очень мощный в этом случае.

# curl -s curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r '.region'
eu-west-1
Алан
источник
3

Это работает для eu-central-1, а также для различных буквенных зон. (У меня недостаточно репутации, чтобы ответить на ответ sed выше)

ec2-metadata --availability-zone | sed 's/[a-z]$//'
Тайлер Келлогг
источник
Должно быть ec2metadata --availability-zone | sed 's/.$//'(без тире)
Владимир Кондратьев
3

Если вы работаете в Windows, вы можете использовать эту однострочную оболочку PowerShell:

$region=(Invoke-RestMethod "http://169.254.169.254/latest/dynamic/instance-identity/document").region
CWA
источник
1

Также искал решение для поиска региона из экземпляра, и вот мое чистое решение Bash:

az=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
region=${az:0:${#az}-1}

если нет регионов, где AZ имеет более двух букв, о которых я не знаю.

Ajax
источник
1

В какой - то момент , так как это большинство из этих ответов были размещены, AWS сделал разумную вещь и реализован новый путь: latest/meta-data/placement/region.

Это означает, что получение региона должно быть таким же простым, как

REGION="$(wget -q -O - http://169.254.169.254/latest/meta-data/placement/region)"
SteveGoob
источник
0

Чтобы узнать информацию о EC2, в которую вы вошли, вы можете использовать инструмент ec2-metadata.

Вы можете установить инструмент, перейдя по этой ссылке. После установки инструмента вы можете запустить

# ec2-metadata -z

чтобы узнать регион.

Эти инструменты установлены с последними (10.10) образцами Ubuntu AMI,

Шеки
источник
4
Это неверно. ec2-metadata -zпоказывает только зону доступности, а не регион.
Мэтт Сольнит
0

Если вы хотите получить регион с помощью JS, это должно сработать:

meta.request("/latest/meta-data/placement/availability-zone",function(err,data){
        if(err)
                console.log(err);
        else{
                console.log(data);
                str = data.substring(0, data.length - 1);
                AWS.config.update({region:str});
                ec2 = new AWS.EC2();
            }
     });

Это было сопоставление, найденное из AWS DOCS, в ответ на вызов API метаданных, просто обрезать последний символ должно работать.

  eu-west-1a :eu-west-1
  eu-west-1b :eu-west-1
  eu-west-1c :eu-west-1
  us-east-1a :us-east-1
  us-east-1b :us-east-1
  us-east-1c :us-east-1
  us-east-1d :us-east-1
  ap-northeast-1a :ap-northeast-1
  ap-northeast-1b :ap-northeast-1
  us-west-1a :us-west-1
  us-west-1b :us-west-1
  us-west-1c :us-west-1
  ap-southeast-1a :ap-southeast-1
  ap-southeast-1b :ap-southeast-1
Сурья Пракаш Патель
источник
0

ec2metadata(без тире) - это текущая команда, которая предоставляет вам всю информацию о хостинге aws для вашего блока ec2. это самый элегантный и безопасный подход. ( ec2-metadataэто старая, уже недействительная команда.)

GViz
источник
Это может зависеть от выбранного вами типа виртуального ящика. Я придерживаюсь Linux.
GViz
0

Метод, использующий только egrep, который должен работать на большинстве запущенных экземпляров Linux без необходимости установки каких-либо дополнительных инструментов. Я проверил это по списку всех текущих регионов AWS, и все они совпадают.

curl http://169.254.169.254/latest/meta-data/placement/availability-zone | egrep -o '(\w)+-(\w)+-[0-9]'

Пояснение к REGEX:

  • "(\ w) +" Соответствует любому количеству букв
  • "-" соответствует только одному тире
  • «[0-9]» соответствует любому 1 числу

Если вы хотите, чтобы это было в переменной, выполните:

region=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone | egrep -o '(\w)+-(\w)+-[0-9]')

Chart96
источник
0

Для решения sed и curl похоже, что формат немного изменился. У меня работает

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | sed -n 's/ "region" : "\(.*\)"[,]/\1/p'
Denken
источник
-1

Вы можете получить регион экземпляра, используя этот запрос curl

$ curl http://169.254.169.254/latest/meta-data/placement/region
us-east-1
Артем Косенко
источник
Это просто дублированный ответ stackoverflow.com/a/62664161/3966682
d4nyll