2015-12-13 8 views
3

у меня есть два сервера в моем инвентаре (хостов)анзибль переменная приращения глобально для всех хостов

[server] 
10.23.12.33 
10.23.12.40 

и пьес (play.yml)

--- 
- hosts: all 
    roles: 
    web 

Внутри веб-роли в каталоге VARS я есть главная .yml

--- 
file_number : 0 

Внутри веб-роли в каталоге задач у меня есть main.yml

--- 
- name: Increment variable 
    set_fact: file_number={{ file_number | int + 1 }} 

- name: create file 
    command: 'touch file{{ file_number }}' 

Теперь я ожидаю, что в первой машине я буду иметь file1 и во второй машине я буду иметь file2, но в обеих машинах я есть file1

Так эта переменная является локальной для каждой машины , как я могу сделать его глобальным для всех машин.

Моя структура файла:

hosts 
play.yml 
roles/ 
    web/ 
    tasks/ 
     main.yml 
    vars/ 
     main.yml 
+0

Это глобальная переменная, но анзибль только оценки 'file_number' один раз задание 'set_fact', и поэтому оно становится равным' 1', независимо от того, сколько узлов оно запускает. Можете ли вы объяснить свой прецедент немного шире? Может быть, есть лучший способ сделать то, что вы пытаетесь сделать (кажется, вам нужно уникальное имя файла для всех хостов)? – ydaetskcoR

+0

@ydaetskcoR, что я точно делаю, меняет конфигурационную строку в файле, которая на первом компьютере будет иметь «username = client1», а на втором компьютере - «username = client2» и т. Д. Для всех хостов. поэтому мне нужно увеличивать переменную для каждой машины. – Nasr

+1

Но вы не представляете, какой порядок хостов будет выполняться. Каждый запуск, скорее всего, будет иметь другой порядок хостов. Возможно, вам лучше назначить это как host var вместо этого, если я не упустил что-то в вашем случае использования – ydaetskcoR

ответ

1

Я не нашел решение с возможностью, хотя я сделал работу вокруг, используя оболочку, чтобы сделать глобальную переменную для всех хостов.

  1. Создать временный файл в/TMP в локальном и месте в нем, начиная отсчет
  2. Прочитайте файл для каждого хоста и увеличение числа внутри файла

Я создал файл и инициализируюсь его в сборник пьес (play.yml)

- name: Manage localhost working area 
    hosts: 127.0.0.1 
    connection: local 
    tasks: 
    - name: Create localhost tmp file 
     file: path={{ item.path }} state={{ item.state }} 
     with_items: 
     - { path: '/tmp/file_num', state: 'absent' } 
     - { path: '/tmp/file_num', state: 'touch' } 

    - name: Managing tmp files 
     lineinfile: dest=/tmp/file_num line='0' 

Затем в веб-роли в main.tml задаче я прочитать файл и увеличиваем его.

- name: Get file number 
    local_action: shell file=$((`cat /tmp/file_num` + 1)); echo $file | tee /tmp/file_num 
    register: file_num 

- name: Set file name 
    command: 'touch file{{ file_num.stdout }}' 

Теперь у меня есть в первом хозяине file1 и во втором хосте file2

1

Теперь я ожидаю, что в первой машине я буду иметь file1 и во второй машине я буду иметь file2, но в обеих машинах я есть file1

Вы должны иметь в виду, что переменные в Ansible не являются глобальными. Переменные (иначе называемые «факты») применяются однозначно для каждого хоста, поэтому file_number для хоста 1 отличается от file_number для хоста2. Вот пример, основанный на свободно, что вы писали:

роли/тест/вары/main.yml:

--- 
file_number: 0 

роли/тест/задачи/main.yml:

--- 
- name: Increment variable 
    set_fact: file_number={{ file_number | int + 1 }} 

- name: debug 
    debug: msg="file_number is {{ file_number }} on host {{ inventory_hostname }}" 

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

--- 
- hosts: all 
    roles: 
    - { role: test } 

- hosts: host1 
    roles: 
    - { role: test } 

- hosts: all 
    roles: 
    - { role: test } 

Итак, в первом играть роль применяется как к host1 & host2. Во второй пьесе он запускается только против host1, а в третьем исполнении он снова запускается как с host1 & host2. Выход этого сборника пьес является:

PLAY [all] ******************************************************************** 

TASK: [test | Increment variable] ********************************************* 
ok: [host1] 
ok: [host2] 

TASK: [test | debug] ********************************************************** 
ok: [host1] => { 
    "msg": "file_number is 1 on host host1" 
} 
ok: [host2] => { 
    "msg": "file_number is 1 on host host2" 
} 

PLAY [host1] ************************************************** 

TASK: [test | Increment variable] ********************************************* 
ok: [host1] 

TASK: [test | debug] ********************************************************** 
ok: [host1] => { 
    "msg": "file_number is 2 on host host1" 
} 

PLAY [all] ******************************************************************** 

TASK: [test | Increment variable] ********************************************* 
ok: [host1] 
ok: [host2] 

TASK: [test | debug] ********************************************************** 
ok: [host1] => { 
    "msg": "file_number is 3 on host host1" 
} 
ok: [host2] => { 
    "msg": "file_number is 2 on host host2" 
} 

Так как вы можете видеть, значение file_number отличается для host1 и host2 после той роли, которую увеличивает значение бежало против host1 больше раз, чем это было host2.

К сожалению, на самом деле нет чистого способа сделать переменную global в пределах Ansible. Вся природа способности Ansible запускать задачи параллельно с большим количеством хостов делает что-то вроде этого очень сложным. Если вы не будете очень осторожны с глобальными переменными в параллельной среде, вы можете легко вызвать race condition, что, вероятно, приведет к непредсказуемым (непоследовательным) результатам.

0

Вы можете использовать решение Matt Martz от here. В основном ваша задача будет, как:

- name: Set file name command: 'touch file{{ play_hosts.server.index(inventory_hostname) }}'

И вы можете удалить весь этот код для поддержания глобальной вар и внешний файл :)

Смежные вопросы