Spec-Zone.ru › Ansible 2.6

Руководство по переносу Ansible 2.0

В этом разделе обсуждаются изменения в поведении между Ansible 1.x и Ansible 2.0.

Он предназначен для помощи в обновлении ваших playbooks, плагинов и других частей вашей инфраструктуры Ansible, чтобы они работали с этой версией Ansible.

Мы рекомендуем вам прочитать эту страницу вместе с Журналом изменений Ansible 2.0, чтобы понять, какие обновления вам могут потребоваться.

Этот документ является частью коллекции по переносу. Полный список руководств по переносу можно найти по адресу руководствам по переносу.

  • Playbook
    • Устаревшие элементы
    • Другие особенности
  • Перенос плагинов
    • Плагины поиска
    • Плагины подключения
    • Плагины действий
    • Плагины обратного вызова
    • Плагины подключения
  • Гибридные плагины
    • Плагины поиска
    • Плагины подключения
    • Плагины действий
    • Плагины обратного вызова
    • Плагины подключения
  • Перенос пользовательских скриптов

Playbook

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

# Syntax in 1.9.x
- debug:
    msg: "{{ 'test1_junk 1\\\\3' | regex_replace('(.*)_junk (.*)', '\\\\1 \\\\2') }}"
# Syntax in 2.0.x
- debug:
    msg: "{{ 'test1_junk 1\\3' | regex_replace('(.*)_junk (.*)', '\\1 \\2') }}"

# Output:
"msg": "test1 1\\3"

Чтобы создать экранированную строку, которая будет работать во всех версиях, у вас есть два варианта:

- debug: msg="{{ 'test1_junk 1\\3' | regex_replace('(.*)_junk (.*)', '\\1 \\2') }}"

использует экранирование key=value, которое не изменилось. Другой вариант — проверить версию ansible:

"{{ (ansible_version|version_compare('2.0', 'ge'))|ternary( 'test1_junk 1\\3' | regex_replace('(.*)_junk (.*)', '\\1 \\2') , 'test1_junk 1\\\\3' | regex_replace('(.*)_junk (.*)', '\\\\1 \\\\2') ) }}"
  • Конец строки. Когда строка с символом конца строки была указана в playbook в формате словаря YAML, символ конца строки удалялся. При указании в формате key=value символы конца строки сохранялись. В версии 2 оба способа указания строки сохранят символы конца строки. Если вы полагались на удаление символа конца строки, вы можете изменить свой playbook, используя следующий пример:

    # Syntax in 1.9.x
    vars:
      message: >
        Testing
        some things
    tasks:
    - debug:
        msg: "{{ message }}"
    
    # Syntax in 2.0.x
    vars:
      old_message: >
        Testing
        some things
      message: "{{ old_messsage[:-1] }}"
    - debug:
        msg: "{{ message }}"
    # Output
    "msg": "Testing some things"
    
  • Изменяется поведение шаблонизации текстовых файлов типа DOS в Ansible v2.

    Ошибка в Ansible v1 приводит к тому, что текстовые файлы типа DOS (использующие возврат каретки и перенос строки) шаблонизируются в текстовые файлы типа Unix (использующие только перенос строки). В Ansible v2 эта давняя ошибка, наконец, была исправлена, и текстовые файлы типа DOS сохраняются правильно. Это может быть непонятно, когда вы ожидаете, что ваш playbook не покажет никаких различий при миграции на Ansible v2, в то время как на самом деле вы увидите, что каждый файл типа DOS полностью заменяется (с тем же содержимым).

  • При указании сложных аргументов в качестве переменной, переменная должна использовать полный синтаксис Jinja2 (`{{var_name}}`) — простые имена переменных больше не поддерживаются. На самом деле, даже указание аргументов с переменными устарело и не будет разрешено в будущих версиях:

    ---
    - hosts: localhost
      connection: local
      gather_facts: false
      vars:
        my_dirs:
          - { path: /tmp/3a, state: directory, mode: 0755 }
          - { path: /tmp/3b, state: directory, mode: 0700 }
      tasks:
        - file:
          args: "{{item}}" # <- args here uses the full variable syntax
          with_items: "{{my_dirs}}"
    
  • перенос задачи включает
  • Более динамично. Угловые случаи форматов, которые не должны были работать, теперь не работают, как ожидалось.
  • переменные, определенные в формате словаря YAML https://github.com/ansible/ansible/issues/13324
  • шаблонизация (переменные в playbooks и шаблонах поиска) улучшена в отношении сохранения оригинального значения вместо преобразования всего в строку. Если вам нужно старое поведение, укажите значение в кавычках, чтобы передать его как строку.
  • Пустые переменные и переменные, установленные в null в формате YAML, больше не преобразуются в пустые строки. Они сохранят значение None. Вы можете переопределить null_representation значение в пустую строку в файле конфигурации, установив переменную среды ANSIBLE_NULL_REPRESENTATION.
  • Дополнительно плагины обратного вызова должны быть разрешены в ansible.cfg. Копирование больше не требуется, но необходимо выполнить разрешение в ansible.cfg.
  • Модуль dnf был переписан. Могут наблюдаться некоторые незначительные изменения в поведении.
  • win_updates был переписан и теперь работает как ожидается.
  • начиная с версии 2.0.1, неявная задача настройки из gather_facts теперь правильно наследует все от playbook, но это может вызвать проблемы для тех, кто устанавливает environment на уровне playbook и зависит от существования ansible_env. Ранее это игнорировалось, но теперь может вызывать ошибку 'Undefined'.

