ansible 安裝與使用

ansible 自動佈署、存留紀錄等功能,對於網管而言都是非常方便的功能,towns 紀錄自己的學習紀錄

安裝

CentOS 7
yum install ansible
建議可以先裝 centos-release-ansible-29,這個是 ansible 的 repository

Ubnutu 19.10
apt update
apt install software-properties-common
apt-add-repository --yes --update ppa:ansible/ansible
apt install ansible

以上的安裝方式,可以安裝到最新的 ansible 版本

參考資料:官方說明
https://docs.ansible.com/ansible/latest/installation_guide/  

補充:

安裝

pip install ansible


結構

inventory - yaml - rules - [] -main.yaml

基本上,要讓 ansible 對其他系統下指令,一定要告訴 ansible 有哪些主機,要做什麼事


指令

ansible-playbook -i [路徑].yaml

inventory => ansible 主機資訊參照檔

ansible-playbook -i [inventory file] [yaml file] -k
使用指定的 inventory file 並打入 SSH 密碼
註:如果不下 -k 就必需使用金鑰方式

ansible-playbook -i [inventory file] [yaml file] -k -K
使用指定的 inventory file,並打入 SSH 密碼及 sudo 權限密碼
註:如果不下 -K 必需在 sudoers 中設定 NOPASSWD

ansible-playbook -i [inventory file] [yaml file] --syntax-check
使用指定的 inventory file,進行語法測試,但不執行

ansible-playbook -i [inventory file] [yaml file] --check
使用指定的 inventory file,進行測試,但不執行

ansible --verison <== 顯示版本

參考資料:

ansible-playbook --help

Chi-Hsuan Huang 大文章
https://medium.com/@chihsuan/ansible-%E8%87%AA%E5%8B%95%E5%8C%96%E9%83%A8%E7%BD%B2%E5%B7%A5%E5%85%B7-b2e8b8534a8d

ansible 教學
https://wiki.shileizcc.com/confluence/display/AN/Ansible

如易大的文章 -- DevOps學習筆記-CD篇-ansible自動化運維5
https://kknews.cc/other/34jb2ky.html

Laravel 道場
https://medium.com/laraveldojo/%E8%AE%93%E6%82%A8%E5%AE%89%E5%BF%83%E5%9F%B7%E8%A1%8C-ansible-playbook-%E7%9A%84%E5%B0%8F%E6%8A%80%E5%B7%A7-2-856a60b19898

tsoliangwu0130 大文章 -- 30 天入門 Ansible 及 Jenkins
https://ithelp.ithome.com.tw/articles/10191403   

ansible中文權威指南
https://chusiang.github.io/ansible-docs-translate/index.html

凍仁大的文章 -- 現代 IT 人一定要知道的 Ansible 自動化組態技巧
https://chusiang.gitbooks.io/automate-with-ansible/content/


ansible 加解密

ansible 本身就有帶加解密功能

ansible-vault decrypt [檔案名稱] <= 檔案解密
ansible-vault encrypt [檔案名稱] <= 檔案加密 
ansible-vault edit [檔案名稱] <= 編輯加密檔

預設使用 AES256 加密


ansible 內建模組

ansible 有很多內建模組,所以在寫 ansible 的 rule 時,在有對應模組情形下,先考慮使用模組,沒有時再考慮使用直接下指令
模組的好處是,可以通用於多版本的 Linux,例如新增帳號,如果使用模組,就可以寫一段,通用CentOS、Ubuntu

參考資料:官方文件
https://docs.ansible.com/ansible/latest/modules/user_module.html   


忽略 SSH host's fingerprint

通常第一次使用 SSH 登入遠端主機時,系統產生 .ssh/known_hosts 指紋檔,用於註記遠端主機避免中間人攻擊,但因為這個必需要按 yes 會造成 ansible 在執行時出現錯誤,這個有幾種方式處理

1. 忽略檢查
於設定檔(/etc/ansible/ansible.cfg or ~/.ansible.cfg)中加入 host_key_checking = False
2. 跳出互動
於 main.yaml 檔中,加入 check_mode: yes 模組
註:只有使用 --check 時,這個才會出現

參考資料:
stackoverflow -- Ben Whaley大回應
https://stackoverflow.com/questions/30226113/ansible-ssh-prompt-known-hosts-issue

