
ChatOpsãšã¯äœã§ããïŒ
ChatOpsã¯ãã€ã³ãã©ã¹ãã©ã¯ãã£ã§ã®äœæ¥ãäžè¬çãªãã£ããã«ç§»è¡ããããšãã«ãDevOpsã®äžçã§ã¯ãŸã æ°é®®ã§çããåºæ¥äºã§ãã éçºè /ã·ã¹ãã 管çè ã¯ãã£ããããçŽæ¥ã³ãã³ããå®è¡ã§ããéçºè /ã·ã¹ãã 管çè ã¯ãªã¢ã«ã¿ã€ã ã§äœãèµ·ãã£ãŠãããã確èªããå€æŽå±¥æŽã衚瀺ããããŒã ãå®è¡ããä»äºã«é¢ããã³ãã¥ãã±ãŒã·ã§ã³ãç¶æããçµéšãå ±æããããšããã§ããŸãã ãããã£ãŠãæ å ±ãšã¯ãŒã¯ãããŒã¯ããŒã å šäœã«å±ããããã«ã¯å€ãã®å©ç¹ããããŸãã
ã³ãŒãã®å±éããã£ããããã®ãµãŒããŒã®å±éãç£èŠã¹ã±ãžã¥ãŒã«ã®è¡šç€ºãSMSã®éä¿¡ãã¯ã©ã¹ã¿ãŒã®ç®¡çãã·ã§ã«ã³ãã³ãã®å®è¡ãªã©ãèããããšãã§ããŸãã ChatOpsã¯ãéåžžã«è€éãªCI / CDã·ã¹ãã ã®é«ã¬ãã«ã®è¡šçŸã§ããã次ã®ãããªãã£ããã³ãã³ãã§ã·ã³ãã«ãããããããŸãã ãã®ã¢ãããŒãã¯ãå¯èŠæ§ãæ¹åããå±éããã»ã¹ã®è€éãã軜æžããããšã«ã¯é©ç°çã§ãã
ChatOpsã®æ¹å
StackStormã¯ãèªååãšChatOpsã«ç¹ã«éç¹ã眮ãããªãŒãã³ãœãŒã¹ãããžã§ã¯ãã§ãã ãã®ãã©ãããã©ãŒã ã¯ãæ§æ管çãç£èŠãã°ã©ããã¢ã©ãŒããªã©ã®èšå€§ãªæ°ã®æ¢åã®DevOpsããŒã«ãæ¥ç¶ããŸãã äžç·ã«ãåäžã®ãã§ãã¯ãã€ã³ããããã¹ãŠãæ¯é ã§ããŸãã ãŸããããã¯ChatOpsã®èŠ³ç¹ããçæ³çã§ãããã£ããããçŽæ¥ããŒã«ããã¯ã¹ãå¶åŸ¡ããããšã§ãèããããã¯ãŒã¯ãããŒãšèããããªãã¯ãŒã¯ãããŒãäœæããã³èªååã§ããŸãã
StackStormã«ã¯Ansibleãçµ±åãããŠãããããŒãžã§ã³1.0以éã§ã¯ãããå€ãã®ChatOpsæ©èœã1.2ããã³1.4ãªãªãŒã¹ã§è¿œå ããããããã䜿çšããŠé¢çœãç«ã®åçãæçš¿ããã ãã§ãªããChatOpsã®å®éã®ã¢ããªã±ãŒã·ã§ã³ãžã®éãéããŸãã ãã®èšäºã§ã¯ãStackStormãã©ãããã©ãŒã ã䜿çšããŠChatOpsãšAnsibleãåäœãããæ¹æ³ã説æããŸãã
ã¡ãªã¿ã«ãStackStormã¯Ansibleã®ããã«ãPythonã§èšè¿°ããã宣èšåã§ãããYaml + Jinjaã䜿çšããŠããŸããããã«ããããããããããªããŸãã
èšç»
æåã«ãUbuntu 14ã§å®è¡ãããå¶åŸ¡ãã·ã³ãã€ã³ã¹ããŒã«ããŸãã次ã«ãHubotãã¬ãŒã ã¯ãŒã¯ãåããAnsibleããã³ChatOpsã³ã³ãããŒã«ããã¯ãå«ãStackStormãã©ãããã©ãŒã ãæ§æããŸãã æåŸã«ãã·ã¹ãã å šäœãSlackãã£ããã«æ¥ç¶ããAnsibleã®ã€ã³ã¿ã©ã¯ãã£ããªäœ¿çšã®ç°¡åã ãå®éã®äŸãããã€ã瀺ããŸãã
å§ããŸããããåæã«ãã©ããŸã§é²ãã ãã æè¡çãªç¹ç°ç¹ãæ¥ããã©ããã確èªãããã£ããããããžã®ã«ãŒãã¢ã¯ã»ã¹ãèš±å¯ãã100以äžã®ãµãŒããŒãããŒã¿ã»ã³ã¿ãŒã管çã§ããããã«ããŸãïŒã¡ãªã¿ã«ãRackSpaceã¯ChatOpsãšé£æºããŸãïŒã
ã¹ããã0. Slackãæºåãã
ãã§ã«è¿°ã¹ãããã«ããã£ãããã©ãããã©ãŒã ãšããŠSlack.comã䜿çšããŸãïŒä»ã®çµ±åãå©çšå¯èœã§ãïŒã Slackã¢ã«ãŠã³ãããŸã ãæã¡ã§ãªãå Žåã¯ç»é²ããŠãã ããã èšå®ã§Hubotçµ±åãæå¹ã«ããŸãã
Hubot - ChatOpså°çšã«èšèšãããGitHubããããã¬ãŒã ã¯ãŒã¯

