Rate this post

chatopsn

n

Что такое ChatOps?

ChatOps предоставляет контекст работы, который вы уже делаете, в разговорах, которые вы ведете

ChatOps по-прежнему остается свежим и необычным в мире DevOps, когда работа переходит в общий чат. Вы можете запускать команды непосредственно из чата, и все в чате могут видеть историю выполняемой команды, делать то же самое, взаимодействовать друг с другом и даже учиться. Информация и процесс принадлежат всей команде, это приносит много преимуществ.nnВы можете приступить к выполнению таких операций, как развертывание кода или серверов предоставления ресурсов из чата, просмотр графиков из инструментов мониторинга, отправка SMS, контроль ваших кластеров или просто запуск простых команд оболочки. ChatOps может представлять собой высокоуровневое представление вашего действительно сложного процесса CI / CD ,упрощая общение в чатом, например !deploy . Этот подход делает чудеса для повышения наглядности и уменьшения сложности в процессе развертываний.n

Расширенные возможности ChatOps

StackStorm — это проект OpenSource, специально ориентированный на автоматизацию событий ChatOps.Платформа поддерживает множество инструментов DevOps, таких как управление конфигурацией, мониторинг, оповещение, графическое отображение и т. д., что позволяет вам управлять всем из одного центра управления.Это идеальный инструмент для ChatOps, предоставляющий возможность создавать и автоматизировать любые мыслимые рабочие процессы и управлять любыми наборами инструментов непосредственно из чата.nnStackStorm имеет возможность интеграции с Ansible и множество расширенных функций ChatOps в версиях платформы 1.0 , 1.2 и 1.4, чтобы помочь вам в реальной работе, а не просто отображать забавные фотографии котенка из чата. Ниже я расскажу, как сделать ChatOps и Ansible возможным с помощью платформы StackStorm.n

Кстати, StackStorm as Ansible является декларативным, написанным на Python и использующим YAML + Jinja.

План

В этом уроке мы собираемся сначала установить управляющую машину Ubuntu 14, которая будет обрабатывать нашу систему ChatOps. Затем настроим платформу StackStorm, включая пакет интеграции Ansible. Наконец, мы подключим систему с Slack и покажем некоторые простые, но реальные примеры использования Ansible непосредственно из чата интерактивным способом.nnИтак, давайте начнем и убедитесь, что мы близки к технологической сингулярности , предоставив root доступ к ботам чата и позволяя им управлять нашими 100 + серверами и кластерами.n

Шаг 0. Подготовьте Slack

Как уже говорилось, давайте использовать Slack.com для чата. Зарегистрируйтесь в Slack, если у вас ее еще нет. Включите интеграцию Hubot в настройках.n

Hubot — бот-движок GitHub, созданный для ChatOps.

nКак только вы закончите, у вас будет API-токен:n

HUBOT_SLACK_TOKEN=xoxb-5187818172-I7wLh4oqzhAScwXZtPcHyxCu

Затем мы сконфигурируем всю платформу StackStorm, покажем некоторые полезные примеры, а также разрешим создавать собственные команды ChatOps.nn

n

nnНо подождите, есть простой способ!n

Легенький режим!

Для тех, кто ленив (большинство DevOps), вот брандмауэр-репо, которое устанавливает все необходимые инструменты в простых сценариях, подготовив платформу для написания команд ChatOps в Slack chat: https://github.com/StackStorm/showcase-ansible-chatopsn

# replace with your tokennexport HUBOT_SLACK_TOKEN=xoxb-5187818172-I7wLh4oqzhAScwXZtPcHyxCungit clone https://github.com/StackStorm/showcase-ansible-chatops.gitncd showcase-ansible-chatopsnnvagrant up

Для тех, кто интересуется деталями — перейдем к ручному режиму и идем дальше.n

Шаг 1. Установите StackStorm

Это действительно так просто, одна команда:n

curl -sSL https://stackstorm.com/packages/install.sh | sudo bash -- --user=demo --password=demo

Этот однострочный интерфейс предназначен только для демонстрационных целей, для развертывания prod вы должны использовать доступные ansible playbooks для установки st2.