Устаревшие элементы

Хотя все перечисленные элементы будут отображать сообщение о deprecation warning, они все равно работают так же, как и в 1.9.x. Обратите внимание, что они будут удалены в версии 2.2 (Ansible всегда ждет два основных релиза, чтобы удалить устаревший элемент).

  • Простые переменные в циклах with_ следует вместо этого использовать синтаксис "{ {var }}", что помогает устранить неоднозначность.
  • Файл требований формата ansible-galaxy. Пользователи должны использовать формат YAML для требований вместо него.
  • Неопределенные переменные в списке цикла with_ в настоящее время не прерывают цикл, но выдают предупреждение; в будущем они будут выдавать ошибку.
  • Использование переменных словаря для установки всех параметров задачи небезопасно и будет удалено в будущей версии. Например:

    - hosts: localhost
      gather_facts: no
      vars:
        debug_params:
          msg: "hello there"
      tasks:
        # These are both deprecated:
        - debug: "{{debug_params}}"
        - debug:
          args: "{{debug_params}}"
    
        # Use this instead:
        - debug:
            msg: "{{debug_params['msg']}}"
    
  • В шаблонах хостов следует использовать запятую (,) или двоеточие (:) вместо точки с запятой (;), чтобы разделять хосты/группы в шаблоне.
  • Диапазоны, указанные в шаблонах хостов, следует использовать в синтаксисе [x:y], а не [x-y].
  • Playbooks, использующие повышение привилегий, должны всегда использовать опции «become*», а не старые опции su*/sudo*.
  • «Короткий формат» для vars_prompt больше не поддерживается. Например:

    vars_prompt:
        variable_name: "Prompt string"
    
  • Указание переменных на верхнем уровне задачи include statement больше не поддерживается. Например:

    - include_tasks: foo.yml
        a: 1
    

Теперь должно быть:

- include_tasks: foo.yml
  vars:
    a: 1
  • Указание any_errors_fatal в задаче больше не поддерживается. Это должно быть установлено только на уровне playbook.
  • Простые переменные в словаре environment (для playbooks/задач и т.д.) больше не поддерживаются. Переменные, указанные там, должны использовать полный синтаксис переменных: ‘{{foo}}’.
  • Теги (или любые директивы) больше не должны указываться с другими параметрами в include задачи. Вместо этого они должны указываться как опция в задаче. Например:

    - include_tasks: foo.yml tags=a,b,c
    

    Должно быть:

    - include_tasks: foo.yml
      tags: [a, b, c]
    
  • Опция first_available_file в задачах устарела. Пользователи должны использовать опцию with_first_found или плагин поиска (‘first_found’, …).

