Поиск по сайту:
Мы не врачи, мы — боль (А.И. Герцен).

Ansible. Переменные, факты и регистры Ansible

06.11.2020
Краткое руководство: Как установить и настроить ansible в Linux для автоматизации

В ваших управляемых системах всегда будет много различий. По этой причине вам необходимо научиться работать с переменными Ansible.

В этой статье вы узнаете, как определять переменные Ansible и ссылаться на них. Вы также узнаете, как использовать факты Ansible для получения информации о ваших управляемых узлах.

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

 

Часть 1: Работа с переменными в Ansible

Начнем сначала с переменных. Имейте в виду, что все это записано в вашем YML-файле.

 

Определение и ссылка на переменные

Вы можете использовать ключевое слово vars для определения переменных непосредственно внутри playbook.

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

---
- name: Working with variables
  hosts: all
  vars:
    fav_color: yellow

 

Как теперь использовать (ссылаться) на переменную fav_color? Ansible использует систему шаблонов Jinja2 для работы с переменными.

Чтобы получить значение переменной fav_color ; вам нужно окружить его парой фигурных скобок следующим образом:

My favorite color is {{ fav_color }}

 

Обратите внимание, что если ваша переменная является первым элементом (или единственным элементом) в строке, то использование кавычек обязательно, как показано ниже:

"{{ fav_color }} is my favorite color."

 

Теперь давайте напишем книгу с именем variables-playbook.yml, которая объединит все это вместе:

[destroyer@andreyex]$ cat variables-playbook.yml 
---
- name: Working with variables
  hosts: node1
  vars:
    fav_color: yellow
  tasks:
    - name: Show me fav_color value
      debug:
        msg: My favorite color is {{ fav_color }}.

 

Мы использовали модуль отладки вместе с параметром модуля msg, чтобы распечатать значение переменной fav_color.

Теперь запустите playbook, и вы увидите, что ваш любимый цвет отображается следующим образом:

[destroyer@andreyex]$ ansible-playbook variables-playbook.yml 

PLAY [Working with variables] **************************************************

TASK [Gathering Facts] *********************************************************
ok: [node1]

TASK [Show me fav_color value] *************************************************
ok: [node1] => {
    "msg": "My favorite color is yellow."
}

PLAY RECAP *********************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

Создание списков и словарей

Вы также можете использовать списки и словари для определения многозначных переменных. Например, вы можете определить список с именем port_nums и установить его значение следующим образом:

  vars:
    port_nums: [21,22,23,25,80,443]

 

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

vars:
    port_nums:
      - 21
      - 22
      - 23
      - 25
      - 80
      - 443

 

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

All the ports {{ port_nums }}

 

Вы также можете получить доступ к определенному элементу списка:

First port is {{ port_nums[0] }}

 

Обратите внимание, что вы используете индекс (позицию) для доступа к элементам списка.

Вы также можете определить словарь с именем users следующим образом:

vars:
    users:
      bob:
        username: bob
        uid: 1122
        shell: /bin/bash
      lisa:
        username: lisa
        uid: 2233
        shell: /bin/sh

 

Есть два разных способа доступа к элементам словаря:

  • dict_name[‘key’] -> users[‘bob’][‘shell’]
  • dict_name.key -> users.bob.shell

 

Обратите внимание, что вы используете ключ для доступа к элементам словаря.

Теперь вы можете редактировать playbook – variables-playbook.yml, чтобы показать списки и словари в действии:

[destroyer@andreyex]$ cat variables-playbook.yml 
---
- name: Working with variables
  hosts: node1
  vars:
    port_nums: [21,22,23,25,80,443]
 
    users: 
      bob:
        username: bob
        uid: 1122
        shell: /bin/bash
      lisa:
        username: lisa
        uid: 2233
        shell: /bin/sh
  tasks:
    - name: Show 2nd item in port_nums
      debug:
        msg: SSH port is {{ port_nums[1] }}

    - name: Show the uid of bob
      debug:
        msg: UID of bob is {{ users.bob.uid }}

Теперь вы можете запустить playbook, чтобы отобразить второй элемент в port_nums и показать uid bob:

[destroyer@andreyex]$ ansible-playbook variables-playbook.yml 