ãã®çµæãSlackã¯æ¬¡ã®ãããªAPIããŒã¯ã³ãæäŸããŸãã
HUBOT_SLACK_TOKEN=xoxb-5187818172-I7wLh4oqzhAScwXZtPcHyxCu
次ã«ãStackStormãã©ãããã©ãŒã ãæ§æããå®éã®äœ¿çšäŸã瀺ããŸãããã¡ãããç¬èªã®ChatOpsã³ãã³ããäœæããæ¹æ³ã説æããŸãã
ããããåŸ ã£ãŠãç°¡åãªæ¹æ³ããããŸãïŒ
æãæ Forãª
æ ãè ïŒã»ãšãã©ã®DevOpséçºè ïŒã«ã¯ãVagrantã䜿çšããŠç¹å¥ã«æºåããããªããžããªããããã·ã³ãã«ãªbashã¹ã¯ãªããã®å©ããåããŠå¿ èŠãªãã®ããã¹ãŠã€ã³ã¹ããŒã«ããã¹ã¿ãŒãã©ã€ã³ãããã£ããã·ã¥ã©ã€ã³ã«çŽæ¥ç§»åããŠãèªåã€ã³ã¹ããŒã«åŸã«ã·ã§ãŒã±ãŒã¹ Slackãã£ããããChatOpsã³ãã³ããããã«èµ·åã§ããŸã-ansible-chatops ïŒ
# export HUBOT_SLACK_TOKEN=xoxb-5187818172-I7wLh4oqzhAScwXZtPcHyxCu git clone https://github.com/StackStorm/showcase-ansible-chatops.git cd showcase-ansible-chatops vagrant up
詳现ã«èå³ããã人ã®ããã«-èªåã¢ãŒãããæåã¢ãŒãã«åãæ¿ããŠããã¹ãŠã®ã¹ããããå®è¡ããŸãã ããŸããããªãå Žåã¯æ³šæããŠãã ãã-ansibleïŒchatopsãã¢ãªããžããªã®äŸãã芧ãã ããã
ã¹ããã1. StackStormãã€ã³ã¹ããŒã«ãã
ã€ã³ã¹ããŒã«ã¯ç°¡åã§ãã 1ããŒã ã®ã¿ïŒ
curl -sSL https://stackstorm.com/packages/install.sh | sudo bash -- --user=demo --password=demo
ããã¯ãã¢ã³ã¹ãã¬ãŒã·ã§ã³çšã§ããããšãå¿ããªãã§ãã ããã éçšç°å¢ãå±éãããšãã¯ã Ansible Playbookã䜿çšããŠçœ²åã確èªã ãã€ã³ã¹ããŒã«ã³ãã³ãã1è¡ã§ä¿¡é Œããªãã§ãã ããïŒ ã€ã³ã¹ããŒã«ã®è©³çŽ°ã¯ãããã¥ã¡ã³ãã«èšèŒãããŠããŸãïŒ docs.stackstorm.com/install/deb.html
ã¹ããã2. StackStormãã©ã°ã€ã³ã®ã€ã³ã¹ããŒã«ïŒAnsible
StackStormã®çµ±åããã¯ïŒãã©ã°ã€ã³ïŒã®ã¢ã€ãã¢ã¯ãã·ã¹ãã ãä»ã®ããŒã«ãå€éšãµãŒãã¹ãšæ¥ç¶ãããšãããã®ã§ãã
ãã®ãããAnsibleããã¯ãå¿ èŠã§ããã€ã³ã¹ããŒã«ïŒ
st2 pack install ansible
Ansibleèªäœã¯Python virtualenvã§å©çšå¯èœã«ãªããŸãïŒ
/opt/stackstorm/virtualenvs/ansible
çµ±åã®å®å šãªãªã¹ãïŒ exchange.stackstorm.org ããã®äžïŒAWS
ãGitHub
ãRabbitMQ
ãPagerduty
ãJenkins
ãNagios
ãDocker
ãåèšã§100以äž
ã¹ããã3. ChatOpsãæ§æãã
次ã«ãç°å¢å€æ°ã䜿çšããŠ
/opt/stackstorm/chatops/st2chatops.env
ãã¡ã€ã«ãæ§æããå¿ èŠããããŸãã
stanley
ãšããååã®Slackããããæ¢ãæ¹æ³ã¯æ¬¡ã®ãšããã§ãã
# Bot name export HUBOT_NAME=stanley export HUBOT_ALIAS='!' # StackStorm API key # Use: `st2 apikey create -k` to generate # Replace with your key (!) export ST2_API_KEY="123randomstring789" # ST2 AUTH credentials # Replace with your username/password (!) export ST2_AUTH_USERNAME="demo" export ST2_AUTH_PASSWORD="demo" # Configure Hubot to use Slack export HUBOT_ADAPTER="slack" # Replace with your token (!) export HUBOT_SLACK_TOKEN="xoxb-5187818172-I7wLh4oqzhAScwXZtPcHyxCu"
å€æŽåŸããµãŒãã¹ãåèµ·åããããšãå¿ããªãã§ãã ããã
sudo service st2chatops restart
ã¹ããã4.æåã®ChatOpsãšã¯ã¹ããªãšã³ã¹
ãã®æç¹ã§ãStanleyãããã¯ãªã³ã©ã€ã³ãã£ããããŠããã¯ãã§ãã 圌ãç¹å®ã®Slackã«ãŒã ã«æåŸ ããã«ã¯ïŒ
/invite @stanley
å©çšå¯èœãªã³ãã³ãã®ãªã¹ããååŸããŸãã
!help
ãã£ãšããªãã¯shipitã奜ãã«ãªãã§ãããïŒ
!ship it
æ¢åã®ããŒã ã§ååã«ãã¬ãŒããã®ã§ãç§ãã¡ã¯æ¬åœã«çå£ãªããšãããŸãã
ã¹ããã5.ç¬èªã®ChatOpsã³ãã³ããäœæãã
StackStormã®æ©èœã®1ã€ã¯ãããŒã ã®åšãã«åçŽãªãšã€ãªã¢ã¹/ã©ãããŒãäœæããæ©èœã§ãããChatOpsã§ã®äœæ¥ã容æã«ãªããŸãã é·ãã³ãã³ããå ¥åãã代ããã«ããããããå奜çã§ç°¡åãªæ§æç³ã«ãã€ã³ãããããšãã§ããŸãã
ãããã£ãŠãå¿ èŠãªã³ãã³ããå«ãç¬èªã®StackStormããã¯ãäœæããŸãã GitHubã§StackStormãã³ãã¬ãŒãããã¯ããã©ãŒã¯ããŸãã æåã®ã¢ã¯ã·ã§ã³ãšã€ãªã¢ã¹
aliases/ansible.yaml
ïŒ
--- name: "chatops.ansible_local" action_ref: "ansible.command_local" description: "Run Ansible command on local machine" formats: - display: "ansible <command>" representation: - "ansible {{ args }}" result: format: | Ansible command `{{ execution.parameters.args }}` result: {~} {% if execution.result.stderr %}*Stdout:* {% endif %} ```{{ execution.result.stdout }}``` {% if execution.result.stderr %}*Stderr:* ```{{ execution.result.stderr }}```{% endif %} extra: slack: color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}"
åèïŒäžèšã®ãšã€ãªã¢ã¹ã¯ã ansible st2çµ±åããã¯ã䜿çšããŸã
æ°ããäœæãããGitHubãªããžããªã«å€æŽãéä¿¡ããããã¯ãã€ã³ã¹ããŒã«ã§ããŸãã ããã«ã¯ãã§ã«ChatOpsãšã€ãªã¢ã¹ããããŸãã
!pack install https://github.com/armab/st2_chatops_aliases
Slackãã£ããããç°¡åãªAnsibleã¢ãããã¯ã³ãã³ããçŽæ¥å®è¡ã§ããããã«ãªããŸããã
!ansible "uname -a"

