Более чистый способ использовать выбор jq - PullRequest
0 голосов
/ 30 октября 2018

Фон моего вопроса загружен; но я хотел бы сосредоточиться только на части jq в этой текущей части (хотя, если бы вы могли помочь во всей ее полноте, это было бы очень приветствовано и оценено).

У меня есть спецификация Terraform, которую я успешно применил для создания группы автоматического масштабирования в AWS (в отношении инициализации Terraform я задам отдельный вопрос, если, возможно, есть лучший способ, чем то, что я делаю). Я хотел запустить некоторую подготовку в каждом из созданных экземпляров, и при этом я решил связать его с командой ansible.

Ansible, как вы, возможно, знаете, работает с файлом инвентаризации / хоста. Следовательно, мне нужно будет обновлять свой хост-файл каждый раз, когда AWS масштабируется или увеличивается, чтобы успешно выполнить следующую команду ANSIB ansible -i ./myansible.hostfile myawsinstances -a "reprovisioning_command" (которая сама по себе имеет другой набор проблем, tbd.)

Что касается создания файла ansible host, я получил то, что мне было нужно, с помощью следующей команды:

пример команды 1

aws ec2 describe-instances | jq .Reservations[].Instances[].PublicIpAddress | sed 's/"//g' | awk '{print "inst"$1 " ansible_ssh_host="$1 " ansible_ssh_user=ubuntu"}' > myansible.hostfile

выходной образец 1 в myansible.hostfile

inst[ip_no1] ansible_ssh_host=[ip_no1] ansible_ssh_user=ubuntu
inst[ip_no2] ansible_ssh_host=[ip_no2] ansible_ssh_user=ubuntu

Мне кажется это довольно длинным и несколько запутанным.

Если бы я просто использовал jq в одиночку вместе с его операциями со строками, такими как:

пример команды 2

aws ec2 describe-instances | jq '"inst" + .Reservations[].Instances[].PublicIpAddress + " ansible_ssh_hosts=" + .Reservations[].Instances[].PublicIpAddress + " ansible_ssh_user=ubuntu"' > myansible.hostfile

Я бы получил дубликаты вывода так:

выходной образец 2 в myansible.hostfile

inst[ip_no1] ansible_ssh_host=[ip_no1] ansible_ssh_user=ubuntu
inst[ip_no2] ansible_ssh_host=[ip_no2] ansible_ssh_user=ubuntu
inst[ip_no1] ansible_ssh_host=[ip_no1] ansible_ssh_user=ubuntu
inst[ip_no2] ansible_ssh_host=[ip_no2] ansible_ssh_user=ubuntu

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

а. Есть ли более чистое командное выражение, которое я мог бы использовать вместо (пример команды 1) для достижения того же (выходной пример 1)?

б. Каким будет правильный способ строго использовать команду jq, например, в (пример команды 2), для получения желаемого (выходной пример 1) без дубликатов, как в (выходной пример 2)?

Большое спасибо заранее.

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Я не уверен, почему вы задаете имя инвентаризации Ansible, которое включает в себя IP-адрес, поскольку это кажется мне довольно бессмысленным, поскольку оно не дает ему удобочитаемое имя или добавляет что-либо полезное по сравнению с использованием только IP адрес.

Если вы удовлетворены отказом от этого требования, то в действительности вы можете просто использовать опцию query интерфейса командной строки AWS и канаву jq и свое форматирование:

cat <<EOF > hosts-file.ini
[all:vars]
ansible_ssh_user=ubuntu

[all]
EOF
aws ec2 describe-instances --query 'Reservations[*].Instances[*].PublicIpAddress' --output text >> hosts-file.ini

Это позволит установить некоторые встроенные переменные на всех уровнях, чтобы установить для пользователя SSH значение ubuntu, а затем сбросить все публичные IP-адреса экземпляра EC2 в блоке all.

0 голосов
/ 30 октября 2018

Во-первых, опция jq's -r удалит крайние кавычки из строковых выводов JSON.

Во-вторых, следующего jq-фильтра, используемого в сочетании с вышеупомянутой опцией -r, должно быть достаточно для достижения ваших целей, хотя это трудно проверить, поскольку вы не предоставили MCVE :

.Reservations[].Instances[].PublicIpAddress
| "inst" + . + " ansible_ssh_hosts=" + . + " ansible_ssh_user=ubuntu"
...