Другие особенности

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

  • Плохое составление переменных:

    with_items: myvar_{{rest_of_name}}
    

    Это работало «случайно», поскольку ошибки были перешаблонизированы и в итоге разрешили переменную, но это никогда не предназначалось для допустимого синтаксиса, и теперь она правильно возвращает ошибку, используйте вместо этого следующее.:

    hostvars[inventory_hostname]['myvar_' + rest_of_name]
    
  • Неправильно написанные директивы:

    - task: dostuf
      becom: yes
    

    Задача всегда выполнялась без повышения привилегий (для этого вам нужен become), но также молча игнорировалась, поэтому playbook «выполнялся», хотя это не должно было быть, теперь это ошибка парсинга.

  • Повторяющиеся директивы:

    - task: dostuf
      when: True
      when: False
    

    Первая when была проигнорирована, и использовалась только вторая, так как playbook выполнялся без предупреждений, игнорируя одну из директив, теперь это ошибка парсинга.

  • Объединение переменных и директив:

    - role: {name=rosy, port=435 }
    
    # in tasks/main.yml
    - wait_for: port={{port}}
    

    Переменная port зарезервирована как директива playbook/задачи для переопределения порта подключения, в предыдущих версиях она сливалась с переменной port и была доступна позже в playbook, это создавало проблемы, если хост пытался повторно подключиться или использовал не кешируемое подключение. Теперь она будет правильно распознана как директива, и переменная port появится как неопределенная, это теперь требует использования неконфликтующих имен и устраняет неоднозначность при добавлении настроек и переменных к вызову роли.

  • Простые операции с with_:

    with_items: var1 + var2
    

    Проблема с функциями «простых переменных», которые должны были шаблонизировать только одну переменную без необходимости в фигурных скобках ({{)}), в некоторых версиях Ansible шаблонизировали полные выражения. Теперь для всех выражений, кроме условных (when), требуется использовать правильное шаблонирование и фигурные скобки:

    with_items: "{{var1 + var2}}"
    

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

Перенос плагинов

В ansible-1.9.x вы обычно копировали существующий плагин, чтобы создать новый. Простое реализация методов и атрибутов, ожидаемых вызывающей стороной плагина, делало его плагином этого типа. В ansible-2.0 большинство плагинов реализуются путем наследования от базового класса для каждого типа плагина. Таким образом, пользовательский плагин не нуждается в содержании методов, которые не настраиваются.

Плагины поиска

  • плагины поиска; импорт версии

Плагины подключения

  • плагины подключения

Плагины действий

  • плагины действий

Плагины обратного вызова

Хотя Ansible 2.0 предоставляет новый API обратного вызова, старый API по-прежнему работает для большинства плагинов обратного вызова. Однако, если ваш плагин обратного вызова использует self.playbook, self.play, или self.task, то вам нужно будет сохранить значения самостоятельно, поскольку Ansible больше не автоматически заполняет плагин обратного вызова ими. Вот небольшой фрагмент, который показывает, как это сделать:

import os
from ansible.plugins.callback import CallbackBase

class CallbackModule(CallbackBase):
    def __init__(self):
        self.playbook = None
        self.playbook_name = None
        self.play = None
        self.task = None

    def v2_playbook_on_start(self, playbook):
        self.playbook = playbook
        self.playbook_name = os.path.basename(self.playbook._file_name)

    def v2_playbook_on_play_start(self, play):
        self.play = play

    def v2_playbook_on_task_start(self, task, is_conditional):
        self.task = task

    def v2_on_any(self, *args, **kwargs):
        self._display.display('%s: %s: %s' % (self.playbook_name,
        self.play.name, self.task))

Плагины подключения

  • плагины подключения