äœã¬ãã«ã§ã¯ãããã¯æ¬¡ãšåãã§ãã
/opt/stackstorm/virtualenvs/ansible/bin/ansible all --connection=local --args='uname -a' --inventory-file='127.0.0.1,'
ããããã€ã³ã¿ã©ã¯ãã£ããªChatOpsã®ãã䟿å©ãªäŸãèŠãŠã¿ãŸãããã
äŸ1.ãµãŒããŒã®ã¹ããŒã¿ã¹ãååŸãã
Ansibleã«ã¯ããã¹ãã«æ¥ç¶ããæåãããš
pong
ãè¿ãpingã¢ãžã¥ãŒã«ããããŸãã ã·ã³ãã«ã ã匷åãªäŸã§ãã¿ãŒããã«ã«è¡ãããšãªããæ°ç§ã§ãã£ãããããµãŒããŒã®ã¹ããŒã¿ã¹ãçŽæ¥ç解ã§ããŸãã
ãããè¡ãã«ã¯ãå®éã®ã³ãã³ããš
action alias
ãèµ·åãã
action
ãããã±ãŒãžã«äœæããŸããããã¯ãã¢ã¯ã·ã§ã³ã®æ§æç³ã§ããããã®ãããªChatOpsã³ã³ã¹ãã©ã¯ããäœæã§ããŸãã
!status 'web'
ã¢ã¯ã·ã§ã³
actions/server-status.yaml
ïŒ
--- name: server_status description: Show server status by running ansible ping ad-hoc command runner_type: local-shell-cmd entry_point: "" enabled: true parameters: sudo: description: "Run command with sudo" type: boolean immutable: true default: true kwarg_op: immutable: true cmd: description: "Command to run" type: string immutable: true default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{hosts}} --module-name=ping" hosts: description: "Ansible hosts to ping" type: string required: true
ãšããã§ãbash
ã¹ã¯ãªããã«å ããŠãActionã¯Pythonã©ã³ããŒãŸãã¯json
ãè¿ãããšãã§ããä»»æã®ãã€ããªãšé£æºã§ããŸã-ããã¯ãã¹ãŠäœ¿çšã®æè»æ§ã§ãã
ã¢ã¯ã·ã§ã³ãšã€ãªã¢ã¹
aliases/server_status.yaml
ïŒ
--- name: chatops.ansible_server_status action_ref: st2_chatops_aliases.server_status description: Show status for hosts (ansible ping module) formats: - display: "status <hosts>" representation: - "status {{ hosts }}" - "ping {{ hosts }}" result: format: | Here is your status for `{{ execution.parameters.hosts }}` host(s): {~} ```{{ execution.result.stdout }}``` extra: slack: color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}" fields: - title: Alive value: "{{ execution.result.stdout|regex_replace('(?!SUCCESS).', '')|wordcount }}" short: true - title: Dead value: "{{ execution.result.stdout|regex_replace('(?!UNREACHABLE).', '')|wordcount }}" short: true footer: "{{ execution.id }}" footer_icon: "https://stackstorm.com/wp/wp-content/uploads/2015/01/favicon.png"
æ£ãããã¹ããAnsibleã€ã³ãã³ããªãã¡ã€ã«ã«è¿œå ããŠãã ããïŒ
/etc/ansible/hosts
ãªããžããªã«ã³ãŒããéä¿¡ããåŸããã£ããããããã¯ããªããŒãããããšãå¿ããªãã§ãã ããïŒ
!pack install armab/st2_chatops_aliases
ãã¹ãŠã®ChatOpsèšå®ãst2ããã¯ã®åœ¢åŒã§ä¿åãããªããžããªããå€æŽããã£ããã§ããã®ã¯éåžžã«äŸ¿å©ã§ããã€ã³ãã©ã¹ãã©ã¯ãã£ã¯ã³ãŒãã®ãããªãã®ã§ãã
Slackã§æ°ããäœæãããã³ãã³ãã®çµæïŒ