Шаг 2. Установите Ansible Integration pack

Идея интеграции пакетов в StackStorm заключается в том, что они соединяют систему с внешними инструментами или службами. Нам нужен пакет Ansible:n

st2 pack install ansible

Помимо пакета Ansible Integration , он устанавливает существующие двоичные файлы в Python virualenv, расположенный в /opt/stackstorm/virtualenvs/ansible/bin .nn

n

n

Шаг 3. Настройка ChatOps

Теперь вам нужно настроить файл /opt/stackstorm/chatops/st2chatops.env в соответствии с вашими потребностями. Для этого стоит взглянуть на все переменные, но сначала убедитесь, что вы редактируете следующие envs:n

# Bot namenexport HUBOT_NAME=stanleynexport HUBOT_ALIAS='!'nn# StackStorm API keyn# Use: `st2 apikey create -k` to generaten# Replace with your key (!)nexport ST2_API_KEY="123randomstring789"nn# ST2 AUTH credentialsn# Replace with your username/password (!)nexport ST2_AUTH_USERNAME="demo"nexport ST2_AUTH_PASSWORD="demo"nn# Configure Hubot to use Slacknexport HUBOT_ADAPTER="slack"nn# Replace with your token (!)nexport HUBOT_SLACK_TOKEN="xoxb-5187818172-I7wLh4oqzhAScwXZtPcHyxCu"
 Перезапустите st2chatops чтобы применить изменения, и все готово к работе:

n

sudo service st2chatops restart

n

Шаг 4. Первый ChatOps

На этом этапе вы должны увидеть Stanley bot  в чате. Пригласите его в свой канал Slack:n

n

n

n

n

n

n

/invite @stanley

Получить список доступных команд:

n

n

n

n

n

n

n

n

n

n

n

n

!help

Бьюсь об заклад, вы полюбите shipit :

n

n

n

n

n

n

n

n

n

n

n

n

!ship it

После игры с существующими командами, давайте продолжим с чем-то серьезным.nn

n

n

n

n

n

n

Шаг 5. Создание собственных команд ChatOps

Одной из функций StackStorm является возможность создания псевдонимов команд, что упрощает работу с ChatOps. Вместо того, чтобы писать длинную команду, вы можете просто привязать ее к чему-то более дружественному и понятному, простому.nnДавайте создадим собственный пакет StackStorm, который будет содержать все необходимые команды. Шаблон пакета StackStorm  псевдонимов aliases/ansible.yaml со следующим содержимым:n

---nname: "chatops.ansible_local"naction_ref: "ansible.command_local"ndescription: "Run Ansible command on local machine"nformats:n  - display: "ansible <command>"n    representation:n      - "ansible {{ args }}"nresult:n  format: |n    Ansible command `{{ execution.parameters.args }}` result: {~}n    {% if execution.result.stderr %}*Stdout:* {% endif %}n    ```{{ execution.result.stdout }}```n    {% if execution.result.stderr %}*Stderr:* ```{{ execution.result.stderr }}```{% endif %}n  extra:n    slack:n      color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}"
n

n

Теперь переместите ваши изменения в разветвленное репо GitHub, и вы сможете установить только что созданный пакет. Для этого уже существует псевдоним ChatOps:

n

n

n

n

n

n

n

n

n

!pack install https://github.com/armab/st2_chatops_aliases

Теперь мы можем запускать простую команду непосредственно из Slack chat:n

!ansible "uname -a"

ansible chatopsnn

n

n

n

n

n

nКоторая на низком уровне эквивалентена:n

/opt/stackstorm/virtualenvs/ansible/bin/ansible all --connection=local --args='uname -a' --inventory-file='127.0.0.1,'n

nНо давайте рассмотрим более полезные примеры, демонстрирующие преимущества интерактивности ChatOps.n

Пример №1: получить статус сервера

У Ansible есть простой модуль ping, который просто соединяется с указанными узлами и возвращает успех pong .Простой, но мощный пример, чтобы понять, состояние серверов прямо из чата в считанные секунды, без входа в терминал.nnЧтобы сделать это, нам нужно создать еще одно action для нашего пакета, в котором выполняется реальные action alias команды и action alias которые является просто синтаксическим синонимами, Реализуем возможным в ChatOps:n

