Использование Ansible и Windows
При использовании Ansible для управления Windows многие синтаксические конструкции и правила, применимые для хостов Unix/Linux, также применимы и для Windows, но есть некоторые различия, связанные с компонентами, такими как разделители путей и задачи, специфичные для операционной системы. Этот документ содержит подробную информацию, специфичную для использования Ansible для Windows.
Сценарии использования
Ansible может использоваться для организации множества задач на серверах Windows. Ниже приведены примеры и информация о распространенных задачах.
Установка программного обеспечения
Существует три основных способа использования Ansible для установки программного обеспечения:
- Использование модуля
win_chocolatey. Этот модуль получает данные о программе из стандартного публичного репозитория Chocolatey. Вместо него можно использовать внутренние репозитории, установив опциюsource. - Использование модуля
win_package. Этот модуль устанавливает программное обеспечение с помощью установщика MSI или .exe из локального/сетевого пути или URL. - Использование модулей
win_commandилиwin_shellдля ручного запуска установщика.
Модуль win_chocolatey рекомендуется, так как он имеет наиболее полную логику проверки, установлено ли пакет и является ли он актуальным.
Ниже приведены примеры использования всех трех вариантов для установки 7-Zip:
# Install/uninstall with chocolatey
- name: Ensure 7-Zip is installed via Chocolatey
win_chocolatey:
name: 7zip
state: present
- name: Ensure 7-Zip is not installed via Chocolatey
win_chocolatey:
name: 7zip
state: absent
# Install/uninstall with win_package
- name: Download the 7-Zip package
win_get_url:
url: https://www.7-zip.org/a/7z1701-x64.msi
dest: C:\temp\7z.msi
- name: Ensure 7-Zip is installed via win_package
win_package:
path: C:\temp\7z.msi
state: present
- name: Ensure 7-Zip is not installed via win_package
win_package:
path: C:\temp\7z.msi
state: absent
# Install/uninstall with win_command
- name: Download the 7-Zip package
win_get_url:
url: https://www.7-zip.org/a/7z1701-x64.msi
dest: C:\temp\7z.msi
- name: Check if 7-Zip is already installed
win_reg_stat:
name: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{23170F69-40C1-2702-1701-000001000000}
register: 7zip_installed
- name: Ensure 7-Zip is installed via win_command
win_command: C:\Windows\System32\msiexec.exe /i C:\temp\7z.msi /qn /norestart
when: 7zip_installed.exists == false
- name: Ensure 7-Zip is uninstalled via win_command
win_command: C:\Windows\System32\msiexec.exe /x {23170F69-40C1-2702-1701-000001000000} /qn /norestart
when: 7zip_installed.exists == true
Некоторые установщики, такие как Microsoft Office или SQL Server, требуют делегирования учетных данных или доступа к компонентам, ограниченным WinRM. Лучший способ обойти эти проблемы — использовать become с задачей. С become, Ansible запустит установщик так, как будто он был запущен интерактивно на хосте.
Примечание
Многие установщики не правильно передают информацию об ошибках через WinRM. В этих случаях, если установка была проверена локально, рекомендуется использовать become.
Примечание
Некоторые установщики перезапускают службы WinRM или HTTP или вызывают их временную недоступность, заставляя Ansible считать систему недоступной.
Установка обновлений
Модули win_updates и win_hotfix могут использоваться для установки обновлений или исправлений на хосте. Модуль win_updates используется для установки нескольких обновлений по категориям, а win_hotfix может использоваться для установки одного обновления или файла исправления, который был загружен локально.
Примечание
Модуль win_hotfix имеет требование, что командлеты DISM PowerShell должны быть присутствовать. Эти командлеты были добавлены по умолчанию только в Windows Server 2012 и более поздних версиях и должны быть установлены на более старых хостах Windows.
Следующий пример показывает, как использовать win_updates.
- name: Install all critical and security updates
win_updates:
category_names:
- CriticalUpdates
- SecurityUpdates
state: installed
register: update_result
- name: Reboot host if required
win_reboot:
when: update_result.reboot_required
Следующий пример показывает, как win_hotfix может использоваться для установки одного обновления или исправления:
- name: Download KB3172729 for Server 2012 R2
win_get_url:
url: http://download.windowsupdate.com/d/msdownload/update/software/secu/2016/07/windows8.1-kb3172729-x64_e8003822a7ef4705cbb65623b72fd3cec73fe222.msu
dest: C:\temp\KB3172729.msu
- name: Install hotfix
win_hotfix:
hotfix_kb: KB3172729
source: C:\temp\KB3172729.msu
state: present
register: hotfix_result
- name: Reboot host if required
win_reboot:
when: hotfix_result.reboot_required
Настройка пользователей и групп
Ansible может использоваться для создания пользователей и групп Windows как локально, так и в домене.
Локальные
Модули win_user, win_group и win_group_membership управляют локальными пользователями, группами и членством в группах Windows.
Ниже приведен пример создания локальных учетных записей и групп, которые могут получить доступ к папке на том же хосте:
- name: Create local group to contain new users
win_group:
name: LocalGroup
description: Allow access to C:\Development folder
- name: Create local user
win_user:
name: '{{ item.name }}'
password: '{{ item.password }}'
groups: LocalGroup
update_password: no
password_never_expires: yes
loop:
- name: User1
password: Password1
- name: User2
password: Password2
- name: Create Development folder
win_file:
path: C:\Development
state: directory
- name: Set ACL of Development folder
win_acl:
path: C:\Development
rights: FullControl
state: present
type: allow
user: LocalGroup
- name: Remove parent inheritance of Development folder
win_acl_inheritance:
path: C:\Development
reorganize: yes
state: absent
Доменные
Модули win_domain_user и win_domain_group управляют пользователями и группами в домене. Ниже приведен пример, гарантирующий создание набора доменных пользователей:
- name: Ensure each account is created
win_domain_user:
name: '{{ item.name }}'
upn: '{{ item.name }}@MY.DOMAIN.COM'
password: '{{ item.password }}'
password_never_expires: no
groups:
- Test User
- Application
company: Ansible
update_password: on_create
loop:
- name: Test User
password: Password
- name: Admin User
password: SuperSecretPass01
- name: Dev User
password: '@fvr3IbFBujSRh!3hBg%wgFucD8^x8W5'
Запуск команд
В тех случаях, когда нет соответствующего модуля для задачи, можно запустить команду или скрипт, используя модули win_shell, win_command, raw, и script.
Модуль raw просто выполняет команду Powershell удаленно. Поскольку raw не имеет обёртки, которые обычно использует Ansible, become, async и переменные окружения не работают.
Модуль script выполняет скрипт с контроллера Ansible на одном или нескольких хостах Windows. Подобно raw, script в настоящее время не поддерживает become, async или переменные окружения.
Модуль win_command используется для выполнения команды, являющейся исполняемым файлом или пакетным файлом, в то время как модуль win_shell используется для выполнения команд в оболочке.
Выбор команды или оболочки
Модули win_shell и win_command могут использоваться для выполнения команды или команд. Модуль win_shell выполняется в оболочке, подобной PowerShell или cmd, поэтому он имеет доступ к операторам оболочки, таким как <, >, |, ;, &&, и ||. Многострочные команды также могут быть выполнены в win_shell.
Модуль win_command просто выполняет процесс вне оболочки. Он по-прежнему может выполнять команду оболочки, такую как mkdir или New-Item, передавая команды оболочки в исполняемый файл оболочки, такой как cmd.exe или PowerShell.exe.
Вот некоторые примеры использования win_command и win_shell:
- name: Run a command under PowerShell
win_shell: Get-Service -Name service | Stop-Service
- name: Run a command under cmd
win_shell: mkdir C:\temp
args:
executable: cmd.exe
- name: Run a multiple shell commands
win_shell: |
New-Item -Path C:\temp -ItemType Directory
Remove-Item -Path C:\temp -Force -Recurse
$path_info = Get-Item -Path C:\temp
$path_info.FullName
- name: Run an executable using win_command
win_command: whoami.exe
- name: Run a cmd command
win_command: cmd.exe /c mkdir C:\temp
- name: Run a vbs script
win_command: cscript.exe script.vbs
Примечание
Некоторые команды, такие как mkdir, del, и copy существуют только в оболочке CMD. Для их выполнения с win_command они должны быть префиксрованы с cmd.exe /c.
Правила аргументов
При выполнении команды через win_command, применяются стандартные правила аргументов Windows:
- Каждый аргумент отделяется пробелом, который может быть пробелом или табуляцией.
- Аргумент может быть заключен в двойные кавычки
". Все, что находится внутри этих кавычек, интерпретируется как один аргумент, даже если он содержит пробелы. - Двойная кавычка, предваряемая обратной косой чертой
\интерпретируется как просто двойная кавычка"и не как разделитель аргументов. - Обратные косые черты интерпретируются буквально, если только они не предшествуют двойным кавычкам; например,
\==\и\"==" - Если за четным числом обратных косых черт следует двойная кавычка, одна обратная косая черта используется для каждой пары, а двойная кавычка используется в качестве разделителя строки для аргумента.
- Если за нечетным числом обратных косых черт следует двойная кавычка, одна обратная косая черта используется для каждой пары, а двойная кавычка экранируется и становится буквальной двойной кавычкой в аргументе.
Учитывая эти правила, вот несколько примеров цитирования:
- win_command: C:\temp\executable.exe argument1 "argument 2" "C:\path\with space" "double \"quoted\""
argv[0] = C:\temp\executable.exe
argv[1] = argument1
argv[2] = argument 2
argv[3] = C:\path\with space
argv[4] = double "quoted"
- win_command: '"C:\Program Files\Program\program.exe" "escaped \\\" backslash" unquoted-end-backslash\'
argv[0] = C:\Program Files\Program\program.exe
argv[1] = escaped \" backslash
argv[2] = unquoted-end-backslash\
# Due to YAML and Ansible parsing '\"' must be written as '{% raw %}\\{% endraw %}"'
- win_command: C:\temp\executable.exe C:\no\space\path "arg with end \ before end quote{% raw %}\\{% endraw %}"
argv[0] = C:\temp\executable.exe
argv[1] = C:\no\space\path
argv[2] = arg with end \ before end quote\"
Дополнительную информацию см. в экранировании аргументов.
Создание и запуск запланированной задачи
WinRM имеет некоторые ограничения, которые вызывают ошибки при выполнении определенных команд. Один из способов обойти эти ограничения — запустить команду через запланированную задачу. Запланированная задача — это компонент Windows, который предоставляет возможность запуска исполняемого файла по расписанию и под другой учетной записью.
В версии Ansible 2.5 были добавлены модули, которые облегчают работу с запланированными задачами в Windows. Следующий пример показывает запуск скрипта в качестве запланированной задачи, который удаляет себя после запуска:
- name: Create scheduled task to run a process
win_scheduled_task:
name: adhoc-task
username: SYSTEM
actions:
- path: PowerShell.exe
arguments: |
Start-Sleep -Seconds 30 # This isn't required, just here as a demonstration
New-Item -Path C:\temp\test -ItemType Directory
# Remove this action if the task shouldn't be deleted on completion
- path: cmd.exe
arguments: /c schtasks.exe /Delete /TN "adhoc-task" /F
triggers:
- type: registration
- name: Wait for the scheduled task to complete
win_scheduled_task_stat:
name: adhoc-task
register: task_stat
until: (task_stat.state is defined and task_stat.state.status != "TASK_STATE_RUNNING") or (task_stat.task_exists == False)
retries: 12
delay: 10
Примечание
Модули, используемые в приведенном выше примере, были обновлены/добавлены в версии Ansible 2.5.
Форматирование путей для Windows
Windows отличается от традиционной операционной системы POSIX во многих аспектах. Одно из основных изменений — переход от / в качестве разделителя путей к \. Это может вызвать серьезные проблемы с тем, как написаны playbook'ы, так как \ часто используется в качестве управляющего символа в системах POSIX.
Ansible поддерживает два разных синтаксиса; каждый по-разному обрабатывает разделители путей для Windows:
Стиль YAML
При использовании синтаксиса YAML для задач правила определяются стандартом YAML:
- При использовании обычной строки (без кавычек), YAML не рассматривает обратную косую черту как управляющий символ.
- При использовании одинарных кавычек
', YAML не рассматривает обратную косую черту как управляющий символ. - При использовании двойных кавычек
", обратная косая черта рассматривается как управляющий символ и должна экранироваться другой обратной косой чертой.
Примечание
Вы должны использовать кавычки только в случае крайней необходимости или если это требуется YAML, а затем использовать одинарные кавычки.
Спецификация YAML рассматривает следующие последовательности экранирования:
-
\0,\\,\",\_,\a,\b,\e,\f,\n,\r,\t,\v,\L,\Nи\P– Экранирование одного символа -
<TAB>,<SPACE>,<NBSP>,<LNSP>,<PSP>– Специальные символы -
\x..– Экранирование 2-значного шестнадцатеричного кода -
\u....– Экранирование 4-значного шестнадцатеричного кода -
\U........– Экранирование 8-значного шестнадцатеричного кода
Вот несколько примеров записи путей Windows:
# GOOD tempdir: C:\Windows\Temp # WORKS tempdir: 'C:\Windows\Temp' tempdir: "C:\\Windows\\Temp" # BAD, BUT SOMETIMES WORKS tempdir: C:\\Windows\\Temp tempdir: 'C:\\Windows\\Temp' tempdir: C:/Windows/Temp
Это пример, который завершится ошибкой:
# FAILS tempdir: "C:\Windows\Temp"
Этот пример демонстрирует использование одинарных кавычек, когда они необходимы:
---
- name: Copy tomcat config
win_copy:
src: log4j.xml
dest: '{{tc_home}}\lib\log4j.xml'
Стиль ключевое слово=значение (legacy)
Синтаксис legacy key=value используется в командной строке для импровизированных команд или внутри playbooks. Использование этого стиля в playbooks не рекомендуется, так как символы обратного слэша требуют экранирования, что усложняет чтение playbooks. Синтаксис legacy зависит от конкретной реализации в Ansible, и кавычки (одинарные и двойные) не оказывают никакого влияния на то, как Ansible его анализирует.
Парсер Ansible ключевое слово=значение parse_kv() учитывает следующие escape-последовательности:
-
\,',",\a,\b,\f,\n,\r,\tи\v– Экранирование одного символа -
\x..– Экранирование 2-значного шестнадцатеричного кода -
\u....– Экранирование 4-значного шестнадцатеричного кода -
\U........– Экранирование 8-значного шестнадцатеричного кода -
\N{...}– Символ Unicode по имени
Это означает, что обратный слэш является символом экранирования для некоторых последовательностей, и обычно безопаснее экранировать обратный слэш в этом формате.
Вот несколько примеров использования путей Windows со стилем ключевое слово=значение:
# GOOD tempdir=C:\\Windows\\Temp # WORKS tempdir='C:\\Windows\\Temp' tempdir="C:\\Windows\\Temp" # BAD, BUT SOMETIMES WORKS tempdir=C:\Windows\Temp tempdir='C:\Windows\Temp' tempdir="C:\Windows\Temp" tempdir=C:/Windows/Temp # FAILS tempdir=C:\Windows\temp tempdir='C:\Windows\temp' tempdir="C:\Windows\temp"
Примеры с ошибками не приводят к полной ошибке, но заменят \t на символ <TAB>, в результате чего tempdir станет C:\Windows<TAB>emp.
Ограничения
Некоторые действия, которые вы не можете выполнить с Ansible и Windows:
- Обновить PowerShell
- Взаимодействовать с слушателями WinRM
Поскольку WinRM зависит от того, что службы активны и работают во время нормальной работы, вы не можете обновлять PowerShell или взаимодействовать с слушателями WinRM с помощью Ansible. Оба этих действия приведут к отказу подключения. Это технически можно избежать, используя async или запланированную задачу, но эти методы хрупкие, если процесс прерывает основное подключение, используемое Ansible, и лучше всего оставить их для процесса начальной загрузки или до создания образа.
Разработка модулей для Windows
Так как модули Ansible для Windows написаны на PowerShell, руководства по разработке модулей для Windows значительно отличаются от руководств для стандартных модулей. Подробнее см. Руководство по разработке модулей для Windows.
См. также
- Руководство пользователя
- Индекс документации
- Работа с Playbooks
- Введение в Playbooks
- Рекомендации по лучшим практикам
- Рекомендации по лучшим практикам
- Список модулей Windows
- Список модулей, специфичных для Windows, все реализованы на PowerShell
- Пользовательский список рассылки
- Есть вопрос? Загляните в группу Google!
- irc.freenode.net
- Чат-канал IRC #ansible
© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.8/user_guide/windows_usage.html