CEOã§ããããµãŒããŒã«ã¢ã¯ã»ã¹ããªããŠãã¹ããŒã¿ã¹ã確èªã§ããŸãã ãã®ã¢ãããŒãã䜿çšãããšãã€ã³ãã©ã¹ãã©ã¯ãã£ã®éä¿¡ãå±éãããã³äœæ¥ããã£ããã§çŽæ¥è¡ãããŸãããªãã£ã¹ã«ãããããªã¢ãŒãã§äœæ¥ããŠãããïŒç§ãã¡ã®äžéšã¯ããŒãããçŽæ¥äœæ¥ã§ããŸãïŒã
äŸ2.ãµãŒãã¹ã®ãªããŒã
ãµãŒãã¹ã®ç°¡åãªåèµ·åãå©ãã«ãªã£ããšããããšã¯ããªãã«èµ·ãã£ãããšããããŸããïŒ çæ³çãªæ¹æ³ã§ã¯ãããŸããããå€ãã®å Žåãè¿ éãªä¿®æ£ãå¿ é ã§ãã ç¹å®ã®ãµãŒããŒã§æå®ããããµãŒãã¹ããªãŒããŒããŒãããChatOpsã³ãã³ããäœæããŸãããã
ã¿ã¹ã¯ã¯ããã®èšèšãååŸããããšã§ãã
!service restart "rabbitmq-server" on "mq-01"
ãããè¡ãã«ã¯ãæ¢åã®st2ããã±ãŒãžã«
actions/service_restart.yaml
ãäœæããŸãã
--- name: service_restart description: Restart service on remote hosts runner_type: local-shell-cmd entry_point: "" enabled: true parameters: sudo: description: "Run command with sudo" type: boolean immutable: true default: true kwarg_op: immutable: true cmd: description: "Command to run" type: string immutable: true default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{hosts}} --become --module-name=service --args='name={{service_name}} state=restarted'" hosts: description: "Ansible hosts" type: string required: true service_name: description: "Service to restart" type: string required: true
ChatOpsãšã€ãªã¢ã¹
aliases/service_restart.yaml
ïŒ
--- name: chatops.ansible_service_restart action_ref: st2_chatops_aliases.service_restart description: Restart service on remote hosts formats: - display: "service restart <service_name> on <hosts>" representation: - "service restart {{ service_name }} on {{ hosts }}" result: format: | Service restart `{{ execution.parameters.service_name }}` on `{{ execution.parameters.hosts }}` host(s): {~} {% if execution.result.stderr %} *Exit Status*: `{{ execution.result.return_code }}` *Stderr:* ```{{ execution.result.stderr }}``` *Stdout:* {% endif %} ```{{ execution.result.stdout }}``` extra: slack: color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}" fields: - title: Restarted value: "{{ execution.result.stdout|regex_replace('(?!SUCCESS).', '')|wordcount }}" short: true - title: Failed value: "{{ execution.result.stdout|regex_replace('(?!(FAILED|UNREACHABLE)!).', '')|wordcount }}" short: true footer: "{{ execution.id }}" footer_icon: "https://stackstorm.com/wp/wp-content/uploads/2015/01/favicon.png"
çµæïŒ

