Steven5538

How to Ansible

Word count: 843Reading time: 3 min
2017/11/19 Share

Ansible 是由 Python 撰寫的自動化部署工具,相較於 SaltStack,其優點在於不用事先於欲管理的機器上部署,僅需在自己這端加入機器即可。然而這樣的方便帶來的就是每次都得重新 SSH 連接,可能無法要求較快的 response。

由於目前工作上的需求,在專案 release 後,需至每台機器手動部署,耗費不少時間 (其實也才五台),這時候就是一個使用 Ansible 的好時機!

1. 配置 Hosts

首先我們需定義有哪些機器,你可以為他們設定 Label,Ansible 支援 multi label group,可以讓你更有效的組合出管理機器規則。

編輯預設的 /etc/ansible/hosts 來新增,或者是新增一個文件在下指令時由 -i PATH 帶入。

1
2
3
4
5
6
7
8
[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

上面是一個簡單的文件配置,我們可以帶入更多的參數,比如登入時的 username,用的是哪個 key。

1
2
3
4
5
6
7
8
[webservers]
foo.example.com ansible_ssh_private_key_file=web.pem ansible_user=web1
bar.example.com ansible_ssh_private_key_file=web.pem ansible_user=web2

[dbservers]
one.example.com ansible_ssh_private_key_file=db.pem ansible_user=db1
two.example.com ansible_ssh_private_key_file=db.pem ansible_user=db2
three.example.com ansible_ssh_private_key_file=db.pem ansible_user=db3

如此就可以為每台機器做不同的配置。
另外,也可以做一個 label 的組合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[product1-webserver]
foo.example.com ansible_ssh_private_key_file=web.pem ansible_user=web1

[product2-webserver]
bar.example.com ansible_ssh_private_key_file=web.pem ansible_user=web2

[product1-dbserver]
one.example.com ansible_ssh_private_key_file=db.pem ansible_user=db1
two.example.com ansible_ssh_private_key_file=db.pem ansible_user=db2

[product2-dbserver]
three.example.com ansible_ssh_private_key_file=db.pem ansible_user=db3

[product1]
product1-webserver
product1-dbserver

[product2]
product2-webserver
product2-dbserver

這樣,當呼叫 prodcuct1 時,便同時包含了 product1-webserverproduct1-dbserver

最後可以用 ping 來確定一下是否每台主機都設置完備。

1
$ ansible all -m ping

2. Ansible Playbook

經過上述的設定後,我們已經可以同時對多台機器下達一樣的指令,比如說:

1
$ ansible all -m shell -a "echo $SHELL"

確認每台上面的 shell 為何。

但若如果今天需要進行複雜的指令操作,比如說專案的部署,顯然要一條一條輸入還是太麻煩了,這時候就可以開始撰寫 playbook,讓 Ansible 能透過 playbook 內的內容進行操作。

現在就讓我們來編輯一個 playbook.yml

1
2
3
4
5
6
7
---
- hosts: webservers
tasks:
- name: ensure apache is at the latest version
yum: name=httpd state=latest
- name: run some command
shell: cat < /tmp/*txt

在這簡單的例子當中,針對 webservers 這個 label 底下的 hosts 進行下面的操作,tasks 是依序執行的。

撰寫完畢後執行:

1
$ ansible-playbook playbook.yml

更複雜的應用例子各位可以參考這裡,由官方提供於一些場景的 playbook 寫法。

另外提一下我個人使用的場景,執行的 deploy script 會檢查 process 是否含有專案名字,如果有的話表示專案還在運行,然而如果用 Ansible shell 去跑的話,會發現有兩個 process,一個由 Ansible 產生的 process 用以呼叫 deploy script。

在這樣的情況下檢查 process 時怎麼樣都不會過,此時可以在 playbook.yml 執行 shell modules 的部分多加一個 args,讓 Ansible 在跑這段指令的時候是直接 pass 給 shell,而不是透過 Ansible 本身呼叫。

1
2
3
4
5
6
7
8
9
---
- hosts: webservers
tasks:
- name: ensure apache is at the latest version
yum: name=httpd state=latest
- name: run some command
shell: cat < /tmp/*txt
args:
executable: /bin/bash

如此便不會再多出一個 process。

CATALOG
  1. 1. 1. 配置 Hosts
  2. 2. 2. Ansible Playbook