n

n

n

n

n

n

!status 'web'

Действия actions/server_status.yaml :n

---nname: server_statusndescription: Show server status by running ansible ping ad-hoc commandnrunner_type: local-shell-cmdnentry_point: ""nenabled: truenparameters:n  sudo:n    description: "Run command with sudo"n    type: booleann    immutable: truen    default: truen  kwarg_op:n    immutable: truen  cmd:n    description: "Command to run"n    type: stringn    immutable: truen    default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{hosts}} --module-name=ping"n  hosts:n    description: "Ansible hosts to ping"n    type: stringn    required: true

Псевдонимов действий aliases/server_status.yaml :

n

n

n

n

n

n

---nname: chatops.ansible_server_statusnaction_ref: st2_chatops_aliases.server_statusndescription: Show status for hosts (ansible ping module)nformats:n  - display: "status <hosts>"n    representation:n      - "status {{ hosts }}"n      - "ping {{ hosts }}"nresult:n  format: |n    Here is your status for `{{ execution.parameters.hosts }}` host(s): {~}n    ```{{ execution.result.stdout }}```n  extra:n    slack:n      color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}"n      fields:n        - title: Aliven          value: "{{ execution.result.stdout|regex_replace('(?!SUCCESS).', '')|wordcount }}"n          short: truen        - title: Deadn          value: "{{ execution.result.stdout|regex_replace('(?!UNREACHABLE).', '')|wordcount }}"n          short: truen      footer: "{{ execution.id }}"n      footer_icon: "https://stackstorm.com/wp/wp-content/uploads/2015/01/favicon.png"

nУбедитесь, что вы настроили хосты в файле Ansible inventory /etc/ansible/hosts .nnПосле внесенных изменений не забудьте переустановить отредактированный пакет из чата (замените его на ваш репозиторий github):n

n

n

n

n

n

n

!pack install https://github.com/armab/st2_chatops_aliases

Очень удобно, что вы можете сохранить всю конфигурацию команды ChatOps в удаленном репо, как пакет StackStorm, и перезагрузить его после редактирования.nn

n

n

n

n

n

nДавайте получим статус сервера:nстатус сервера в chatopsnЭто действительно мощно, любой может запустить без доступа к серверу! При таком подходе сотрудничество, деплой и работу вокруг инфраструктуры можно выполнять из любого места в чате: находитесь ли вы в офисе или работаете удаленно (некоторые из нас могут работать непосредственно с пляжа).n

Пример №2: перезапустить службы

У вас были ситуации, когда простой перезапуск службы может решить проблему? Не идеальный способ фиксации сбоя, но иногда вам просто нужно быстро решить проблему. Давайте напишем команду ChatOps, которая перезапускает определенные службы на определенных хостах.nnМы хотим сделать что-то вроде этого:n

!service restart "rabbitmq-server" on "mq"

nВ ранее созданных пакетах StackStorm добавим actions/service_restart.yaml :n

---nname: service_restartndescription: Restart service on remote hostsnrunner_type: local-shell-cmdnentry_point: ""nenabled: truenparameters:n  sudo:n    description: "Run command with sudo"n    type: booleann    immutable: truen    default: truen  kwarg_op:n    immutable: truen  cmd:n    description: "Command to run"n    type: stringn    immutable: truen    default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{hosts}} --become --module-name=service --args='name={{service_name}} state=restarted'"n  hosts:n    description: "Ansible hosts"n    type: stringn    required: truen  service_name:n    description: "Service to restart"n    type: stringn    required: true
n

n

Псевдоним для ChatOps: aliases/service_restart.yaml :

n

n

n

