#bash #ansible
Вопрос:
Я пытаюсь передать список/массив строк из моего сценария bash в мой сценарий ansible:
Отрывок из сценария bash:
configureChrony() {
ntpServer="initVal"
ntpServers=()
while ! [[ -z "$ntpServer" ]]; do
read -e -p "Please input the ip address or domain name of the TP server you wish to add: " ntpServer
if ! [[ -z "$ntpServer" ]]; then
ntpServers =($ntpServer)
fi
done
ansible-playbook -i localhost, test.yml --extra-vars="ntp_list = $ntpServers"
}
тест.yml
---
- name: "This is a test"
hosts: all
gather_facts: no
tasks:
- name: print variable - with_items
debug:
msg: "{{ item.name }}"
with_items:
- "{{ ntp_list }}"
При тестировании сценария bash я получаю эту ошибку:
Which timekeeping service would you like to use [ntp/chrony]: chrony
Please input the ip address or domain name of the TP server you wish to add: Test1
Please input the ip address or domain name of the TP server you wish to add: Test2
Please input the ip address or domain name of the TP server you wish to add:
PLAY [This is a test] ****************************************************************************************************************************************
TASK [print variable - with_items] ***************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "'ntp_list' is undefined"}
PLAY RECAP ***************************************************************************************************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
Проблема в том, как я передаю список/массив из сценария bash в сценарий ansible, когда они оба запускаются с учетом требуемых данных.
Желаемый вывод — для каждого элемента списка, который будет выведен на экран.
Test1
Test2
Любая помощь будет признательна.
Комментарии:
1.
ntpServers
представляет собой массив. Используйте${ntpServers[@]}
, чтобы развернуть его в виде списка слов.2. Итак, ansible-playbook -i локальный хост, test.yml —extra-vars=»ntp_list = ${ntpServers [@]}»? @Рено Пакале
3. Да, именно так должны быть расширены массивы
bash
.4. @RenaudPacalet Теперь у меня есть эта ошибка:
ansible-playbook: error: unrecognized arguments: Test2
5. Если бы вы вводили
ansible
команду вручную без параметров bash, как бы она выглядела (особенно--extra-vars="ntp_list = ..."
часть)? Пожалуйста, не отвечайте в комментарии, добавьте это к своему вопросу. И проверьте, что это работает до этого. Тогда мы сможем предложитьbash
синтаксис, который делает именно это, не зная, какansible
это работает.
Ответ №1:
Прямой ответ
Вы действительно не можете передать массив bash в виде списка внутри дополнительного var в ansible. Это возможно, но для этого потребуется выполнить цикл над массивом bash и преобразовать его в формат для анализа json, который вы вводите в дополнительный var.
Самый простой способ IMO-передать объединение всех элементов массива внутри строки, которую вы позже разделите в учебнике.
Использование формы ${somevar[@]}
здесь не сработает, так как каждый элемент массива bash в конечном итоге будет проанализирован в качестве нового аргумента для вашей команды ansible. Вам придется использовать вместо ${somevar[*]}
этого . Вам также нужно правильно процитировать дополнительный var, чтобы и bash, и ansible могли успешно его проанализировать. Правильный вызов команды в вашем сценарии-это:
ansible-playbook test.yml --extra-vars "ntp_list_raw='${ntpServers[*]}'"
Теперь вам нужно немного доработать свой ансибельный сборник пьес, чтобы разделить полученное значение на список:
---
- name: "This is a test"
hosts: localhost
gather_facts: no
vars:
ntp_list: "{{ ntp_list_raw.split(' ') }}"
tasks:
- name: Print split variable items
debug:
var: item
loop: "{{ ntp_list }}"
А теперь ввод значений и вызов playbook из вашего сценария дает:
Please input the ip address or domain name of the TP server you wish to add: toto
Please input the ip address or domain name of the TP server you wish to add: pipo
Please input the ip address or domain name of the TP server you wish to add: bingo
Please input the ip address or domain name of the TP server you wish to add:
PLAY [This is a test] *********************************************************************
TASK [Print split variable items] *********************************************************************
ok: [localhost] => (item=toto) => {
"ansible_loop_var": "item",
"item": "toto"
}
ok: [localhost] => (item=pipo) => {
"ansible_loop_var": "item",
"item": "pipo"
}
ok: [localhost] => (item=bingo) => {
"ansible_loop_var": "item",
"item": "bingo"
}
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Идем дальше
Если ваша единственная цель-запросить ваши серверы ntp в интерактивном режиме, вы можете сделать все вышеперечисленное непосредственно в своем учебнике, используя vars_prompt
---
- name: "This is a test"
hosts: localhost
gather_facts: no
vars_prompt:
- name: ntp_list_raw
prompt: "Please enter ntp servers separated by a comma without spaces"
private: no
vars:
ntp_list: "{{ ntp_list_raw.split(',') }}"
tasks:
- name: Print split variable
debug:
var: item
loop: "{{ ntp_list }}"
что дает:
$ ansible-playbook test.yaml
Please enter ntp servers separated by a comma without spaces []: toto,pipo,bingo
PLAY [This is a test] *********************************************************************
TASK [Print split variable] *********************************************************************
ok: [localhost] => (item=toto) => {
"ansible_loop_var": "item",
"item": "toto"
}
ok: [localhost] => (item=pipo) => {
"ansible_loop_var": "item",
"item": "pipo"
}
ok: [localhost] => (item=bingo) => {
"ansible_loop_var": "item",
"item": "bingo"
}
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Вы даже можете обойти приглашение, указав значение в качестве дополнительного параметра напрямую:
$ ansible-playbook test.yaml -e ntp_list_raw=toto,pipo,bingo
PLAY [This is a test] *********************************************************************
TASK [Print split variable] *********************************************************************
ok: [localhost] => (item=toto) => {
"ansible_loop_var": "item",
"item": "toto"
}
ok: [localhost] => (item=pipo) => {
"ansible_loop_var": "item",
"item": "pipo"
}
ok: [localhost] => (item=bingo) => {
"ansible_loop_var": "item",
"item": "bingo"
}
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Комментарии:
1. Спасибо, я буду использовать ваше прямое решение, так как оно более понятно для пользователя. Я бы подумал, что это было бы возможно с ansible, но, думаю, нет.