Гибридные плагины

В определенных случаях вам может потребоваться плагин, который поддерживает как ansible-1.9.x, так и ansible-2.0. Подобно переносу плагинов из v1 в v2, вам нужно понять, как работают плагины в каждой версии, и поддерживать оба требования.

Поскольку система плагинов ansible-2.0 более продвинутая, адаптация вашего плагина для предоставления аналогичных элементов (подклассов, методов) для ansible-1.9.x, как ожидается в ansible-2.0, становится проще. Таким образом, ваш код будет выглядеть намного чище.

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

  • Проверьте, доступны ли классы ansible-2.0, и если они отсутствуют (ansible-1.9.x), имитируйте их с необходимыми методами (например, __init__)
  • Когда импортируются модули Python ansible-2.0, и они терпят неудачу (ansible-1.9.x), перехватывайте исключение ImportError и выполняйте эквивалентные импорты для ansible-1.9.x. С возможными переводами (например, импортируя определенные методы).
  • Используйте наличие этих методов в качестве квалификатора версии Ansible, которую вы используете. Таким образом, вместо проверки версий можно использовать проверки возможностей. (См. примеры ниже)
  • Документируйте каждый случай if-then-else, для какой конкретной версии нужен каждый блок. Это поможет другим понять, как им нужно адаптировать свои плагины, а также поможет вам удалить поддержку устаревшей версии ansible-1.9.x, когда она будет устаревшей.
  • При разработке плагинов очень полезно иметь метод warning() во время разработки, но также важно выводить предупреждения для тупиков (случаи, которые, как ожидается, никогда не будут вызваны) или граничных случаев (например, случаи, когда ожидается неправильная конфигурация).
  • Полезно изучить другие плагины в ansible-1.9.x и ansible-2.0, чтобы понять, как работает API, и какие модули, классы и методы доступны.

Плагины поиска

В качестве простого примера мы собираемся создать гибридный fileglob плагин поиска.

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

import os
import glob

try:
    # ansible-2.0
    from ansible.plugins.lookup import LookupBase
except ImportError:
    # ansible-1.9.x

    class LookupBase(object):
        def __init__(self, basedir=None, runner=None, **kwargs):
            self.runner = runner
            self.basedir = self.runner.basedir

        def get_basedir(self, variables):
            return self.basedir

try:
    # ansible-1.9.x
    from ansible.utils import (listify_lookup_plugin_terms, path_dwim, warning)
except ImportError:
    # ansible-2.0
    from __main__ import display
    warning = display.warning

class LookupModule(LookupBase):

    # For ansible-1.9.x, we added inject=None as valid argument
    def run(self, terms, inject=None, variables=None, **kwargs):

        # ansible-2.0, but we made this work for ansible-1.9.x too !
        basedir = self.get_basedir(variables)

        # ansible-1.9.x
        if 'listify_lookup_plugin_terms' in globals():
            terms = listify_lookup_plugin_terms(terms, basedir, inject)

        ret = []
        for term in terms:
            term_file = os.path.basename(term)

            # For ansible-1.9.x, we imported path_dwim() from ansible.utils
            if 'path_dwim' in globals():
                # ansible-1.9.x
                dwimmed_path = path_dwim(basedir, os.path.dirname(term))
            else:
                # ansible-2.0
                dwimmed_path = self._loader.path_dwim_relative(basedir, 'files', os.path.dirname(term))

            globbed = glob.glob(os.path.join(dwimmed_path, term_file))
            ret.extend(g for g in globbed if os.path.isfile(g))

        return ret

Примечание

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

Плагины подключения

  • плагины подключения

Плагины действий

  • плагины действий

Плагины обратной связи

  • плагины обратной связи

Плагины подключения

  • плагины подключения

Портирование пользовательских скриптов

Пользовательские скрипты, которые использовали API ansible.runner.Runner в версии 1.x, необходимо портировать в 2.x. Обратитесь к: API Python

© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.6/porting_guides/porting_guide_2.0.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API