## 課程六 :Ansible基礎
### 2022年下學期,明新科技大學資管系
### 講師:胡嘉璽
---
## 課程重點
* Ansible的基礎
* Ansible的角色
* 試試ansible
* command/shell模組
---
## 課程重點
* <font color="#00F">Ansible的基礎</font>
* Ansible的角色
* 試試ansible
* command/shell模組
----
### 什麼是Ansible
* 一個自動化電腦主機的工具
* 建立雲端主機、安裝軟體,啟動服務,管理服務
* 利用`yaml`設定檔進行
* 可同時管理多台Linux及Windows主機
* 基礎設施即程式 (Infrastructure as Code)概念實作
----
### Ansible的元件

----
### Ansible的元件
* 控制端點
* Ansible 引擎 (Ansible Automation Engine)
* 元件資料庫及hub
* 被控主機
* Playbook
----
### Ansible的元件 - 控制端點
使用者透過在 control node 上面的 ansible 元件,下達指令來操作自動化管理指令。這個 control node 主要透過 ssh 協定, 直接連線到要被管理的系統上 (host) 進行操作任務。 host 只要能夠讓 control node 透過 ssh 連線進去即可, 其他不需要安裝
----
### Ansible 引擎
包括了主機清單、命令列控制,執行指令(就是模組)以及第三方廠商或原廠或自己開發的外掛。
----
### 元件資料庫及hub
別人寫好的playbook,放在網路/雲端或hub上讓大家可以下載使用
----
### 被控主機
* 內網上的主機
* 雲端主機
* 網路設備
----
### Playbook
playbook 就是類似 shell script, 將一堆任務寫在一起,丟給 ansible 直接執行即可。因此,上面談到的模組運作,也是寫入到這裡來
----
### 執行流程
使用者透過自己撰寫/修改下程的playbook,引用ansible提供的模組/外掛功能,撰寫好需要的步驟,同時將需要管理的主機名稱寫入到清單列表中, 接下來,就將playbook丟進 ansible去主機上執行
---
## 課程重點
* Ansible的基礎
* <font color="#00F">Ansible的角色</font>
* 試試ansible
* command/shell模組
----
### 重要的檔案
* Inventory:存放主機的資料,包括group及ungroup
* Group: 具有相同特色的主機
* Ungroup:其它不在群組中的主機
* Modules: 就是在主機上執行的程式碼
* Tasks: 組合modules的工作,可能附帶參數
* Playbooks: 組合task的一個`yaml`檔案
* Roles: 可分派的自動化程式碼,可以分享出去,讓程式執行更方便
----
### 安裝Ansible
* control node上一定要安裝Python 3.8以上
* host上只要安裝python即可
* control node不能是Windows,可以是Linux或MacOS
```shell=
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py --user
python3 -m pip install --user ansible
```
----
### 使用者權限的設定
* 在control node上可以用非`sudo`使用者
* 在host上需要使用`sudo`使用者,要確定ssh過去的使用者有系統管理權限
* 可以是不同使用者,只要設定好免密碼ssh即可
* 在server輸入`sudo visudo`,改成下面樣子存檔
```
%sudo ALL=(ALL:ALL) NOPASSWD:ALL
```
---
### 課程重點
* Ansible的基礎
* Ansible的角色
* <font color="#00F">試試ansible</font>
* command/shell模組
----
### 試試ansible
* 單一主機:替主機命名及設定參數,如IP、使用者/密碼/ssh key/通訊埠
* 多台主機:將不同名命的主機放入一個群組
```=
server1 ansible_host=10.0.2.4 ansible_user=ansible ansible_port=22 ansible_ssh_private_key_file=~/.ssh/ansible
server2 ansible_host=10.0.2.4 ansible_user=ansible ansible_port=22 ansible_ssh_private_key_file=~/.ssh/ansible
[webservers]
server1
```
----
### 執行ad hoc指令
```shell=
ansible@must:~$ ansible -i inventory server1 -m command -a "ping google.com -c 5"
server1 | CHANGED | rc=0 >>
PING google.com (142.251.43.14) 56(84) bytes of data.
64 bytes from tsa03s08-in-f14.1e100.net (142.251.43.14): icmp_seq=1 ttl=56 time=2.63 ms
64 bytes from tsa03s08-in-f14.1e100.net (142.251.43.14): icmp_seq=2 ttl=56 time=2.71 ms
64 bytes from tsa03s08-in-f14.1e100.net (142.251.43.14): icmp_seq=3 ttl=56 time=3.15 ms
64 bytes from tsa03s08-in-f14.1e100.net (142.251.43.14): icmp_seq=4 ttl=56 time=2.72 ms
64 bytes from tsa03s08-in-f14.1e100.net (142.251.43.14): icmp_seq=5 ttl=56 time=3.14 ms
--- google.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4038ms
rtt min/avg/max/mdev = 2.631/2.869/3.148/0.226 ms
ansible@must:~$
```
----
### 執行內建模組
* 例如執行`apt update`,則使用`ansible.builtin.apt`及其參數
```shell=
ansible@must:~$ ansible -i inventory server1 -m ansible.builtin.apt -a 'update_cache=true'
server1 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"msg": "Failed to lock apt for exclusive operation: Failed to lock directory /var/lib/apt/lists/: E:Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)"
}
ansible@must:~$
```
----
### 使用`sudo`方式執行
* 上一例的錯誤,如果需要使用系統管理員,加上參數`--become`
* 例如要執行`sudo apt update`,如下:
```shell=
ansible@must:~$ ansible -i inventory server1 -m ansible.builtin.apt -a 'update_cache=true' --become
server1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"cache_update_time": 1670836316,
"cache_updated": true,
"changed": true
}
```
----
### 同時更新upgrade
```shell=
ansible@must:~$ ansible -i inventory server1 -m ansible.builtin.apt -a 'update_cache=true upgrade=full' --become
server1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"msg": "Reading package lists...\nBuilding dependency tree...\nReading state information...\nCalculating upgrade...\nThe following packages were automatically installed and are no longer required:\n libflashrom1 libftdi1-2\nUse 'sudo apt autoremove' to remove them.\n0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.\n",
"stderr": "",
"stderr_lines": [],
"stdout": "Reading package lists...\nBuilding dependency tree...\nReading state information...\nCalculating upgrade...\nThe following packages were automatically installed and are no longer required:\n libflashrom1 libftdi1-2\nUse 'sudo apt autoremove' to remove them.\n0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.\n",
"stdout_lines": [
"Reading package lists...",
"Building dependency tree...",
"Reading state information...",
"Calculating upgrade...",
"The following packages were automatically installed and are no longer required:",
" libflashrom1 libftdi1-2",
"Use 'sudo apt autoremove' to remove them.",
"0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded."
]
}
```
----
### 常用ansible的module - 檔案相關
* copy :從 control node 複製資料到 managed host
* file :設定檔案權限或其他參數
* lineinfile :判斷搜尋某一個資料行是否在或不在某個檔案中
* synchronize: 使用 rsync 進行資料同步
----
### 軟體安裝與移除等相關模組
* package: 依據 distribution 的版本,自動判斷需要的軟體管理指令
* yum: 使用 yum
* apt: 使用 apt-get 等軟體功能 (debian/ubuntu)
* dnf: 使用 dnf (fedora/redhat)
* pip: 透過 PyPI 管理 python 的可安裝模組
----
### 不分主機的Linux distro