ãããŠãããªãã¯äœãç¥ã£ãŠããŸããïŒ Slackã¢ãã€ã«ã¢ããªã®ãããã§ãæºåž¯é»è©±ããçŽæ¥ãµãŒãã¹ããªããŒãã§ããŸãïŒ
äŸ3. MySQLããã»ã¹ãªã¹ã
MySQLãµãŒããŒã§å®è¡ãããŠããSQLã¯ãšãªã®ãªã¹ãã衚瀺ããç°¡åãªSlackã³ãã³ããäœæããŸãã
!show mysql processlist
ã¢ã¯ã·ã§ã³
actions/mysql_processlist.yaml
ïŒ
--- name: mysql_processlist description: Show MySQL processlist runner_type: local-shell-cmd entry_point: "" enabled: true parameters: sudo: immutable: true default: true kwarg_op: immutable: true cmd: description: "Command to run" type: string immutable: true default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{ hosts }} --become --become-user=root -m shell -a \"mysql --execute='SHOW PROCESSLIST;' | expand -t 10\"" hosts: description: "Ansible hosts" type: string default: db
ChatOpsã®ã¢ã¯ã·ã§ã³ãšã€ãªã¢ã¹ïŒ
aliases/mysql_processlist.yaml
ïŒ
--- name: chatops.mysql_processlist action_ref: st2_chatops_aliases.mysql_processlist description: Show MySQL processlist formats: - display: "show mysql processlist <hosts=db>" representation: - "show mysql processlist {{ hosts=db }}" - "show mysql processlist on {{ hosts=db }}" result: format: | {% if execution.status == 'succeeded' %}MySQL queries on `{{ execution.parameters.hosts }}`: ```{{ execution.result.stdout }}```{~}{% else %} *Exit Code:* `{{ execution.result.return_code }}` *Stderr:* ```{{ execution.result.stderr }}``` *Stdout:* ```{{ execution.result.stdout }}``` {% endif %}
hosts
ãã©ã¡ãŒã¿ãŒããªãã·ã§ã³ïŒããã©ã«ãã§ã¯
db
ïŒã«ãããããããã2ã€ã®ã³ãã³ãã¯åçã§ãã
!show mysql processlist !show mysql processlist 'db'