ansible 中文指南
https://chusiang.github.io/ansible-docs-translate/playbooks_checkmode.html

官方說明 -- always_run check_mode
https://docs.ansible.com/ansible/latest/user_guide/playbooks_checkmode.html  


這兩個訊息是說明 inventory/hosts 及 playbook.yaml 中 [] 與  hosts: 名稱不同

[WARNING]: Could not match supplied host pattern, ignoring: aaa

PLAY [aaa] *********************************************************************
skipping: no hosts matched 


刪除使用者、建立使用者

在 ansible 中,有關於使用者管理模組,依照官方的參考文件,就可以做到了

roles/adduser/tasks/main.yaml
- name: add the user 'test'
  user:
    name: test
    password: "--"
    state: present
    shell: /bin/bash
    append: yes
    create_home: yes

roles/deluser/tasks/main.yaml
- name: del the user 'test'
  user:
    name: test
    state: absent
    remove: yes

參考資料:
官方文件 user – Manage user accounts
https://docs.ansible.com/ansible/latest/modules/user_module.html

stackoverflow -- 刪除特定 user
https://stackoverflow.com/questions/37441796/ansible-for-user-management-removing-dead-accounts 

加入使用者(將 ansible 當 script 寫)
---
- hosts: inventory
  vars:
   ansible_become: yes
   ansible_become_method: sudo
   ansible_become_user: root
  tasks:

    - name: Add User
      become: yes
      user:
       name: "{{ item }}"
       password: "$6$iNWEaQTHzdMAw2sg$zz2/WPSCyttXomrY95rP0I7U9whc.6uzTF6urhzRNpz5cnz/LGFvuhT/XhbC/sreHnkOBV3jJLZGbeYtfvI0c/"
       state: present
       shell: /bin/bash
      loop:
        - towns1
        - towns2
        - towns3

說明1:中用的 password 是使用 python 建立的
說明2:shell: /bin/bash,這個是 ubuntu 才需要的,不寫的話,使用者預設沒有 shell

------------------------------------------------------------------------------

刪除使用者(將 ansible 當 script 寫)
---
- hosts: test
  vars:
   ansible_become: yes
   ansible_become_method: sudo
   ansible_become_user: root
  tasks:

   - name: Delete User
     user:
      name: "{{ item }}"
      state: absent
      remove: yes
     loop:
      - towns1
      - towns2
      - towns3

--------------------------------------------------------------------------

變更使用者密碼(將 ansible 當 script 寫)

---
- hosts: test
  vars:
    ansible_become: yes
    ansible_become_method: sudo
    ansible_become_user: root
  gather_facts: no
  tasks:

    - name: update password
      user:
        name: "{{ item }}"
        password: "$6$DsyALxo7UBurSX2g$icN.HZZIO.JFAbn3uSzpaM4Ci8tsKeXCxNdSF855y2o8mzaYdT/UR2M5hbtTAE/cUd59QFK4Iyb0tmEIYbaNy1"
        update_password: always
      loop:
        - towns1
        - towns2
        - towns3


複製、解壓、安裝

 

參考資料:
官方文件
copy – Copy files to remote locations
https://docs.ansible.com/ansible/latest/modules/copy_module.html

unarchive – Unpacks an archive after (optionally) copying it from the local machine
https://docs.ansible.com/ansible/latest/modules/unarchive_module.html

stackovervlow 討論
Creates directory -- leucos大回應
https://stackoverflow.com/questions/22844905/how-to-create-a-directory-using-ansible

cd -- Marcin Płonkas大回應
https://stackoverflow.com/questions/19369931/ansible-how-to-change-active-directory-in-ansible-playbook  


command 與 shell 的差別

command 純指令,可用指令的參數

shell 使用 shell script,可連用其他 script 或 指令,感覺比較實用

參考資料:
stackovervlow 討論 -- Sylvain Leroux  Greg Dubicki 說明
https://stackoverflow.com/questions/24679591/ansible-command-module-says-that-is-illegal-character 


[funtion] listen_ports_facts -- Gather facts on processes listening on TCP and UDP ports

 