---nname: chatops.ansible_service_restartnaction_ref: st2_chatops_aliases.service_restartndescription: Restart service on remote hostsnformats:n  - display: "service restart <service_name> on <hosts>"n    representation:n      - "service restart {{ service_name }} on {{ hosts }}"nresult:n  format: |n    Service restart `{{ execution.parameters.service_name }}` on `{{ execution.parameters.hosts }}` host(s): {~}n    {% if execution.result.stderr %}n    *Exit Status*: `{{ execution.result.return_code }}`n    *Stderr:* ```{{ execution.result.stderr }}```n    *Stdout:*n    {% endif %}n    ```{{ execution.result.stdout }}```n  extra:n    slack:n      color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}"n      fields:n        - title: Restartedn          value: "{{ execution.result.stdout|regex_replace('(?!SUCCESS).', '')|wordcount }}"n          short: truen        - title: Failedn          value: "{{ execution.result.stdout|regex_replace('(?!(FAILED|UNREACHABLE)!).', '')|wordcount }}"n          short: truen      footer: "{{ execution.id }}"n      footer_icon: "https://stackstorm.com/wp/wp-content/uploads/2015/01/favicon.png"
n

n

Давайте теперь попробуем:

n

n

nchatopsnИ знаешь, что? Благодаря мобильному клиенту Slack вы можете запускать эти команды чата и со своего мобильного телефона!n

Пример №3: Получить в настоящее время MySQL-запросы

Мы хотим, чтобы простая команда slack запрашивала список процессов mysql с сервера db:n

n

n

n

n

n

n

!show mysql processlist

Действие actions/mysql_processlist.yaml :

n

n

n

n

n

n

---nname: mysql_processlistndescription: Show MySQL processlistnrunner_type: local-shell-cmdnentry_point: ""nenabled: truenparameters:n  sudo:n    immutable: truen    default: truen  kwarg_op:n    immutable: truen  cmd:n    description: "Command to run"n    type: stringn    immutable: truen    default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{ hosts }} --become --become-user=root -m shell -a \"mysql --execute='SHOW PROCESSLIST;' | expand -t 10\""n  hosts:n    description: "Ansible hosts"n    type: stringn    default: db
n

n

Action alias для ChatOps: aliases/mysql_processlist.yaml :

n

n

n

---nname: chatops.mysql_processlistnaction_ref: st2_chatops_aliases.mysql_processlistndescription: Show MySQL processlistnformats:n  - display: "show mysql processlist <hosts=db>"n    representation:n      - "show mysql processlist {{ hosts=db }}"n      - "show mysql processlist on {{ hosts=db }}"nresult:n  format: |n    {% if execution.status == 'succeeded' %}MySQL queries on `{{ execution.parameters.hosts }}`: ```{{ execution.result.stdout }}```{~}{% else %}n    *Exit Code:* `{{ execution.result.return_code }}`n    *Stderr:* ```{{ execution.result.stderr }}```n    *Stdout:* ```{{ execution.result.stdout }}```n    {% endif %}
n

n

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

n

n

n

n

n

n

n

n

n

!show mysql processlistn!show mysql processlist 'db'

nn

n

n

n

n

n

nВаш администратор базы данных будет счастлив!n

Пример №4: получить статистику HTTP nginx

Мы хотим показать коды состояния HTTP, сортировать их по поступлению, чтобы понять, сколько 200 или 50x есть на определенных серверах:n

n

n

n

n

n

n

!show nginx stats on 'web'

Фактическое действие, выполняющее actions/http_status_codes.yaml команды actions/http_status_codes.yaml :

n

n

n

n

n

n

---nname: http_status_codesndescription: Show sorted http status codes from nginx logsnrunner_type: local-shell-cmdnentry_point: ""nenabled: truenparameters:n  sudo:n    immutable: truen    default: truen  kwarg_op:n    immutable: truen  cmd:n    description: "Command to run"n    type: stringn    immutable: truen    default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{hosts|replace('http://','')}} --become -m shell -a \"awk '{print \\$9}' /var/log/nginx/access.log|sort |uniq -c |sort -k1,1nr 2>/dev/null|column -t\""n  hosts:n    description: "Ansible hosts"n    type: stringn    required: true
n

n

Псевдоним: aliases/http_status_codes.yaml

n

n

n

---nname: chatops.http_status_codesnaction_ref: st2_chatops_aliases.http_status_codesndescription: Show sorted http status codes from nginx on hostsnformats:n  - display: "show nginx stats on <hosts>"n    representation:n      - "show nginx stats on {{ hosts }}"nresult:n  format: "```{{ execution.result.stdout }}```"
n