DBAã幞ãã«ãªããŸãïŒ
äŸ4. nginxããHTTPçµ±èšãååŸãã
nginxãã°ããHTTPã¹ããŒã¿ã¹ã³ãŒãã®é åãååŸããããããçªå·ã§äžŠã¹æ¿ããŠãã£ããã§é©åã«è¡šç€ºããŠãæ£åžžç¯å²å ã§ãããã©ããã«ããããããWebãµãŒããŒã«
200
ãŸãã¯
50x
ãšã©ãŒãããã€ããããç解ããŸãã
!show nginx stats on 'web'
ãããè¡ãã«ã¯ãã·ã§ã«ã³ãã³ã
actions/http_status_codes.yaml
ãå®è¡ããã¢ã¯ã·ã§ã³ãäœæããŸãã
--- name: http_status_codes description: Show sorted http status codes from nginx logs runner_type: local-shell-cmd entry_point: "" enabled: true parameters: sudo: immutable: true default: true kwarg_op: immutable: true cmd: description: "Command to run" type: string immutable: true default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{ hosts }} --become -m shell -a \"awk '{print \\$9}' /var/log/nginx/access.log|sort |uniq -c |sort -k1,1nr 2>/dev/null|column -t\"" hosts: description: "Ansible hosts" type: string required: true
ãšã€ãªã¢ã¹
aliases/http_status_codes.yaml
ïŒ
--- name: chatops.http_status_codes action_ref: st2_chatops_aliases.http_status_codes description: Show sorted http status codes from nginx on hosts formats: - display: "show nginx stats on <hosts>" representation: - "show nginx stats on {{ hosts }}" result: format: "```{{ execution.result.stdout }}```"
Ansibleã®ã³ã¢éçºè ã§ããBrian Cocaã®çŽ æŽãããã¢ã€ãã¢ã«æè¬ããŸãïŒ

