У меня есть playbook, который ищет конкретный контейнер на серверах (вся среда), а затем получает контейнер Docker ID на серверах, который имеет желаемый сервис. Последний шаг - команда exec bash внутри контейнера. Мой код:
shell: docker ps | grep '{{service}}:'
register: ps
changed_when: ps.stdout != ""
- name: get id container with {{service}}
shell: docker ps | grep '{{service}}:' | awk '{print $1}'
register: id
when: ps is changed
- name: alembic upgrade head exec
shell: docker exec -i {{id.stdout}} bash -c 'pwd'
register: pwd
when: id is changed
- debug: var=pwd.stdout_lines
when: id is changed
Выход:
PLAY [dev2] ******************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************
ok: [dev2_3]
ok: [dev2_4]
ok: [dev2_1]
TASK [search server with graphql] ********************************************************************************************************************************************************************************************************
ok: [dev2_1]
changed: [dev2_3]
changed: [dev2_4]
TASK [get id container with graphql] *****************************************************************************************************************************************************************************************************
skipping: [dev2_1]
changed: [dev2_3]
changed: [dev2_4]
TASK [alembic upgrade head exec] *********************************************************************************************************************************************************************************************************
skipping: [dev2_1]
changed: [dev2_3]
changed: [dev2_4]
TASK [debug] *****************************************************************************************************************************************************************************************************************************
skipping: [dev2_1]
ok: [dev2_3] => {
"pwd.stdout_lines": [
"/usr/src/app"
]
}
ok: [dev2_4] => {
"pwd.stdout_lines": [
"/usr/src/app"
]
}
Проблема в том, что если у вас есть группа хостов с 10 серверами, то желаемое обслуживание будет на 5 серверах, на вышеупомянутой конфигурации это будет выполняться пять раз.
Что мне нужно: последняя задача, которую она должна быть выполнена один раз, на любом сервере, который соответствует условию "id is change"
run_once: yes
всегда выполнять задачу на первом хосте из списка, так что это случайный случай, если первый хост будет иметь желаемый статус, он будет выполнен правильно, если нет, playbook закончится с ошибкой - первый хост не имеет желаемой переменной (id .stdout)