n

Результат:

n

n

nnТеперь чат больше похож на центр управления. Вы можете делать что-то на своих хостах из чата, и каждый может видеть результат!n

Пример №5: Патч безопасности

Представьте, что вы должны исправить еще одну критическую уязвимость, такую ​​как Shellshock . Нам нужно обновить bash на всех машинах с помощью Ansible. Вместо того, чтобы запускать его как специальную команду, давайте playbooks/update_package.yaml сделаем красиво playbooks/update_package.yaml :n

---n- name: Update package on remote hosts, run on 25% of servers at a timen  hosts: "{{ hosts }}"n  serial: "25%"n  become: Truen  become_user: rootn  tasks:n    - name: Check if Package is installedn      command: dpkg-query -l {{ package }}n      register: is_installedn      failed_when: is_installed.rc > 1n      changed_when: nonn    - name: Update Package only if installedn      apt: name={{ package }}n        state=latestn        update_cache=yesn        cache_valid_time=600n      when: is_installed.rc == 0

Вы можете видеть, что переменные {{ hosts }} и {{ package }} в playbook вводятся снаружи, см. Действия StackStorm action actions/update_package.yaml :n

---nname: update_packagendescription: Update package on remote hostsnrunner_type: local-shell-cmdnentry_point: ""nenabled: truenparameters:n  sudo:n    immutable: truen    default: truen  kwarg_op:n    immutable: truen  timeout:n    default: 6000n  cmd:n    description: "Command to run"n    immutable: truen    default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible-playbook /opt/stackstorm/packs/${ST2_ACTION_PACK_NAME}/playbooks/update_package.yaml --extra-vars='hosts={{hosts|replace('http://','')}} package={{package}}'"n  hosts:n    description: "Ansible hosts"n    type: stringn    required: truen  package:n    description: "Package to upgrade"n    type: stringn    required: true
n

n

И вот псевдоним действия, который позволяет запускать playbook как простую команду в чате,

n

n

naliases/update_package.yaml :n

---nname: chatops.ansible_package_updatenaction_ref: st2_chatops_aliases.update_packagendescription: Update package on remote hostsnformats:n  - display: "update <package> on <hosts>"n    representation:n      - "update {{ package }} on {{ hosts }}"n      - "upgrade {{ package }} on {{ hosts }}"nresult:n  format: |n    Update package `{{ execution.parameters.package }}` on `{{ execution.parameters.hosts }}` host(s): {~}n    {% if execution.result.stderr %}n    *Exit Status*: `{{ execution.result.return_code }}`n    *Stderr:* ```{{ execution.result.stderr }}```n    *Stdout:*n    {% endif %}n    ```{{ execution.result.stdout }}```n  extra:n    slack:n      color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}"n      fields:n        - title: Updated nodesn          value: "{{ execution.result.stdout|regex_replace('(?!changed=1).', '')|wordcount }}"n          short: truen        - title: Executed inn          value: ":timer_clock: {{ execution.elapsed_seconds | to_human_time_from_seconds }}"n          short: truen      footer: "{{ execution.id }}"n      footer_icon: "https://stackstorm.com/wp/wp-content/uploads/2015/01/favicon.png"
n

n

В заключение:

n

n

n

n

n

n

n

n

n

!update 'bash' on 'all'

nn

n

n

n

n

n

nБольшая часть нашей работы, как инженеров DevOps, — это оптимизировать процессы, упрощая жизнь разработчиков, улучшая сотрудничество в команде, диагностировать проблемы быстрее, автоматизируя среду и привнося нужные инструменты, чтобы сделать компанию успешной.nChatOps решает это на совершенно новом эффективном уровне!nnЭто простые примеры. Более сложные ситуации, когда несколько инструментов DevOps привязаны к динамическим рабочим процессам, будут рассмотрены в будущих статьях. Именно здесь StackStorm демонстрирует свою супермощность, принимая решения о том, что делать в зависимости от ситуации: управляемая событиями архитектура, такая как системы самовосстановления.n

Хотите упростить работу?  Обращайтесь [email protected]

n

n