Представьте, что у Вас 20 серверов 1С и пришло время обновления релиза платформы. Нужно на каждом сервере установить новую версию платформы, удалить старую, поднять службу агента сервера и т.д. Накапливается масса рутинных операций. Есть несколько вариантов решения. Пойдем от сложного к простому:
- Вручную
- Полуавтоматический — подготовить скрипт установки и выполнить его на каждой машине
- Автоматический — воспользоваться системой удаленного управления конфигурациями, т.е. с одной машины дать всем серверам команду на выполнение скрипта установки
В статье будет показано как использовать Ansible для подобного рода задач.
Ansible — система управления конфигурациями, написанная на Python, с использованием декларативного языка разметки для описания конфигураций. Используется для автоматизации настройки и развертывания программного обеспечения. Обычно используется для управления Linux-узлами, но Windows также поддерживается.
С помощью Ansible вы можете написать сценарий автоматизации любой сложности, от создания пользователя, до поднятия сложного окружения продуктивного сервера.
Пойдем по порядку:
В качестве управляющей ноды (где будет установлен Ansible) может выступать только машина с ОС Linux. Поддерживается большинство дистрибутивов. В качестве хостов (где будут выполняться сценарии) могут выступать как Linux, так и Windows машины.
В примере, на управляющей ноде установлена ОС CentOS 7
Установка Ansible:
sudo yum install ansible
Подготовка файла Inventory:
Файл Inventory содержит в себе список хостов, к которым Ansible может подключиться. По умолчанию это файл /etc/ansible/hosts.
Файл имеет гибкую настройку, мы будем использовать следующую сигнатуру указания хостов.
[group_name] server_ip
Добавим в него два сервера и объединим их в группу [appservers]
[appservers] 192.168.0.15 192.168.0.16
Подготовка Windows хоста для работы с Ansible:
Если в случае с Linux хостами доступ к ним осуществляется по SSH и все работает “из коробки”, то для того чтобы Ansible мог управлять Windows хостами, нужно на них включить службу удаленного управления (WS-Management).
В репозитории Ansible есть PowerShell скрипт который выполнит всю предварительную настройку Windows хоста:
https://github.com/ansible/ansible/blob/devel/examples/scripts/ConfigureRemotingForAnsible.ps1
Запускаем скрипт на Windows машине
powershell.exe -File ConfigureRemotingForAnsible.ps1
Более подробную информацию по настройке Windows хоста можно посмотреть тут:
https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html
Настройка подключения Ansible к группам хостов:
После того как мы подготовили файл Inventory и настроили хост машины, нужно указать параметры подключения к этим машинам (под каким пользователем, через что подключаемся). Настройки подключения хранятся в каталоге /etc/ansible/group_vars
Для каждой группы создается одноименный файл, в котором указываются параметры подключения.
Создаем каталог:
mkdir /etc/ansible/group_vars
Создаем файл с именем нашей группы appservers:
vi /etc/ansible/group_vars/appservers
И вводим в него следующие параметры:
ansible_user: ansible ansible_port: 5985 ansible_connection: winrm ansible_winrm_transport: credssp ansible_winrm_server_cert_validation: ignore
Теперь, ко всем хостам группы appservers, Ansible будет подключаться используя вышеуказанные параметры. Пароль от пользователя ansible мы также можем указать в файле appservers добавив строку:
ansible_password: p@ssw0rd
В целях безопасности мы этого не делаем и запрашивать пароль будем в момент запуска сценария, указав ключ —ask-pass
Проверка подключения Ansible к группе хостов:
Для проверки подключения будем использовать модуль win_ping. Все модули которые могут выполнятся на Windows хостах начинаются с префикса win_. Подробное описание всех модулей можно найти в официальном сайте.
Выполняем команду
ansible appservers -m win_ping
В случае успешного подключения получим сообщение
192.168.0.15 | SUCCESS => { "changed": false, "ping": "pong" }
Плэйбуки (сценарии) Ansible
Playbook (файл сценариев) — это файл, в котором описываются действия, которые нужно выполнить на какой-то группе хостов. Сценарии описываются в формате YAML
Плэйбук представляет собой набор задач (tasks). Каждая задача выполняется определенным модулем.
В плэйбуке по установке сервера 1С использованы следующие модули:
- win_service — модуль для работы со службами
- set_fact — модуль для работы с переменными
- win_package — модуль установки/удаления пакетов Windows
Отдельно стоит отметить шифрование паролей в плэйбуке. Для этого используется ansible-vault (зашифрованное хранилище)
Чтобы поместить пароль в хранилище воспользуемся следующей командой:
echo -n "p@ssw0rd" | ansible-vault encrypt_string
Ansible потребует установить пароль для vault. Важно его запомнить, т.к. при утере восстановить исходный пароль будет уже невозможно.
В результате выполнения команды получим пароль в зашифрованном виде:
!vault | $ANSIBLE_VAULT;1.1;AES256 64396632346366373434356466396230364121656130363134316537306339643265656637366565 3763393238623632663732623034313738386561356232320a333766336638646137316463363031 66666435333939663832353937623638643764336662343834663338623666653965366233343536 3232633839646337300a333935333663613864306230343538653837353936373564623636366664 3537
Теперь вместо пароля мы можем указывать данную строку.
Пример плэйбука по установке платформы:
---
# Playbook для обновления релиза платформы на серверах приложений
- name: Install 1C Enterprise Application Server
hosts: appservers
# Переменные доступные плэйбуку
vars:
v8version: 8.3.15.1565
server_agent_srv_name: '1C:Enterprise 8.3 Server Agent'
server_agent_params: '-srvc -agent -regport 1541 -port 1540 -range 1560:1591 -d "C:Program Files1cv8srvinfo" -debug'
ras_srv_name: '1C:Remote Administation Service (RAS)'
platform_distr_path: \1CПлатформа8_3_15_1565setup.exe
bin_path: C:Program Files1cv8{{ v8version }}in
srv_1c_pwd: !vault |
$ANSIBLE_VAULT;1.1;AES256
64396632346366373434356466396230364121656130363134316537306339643265656637366565
3763393238623632663732623034313738386561356232320a333766336638646137316463363031
66666435333939663832353937623638643764336662343834663338623666653965366233343536
3232633839646337300a333935333663613864306230343538653837353936373564623636366664
3537
tasks:
- name: Test connection
win_ping:
# Проверка наличия службы сервера 1С
- name: Check if a server agent service is installed
win_service:
name: '{{ server_agent_srv_name }}'
register: server_agent_srv_info
# Проверка наличия службы удаленного администрирования RAS
- name: Check if a RAS service is installed
win_service:
name: '{{ ras_srv_name }}'
register: ras_srv_info
# Остановка службы сервера 1С
- name: Stop server agent service
win_service:
name: '{{ server_agent_srv_name }}'
state: stopped
when: server_agent_srv_info.exists
# Остановка службы службы удаленного администрирования RAS
- name: Stop RAS service
win_service:
name: '{{ ras_srv_name }}'
state: stopped
when: ras_srv_info.exists
# Удаление службы сервера 1С
- name: Remove server agent service
win_service:
name: '{{ server_agent_srv_name }}'
state: absent
when: server_agent_srv_info.exists
# Сохранение параметров службы сервера 1С (?<=ragent.exes).*(?=")
- name: Save server agent params
set_fact:
server_agent_params: "{{ server_agent_srv_info.path | regex_search('(?<=ragent.exe\s).*(?=")') }}"
when: server_agent_srv_info.exists
# Удаление службы удаленного администрирования RAS
- name: Remove RAS service
win_service:
name: '{{ ras_srv_name }}'
state: absent
when: ras_srv_info.exists
# Удаление платформы
- name: Uninstall 1C Enterpise 8.3
win_package:
product_id: '{24877BC3-0D30-4F0E-A840-EDB9DBB30D47}' # HKLM:SoftwareMicrosoftWindowsCurrentVersionUninstall
state: absent
# Установка сервера 1С
- name: Install 1C Enterprise Application Server
win_package:
path: '{{ platform_distr_path }}'
product_id: '{24877BC3-0D30-4F0E-A840-EDB9DBB30D47}'
arguments: 'DESIGNERALLCLIENTS=1 THINCLIENTFILE=0 THINCLIENT=1 WEBSERVEREXT=1 SERVER=1 CONFREPOSSERVER=0 CONVERTER77=0 SERVERCLIENT=1 LANGUAGES=RU'
# Создание службы агента сервера 1С
- name: Create a new server agent service
win_service:
name: '{{ server_agent_srv_name }}'
path: '{{ bin_path }}
agent.exe {{ server_agent_params }}'
start_mode: auto
username: srv_1c
password: '{{ srv_1c_pwd }}'
# Создание службы удаленного администрирования RAS
- name: Create a new RAS service
win_service:
name: '{{ ras_srv_name }}'
path: '{{ bin_path }}
as.exe cluster --service --port=1545 localhost:1540'
start_mode: auto
Запуск плэйбука:
ansible-playbook playbook.yml --ask-vault-pass --ask-pass
Ключ —ask-vault-pass потребует ввода пароля от зашифрованного хранилища
Ключ —ask-pass потребует ввода пароля от учетной записи под которой ansible подключается к хост машине (в нашем случае это УЗ ansible)
Лог выполнения:
PLAY [Install 1C Enterprise Application Server] *************************************************************************************************************************************************** TASK [Gathering Facts] **************************************************************************************************************************************************************************** ok: [192.168.0.15] TASK [Test connection] **************************************************************************************************************************************************************************** ok: [192.168.0.15] TASK [Check if a server agent service is installed] *********************************************************************************************************************************************** ok: [192.168.0.15] TASK [Check if a RAS service is installed] ******************************************************************************************************************************************************** ok: [192.168.0.15] TASK [Stop server agent service] ****************************************************************************************************************************************************************** ok: [192.168.0.15] TASK [Stop RAS service] *************************************************************************************************************************************************************************** ok: [192.168.0.15] TASK [Remove server agent service] **************************************************************************************************************************************************************** changed: [192.168.0.15] TASK [Remove RAS service] ************************************************************************************************************************************************************************* changed: [192.168.0.15] TASK [Uninstall 1C Enterpise 8.3] ***************************************************************************************************************************************************************** changed: [192.168.0.15] TASK [Install 1C Enterprise Application Server] *************************************************************************************************************************************************** changed: [192.168.0.15] TASK [Create a new server agent service] ********************************************************************************************************************************************************** changed: [192.168.0.15] TASK [Create a new RAS service] ******************************************************************************************************************************************************************* changed: [192.168.0.15] PLAY RECAP **************************************************************************************************************************************************************************************** 192.168.0.15 : ok=13 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Плэйбук выполнился без ошибок. Платформа обновлена, службы подняты.
Полезные ссылки:
Официальная документация Ansible: https://docs.ansible.com/
Репозиторий Ansible: https://github.com/ansible/ansible
Пойдем от сложного к простому:
…
4. Политикой домена с запуском cmd скрипта с 2мя строками msiexec удаления — установки платформы + ещё 2 строки для удаления — установки RAS.
Запамятовал уже как, но раньше делали, что все клиенты стартутют из одной папки
(1) а ежели нет домена…. читаем статью?
(3) Если нет общего домена или домены не в лесе — то это, скорее всего, разные (независимые) организации. Будь я сотрудником безопасности этих организаций, у меня возникли бы вопросы. Например, о безопасности «поднятия хоста» удаленного управления на продакш сервере 1С, куда может в любой момент прилететь по ssh команда с правами администратора.
По мне так намного «секьюрней» выполнять из планировщика заданий или автозагрузки системы ps1 файл в облаке (под локальным админом) который бы устанавливал msi файл из того же облака.
Как откатить изменения, если что-то пошло не так?
(4) если нет общего домена, то это, скорее всего магазины). На самом деле без vpn доступ по ssh (с каким-нибудь fail2ban) как раз мировая норма, в отличие от того же проброса 3389 наружу. Автор — молодчага, хотя бы просто потому, что бикоз хи кэн)
(5) Отката нет, но можно описать сценарий по условию, на случай, если что-то пошло не так. Например, если служба не запустилась.
Либо какие-то «бекапы» делать перед выполнением и возвращаться к ним опять же отдельными тасками.
(7)
А не проще родными средствами (PowerShell)?
(9) ssh — транспортный протокол, pwsh — язык и среда исполнения, как одно заменяет другое? Если Вы имели в виду использование транспорта winrm или ipc$ через тот же psexec, то тут, конечно, вопрос личных предпочтений, кому как удобней)
(10)Ну не придирайтесь :). Вы ведь поняли, что речь идет о средствах управления, а не о транспортном протоколе. Playbook из статьи как раз использует WinRM, а PowerShell может быть настроен через ssh так, что вопрос был в том, что не проще ли использовать штатное средство удаленного администрирования (PowerShell), которое уже входит в состав системы и настраивается несколькими строками (Enable-PSRemoting … или GPO etc.)?
Ну и собственно:
$session = New-PSSession -ComputerName «МойКомпьютер»
Invoke-Command -Session $session -ScriptBlock МойКусокКода
Или интерактивно:
Enter-PSSession $session
Ну и далее руками.
Просто Вы написали, что круто, потому, что хи кен, а я спросил what is this for? 🙂
(9) не проще, если у вас часть серверов на Win, часть на Linux. Playbooks удобны тем, что весь зоопарк управляется единообразно.
автору — вы не пробовали ssh пару ключей (закрытый/открытый) для аутентификацци с Linux на Win? Хранить пароль в текстовике некошерно, а вводит вручную — лень 🙂
(12)Согласен. Примерно это и хотел услышать. И наверное все определяется соотношением Windows и Linux серверов/рабочих станций. Полагаю, что если у вас 10500 серверов Windows и 20 Linux имеет смысл установить PowerShell на эти 20 серверов. Соответственно если 100500 серверов/рабочих станций Linux и 20 Windows, предлагаемая схема вполне рабочая.
(14)Ансибл сейчас на хайпе, у него куча готовых ролей, разного рода инструменты типа Ansible Tower и AWX. То есть, теоретически это удобнее чем самому писать скрипты на PS
(15)Я так понимаю, ключевое слово — на хайпе 🙂 На мой взгляд, несколько странно платить деньги за операционную систему и не пользоваться предоставляемыми инструментами и возможностями, за которые вы заплатили.
Ansible Tower — по моему совершенно не бесплатен, тогда уж надо сравнивать с System Center.
Ну вот теоретически :), а практически — возникли ошибки при выполнении playbook, не стартовала служба или что-то еще, что Вы будете делать? Полагаю, что что-то типа $session = New-PSSession и.т.п. 🙂
(16)да, все так, для каждого кейса свой инструмент. если плейбук кривой, то да, цепляемся по ssh, стартуем службу руками, материмся, переписываем плейбук… Никакой магии. Но в целом, многие сейчас пропагандируют IAC, декларативное описание инфрастурктруры и все такое. А инструменты типа Ansible хорошо в эту идеологию укладываются.
(17)IAC можно реализовать как в декларативном так и в процедурном стиле, тут наверное вопрос вкуса. Если хочется декларативного подхода, можно использовать DSC, который является штатной фичей ОС Windows и под капотом которого как и в случае с Ansible — все те же процедуры. Тут наверное стоит учесть размер инфрастуктуры. Если она небольшая — то это как из пушки по воробьям.
(18)если вы говорите про то, что нечего тащить инструментарий Linux на Win, если есть стабильные нативные решения, то я не спорю. Плясать потом с виртуалками или с Windows Subsystem Linux — то еще удовольствие. Другое дело, если у вас скажем 50 серверов на Linux и парочка на Win, и те скоро мигрируют…
(19)Полностью с Вами согласен.
(13) Изначально так и хотел сделать, но при работе через WinRM использование ssh ключей не поддерживается.
В версии 2.8 добавили экспериментальный функционал по этому поводу. Как попробую, обязательно поделюсь опытом.
такой режим подойтет только если уже вручную устанвливали сервер 1с и установленные компоненты уже сохранились в C:ProgramData1C1CEStart1CEStart.cfg
при этом каждый раз надо искать product_id
Показать
(22)
…
src: files/getmsifile.ps1
dest: C:1cinstallgetmsifileinfo.ps1
— name: get msi product id
win_shell: C:1cinstallgetmsifileinfo.ps1
…
Вот и возникает вопрос, а нужен ли здесь Ansible?