Использование 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 through Chocolatey
win_chocolatey:
name: 7zip
state: present
- name: Ensure 7-Zip is not installed through 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 through win_package
win_package:
path: C:\temp\7z.msi
state: present
- name: Ensure 7-Zip is not installed through 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 through 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 through 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 управляют локальными пользователями, группами и членством в группах.
Ниже приведен пример создания локальных учетных записей и групп, которые могут получить доступ к папке на том же хосте:
- 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: false
password_never_expires: true
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: true
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: false
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 во многих аспектах. Одно из основных отличий — изменение разделителя путей с / на \. Это может привести к серьезным проблемам при написании playbooks, поскольку \ часто используется как символ экранирования в системах 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 key=value
Легальный синтаксис key=value используется в командной строке для разовых команд или внутри playbooks. Использование этого стиля в playbooks не рекомендуется, поскольку символы обратной косой черты необходимо экранировать, что усложняет чтение playbooks. Легальный синтаксис зависит от конкретной реализации в Ansible, и кавычки (одинарные и двойные) не оказывают никакого влияния на способ его обработки Ansible.
Парсер Ansible key=value parse_kv() обрабатывает следующие последовательности экранирования:
-
\,',",\a,\b,\f,\n,\r,\tи\v– Экранирование одного символа -
\x..– Экранирование 2-значного шестнадцатеричного кода -
\u....– Экранирование 4-значного шестнадцатеричного кода -
\U........– Экранирование 8-значного шестнадцатеричного кода -
\N{...}– Экранирование символа по имени Юникода
Это означает, что обратная косая черта является символом экранирования для некоторых последовательностей, и обычно безопаснее экранировать обратную косую черту в этом формате.
Вот несколько примеров использования путей Windows со стилем key=value:
# 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 полагается на то, что службы активны и работают во время обычной работы, с Ansible нельзя обновлять PowerShell или взаимодействовать с прослушивателями WinRM. Оба этих действия приведут к отказу подключения. Это можно технически избежать, используя async или задачу планировщика, но эти методы небезопасны, если процесс прерывает подключение, используемое Ansible, и лучше всего оставить их для процесса загрузки или перед созданием образа.
Разработка модулей Windows
Поскольку модули Ansible для Windows написаны на PowerShell, руководства по разработке для модулей Windows существенно отличаются от руководств по стандартным модулям. Подробнее ознакомьтесь с инструкцией по разработке модулей Windows.
См. также
- Playbooks Ansible
-
Введение в playbooks
- Советы и рекомендации для playbooks Ansible
-
Советы и рекомендации по playbooks
- Список модулей Windows
-
Список специфических модулей для Windows, все реализованы на PowerShell
- Связь
-
Есть вопросы? Нужна помощь? Хотите поделиться своими идеями? Посетите руководство Ansible по общению
© 2012–2018 Michael DeHaan
© 2018–2024 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/latest/os_guide/windows_usage.html