towns 用這個功能的目的是為了確認各台 server 中的 listening port,不過,他使用了 netsat 指令,CentOS7、Ubuntu 8,以上的版本,已經沒有預設安裝 net-tools 這個套件了,如要使用記得安裝

這個功能使用上的必要條件
1. ansible 必需是 2.9 版以上
2. guset 必需有安裝 net-tools 套件(該功能使用 netstat 指令)

參考資料:

James 大口述

ansible 官網
https://docs.ansible.com/ansible/latest/modules/listen_ports_facts_module.htm


.stdout 及 .results 的差別

當資料取出使用 debug 時,只能使用 .results 方式將資料寫入檔案

參考資料:
James 大口述


直接使用 ansible 的模式

注意:當將ansible 當指令使用時,需注意到是否有設定 playbook 或 config,否則很多需要 root 權限的指令將無法使用

ansible -i [inventory file] <主機群組or主機名稱> -m [MODULE_NAME]
ansible -i [inventory file] <主機群組or主機名稱> -m setup
ansible -i [inventory file] <主機群組or主機名稱> -m setup -a 'filter=ansible_distribution'
ansible -i [inventory file] <主機群組or主機名稱> -m shell -a 'netstat -tulnp | grep ":53"'
ansible -i [inventory file] <主機群組or主機名稱> -m command -a '/bin/systemctl status dnsmasq.service'

註:這樣的方式,必需先在設定檔中,將參數先寫號,否則無法執的

範例
ansible -i /etc/ansible/hosts Ubuntu -m shell -a 'sudo usermod -aG sudo user1'
將 user1 加入 sudo 群組中

------------------------------------------

ansible -i inventory/hosts test -m setup -a 'filter=ansible_distribution' -k
檢查 test 群組中主機系統商的名稱

註1:當連接的主機未使用 keypair 方式認證時,請加上 -k 參數,如果需要 sudo 權限請加 -K
註2:a 是要帶模組的參數

------------------------------------------

ansible -i inventory/hosts test -m gather_facts --tree /tmp/facts
檢查 test 群組中主機系統所有資訊,這個與 setup 模組是相同的,但因資訊過多,建意加上 -a 並進行過濾

------------------------------------------

ansible -i inventory/hosts all -b --become-method sudo --become-user root -m shell -a 'systemctl stop systemd-timesyncd.service' -kK

關閉 systemd-timesyncd.service 服務。
這一段是下參數 -b --become-method sudo --become-user root
個就是等於在 playbook 或 config 設定的這一段
  vars:
    ansible_become: yes
    ansible_become_method: sudo
    ansible_become_user: root
所以,當使用類似指令方式時,如果沒有設定 config,以上參數一定要帶,否則,指令會直接帶執行帳號進行,而 -kK 則只能吃到 -k

------------------------------------------

指定單一主機取的時間

ansible 192.168.56.99 -i inventory/hosts -m command -a 'date' -k

註:多台可用“,”分隔

------------------------------------------

關閉 WARNING

為什麼要關閉訊息,因為 towns 有時只是需要看到結果,過多的資訊反而是難閱讀的,不過,關閉 warning 是不好的,用完建議打開

deprecation_warnings = False <= 關閉 DEPRECATION WARNING 訊息
ANSIBLE_PYTHON_INTERPRETER=auto_silent <= 關閉 [WARNING] discovered Python interpreter 訊息

DEPRECATION_WARINGS=False ANSIBLE_PYTHON_INTERPRETER=auto_silent ansible -i inventory/hosts time_check -m shell -a "date"
DEPRECATION_WARINGS=False ANSIBLE_PYTHON_INTERPRETER=auto_silent ansible -i inventory/hosts time_check -m shell -a "date '+%T'"

註1:deprecation_warnings = False 這個值可以寫在 ansible.cfg 中因為他是個參數。
註2:ansible_python_interpeter=auto_silent 這個值不可以寫在 ansible.cfg 中,需要寫在 host_vars, in vars files,因為,他是個變數 = =,而且,請用小寫。
註3:如果要寫在指令請,請用大寫 = =

參考資料:
官方網頁 -- All modules
https://docs.ansible.com/ansible/2.8/modules/list_of_all_modules.html

https://docs.ansible.com/ansible/2.3/setup_module.html

