Найти регион в экземпляре 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на основе комментариев


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

Должно ли это работать в любом регионе / аз (и на любом 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]$//'

6

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

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


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

1

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

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

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


1

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

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

REGION="$(wget -q -O - http://169.254.169.254/latest/meta-data/placement/region)"

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это старая, уже недействительная команда.)


Это может зависеть от выбранного вами типа виртуального ящика. Я придерживаюсь 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]')


0

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.