PLAY [Работа с переменными] **************************************************

TASK [Показать 2-й элемент в port_nums] **********************************************
ok: [node1] => {
    "msg": "SSH port is 22"
}

TASK [Показать идентификатор bob] *****************************************************
ok: [node1] => {
    "msg": "UID of bob is 1122"
}

 

Включая внешние переменные

Точно так же, как вы можете импортировать (или включать) задачи в playbook. То же самое можно сделать и с переменными. То есть в playbook вы можете включать переменные, определенные во внешнем файле.

Читать  Как передать имя пользователя и пароль в Ansible?

Чтобы продемонстрировать, давайте создадим файл с именем myvars.yml , который содержит наш port_nums список и пользователей словаря:

[destroyer@andreyex]$ cat myvars.yml 
---
port_nums: [21,22,23,25,80,443]

users:
  bob:
    username: bob
    uid: 1122
    shell: /bin/bash
  lisa:
    username: lisa
    uid: 2233
    shell: /bin/sh

 

Теперь вы можете использовать ключевое слово vars_files в вашем файле variables-playbook.yml, чтобы включить переменные в myvars.yml следующим образом:

[destroyer@andreyex]$ cat variables-playbook.yml 
---
- name: Working with variables
  hosts: node1
  vars_files: myvars.yml
  tasks:
    - name: Show 2nd item in port_nums
      debug:
        msg: SSH port is {{ port_nums[1] }}

    - name: Show the uid of bob
      debug:
        msg: UID of bob is {{ users.bob.uid }}

 

Имейте в виду, что vars_files выполняет предварительную обработку и загружает переменные прямо в начале playbook. Вы также можете использовать модуль include_vars для динамической загрузки ваших переменных в playbook:

[destroyer@andreyex]$ cat variables-playbook.yml 
---
- name: Working with variables
  hosts: node1
  tasks:
    - name: Load the variables
      include_vars: myvars.yml

    - name: Show 2nd item in port_nums
      debug:
        msg: SSH port is {{ port_nums[1] }}

 

Получение пользовательского ввода

Вы можете использовать ключевое слово vars_prompt, чтобы предложить пользователю установить значение переменной во время выполнения.

Например, следующий сборник программ greet.yml просит запущенного пользователя ввести свое имя, а затем отображает персонализированное приветственное сообщение:

[destroyer@andreyex]$ cat greet.yml 
---
- name: Greet the user
  hosts: node1
  vars_prompt:
     - name: username
       prompt: What's your name?
       private: no

  tasks:
    - name: Greet the user
      debug:
        msg: Hello {{ username }}

 

Обратите внимание, что я использовал private: no, чтобы вы могли видеть свой ввод на экране по мере его ввода; по умолчанию он скрыт.

Теперь запустите playbook и введите свое имя:

[destroyer@andreyex]$ ansible-playbook greet.yml 
What's your name?: destroyer

PLAY [Приветствуем пользователей] **********************************************************

TASK [Приветствуем пользователей] **********************************************************
ok: [node1] => {
    "msg": "Hello destroyer"
}

 

Установка переменных хоста и группы

Вы можете установить переменные, специфичные для ваших управляемых хостов. Поступая так, вы можете создавать гораздо более эффективные playbooks, поскольку вам не нужно писать повторяющиеся задачи для разных узлов или групп.

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

[destroyer@andreyex]$ cat myhosts 
[proxy]
node1

[webservers]
node2
node3

[dbservers]
node4

 

Теперь создадим переменные, специфичные для ваших управляемых узлов; Во- первых, вам нужно создать каталог с именем host_vars. Затем внутри host_vars вы можете создать файлы переменных с именами файлов, соответствующими именам хостов вашего узла:

[destroyer@andreyex]$ mkdir host_vars
[destroyer@andreyex]$ echo "message: I am a Proxy Server" >> host_vars/node1.yml
[destroyer@andreyex]$ echo "message: I am a Web Server" >> host_vars/node2.yml
[destroyer@andreyex]$ echo "message: I am a Web Server" >> host_vars/node3.yml
[destroyer@andreyex]$ echo "message: I am a Database Server" >> host_vars/node4.yml

 

