Подтвердить что ты не робот

Можно ли установить факт массива в Ansible?

Можно ли установить факт, содержащий массив в недоступном, используя set_fact? Какой правильный синтаксис для него?

4b9b3361

Ответ 1

В самом деле. Вам нужно процитировать весь массив:

- name: set fact
  set_fact: foo="[ 'one', 'two', 'three']"

- name: debug
  debug: msg={{ item }}
  with_items: foo

Вышеупомянутые задачи должны генерировать следующий вывод:

TASK: [set fact] **************************************************************
ok: [localhost]

TASK: [debug] *****************************************************************
ok: [localhost] => (item=one) => {
    "item": "one",
    "msg": "one"
}
ok: [localhost] => (item=two) => {
    "item": "two",
    "msg": "two"
}
ok: [localhost] => (item=three) => {
    "item": "three",
    "msg": "three"
}

Ответ 2

Да, это возможно. Как упоминалось в другом ответе, вы можете установить массив, используя двойные кавычки, например:

- name: set foo fact to an array
  set_fact: foo="[ 'one', 'two', 'three' ]"

Однако, я думал, что создаю еще один ответ, чтобы указать, что его также можно добавить в существующий массив, например:

- name: add items to foo array fact
  set_fact: foo="{{foo}} + [ 'four' ]"

Объединив их и добавив отладку в качестве playbook (который я называю facts.yml) следующим образом:

---
- name: test playbook
  gather_facts: false
  hosts: localhost
  tasks:
    - name: set foo fact to an array
      set_fact: foo="[ 'one', 'two', 'three' ]"
    - debug: var=foo
    - name: add items to foo array fact
      set_fact: foo="{{foo}} + [ 'four' ]"
    - debug: var=foo

Производит (через ansible-playbook facts.yml) следующее:

PLAY [test playbook] ********************************************************** 

TASK: [set foo fact to an array] ********************************************** 
ok: [localhost]

TASK: [debug var=foo] ********************************************************* 
ok: [localhost] => {
    "foo": [
        "one", 
        "two", 
        "three"
    ]
}

TASK: [add items to foo array fact] ******************************************* 
ok: [localhost]

TASK: [debug var=foo] ********************************************************* 
ok: [localhost] => {
    "foo": [
        "one", 
        "two", 
        "three", 
        "four"
    ]
}

PLAY RECAP ******************************************************************** 
localhost                  : ok=4    changed=0    unreachable=0    failed=0   

Ответ 3

Добавляя к уже предоставленным ответам, я хотел бы показать вам другой способ определите список с помощью set_fact, используя обычный синтаксис YAML вместо который Ansible core предпочитает использовать в своих документах. Эта пользовательский формат, как в этом случае, показал, что это приводит к путанице.

Рассмотрим следующий пример:

- name: 'Set the foo variable to a static list using the YAML syntax'
  set_fact:
    foo:
      - 'one'
      - 'two'
      - 'three'

Прямо вперед, не так ли? Как и в любом нормальном документе YAML. Так почему бы и не использовать его в файле задач Ansible YAML?

О комбинации списков, упомянутых @lindes-hw. Существует более одного способ сделать это. В следующих примерах для определения списка используется синтаксис Jinja2:

- name: 'Set the foo variable to a combined static list using the Jinja2 syntax'
  set_fact:
    foo: '{{ [ "one" ] + [ "two", "three" ] }}'

- name: 'Set the foo variable to a combined static list using the Jinja2 syntax and Jinja2 filters'
  set_fact:
    foo: '{{ [ "one" ] | union([ "two", "three" ]) }}'

Во втором примере используется фильтр union. См. набор фильтров теории в документах Ansible.

Ответ 4

У меня было аналогичное требование для создания списка объектов сервера на основе списка IP-адресов.

vars:
  server_ips: one,two,three
tasks:
  - name: build items list
    set_fact: 
      foo: "{{foo|default([]) + [{'ip': {'addr': item, 'type': 'V4'}}] }}"
    with_items: "{{server_ips.split(',')}}"
  - debug:
      msg: "{{ foo }}"

Дает следующий результат

TASK [setup] *******************************************************************
ok: [localhost]

TASK [build items list] ********************************************************
ok: [localhost] => (item=one)
ok: [localhost] => (item=two)
ok: [localhost] => (item=three)

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": [
        {
            "ip": {
                "addr": "one", 
                "type": "V4"
            }
        }, 
        {
            "ip": {
                "addr": "two", 
                "type": "V4"
            }
        }, 
        {
            "ip": {
                "addr": "three", 
                "type": "V4"
            }
        }
    ]
}