james、tina 大口述 

https://docs.ansible.com/ansible/2.9/modules/command_module.html

https://docs.ansible.com/ansible/2.9/modules/shell_module.html

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/systemd_module.html

stackoverflow 討論
https://stackoverflow.com/questions/43791040/suppress-ansible-ad-hoc-warning

官方說明 -- Interpreter Discovery
https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html

------------------------------------------

列出檔案

列出指定日期的檔案
DEPRECATION_WARINGS=False ANSIBLE_PYTHON_INTERPRETER=auto_silent ansible -i inventory/hosts all -m shell -a 'ls -alR /var/log/ --full-time | grep 2022-01-04' -kK

------------------------------------------

列出使用者
ansible -i inventory/hosts all -m shell -a 'grep "/home" /etc/passwd | awk -F: "{print $1}"' -kK
ansible -i inventory/hosts all -m shell -a 'grep "/home" /etc/passwd | awk -F: "$3>=1000{print $1}"'


Ansible-lint 來檢查 playbook

ansible-lint test.yaml <== 檢查 test.yaml 內容是否有問題

參考資料:tsoliangwu0130 大文章


ansible.cfg 中的設定值如何寫入 inventory host 檔中

 

參考資料:stackoverflow -- Rico
https://stackoverflow.com/questions/23074412/how-to-set-host-key-checking-false-in-ansible-inventory-file 


忽略 host-key-check

因為 ansible 是使用 ssh 登入,所以當該主機為第一次登入時,都會在client .ssh/known_hosts 寫入 server 端的 ECDSA key fingerprint 資訊,這是為了避免 server 端變更的安全機制,不過,如果有一堆機器是第一次登入,towns 是否要一台一台改啊?

在 ansible.cfg 中,將下面參數啟用
[defaults]
host_key_checking = false

參考資料:stackoverflow -- techraf
https://stackoverflow.com/questions/42462435/ansible-provisioning-error-using-a-ssh-password-instead-of-a-key-is-not-possibl

補充:這個參數只是不跳出詢問 yes/no 但,還是會寫入 client .ssh/known_hosts,所以在第一次執行後,請將該參數關閉,還是要安全一點的


使用 python 建立加密密碼

1. 使用 python
python -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))'

這個密碼產生的結果,與在 CentOS 下使用 passwd 建立的密碼是相同的

2. 使用 mkpasswd
mkpasswd --method=sha-512
註:在 CentOS 7 下必需安裝 expect 套件

參考資料:yi大


寫 ansible 的建議

gather_facts: no
這個模組主要是要收集遠端電腦的資訊,預設為開啟,不過,有時會造成執行時系統停止,因為無法取得資料或是需要人工回應,所以建議在寫 playbook 時就直接關閉這個模組功能

補充:當使用該功能執行時出現系統停止,需要考慮一個可能性,是否有硬體損壞,所以 ansible 在抓資料時,當掉了

參考資料:

ryan 大口述

Phil Huang 大文章
https://blog.pichuang.com.tw/20180622-suggestions_to_improve_your_ansible_playbook/

官方說明
https://docs.ansible.com/ansible/2.9/modules/gather_facts_module.html 


關於 ansible config 的讀取順序

ansible 文件中有說明,會抓取最後一個設定,如果沒有設定則依以下順序

* ANSIBLE_CONFIG (環境變數)
* ansible.cfg (當前目錄)
* .ansible.cfg (使用者家目錄)
* /etc/ansible/ansible.cfg (預設設定檔)

參考資料
官方說明
https://ansible-docs.readthedocs.io/zh/stable-2.0/rst/intro_configuration.html#getting-the-latest-configuration

ryan 口述


ansible 說明

ansible-doc lineinfile => 說明 lineinfile 模組使用方式
註:= 必用、 - 選用

參考資料
rudy 口述


playbook 直接寫入 shell script

要在 playbook 中直接寫入 shell script,可以這樣寫 shell: | ,下面就可以使用完整的 shell script 了

參考資料
rudy 口述


ansible 的 inventory 中,群組名稱不能使用 "-",只能用 "_"

留言

這個網誌中的熱門文章

zimbra 安裝、管理、設定

Fortigate 100D -- 管理、設定

IT 隨手記6