----
### 系統管理模組
* firewalld: 使用 firewalld 管理 managed host 防火牆
* reboot: 對 managed host 重新開機
* service: 對服務管理
* user: 新增/移除/管理使用者帳號與密碼
----
### 網路工具模組
* get_url: 從 http, https, ftp 等網站下載檔案資料
* nmcli: 就是管理網路參數設定的模組
* uri:與網路服務互動
----
### 使用copy模組
* 黃色表示改變,綠色表示成功,紅色表示錯誤
```
ansible -i inventory server1 -m copy -a 'src=~/inventory dest=/home/ansible/abc'
```

----

----

----

---
## 課程重點
* Ansible的基礎
* Ansible的角色
* 試試ansible
* <font color="#00F">command/shell模組</font>
----
### command模組
ansible沒有針對某些小功能開發模組。或進行的動作,不需要動到ansible的設定,如只想要知道測試指令有沒有成功,不需要自己開發模組,直接使用 command 這個模組即可。
----
### command模組範例
```shell=
ansible@must:~$ ansible -i inventory server1 -m command -a 'ping google.com -c 5'
server1 | CHANGED | rc=0 >>
PING google.com (172.217.163.46) 56(84) bytes of data.
64 bytes from maa05s01-in-f14.1e100.net (172.217.163.46): icmp_seq=1 ttl=115 time=3.05 ms
64 bytes from maa05s01-in-f14.1e100.net (172.217.163.46): icmp_seq=2 ttl=115 time=3.68 ms
64 bytes from maa05s01-in-f14.1e100.net (172.217.163.46): icmp_seq=3 ttl=115 time=3.63 ms
64 bytes from maa05s01-in-f14.1e100.net (172.217.163.46): icmp_seq=4 ttl=115 time=3.09 ms
64 bytes from tsa01s13-in-f14.1e100.net (172.217.163.46): icmp_seq=5 ttl=115 time=2.73 ms
--- google.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4043ms
rtt min/avg/max/mdev = 2.729/3.236/3.684/0.365 ms
```
----
### command模組範例
```shell=
ansible@must:~$ ansible -i inventory server1 -m command -a 'ip ad'
server1 | CHANGED | rc=0 >>
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:a1:ab:51 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.4/24 metric 100 brd 10.0.2.255 scope global dynamic enp0s3
valid_lft 339sec preferred_lft 339sec
inet6 fe80::a00:27ff:fea1:ab51/64 scope link
valid_lft forever preferred_lft forever
```
----
### 同時執行多個指令
```shell=
ansible@must:~$ ansible -i inventory server1 -m shell -a 'id ansible; cat /etc/hosts'
server1 | CHANGED | rc=0 >>
uid=1000(ansible) gid=1000(ansible) groups=1000(ansible),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lxd)
127.0.0.1 localhost
127.0.1.1 server
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
```
----
### command和shell使用時機
* ansible 強調,在 ansible 管理機制下,所有的動作應該都可以被重複執行,同時動作應該是可以被追蹤的!但是, 使用 command 或 shell 模組時,內接的指令實際上無法進行追蹤!因此, ansible 不建議使用這些 command 或 shell
----
### command和shell使用時機
* 就系統管理的角度來看,某時會managed host看一下某些重要資訊,此時, 透過 command/shell 的簡易功能,你可以不用 ssh 而是使用 ansible 自動化幫你管理這些主機資訊, 應該比自己下達 ssh 指令來的更容易管理
----
### command和shell使用時機
* 預設的情況下,如果你沒有加上任何模組時,那麼 -a 後面加的參數,預設就會以 -m command 模組去執行
----
{"metaMigratedAt":"2023-06-17T16:35:32.628Z","metaMigratedFrom":"YAML","title":"明新科大2022年ansible-6","breaks":true,"slideOptions":"{\"theme\":\"sky\",\"transition\":\"fade\"}","contributors":"[{\"id\":\"33d47e04-0bab-4c19-9d2f-fbbbae0b7706\",\"add\":9723,\"del\":380}]"}