---
# System prepended metadata

title: Ansible
tags: [Ansible]

---

# Ansible
###### tags: `Ansible`
> 2021/06/03
> Ansible 是可以控制遠端或本機機器的工具，主要可以利用 Ansible 做大量重複的事情，或是查看服務狀況。

> 案例
> 利用 Ansible 修改同群組內所有機器的某支 config ，只需要將所有機器寫進 /etc/ansible/hosts 裡，並編寫 yml 檔案執行修改，我們只需要執行這個 yml 檔就能完成群組內所有機器的 config 修改

> 2021/07/29
> 新增 RHEL8 安裝方法
- - -


## 安裝 Ansible
CnetOS7: `# yum install ansible`

RHEL8:
```
# dnf update -y
# python3 -V
# subscription-manager repos --enable ansible-2.9-for-rhel-8-x86_64-rpms
# dnf -y install ansible
```
- - -


## 設置 localhost 使用
- `/etc/ansible/hosts` 增加 `127.0.0.1`
- 產生 server 端金鑰: 
  `ssh-keygen -A`
- 啟動 ssh service: 
  `service sshd start`
- 產生 client 端金鑰: 
  `ssh-keygen -b 4096`
- 將 client 端金鑰加入本地: 
  `ssh-copy-id -i ~/.ssh/id_rsa.pub [username]@[ipaddr]`
- 測試指令
  ```
  $ ansible localhost -m shell -a '/bin/echo hello'
  127.0.0.1 | CHANGED | rc=0 >>
  hello
  ```
- - -


## 設置 pip 版本
目前 python2.7 已不被官方支援，所以 pip 版本只支援到 `20.3.4`
- 安裝 pip: `yum install python-pip`
- 更新 pip 至 `20.3.4`: `python -m pip install --upgrade "pip < 21.0"`
- - -


## 安裝 Python module
Ansible 使用 Python 來執行各項 module，像是 pids module 就會需要 python 的 psutil，所以我們需要安裝 psutil
- 安裝 psutil: `pip install psutil`

其他遇到類似需要安裝 Python module 的部份也如上述方法安裝

#### ※ 若遠端操控機器則是使用遠端機器上的 Python，所以是遠端的機器需要安裝 Python module
- - -


## 編寫 playbook
```yaml=
- name: RRN System Check                                      # 計畫名稱
  hosts: localhost                                            # 對象
  vars:                                                       # 設變數
    services_running: []                                      # 變數名稱: 型態
    newline_character: "\n"
  tasks:

    - name: Getting radius PID                                # 任務名稱
      pids:                                                   # module
        name: radiusd                                         # 監看的 process
      register: pids_of_radiusd                               # 接收變數
      
    - name: Check radius PID                                  # 任務名稱
      fail:                                                   # 設置錯誤
        msg: No radius service                                # 錯誤訊息
      when: not pids_of_radiusd.pids                          # when 為判斷式
                                                              # 當成立時執行此任務
                                                              # 不成立則 skip 此任務

    - name: Output radius PID                                     # 任務名稱
      debug:                                                      # module
        msg: "PIDS of radiusd:{{pids_of_radiusd.pids|join(',')}}" # 顯示訊息
                                   # 變數使用 {{ vars }} 顯示
```
- - -


## 執行 playbook
### vi cpu_usage.yml
```yaml=
### cpu_usage.yml
# Get CPU usage

- name: CPU usage
  hosts: localhost
  tasks:
    - name: Get CPU usage
      shell: "top -b -n1 | grep 'Cpu(s)' | awk '{print $2 + $4}' "
      register: cpu_usage
 
    - name: Output CPU usage facts 
      debug: 
        msg: 
          - "CPU usage: {{cpu_usage['stdout']}}%"
```

### ansible-playbook cpu_usage.yml
```
$ ansible-playbook cpu_usage.yml

PLAY [CPU usage] ********************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [127.0.0.1]

TASK [Get CPU usage] ****************************************************************************************************************************************
changed: [127.0.0.1]

TASK [Output CPU usage facts] *******************************************************************************************************************************
ok: [127.0.0.1] => {
    "msg": "CPU usage: 13.4%"
}

PLAY RECAP **************************************************************************************************************************************************
127.0.0.1                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```
- - -


## Ansible default logfile
### vi /etc/ansible/ansible.cfg
```
log_path = /dir/file.log
```

### ansible-playbook cpu_usage.yml
```
2021-06-03 23:41:26,080 p=17352 u=root n=ansible | PLAY [CPU usage] ********************************************************************************************************************************************
2021-06-03 23:41:26,087 p=17352 u=root n=ansible | TASK [Gathering Facts] **************************************************************************************************************************************
2021-06-03 23:41:27,275 p=17352 u=root n=ansible | ok: [127.0.0.1]
2021-06-03 23:41:27,283 p=17352 u=root n=ansible | TASK [Get CPU usage] ****************************************************************************************************************************************
2021-06-03 23:41:27,907 p=17352 u=root n=ansible | changed: [127.0.0.1]
2021-06-03 23:41:27,915 p=17352 u=root n=ansible | TASK [Output CPU usage facts] *******************************************************************************************************************************
2021-06-03 23:41:27,950 p=17352 u=root n=ansible | ok: [127.0.0.1] => {
    "msg": "CPU usage: 13.4%"
}
2021-06-03 23:41:27,951 p=17352 u=root n=ansible | PLAY RECAP **************************************************************************************************************************************************
2021-06-03 23:41:27,951 p=17352 u=root n=ansible | 127.0.0.1                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

### ansible-playbook -v cpu_usage.yml
```
2021-06-03 23:51:47,376 p=17661 u=root n=ansible | Using /etc/ansible/ansible.cfg as config file
2021-06-03 23:51:47,536 p=17661 u=root n=ansible | PLAY [CPU usage] ********************************************************************************************************************************************
2021-06-03 23:51:47,543 p=17661 u=root n=ansible | TASK [Gathering Facts] **************************************************************************************************************************************
2021-06-03 23:51:48,771 p=17661 u=root n=ansible | ok: [127.0.0.1]
2021-06-03 23:51:48,779 p=17661 u=root n=ansible | TASK [Get CPU usage] ****************************************************************************************************************************************
2021-06-03 23:51:49,409 p=17661 u=root n=ansible | changed: [127.0.0.1] => {"changed": true, "cmd": "top -b -n1 | grep 'Cpu(s)' | awk '{print $2 + $4}' ", "delta": "0:00:00.174965", "end": "2021-06-03 23:51:49.360877", "rc": 0, "start": "2021-06-03 23:51:49.185912", "stderr": "", "stderr_lines": [], "stdout": "13.4", "stdout_lines": ["13.4"]}
2021-06-03 23:51:49,417 p=17661 u=root n=ansible | TASK [Output CPU usage facts] *******************************************************************************************************************************
2021-06-03 23:51:49,450 p=17661 u=root n=ansible | ok: [127.0.0.1] => {
    "msg": "CPU usage: 13.4%"
}
2021-06-03 23:51:49,453 p=17661 u=root n=ansible | PLAY RECAP **************************************************************************************************************************************************
2021-06-03 23:51:49,453 p=17661 u=root n=ansible | 127.0.0.1                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```


## 結論
Ansible 是一個滿多功能的工具，幾乎所有事情都能做到，只是在於 module 的安裝在客戶那邊是比較麻煩的，如果不使用 Ansible 的 pids module，也可以使用 cmd 的 ps 來做關於 process 的監控。
Ansible 的 log 就是記錄所有輸出，使用 `ansible-playbook -v` 可以得到更詳細的 log。