Теперь давайте создадим книгу с именем motd.yml, которая демонстрирует, как работают host_vars :

[destroyer@andreyex]$ cat motd.yml 
---
- name: Set motd on all nodes
  hosts: all
  tasks:
    - name: Set motd = value of message variable.
      copy: 
        content: "{{ message }}"
        dest: /etc/motd

 

Мы использовали модуль копирования, чтобы скопировать содержимое переменной сообщения в файл /etc/motd на всех узлах. Теперь после запуска playbook; вы должны увидеть, что содержимое /etc/motd было обновлено на всех узлах с соответствующим значением сообщения :

[destroyer@andreyex]$ ansible all -m command -a "cat /etc/motd"
node1 | CHANGED | rc=0 >>
I am a Proxy Server
node2 | CHANGED | rc=0 >>
I am a Web Server
node3 | CHANGED | rc=0 >>
I am a Web Server
node4 | CHANGED | rc=0 >>
I am a Database Server

 

Потрясающие! Точно так же вы можете создать каталог group_vars, а затем включить все связанные с группой переменные в имя файла, которое соответствует имени группы, как показано ниже:

[destroyer@andreyex]$ mkdir group_vars
[destroyer@andreyex]$ echo "pkg: squid" >> group_vars/proxy
[destroyer@andreyex]$ echo "pkg: httpd" >> group_vars/webservers
[destroyer@andreyex]$ echo "pkg: mariadb-server" >> group_vars/dbservers

Мы позволили вам создать playbook, который работает на всех узлах; каждый узел установит пакет, заданный в соответствующей групповой переменной узла pkg.

 

Читать  Ansible: playbook в Ansible

Понимание приоритета переменных

Как вы уже видели; Переменные Ansible могут быть установлены на разных уровнях (или уровнях).

Если одна и та же переменная установлена на разных уровнях; самый конкретный уровень получает приоритет. Например, переменная, установленная на уровне воспроизведения, имеет приоритет над той же переменной, установленной на уровне хоста ( host_vars ).

Более того, переменная, заданная в командной строке с помощью –extra-vars, имеет наивысший приоритет, то есть она перезапишет все остальное.

Чтобы продемонстрировать это, давайте создадим книгу с именем variable-Priordence.yml, которая содержит следующий контент:

[destroyer@andreyex]$ cat variable-precedence.yml 
---
- name: Understanding Variable Precedence
  hosts: node1
  vars:
    fav_distro: "Ubuntu"
  tasks:
    - name: Show value of fav_distro
      debug:
        msg: Favorite distro is {{ fav_distro }}

 

Теперь давайте запустим playbook, используя параметр -e (–extra-vars ), чтобы установить значение переменной fav_distro на «CentOS» из командной строки:

[destroyer@andreyex]$ ansible-playbook variable-precedence.yml -e "fav_distro=CentOS"

PLAY [Understanding Variable Precedence] ***************************************

TASK [Show value of fav_distro] ************************************************
ok: [node1] => {
    "msg": "Favorite distro is CentOS"
}

 

Обратите внимание на то, что значение «CentOS» в командной строке fav_distro имеет приоритет над значением «Ubuntu» в fav_distro.

 

Часть 2: Сбор и демонстрация фактов

Вы можете получить или обнаружить переменные, которые содержат информацию о ваших управляемых хостах. Эти переменные называются фактами, и Ansible использует модуль настройки для сбора этих фактов. IP-адрес одного из ваших управляемых узлов является примером факта.

Вы можете запустить следующую специальную команду, чтобы собрать и показать все факты о node1:

[destroyer@andreyex]$ ansible node1 -m setup

 

Вот результат:

node1 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.0.0.5"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::20d:3aff:fe0c:54aa"
        ],
        "ansible_apparmor": {
            "status": "disabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "06/02/2017",
        "ansible_bios_version": "090007",
        "ansible_cmdline": {
            "BOOT_IMAGE": "(hd0,gpt1)/vmlinuz-4.18.0-193.6.3.el8_2.x86_64",
            "console": "ttyS0,115200n8",
            "earlyprintk": "ttyS0,115200",
            "ro": true,
            "root": "UUID=6785aa9a-3d19-43ba-a189-f73916b0c827",
            "rootdelay": "300",
            "scsi_mod.use_blk_mq": "y"
        },
        "ansible_default_ipv4": {
            "address": "10.0.0.5",
            "alias": "eth0",
            "broadcast": "10.0.0.255",
            "gateway": "10.0.0.1",
            "interface": "eth0",
            "macaddress": "00:0d:3a:0c:54:aa",

 

Это только часть всех фактов, связанных с node1, которые вы увидите на своем терминале. Обратите внимание, как факты хранятся в словарях или списках, и все они принадлежат словарю ansible_facts.

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

[destroyer@andreyex]$ ansible-playbook motd.yml 

PLAY [Set motd on all nodes] ***************************************************

TASK [Gathering Facts] *********************************************************
ok: [node4]
ok: [node3]
ok: [node2]
ok: [node1]

 

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

[destroyer@andreyex]$ cat motd.yml 
---
- name: Set motd on all nodes
  gather_facts: false 
  hosts: all
  tasks:
    - name: Set motd = value of message variable.
      copy: 
        content: "{{ message }}"
        dest: /etc/motd

 

Если вы снова запустите motd.yaml playbook; он пропустит сбор фактов:

[destroyer@andreyex]$ ansible-playbook motd.yml 

PLAY [Set motd on all nodes] ***************************************************

TASK [Set motd = value of message variable.] ********************************

 

Таким же образом вы показываете значение переменной; вы также можете использовать, чтобы показать ценность факта. В следующем сборнике show-fact.yml показана ценность нескольких фактов на node1 :

[destroyer@andreyex]$ cat show-facts.yml 
---
- name: show some facts
  hosts: node1
  tasks:
    - name: display node1 ipv4 address
      debug:
        msg: IPv4 address is {{ ansible_facts.default_ipv4.address }}

    - name: display node1 fqdn
      debug:
        msg: FQDN is {{ ansible_facts.fqdn }} 

    - name: display node1 OS distribution
      debug:
        msg: OS Distro is {{ ansible_facts.distribution }}

 

Теперь запустите playbook, чтобы отобразить значения фактов:

[destroyer@andreyex]$ ansible-playbook show-facts.yml 

PLAY [show some facts] ******

TASK [Gathering Facts] *******
ok: [node1]

TASK [display node1 ipv4 address] *******
ok: [node1] => {
    "msg": "IPv4 address is 10.0.0.5"
}

TASK [display node1 fqdn] ********
ok: [node1] => {
    "msg": "FQDN is node1.linuxhandbook.local"
}

TASK [display node1 OS distribution] ******
ok: [node1] => {
    "msg": "OS Distro is CentOS"
}

PLAY RECAP **********
node1          : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

Создание постоянных фактов

Вы можете создать свои собственные пользовательские факты. Для этого вы можете использовать модуль set_fact для временного добавления фактов или каталог /etc/ansible/facts.d для добавления постоянных фактов на ваши управляемые узлы.

Читать  Ansible. Принятие решений в Ansible

Мы собираемся показать вам, как добавить постоянные факты к вашим управляемым узлам. Это трехэтапный процесс:

  1. Создайте файл фактов на вашем контрольном узле.
  2. Создайте каталог /etc/ansible/facts.d на управляемом узле (ах).
  3. Скопируйте файл фактов (шаг 1) с управляющего узла на ваш управляемый (ые) узел (ы).

Итак, сначала давайте создадим файл cool.fact на вашем управляющем узле, который включает некоторые интересные факты:

[destroyer@andreyex]$ cat cool.fact 
[fun]
kiwi=fruit
matrix=movie
octupus='8 legs'

 

Обратите внимание, что имя файла фактов должно иметь расширение.fact.

На втором этапе вы собираетесь использовать файловый модуль для создания и каталог /etc/ansible/facts.d на управляемом узле (ах). И , наконец , на третьем этапе, вы собираетесь использовать копию модуль для копирования cool.fact файла из узла управления для управляемого узла (ов).

В следующем сборнике custom-fact.yml сочетаются шаги 2 и 3:

[destroyer@andreyex]$ cat custom-facts.yml 
---
- name: Adding custom facts to node1
  hosts: node1
  tasks:
    - name: Create the facts.d directory
      file:
        path: /etc/ansible/facts.d
        owner: destroyer
        mode: 775
        state: directory
        
    - name: Copy cool.fact to the facts.d directory
      copy:
        src: cool.fact
        dest: /etc/ansible/facts.d

 

Теперь запустите playbook:

[destroyer@andreyex]$ ansible-playbook custom-facts.yml 

PLAY [Adding custom facts to node1] **********************************

TASK [Gathering Facts] ****************************
ok: [node1]

TASK [Create the facts.d directory] ******************************
changed: [node1]

TASK [Copy cool.fact to the facts.d directory] **********************
changed: [node1]

 

В cool теперь постоянно часть NODE1 фактов; вы можете проверить с помощью следующей специальной команды:

[destroyer@andreyex]$ ansible node1 -m setup -a "filter=ansible_local"

"ansible_local": {
            "cool": {
                "fun": {
                    "kiwi": "fruit",
                    "matrix": "movie",
                    "octupus": "'8 legs'"
                }
            }
        }

 

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

An octopus has {{ ansible_local.cool.fun.octupus }}

 

Часть 3: Захват вывода с помощью регистров в Ansible

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

Вы можете использовать регистр для захвата вывода задачи и сохранения его в переменной. Это позволяет вам использовать вывод задачи в другом месте книги, просто обращаясь к зарегистрированной переменной.

Следующий файл register-playbook.yml показывает вам, как записать вывод задачи в зарегистрированной переменной, а затем отобразить его содержимое:

[destroyer@andreyex]$ cat register-playbook.yml 
--- 
- name: Register Playbook
  hosts: proxy
  tasks:
    - name: Run a command
      command: uptime
      register: server_uptime

    - name: Inspect the server_uptime variable
      debug:
        var: server_uptime

    - name: Show the server uptime
      debug:
        msg: "{{ server_uptime.stdout }}"

 

Playbook запускается с выполнения команды uptime на хостах группы прокси (node1) и регистрирует выходные данные команды в переменной server_uptime.

Затем вы используете модуль отладки вместе с параметром var module для проверки переменной server_uptime. Обратите внимание, что здесь не нужно заключать переменную в фигурные скобки.

Наконец, последняя задача в playbook показывает вывод (stdout) зарегистрированной переменной server_uptime.

Запустите playbook, чтобы увидеть все это в действии:

[destroyer@andreyex]$ ansible-playbook register-playbook.yml 

PLAY [Register Playbook Showcase] **********************************************

TASK [Gathering Facts] *********************************************************
ok: [node1]

TASK [Run a command] ***********************************************************
changed: [node1]

TASK [Inspect the server_uptime variable] **************************************
ok: [node1] => {
    "server_uptime": {
        "changed": true,
        "cmd": [
            "uptime"
        ],
        "delta": "0:00:00.004221",
        "end": "2020-10-29 05:04:36.646712",
        "failed": false,
        "rc": 0,
        "start": "2020-10-29 05:04:36.642491",
        "stderr": "",
        "stderr_lines": [],
        "stdout": " 05:04:36 up 3 days,  6:56,  1 user,  load average: 0.24, 0.07, 0.02",
        "stdout_lines": [
            " 05:04:36 up 3 days,  6:56,  1 user,  load average: 0.24, 0.07, 0.02"
        ]
    }
}

TASK [Show the server uptime] **************************************************
ok: [node1] => {
    "msg": " 05:04:36 up 3 days,  6:56,  1 user,  load average: 0.24, 0.07, 0.02"
}

PLAY RECAP *********************************************************************
node1                      : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

Обратите внимание, что зарегистрированная переменная server_uptime на самом деле является словарем, содержащим множество других ключей помимо ключа stdout. Она также содержит другие ключи, такие как rc (код возврата), start (время выполнения команды), end (время завершения команды), stderr (любые ошибки) и т. д.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (4 оценок, среднее: 5,00 из 5)
Загрузка...
Поделиться в соц. сетях:


0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

**ссылки nofollow

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

Это может быть вам интересно


Рекомендуемое
Как правило, для загрузки файла с расширениями exe и zip…

Спасибо!

Теперь редакторы в курсе.