Вы пытаетесь выполнить тот вид манипулирования данными, в котором Ansible действительно не так хорош. Каждый раз, когда вы пытаетесь изменить существующую переменную - особенно если вы пытаетесь установить вложенное значение - вы усложняете жизнь. Сказав это, можно делать то, что вы хотите. Например:
---
- hosts: localhost
gather_facts: false
vars:
imported_var: {}
tasks:
- name: Checking sshd status
command: systemctl is-active sshd
register: sshd_stat
ignore_errors: true
- name: Checking httpd status
command: systemctl is-active httpd
register: httpd_stat
ignore_errors: true
- set_fact:
imported_var: "{{ imported_var|combine({'status_checks': []}) }}"
- set_fact:
imported_var: >-
{{ imported_var|combine({'status_checks':
imported_var.status_checks + [{'sshd_status': (sshd_stat.rc == 0)|ternary('good', 'bad')}]}) }}
- set_fact:
imported_var: >-
{{ imported_var|combine({'status_checks':
imported_var.status_checks + [{'httpd_status': (httpd_stat.rc == 0)|ternary('good', 'bad')}]}) }}
- debug:
var: imported_var
В моей системе (которая работает sshd
, но не работает httpd
, это выдаст:
TASK [debug] **********************************************************************************
ok: [localhost] => {
"imported_var": {
"status_checks": [
{
"sshd_status": "good"
},
{
"httpd_status": "bad"
}
]
}
}
Вы можете значительно упростить сборник пьес, реструктурировав свои данные. Сделайте status_checks
переменной верхнего уровня, и вместо того, чтобы она была списком, пусть это будет словарь, который отображает имя службы в соответствующий статус. Объедините это с некоторыми циклами, и вы получите нечто гораздо более простое:
---
- hosts: localhost
gather_facts: false
tasks:
# We can use a loop here instead of writing a separate task
# for each service.
- name: Checking service status
command: systemctl is-active {{ item }}
register: services
ignore_errors: true
loop:
- sshd
- httpd
# Using a loop in the previous task means we can use a loop
# when creating the status_checks variable, which again removes
# a bunch of duplicate code.
- name: set status_checks variable
set_fact:
status_checks: "{{ status_checks|default({})|combine({item.item: (item.rc == 0)|ternary('good', 'bad')}) }}"
loop: "{{ services.results }}"
- debug:
var: status_checks
Выше будет выводиться:
TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"status_checks": {
"httpd": "bad",
"sshd": "good"
}
}
Если вы действительно хотите добавить эту информацию в imported_var
, вы можете сделать это в одной задаче:
- set_fact:
imported_var: "{{ imported_var|combine({'status_checks': status_checks}) }}"