ãŸããŸãã
äŸ5.ã»ãã¥ãªãã£ããã
Shellshockã®ãããªå¥ã®é倧ãªè匱æ§ãç·æ¥ã«ä¿®æ£ããå¿ èŠããããšæ³åããŠãã ããã ãããè¡ãã«ã¯ããã¹ãŠã®ãµãŒããŒã§
bash
ãæŽæ°ããŸãã Ansibleã¯ããããããã®ãããªã¢ãããã¯æäœã«æé©ãªããŒã«ã§ãã ããããåäžè¡ã®ansibleã³ãã³ããå®è¡ãã代ããã«ãå å®ãªãã¬ã€ããã¯ãäœæããŸãããã
playbooks/update_package.yaml
ïŒ
--- - name: Update package on remote hosts, run on 25% of servers at a time hosts: "{{ hosts }}" serial: "25%" become: True become_user: root tasks: - name: Check if Package is installed command: dpkg-query -l {{ package }} register: is_installed failed_when: is_installed.rc > 1 changed_when: no - name: Update Package only if installed apt: name={{ package }} state=latest update_cache=yes cache_valid_time=600 when: is_installed.rc == 0
Playbook
ãããã±ãŒãžãæ¢ã«ã€ã³ã¹ããŒã«ãããŠããå Žåã«ã®ã¿ããã±ãŒãž
Playbook
æŽæ°ããŸããæäœã¯äžåºŠã«20ïŒ ã®ãã¹ãïŒ5ã€ã®ã¹ãããã§å®è¡ïŒã§å®è¡ãããŸãã éåžžã«å€ãã®ãµãŒããŒã§
nginx
ãããªãã£ãšæ·±å»ãªãã®ãæŽæ°ããå¿ èŠããããšãã«åœ¹ç«ã¡ãŸãã ãããã£ãŠãWebã¯ã©ã¹ã¿ãŒå šäœãdownã«éä¿¡ããŸããã ããã«ãããŒããã©ã³ãµãŒããã®åæãã°ã«ãŒãã§è¿œå ã§ããŸãã å®ç掻ã®äŸã
ãã¬ã€ããã¯å€æ°
{{hosts}}
ãš
{{package}}
ã¯ãStackStormããã±ãŒãžã®
actions/update_package.yaml
ç±æ¥ããããšãããããŸãã
--- name: update_package description: Update package on remote hosts runner_type: local-shell-cmd entry_point: "" enabled: true parameters: sudo: immutable: true default: true kwarg_op: immutable: true timeout: default: 6000 cmd: description: "Command to run" immutable: true # default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible-playbook /opt/stackstorm/packs/${ST2_ACTION_PACK_NAME}/playbooks/update_package.yaml --extra-vars='hosts={{ hosts }} package={{ package }}'" hosts: description: "Ansible hosts" type: string required: true package: description: "Package to upgrade" type: string required: true
ã¢ã¯ã·ã§ã³ãšã€ãªã¢ã¹ãç°¡åãªChatOpsã³ãã³ããšããŠãã¬ã€ããã¯ãå®è¡ã§ããŸãã
aliases/update_package.yaml
ïŒ
--- name: chatops.ansible_package_update action_ref: st2_chatops_aliases.update_package description: Update package on remote hosts formats: - display: "update <package> on <hosts>" representation: - "update {{ package }} on {{ hosts }}" - "upgrade {{ package }} on {{ hosts }}" result: format: | Update package `{{ execution.parameters.package }}` on `{{ execution.parameters.hosts }}` host(s): {~} {% if execution.result.stderr %} *Exit Status*: `{{ execution.result.return_code }}` *Stderr:* ```{{ execution.result.stderr }}``` *Stdout:* {% endif %} ```{{ execution.result.stdout }}``` extra: slack: color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}" fields: - title: Updated nodes value: "{{ execution.result.stdout|regex_replace('(?!changed=1).', '')|wordcount }}" short: true - title: Executed in value: ":timer_clock: {{ execution.elapsed_seconds | to_human_time_from_seconds }}" short: true footer: "{{ execution.id }}" footer_icon: "https://stackstorm.com/wp/wp-content/uploads/2015/01/favicon.png"
ããã«ãããŸãïŒ
!update 'bash' on 'all'

DevOpsãšã³ãžãã¢ã®ä»äºã®éèŠãªéšåã¯ãããã»ã¹ã®æ¹åãéçºè ã®äœæ¥ã®å®¹æåãããŒã ã³ãã¥ãã±ãŒã·ã§ã³ã®æ¹åãé©åãªããŒã«ã®èªååãšäœ¿çšã«ããåé¡ã®è¿ éãªèšºæããã¹ãŠäŒç€Ÿãæåãããããšã§ãã
ChatOpsã¯ããããã®åé¡ããŸã£ããæ°ããå¹æçãªæ¹æ³ã§è§£æ±ºããã®ã«åœ¹ç«ã¡ãŸãã
çµè«ãšããŠã ç¥èãªç
ãåç¥ã®ããã«ãAnsible
cowsay
ã ChatOpsã«ç§»åããŸãããïŒ
ãŸãããŠãŒãã£ãªãã£èªäœãã€ã³ã¹ããŒã«ããŸãã
sudo apt-get install cowsay
ã¢ã¯ã·ã§ã³
actions/cowsay.yaml
ïŒ
--- name: cowsay description: Draws a cow that says what you want runner_type: local-shell-cmd entry_point: "" enabled: true parameters: sudo: immutable: true kwarg_op: immutable: true cmd: description: "Command to run" type: string immutable: true default: "/usr/games/cowsay {{message}}" message: description: "Message to say" type: string required: true
ãšã€ãªã¢ã¹
aliases/cowsay.yaml
ïŒ
--- name: chatops.cowsay action_ref: st2_chatops_aliases.cowsay description: Draws a cow that says what you want formats: - display: "cowsay <message>" representation: - "cowsay {{ message }}" ack: enabled: false result: format: | {% if execution.status == 'succeeded' %}Here is your cow: ```{{ execution.result.stdout }}``` {~}{% else %} Sorry, no cows this time {~} Exit Code: `{{ execution.result.return_code }}` Stderr: ```{{ execution.result.stderr }}``` Hint: Make sure `cowsay` utility is installed. {% endif %}
Cowã®èãªãChatOpsã«é»è©±ïŒ
!cowsay 'Holy ChatOps Cow!'

åèïŒã³ãã³ãå®è¡ã®ãã¹ãŠã®çµæã¯ãStackStormã³ã³ãããŒã«ããã«ã§è¡šç€ºã§ããŸãã
httpsïŒ// chatops / loginïŒdemo
passwordïŒdemo
ïŒ Vagrantãã¢ã䜿çšããªãã£ãå Žåããã¹ãåãIPã«çœ®ãæããŸãïŒïŒ
åæ¢ããªãã§ãã ããïŒ
ãããã¯ã·ã³ãã«ã§ãããæŠéã®ãŠãŒã¹ã±ãŒã¹ã§ãã è€æ°ã®DevOpsããŒã«ãçµã¿åãããŠåçãªã¯ãŒã¯ãããŒãäœæããå Žåã®ããè€éãªããšã«ã€ããŠã¯ãä»åŸã®èšäºã§èª¬æããŸãã ããã§ã StackStormã¯ç¶æ³ã«å¿ããŠæ±ºå®ãäžãããã¹ãŠã®åãçºæ®ããŸããããã¯ãã€ã³ã·ãã³ãåŸã®èªå·±ä¿®åŸ©ã·ã¹ãã ã®ãããªã€ãã³ãæåã¢ãŒããã¯ãã£ãšåŒã°ããŸãã
StackStormã§å¿ èŠãªæ©èœãèŠã€ãããªãã£ãå Žåã¯ãã¢ã€ãã¢ãææ¡ãããã GitHubã«ãã«ãªã¯ãšã¹ããè¿œå ããŸã ïŒPythonãã¡ã€ã³èšèªã§ãïŒã ãŸãã質åãããããäœéšãå ±æãããã§ããã³ãã¥ããã£ããããŸãã å ¬éSlackãã£ã³ãã« ïŒ#StackStorm
äºåã«ã€ã³ã¹ããŒã«ãããŠããŸãïŒããã³IRCïŒ#StackStorm
ã§ãã
ãæž èŽããããšãããããŸãããDevOpsã®äžçã«ããããã®ããªãæ°ããã¢ãããŒãã®ç¹åŸŽãæããã«ããããšãã§ãããšæããŸãã
ãŸããã©ã®ãããªå Žåã«ChatOpsã䜿çšããŸããïŒ ã¢ã€ãã¢ãã¹ããŒãªãŒãå ±æããŠãã ããïŒã¹ããŒãªãŒã倧奜ãã§ãïŒã