python自動化管理Ansible(Ansible,Fabric,hosts)

一、Ansible介紹

Ansible是一個簡單的自動化運維工具,可完成配置管理、應用部署、服務編排以及其他各種IT需求。Ansible也是一款基於Python語言實現的開源軟件,其依賴Jinja2、paramiko和PYYAML這幾個Python庫。

Ansible的作者是Michael Dehaan,Michael Dehaan同時也是知名軟件Cobber的作者和Func的共同作者。Michael Dehaan與2012年創建了AnsibleWorks公司,之後改名爲Ansible公司。Ansible公司與2015年10月被紅帽公司(Red Hat)收購。

在這一小節,我們將首先介紹Ansible的優點,然後比較Ansible與Fabric之間的差異。

1、Ansible的優點

Ansible作爲配置工具,通常與Puppet、Chef、Saltstack進行比較,如下所示:

工具 發佈時間 語言 架構 協議
Puppet 2005年 Ruby C/S http
Chef 2008年 Ruby C/S http
Saltstack 2012年 Python C/S(可無Client) ssh/zmq/raet
Ansible 2013年 Python 無Client ssh

從發佈時間來看,Ansible完全沒有優勢,那麼,是什麼特性讓Ansible進入了工程師的視野,並且逐步獲得青睞呢?我們需要了解一下Ansible有哪些優點。

Ansible具有以下幾個優點:

(1)部署簡單

只需要在主控端部署Ansible環境,被控端無須做任何操作。換句話說,在安裝Ansible時,遠程服務器無煩安裝任何依賴。因此,相對於其他配置管理器,Ansible安裝部署非常簡單,省去了客戶端的安裝。在數千臺規模的大型數據中心意味着少了一些路由和安全策略的配置,省去了很多不必要的麻煩。

(2)基於ssh進行配置管理,充分利用現成的機制

Ansible不依賴與客戶端,直接使用ssh進行配置管理,在Ansible早期版本中,默認使用paramiko進行配置管理,從Ansible1.3版本開始,Ansible默認使用OpenSSH實現個服務器間通信。

(3)Ansible不需要守護進程

因爲Ansible依賴OpenSSH進行通信,不需要安裝客戶端,因此服務端也不需要像其他配置管理一樣使用一個守護進程。Ansible的安裝和維護都變得更加簡單,系統更加安全可靠。

(4)日誌集中存儲

所有操作日誌都存儲在Ansible發起服務器,可以採用自定義的格式,這樣可以很方便地知曉哪些服務器操作有問題,哪些已經成功,也便於日後追溯。

(5)Ansible簡單易用

Ansible和其他配置管理工具一樣,運行一個部署命令就可以完成應用部署,使用非常簡單。此外,Ansible使用YAML語法管理配置,YAML本身是一種可讀性非常強的標記語言,工程師幾乎像閱讀英文一樣閱讀YAML的配置文件。因爲Ansible使用YAML管理配置,所以使用Ansible不需要使用者具有任何編程背景。運維自動化工具本身是用來簡化運維工作的,如果本身比較複雜(如Puppet),甚至需要一定的程序開發能力,那麼就會增加使用者的使用難度和犯錯的概率。

(6)Ansible功能強大

Ansible通過模塊來實現各種功能,目前,Ansible已經有了950多個模塊,工程師也可以使用任何語言編寫自定義的Ansible模塊。

(7)Ansible設計優秀,便於分享

Ansible使用role組織Playbook,並提供了分享role的平臺(galaxy.ansible.com),便於大家分享和複用。充分使用role,可以編寫可讀性更強的配置文件。使用開源的role,能夠有效節省編寫Playbook的時間。

(8)Ansible對雲計算和大數據平臺都有很好的支持

從Ansible的模塊列表可以看到,Ansible包含了大量與雲服務、AWS、OpenStack、Docker等相關的模塊。並且,Ansible便於擴展,當出現新事務時可以根據需要編寫自定義的模塊。

Ansible作爲自動化系統運維的一大利器,在構建整個體系過程中有着舉足輕重的地位。其簡單易用、易於安裝、功能強大、便於分享、內含大量模板等都是它的魅力所在,再加上易封裝、接口調用方便,Ansible正在被越來越多的大公司採用。

2、Ansible與Fabric之間的比較

簡單來說,Fabric像是一個工具箱,提供了很多好用的工具,用於在遠程服務器執行命令。而Ansible則提供了一套簡單的流程,只需要按照它的流程來做就能輕鬆完成任務。這就像是庫和框架的關係一樣,其中,Fabric是庫,Ansible是框架。

(1)Fabric與Ansible之間的共同點

1.都是基於paramiko開發;
2.都使用ssh和遠程服務器通訊,不需要在遠程服務器上安裝客戶端。

(2)Fabric與Ansible之間的主要區別

1. Fabric簡單,Ansible複雜。因此,Fabric學習成本低,Ansible的學習成本高;
2. Fabric通過ssh執行簡單的命令,Ansible將模塊拷貝到遠程服務器後執行,執行完成以後刪除模塊;
3. 使用Fabric需要具有Python編程背景,使用Ansible則不需要;
4. Fabric對常用的管理操作和ssh連接操作進行了封裝,工程師通過編寫簡單的代碼就能完成要做的事情。Ansible不需要工程師編寫任何代碼,直接編寫YAML格式的配置文件來描述要做的事情;
5. Fabric提供了基本的接口,業務邏輯需要用戶自己實現;Ansible提供了大量的模塊,用戶只需要學習模塊的用法即可完成複雜的任務。

二、Ansible使用入門

在這一小節我們介紹Ansible的安裝與基本使用,然後在接下來的章節中介紹Ansible的高級用法。

ansible使用原則:

  • 確定要操作哪些服務器(服務器列表)
  • 確定對這些服務器進行什麼樣的操作(命令

關於hosts文件:

  • 默認讀取/etc/ansible/hosts文件
  • 通過命令行參數-i指定hosts文件
  • 通過/etc/ansible/ansible.cfg裏面的inventory選項指定hosts文件

1、安裝Ansible

Ansible不需要安裝客戶端,因此,相對於其他配置管理工具,Ansible的安裝簡單得多,只需要在控制端安裝Ansible即可。Ansible使用Python語言開發,我們可以直接使用pip進行安裝,也可以使用Linux下的包管理工具(如yumI、apt-get)進行安裝。如下所示:

[root@python ~]# pip3 install ansible

檢查Ansible是否安裝成功,如下所示:

[root@python ~]# ansible --version
ansible 2.9.9
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Aug  7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

Ansible依賴Python與SSH,因此服務器需要安裝SSH和Python 2.5或2.5以上版本的Python。SSH和Python是大多數操作系統中默認安裝的軟件,這進一步降低了Ansible安裝部署的難度。除了SSH和Python以外,服務器端不需要再預裝任何軟件。在控制端(Ansible命令運行的那臺機器)需要安裝Python 2.6或更高版本的Python程序,且Ansible的控制端只能運行在Linux下。
與其他庫和工具不同的是,Ansible包含了多個工具。安裝完Ansible以後,控制端會增加以下幾個可執行程序:

ansible
ansible-doc
ansible-playbook
ansible-vault
ansible-console
ansible-galaxy
ansible-pull

這些可執行程序將在之後使用時進行詳細介紹。

2、Ansible的架構

爲了更好的理解Ansible,在介紹Ansible的使用之前,我們先看一下Ansible的架構圖,如下所示:

python自動化管理Ansible(Ansible,Fabric,hosts)

在Ansible中,用戶通過編排引擎操作主機。其中,主機可以通過配置文件配置,調用雲計算的接口獲取,或者訪問CMDB中的數據庫。Ansible的編排引擎有Inventory、API、Modules(模塊)和Plugins組成。Ansible的典型用法是:工程師將需要遠程服務器執行的操作寫在Ansible Playbook中,然後使用Ansible執行Playbook中的操作。

3、Ansible的運行環境

使用Ansible操作遠程服務器時,首先需要確定的是操作哪些服務器,然後再確定對這些服務器執行哪些操作。

Ansible會默認讀取/etc/ansible/hosts文件中配置的遠程服務器列表。在我們這一小節,/etc/ansible/hosts文件內容如下:

[root@python ~]# mkdir /etc/ansible
[root@python ~]# vim /etc/ansible/hosts

[test]
127.0.0.1
192.168.1.80

Ansible中存在一個名爲ping的模塊,該模塊並不是測試服務器的網絡是否連接,而是嘗試建立SSH連接,以便驗證用戶的SSH是否已經正確配置。如下所示:

[root@python ~]# ansible test -m ping

python自動化管理Ansible(Ansible,Fabric,hosts)

修改test的權限

[root@python ~]# chmod  755 /etc/sudoers
[root@python ~]# vim /etc/sudoers
test    ALL=(ALL)       ALL                   #92行左右添加
[root@python ~]# vim /etc/ansible/hosts

[test]
127.0.0.1 ansible_user=root ansible_port=22
192.168.1.80

再次測試一下

root@python ~]# ansible test -m ping

python自動化管理Ansible(Ansible,Fabric,hosts)

常見錯誤解決方案如下:
(1)ansible管理節點生成ssh-key
[root@192 ~]# ssh-keygen 

執行成功後,將會在~/.ssh目錄下生成2個文件:id_rsa和id_rsa.pub

(2)添加目標節點的ssh認證信息
[root@192 ~]# ssh-copy-id [email protected]
[root@192 ~]# ssh-copy-id [email protected]
(3)測試
[root@192 ~]# ansible test -m ping
192.168.79.133 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
47.100.98.242 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

Ansible默認使用當前用戶和默認的22端口號與遠程服務器建立SSH連接。如果需要使用其他用戶,或者使用非默認的SSH端口號,可以在host之後增加用戶名和端口號的配置。如下所示:

[root@192 ~]# cat /etc/ansible/hosts
[test]
192.168.79.133 ansible_user=test ansible_port=22
47.100.98.242 ansible_user=laoyu ansible_port=80

一般情況下,工作環境的服務器ssh用戶名和ssh端口號都是相同的。如果我們有很多的遠程服務器,每一臺服務器都需要配置ansible_user或ansible_port參數,如果依然使用前面的配置方式進行配置,會顯得非常冗餘。對於這種情況,可以在Ansible配置文件中修改相應的配置。

Ansible默認使用/etc/ansible/ansible.cfg文件,我們可以在ansible.cfg中設定一些默認值,這樣就需要對同樣的內容輸入多次。如下所示:

[root@192 ~]# cat /etc/ansible/ansible.cfg
[defaults]
remote_port = 2090
remote_user = test

4、Ansible的ad-hoc模式

ping模塊是Ansible中最簡單的模塊,而command模塊則是工程師最熟悉的模塊。command模塊的作用非常簡單,就是在服務器中執行shell命令。在Ansible中,通過-m參數指定模塊名稱,通過-a參數指定模塊的參數。因此,使用command模塊在遠程服務器執行shell命令的語句如下:

[root@python ~]# ansible test -m command -a "hostname"
127.0.0.1 | CHANGED | rc=0 >>
python
192.168.1.80 | CHANGED | rc=0 >>
python
[root@python ~]# ansible test -m command -a "whoami"
192.168.1.80 | CHANGED | rc=0 >>
root
127.0.0.1 | CHANGED | rc=0 >>
root

command是Ansible中的默認模塊,當我們省略-m參數時,默認使用command模塊。如下所示:

[root@python ~]# ansible test -m command -a "whoami"
192.168.1.80 | CHANGED | rc=0 >>
root
127.0.0.1 | CHANGED | rc=0 >>
root

大部分情況下,Ansible的模塊包含多個參數,參數使用“key=value”的形式表示,各個參數之間使用空格分隔。如下所示:

(1)創建ansible.cfg文件

[root@python ~]# vim /etc/ansible/ansible.cfg
[defaults]
remote_port = 22
remote_user = root

再次測試一下

[root@python ~]# ansible test -m ping

python自動化管理Ansible(Ansible,Fabric,hosts)

[root@python ~]# ansible test -m command -a "hostname"

python自動化管理Ansible(Ansible,Fabric,hosts)

(2)將本地文件拷貝到服務器

[root@python ~]# cd /tmp/
[root@python tmp]# mkdir abc
[root@python tmp]# cd abc/
[root@python abc]# ls
nginx.conf  restart.sh     #要拷貝的文件

進行拷貝

[root@python abc]# ansible test -m copy -a "src=/tmp/abc/nginx.conf dest=/opt/nginx.conf"

python自動化管理Ansible(Ansible,Fabric,hosts)

查看一下是否有拷貝的文件

[root@python abc]# ls /opt/ | grep nginx.conf
nginx.conf

<1>創建劇本(拷貝)

[root@python abc]# vim test_playbook.yml

---
- hosts: test
  become: yes               #是否支持root權限
  become_method: sudo
  tasks:                    #任務
  - name: copy file         #描敘
    copy: src=/opt/nginx.conf dest=/tmp/abc/nginx.conf #拷貝的

  - name: package install   #描敘
    yum: name={{item}} state=present        #安裝的
    with_items:
      - tmux

執行一下

[root@python abc]# ansible-playbook test_playbook.yml 

python自動化管理Ansible(Ansible,Fabric,hosts)

查看是否有拷貝的文件

[root@python abc]# ls | grep nginx.conf 
nginx.conf

(3)在遠程服務器中安裝軟件

[root@python abc]# ansible test -m yum -a "name=tmux state=present" -become

python自動化管理Ansible(Ansible,Fabric,hosts)

5、使用playbook控制服務器

前面通過Ansible命令執行操作的方式,稱爲ad-hoc。我們可以使用ad-hoc來執行非常簡單的操作,也可以使用ad-hoc的方式來學習模塊的使用方式。但是,在實際的生產環境中,我們一般將遠程服務器需要做的事情寫在一個YAML配置文件中。

例如,將本地文件拷貝到遠程服務器並修改文件所有者,然後安裝軟件的功能,寫在YAML的配置文件中以後,其內容如下:

[root@192 ~]# cat test_playbook.yml
---
- hosts: test
  become: yes
  become_method: sudo
  tasks:
    - name: copy file
      copy: src=~/s.txt dest=/opt/s.txt

    - name: change mode
      file: dest=/opt/s.txt mode=500 owner=root group=root

    - name: ensure packages installed
      yum: name={{item}} state=present
      with_items:
        - git
        - tmux

這個YAML文件稱爲Ansible Playbook。Playbook中首先包含了一些聲明信息,如hosts關鍵字聲明該Playbook應用的服務器列表,become和become_method表示在遠程服務器通過sudo執行操作。Playbook最後包含了若干個task,每一個task對應於前面的一條ad-hoc命令。具體執行時,多個task按序執行。如果你不能完全理解YAML文件,現在只需要對Ansible的執行方式有一個認識即可。後續小節將會詳細講解如何編寫Ansible Playbook。

有了Playbook以後,通過ansible-playbook命令執行,如下所示:

[root@192 ~]# ansible-playbook test_palybook.yml
PLAY [test] ****************************************************************************************************************

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

TASK [copy file] ***********************************************************************************************************
ok: [127.0.0.1]
ok: [47.100.98.242]

TASK [change mode] *********************************************************************************************************
ok: [127.0.0.1]
ok: [47.100.98.242]

TASK [ensure packages installed] *******************************************************************************************
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a 
loop to supply multiple items and specifying `name: "{{item}}"`, please use `name: ['git', 'tmux']` and remove the loop. 
This feature will be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in
 ansible.cfg.
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a 
loop to supply multiple items and specifying `name: "{{item}}"`, please use `name: ['git', 'tmux']` and remove the loop. 
This feature will be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in
 ansible.cfg.
changed: [47.100.98.242] => (item=['git', 'tmux'])
changed: [127.0.0.1] => (item=['git', 'tmux'])

PLAY RECAP *****************************************************************************************************************
127.0.0.1                  : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
47.100.98.242              : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@desktop-kh5f5dc ~]# 

上面這條命令的效果與上一小節中多條ad-hoc命令的效果是一樣的。關於YAML的語法,如何編寫playbook以及模塊的使用方式等,將在本章的後續小節中進行詳細講解。在這一小節中,我們只需要知道Ansible有兩種操作遠程服務器的方式,分別是:ad-hoc與Playbook。

三、Inventory管理

在Ansible中,將可管理的服務器的集合稱爲Inventory。因此,Inventory管理便是服務器管理。這一節中,我們將會詳細討論Inventory管理。

1、hosts文件位置

我們已經演示了Ansible如何對遠程服務器執行操作,可以看到,Ansible在執行操作是,首先需要確定對哪些服務器執行操作。默認情況下,Ansible讀取/etc/ansible/hosts文件中的服務器配置,獲取需要操作的服務器列表。Ansible定義與獲取服務器列表的方式比這個要靈活得多。

在Ansible中,有3種方式制定hosts文件,分別是:

  • 默認讀取/etc/ansible/hosts文件;
  • 通過命令行參數-i指定hosts文件;
  • 通過ansible.cfg文件中的inventory選項(老版本的Ansible中通過hostfile選項指定)指定hosts文件。

例如:當前系統中除了/etc/ansible/hosts文件以外,在test用戶的home目錄下也存在一個名爲hosts的文件,該hosts文件的內容如下所示:

[test]
127.0.0.1
192.168.1.80

使用/etc/ansible/hosts文件

[root@python ~]# ansible test --list-hosts
  hosts (2):
    127.0.0.1
    192.168.1.80

-i選項指定hosts文件

[root@python ~]# ansible test -i hosts --list-hosts
  hosts (2):
    127.0.0.1
    192.168.1.80

修改ansible.cfg文件,添加inventory選項,指定hosts文件的路徑

[root@python ~]# vim /etc/ansible/ansible.cfg 

[defaults]
remote_user = root
remote_port = 22
inventory = /etc/ansible/hosts

2、靈活定義hosts文件內容

(1)分組定義服務器

[root@python ~]# vim /etc/ansible/hosts 

[demo]
127.0.0.1
[xgp]
192.168.1.80
[wsd]
192.168.1.60

1)查看單個分組的服務器列表

[root@python ~]# ansible demo --list-hosts
  hosts (1):
    127.0.0.1
[root@python ~]# ansible xgp --list-hosts
  hosts (1):
    192.168.1.80
[root@python ~]# ansible wsd --list-hosts
  hosts (1):
    192.168.1.60
[root@python ~]# ansible all --list-hosts
  hosts (3):
    127.0.0.1
    192.168.1.80
    192.168.1.60

python自動化管理Ansible(Ansible,Fabric,hosts)

2)查看多個分組的服務器列表(冒號分隔組名)

[root@python ~]# ansible xgp:wsd -i hosts --list-hosts
  hosts (2):
    192.168.1.80
    192.168.1.60

3)使用all和星號匹配服務器

[root@python ~]# ansible '*' -i hosts --list-hosts
[root@python ~]# ansible 'all' -i hosts --list-hosts
  hosts (3):
    127.0.0.1
    192.168.1.60
    192.168.1.80

(2)Ansible定義組匹配服務器

[root@python ~]# vim hosts
[demo]
127.0.0.1
[xgp]
192.168.1.80
[wsd]
192.168.1.60
[common:children]
xgp
wsd

查看服務器列表

[root@python ~]# ansible common -i hosts --list-hosts
  hosts (2):
    192.168.1.80
    192.168.1.60

(3)批量定義服務器

[root@python ~]# vim hosts

[demo]
127.0.0.1
[xgp]
192.168.1.80
[1:3].xgp.top
[wsd]
192.168.1.60
[a:d].xgp.top
[common:children]
xgp
wsd

查看服務列表

[root@python ~]# ansible xgp:wsd -i hosts --list-hosts
  hosts (9):
    192.168.1.80
    1.xgp.top
    2.xgp.top
    3.xgp.top
    192.168.1.60
    a.xgp.top
    b.xgp.top
    c.xgp.top
    d.xgp.top

3、靈活匹配hosts文件內容

Ansible還支持通配符和正則表達式等更靈活的方式來匹配服務器。

Ansible官方給出了ansible命令的語法格式:

ansible <pattern_goes_here> -m <module_name> -a <arguments>

例如:重啓所有web服務器中的Apache進程:

ansible webservers -m service -a "name=httpd state=restarted"
ansible web*.duxuejun.com =-m service -a "name=httpd state=restarted"

遠程服務器匹配規則:

匹配規則 含義
192.168.1.10 或者 web.duxuejun.com 匹配目標IP地址或服務器名稱,如果含有多個IP或服務器,使用“:”分隔
webservers 匹配目標爲webservers,多個分組使用“:”分隔
all或者"*" 匹配所有的服務器
webservers:!dbservers 匹配在webservers中,不在dbservers組中的服務器
webservers:&dbservers 匹配同時在webservers組以及dbservers組中的服務器
*.duxujun.com或192.168.* 使用通配符進行匹配
webservers[0],webservers[1:],webservers[-1] 使用索引或切片操作的方式匹配組中的服務器
~(web|db).*.duxuejun.com 以~開頭的匹配,表示使用正則表達式匹配

4、Inventory行爲參數

參數                             默認值                說明
ansible_ssh_host                主機的名字            ssh的目的主機或ip
ansible_ssh_port                22                  ssh目的端口
ansible_ssh_user                root                ssh登陸使用的用戶名
ansible_ssh_pass                none                ssh認證所使用的密碼
ansible_connection              smart               Ansible使用何種連接模式連接到主機
ansible_ssh_private_key_file    none                ssh認證所使用的私鑰
ansible_shell_type              sh                  命令所使用的shell
ansible_python_interpreter      /usr/bin/python     主機上的python解釋器
ansible_*_interpreter           none                類似python解釋器的其他語言版

5、改變行爲參數的默認值

可以在ansible.cfg文件的[defaults]部分更改一些行爲參數的默認值              
ansible.cfg文件                 inventory文件     
ansible_ssh_user                remote_user
ansible_ssh_port                remote_port
ansible_ssh_private_key_file    private_key_file
ansible_shell_type              executable

6、定義服務器變量

在hosts文件中,除了定義行爲參數以外,還可以定義普通的變量,以便在不同的服務器中使用不同的配置。比如:可以在2臺服務器中分別啓動MySQL,1臺服務器的MySQL的端口是3306,另一臺服務器MySQL的端口是3307。定義普通參數和定義行爲參數的方法是一樣的,只是行爲參數的名字有Ansible預先定義,普通參數的名稱有我們自己定義。在Ansible中,參數名必須爲字母、數字和下劃線的組合,並且首字符必須爲字母。

(1)變量的取值不同

假定,我們在/etc/ansible/hosts文件中爲不同的服務器定義一個相同的變量名,但是取值不同。如下所示:

[root@python ~]# vim hosts

[test]
192.168.1.60 ansible_port=22
192.168.1.80 ansible_port=22

在測試環境中,我們可以通過echo方式顯示變量的值。如下所示:

[root@python ~]# ansible  test -i ./hosts -a 'echo {{ansible_port}}' 
192.168.1.60 | CHANGED | rc=0 >>
22
192.168.1.80 | CHANGED | rc=0 >>
22

(2)變量的取值相同

如果test組下的兩個服務器mysql_port變量取值相同,我們也可以通過組的名稱加上“:vars”後綴來定義變量,如下所示:

[root@python ~]# vim hosts

[test]
192.168.1.40
192.168.1.80

[test:vars]
ansible_port = 22

隨着業務的發展,管理的hosts文件越來越大,使用的變量越來越多了,依然使用一個hosts文件管理服務器和變量的話,就會逐漸變得難以管理。

Ansible提供了更好的方法來管理服務器和羣組的變量,即:爲每個服務器和羣組創建獨立的變量文件。其定義方式是,將組的變量存放在一個名爲group_vars命令下,目錄下的文件名與組的名稱相同,文件的擴展名可以是.yml或.yaml,也可以沒有任何擴展名。服務器的變量存放在一個名爲host_vars目錄下,該目錄下的文件名爲服務器的名稱。

Ansible將依次在Playbook所在的目錄、hosts文件所在的目錄和/etc/ansible目錄下尋找group_vars目錄和host_vars目錄。目前,假設group_vars目錄和host_var目錄都位於/etc/ansible目錄下。

對於我們前面定義mysql_port變量的例子,將變量存放在獨立的文件以後,/etc/ansible目錄的結構如下:

[root@192 ansible]# tree
.
├── ansible.cfg
├── group_vars
│   └── test.yaml
├── hosts
└── host_vars
    └── 127.0.0.1.yaml

其中,test.yaml文件定義了hosts文件中test組的變量,127.0.0.1.yaml文件定義了hosts文件中127.0.0.1這臺服務器使用的變量。如:test.yaml文件的內容如下:

[root@192 ansible]# cat group_vars/test.yaml 
ansible_port: 22

注意:我們在hosts文件中定義變量時,使用的是“var = value”格式定義。將變量保存在一個獨立的文件時,使用的是“var:value”格式定義。這是因爲Ansible解析這兩個文件時,認爲hosts是一個ini格式的文件,而保存變量的文件是一個YAML格式的文件。

[root@python ~]# ansible  test -i ./hosts -a 'echo {{ansible_port}}' 
192.168.1.40 | CHANGED | rc=0 >>
22
192.168.1.80 | CHANGED | rc=0 >>
22

四、YAML語法

1、YAML語法規則

1. YAML文件第一行爲“---”,表示這是一個YAML文件;
2. YAML中字段大小寫敏感;
3. YAML與Python一樣,通過縮進來表示層級關係;
4. YAML的縮進不允許使用Tab鍵,只允許使用空格,且空格的數目不重要,只要相同層級的元素左側對齊即可;
5. “#”表示註釋,從這個字符一直到行尾都會被解析器忽略

2、YAML支持的3中格式數據

1. 對象:鍵值對的集合,有稱爲映射,類似於Python中的字典;
2. 數組:一組按次序排列的值,有稱爲序列(sequence),類似於Python的列表;
3. 純量(scalars):單個的、不可再分的值,比如:字符串、布爾值與數字。

3、安裝PyYAML庫

Python標準庫沒有包含解析YAML格式的庫,需要安裝第三方的PyYAML庫。

pip3 install -i https://pypi.douban.com/simple/ PyYAML

4、定義與解析YAML文件

(1)數組格式

使用YAML表示數組非常容易,只需要用“-”將元素按序列出即可。假設我們有下面這樣一個YAML文件,文件的內容保存在一個名爲data.yaml的文件中,如下所示:

---
# 一個美味的水果列表
- Apple
- Orange
- Strawberry
- Mango

解析結果:

In [1]: import yaml                                                                

In [2]: with open('data.yaml') as f: 
   ...:     print(yaml.load(f)) 
   ...:                                                                            
['Apple', 'Orange', 'Strawberry', 'Mango']

(2)對象

在YAML中,對象以“key:value”的形式進行定義,如下所示:

---
# 一個職工的記錄
name: 愛運維
job: devops
skill: Elite
age: 23
knowoop: True
likes_emacs: TRUE
users_cvs: false

解析結果:

In [3]: with open('dev.yaml') as f: 
   ...:     print(yaml.load(f)) 
   ...:
{'name': '愛運維', 'job': 'devops', 'skill': 'Elite', 'age': 23, 'knowoop': True, 'likes_emacs': True, 'users_cvs': False}

YAML中可以使用多種方式制定布爾值,如以上YAML文件中的“True”、“TRUE”、“false”,轉換爲Python代碼後,對變量的取值進行了格式化。

(3)對象和數組嵌套

YAML中的對象和數組是可以任意嵌套的,如下所示:

---
# 一個職工的記錄
name: 愛運維
job: devops
skill: Elite
age: 23
knowoop: True
likes_emacs: TRUE
users_cvs: false
foods:
    - Apple
    - Orange
    - Strawberry
    - Mango
languages:
    ruby: Elite
    python: Elite
    shell: Lame

(4)注意事項

在YAML中定義字符串的時候,不需要使用單引號或者雙引號,直接將字符串寫在文件中即可。如下所示:

str: this is a string

如果字符串中包含了特殊字符,需要使用雙引號包含起來。比如:字符串中包含冒號。冒號是YAML中的特殊字符,因此需要使用雙引號包含起來。

foo: "somebody said I should put a colon here: so I did"

如果字符串內容比較長,可以使用“>”來摺疊換行。

that: >
    Foo
    Bar

將以上YAML文件轉換爲Python的內部對象後,“Foo”和“Bar”都是字符串的一部分。

{'that': 'Foo Bar\n'}

五、Ansible模塊

1、Ansible的模塊工作原理

1. 將模塊拷貝到遠程服務器
2. 執行模塊定義的操作,完成對服務器的修改
3. 在遠程服務器刪除模塊

Ansible中的模塊是冪等的,也就是說,多次執行相同的操作,只有第一次會起作用。這也是在編寫自定義的Ansible模塊的時候需要注意的。

2、模塊列表與幫助信息

Ansible模塊非常多,如果以模塊的功能進行分類的話,可以分爲以下模塊:

雲模塊
命令模塊
數據庫模塊
文件模塊
資產模塊
消息模塊
監控模塊
網絡模塊
通知模塊
包管理模塊
源碼控制模塊
系統模塊
單元模塊
web設施模塊
Windows模塊
……

查看Ansible模塊幫助信息,如下所示:

[root@python ~]# ansible-doc -l

查看指定模塊的幫助信息,如下所示

[root@python ~]# ansible file
[WARNING]: Could not match supplied host pattern, ignoring: file
[WARNING]: No hosts matched, nothing to do
usage: ansible [-h] [--version] [-v] [-b] [--become-method BECOME_METHOD] [--become-user BECOME_USER] [-K] [-i INVENTORY]
               [--list-hosts] [-l SUBSET] [-P POLL_INTERVAL] [-B SECONDS] [-o] [-t TREE] [-k]
               [--private-key PRIVATE_KEY_FILE] [-u REMOTE_USER] [-c CONNECTION] [-T TIMEOUT]
               [--ssh-common-args SSH_COMMON_ARGS] [--sftp-extra-args SFTP_EXTRA_ARGS] [--scp-extra-args SCP_EXTRA_ARGS]
               [--ssh-extra-args SSH_EXTRA_ARGS] [-C] [--syntax-check] [-D] [-e EXTRA_VARS] [--vault-id VAULT_IDS]
               [--ask-vault-pass | --vault-password-file VAULT_PASSWORD_FILES] [-f 

3、常用的Ansible模塊

Ansible提供的功能越豐富,所需要的模塊也就越多。默認情況下,模塊存儲在/usr/share/ansible目錄中。

(1)ping

[root@python ~]# ansible test -m ping
192.168.1.40 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
Enter passphrase for key '/root/.ssh/id_rsa': 
192.168.1.80 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

(2)遠程命令模塊

1)command模塊

ansible test -m command -a 'hostname'
ansible test -m command -a '/sbin/shutdown -t now'
ansible test -a 'hostname'

command模塊在執行Linux命令時,不能使用管道。如下所示:

ansible test -m command -a 'cat /etc/passwd | wc -l'

執行後報錯如下:

192.168.1.40 | FAILED | rc=1 >>
cat:無效選項 -- l
Try 'cat --help' for more information.non-zero return code
192.168.1.80 | FAILED | rc=1 >>
cat:無效選項 -- l
Try 'cat --help' for more information.non-zero return code

2)raw模塊

如果執行的命令需要使用管道,可以使用raw模塊,如下所示:

[root@python ~]#  ansible test -m raw -a 'cat /etc/passwd | wc -l'
192.168.1.80 | CHANGED | rc=0 >>
45
Shared connection to 192.168.1.80 closed.

192.168.1.40 | CHANGED | rc=0 >>
44
Shared connection to 192.168.1.40 closed.

raw模塊相當於使用ssh直接執行Linux命令,不會進入到Ansible的模塊的子系統中。

3)shell模塊

除了使用raw模塊以外,也可以使用shell模塊,如下所示:

[root@python ~]# ansible test -m shell -a 'cat /etc/passwd | wc -l'
192.168.1.40 | CHANGED | rc=0 >>
44
192.168.1.80 | CHANGED | rc=0 >>
45

shell模塊還可以執行遠程服務器上的shell腳本,其中,腳本文件的路徑需要使用絕對路徑,如下所示:

ansible test -m shell -a '/home/test/test.sh'

統計某個文件有多少行

[root@python ~]# ansible common -m raw -a 'cat /etc/passwd | wc -l'
192.168.1.40 | CHANGED | rc=0 >>
43
Shared connection to 192.168.1.40 closed.

192.168.1.80 | CHANGED | rc=0 >>
45
Shared connection to 192.168.1.80 closed.

[root@python ~]# ansible common -m shell -a 'cat /etc/passwd | wc -l'
192.168.1.40 | CHANGED | rc=0 >>
43
192.168.1.80 | CHANGED | rc=0 >>
45

引用文件的方式

[root@python ~]# vim test.sh 

#!/usr/bin/bash
cat /etc/passwd | wc -l
[root@python ~]# ansible common -m script -a 'test.sh'
192.168.1.40 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.1.40 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.1.40 closed."
    ], 
    "stdout": "43\r\n", 
    "stdout_lines": [
        "43"
    ]
}
192.168.1.80 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.1.80 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.1.80 closed."
    ], 
    "stdout": "45\r\n", 
    "stdout_lines": [
        "45"
    ]
}
(3)file

file模塊主要用於對遠程服務器上的文件(包括鏈接和目錄)進行操作,包括修改文件的權限、修改文件的所有者、創建文件、刪除文件等。

file模塊使用示例:

# 創建一個目錄
ansible test -m file -a 'path=/tmp/dd state=directory mode=0o755'

# 修改文件的權限
ansible test -m file -a "path=/tmp/dd state=touch mode='u=rw,g=r,o=r'"

# 創建一個軟鏈接
ansible test -m file -a 'src=/tmp/dd dest=/tmp/dd1 state=link owner=root group=root'

# 修改一個文件的所有者
ansible test -m file -a "path=/tmp/dd owner=root group=root mode=0o644" -become

file模塊中重要選項:

1. path: 指定文件/目錄的路徑
2. recurse: 遞歸設置文件屬性,只對目錄有效
3. group: 定義文件/目錄的組
4. mode: 定義文件/目錄的權限
5. owner: 定義文件/目錄的所有者
6. src: 要被鏈接的源文件路徑,只應用於state爲link的情況
7. dest: 被鏈接到的路徑,只應用於state爲link的情況
8. force: 在兩種情況下會強制創建軟鏈接,一種情況是源文件不存在,但之後會建立的情況;另一種情況是目標軟鏈接已經存在,需要先取消了之前的軟鏈接,然後再創建新的軟鏈接,默認取值爲no
9. state: 該選項有多個取值,包括directory、file、link、hard、touch、absent。各個取值的含義如下:取值爲directory,如果目錄不存在,創建目錄;取值爲file時,即使文件不存在也不會被創建;取值爲link時,創建軟鏈接;取值爲hard時,創建硬鏈接;取值爲touch時,如果文件不存就創建一個新文件,如果文件或目錄已經存在,更新其最後訪問時間和修改時間;取值爲absent時,刪除目錄、文件或者鏈接

<1>創建文件

[root@python ~]# ansible  common -m file -a 'path=/opt/test.md state=touch'
查看一下

python自動化管理Ansible(Ansible,Fabric,hosts)

<2>創建目錄

[root@python ~]# ansible  common -m file -a 'path=/opt/test mode=0755 state=directory'
查看一下

python自動化管理Ansible(Ansible,Fabric,hosts)

<3>創建並刪除文件

[root@python ~]# ansible  common -m file -a 'path=/opt/abc mode=0640 state=touch'
//創建
查看一下

python自動化管理Ansible(Ansible,Fabric,hosts)

[root@python ~]# ansible  common -m file -a 'path=/opt/abc mode=0640 state=absent'

python自動化管理Ansible(Ansible,Fabric,hosts)

<4>創建並改變文件所有者

[root@python ~]# ansible  common -m file -a 'path=/opt/abc mode=0640 state=touch'

[root@python ~]# ansible  common -m file -a 'path=/opt/abc mode=0640 owner=test group=root' -become

python自動化管理Ansible(Ansible,Fabric,hosts)

(4)copy

copy模塊用來將主控節點的文件或者目錄拷貝到遠程服務器上,類似於Linux下的scp命令。但是,copy模塊比scp命令更強大,在拷貝文件到遠程服務器上的同時,也可以設置文件在遠程服務器上的權限和所有者。

copy模塊的使用示例:

# 拷貝文件到遠程服務器
ansible test -m copy -a 'src=test.sh dest=/tmp/test.sh'

# 拷貝文件到遠程服務器,如果遠程服務器已經存在這個文件,則備份文件
ansible test -m copy -a 'src=test.sh dest=/tmp/test.sh backup=yes force=yes'

# 拷貝文件到遠程服務器,並且修改文件的所有者和權限
ansible test -m copy -a 'src=tes.sh dest=/tmp/tes.sh owner=root group=root mode=644 force=yes' -become

copy模塊中重要選項:

1. src:要複製到遠程服務器的文件地址,可以是絕對路徑,也可以是相對路徑。如果路徑時一個目錄,將遞歸複製。在這種情況下,如果使用“/”結尾,則複製目錄裏的內容;如果沒有用“/”來結尾,則將包含目錄在內的整個內容複製,類似於rsync
2. dest:文件要複製到的目的地,必須是一個絕對路徑,如果源文件是一個目錄,那麼dest指向的也必須是一個目錄
3. force:默認取值爲yes,表示目標主機包含該文件,但是內容不同時,會強制覆蓋;如果該選項設置爲no,只有當目標主機的目標位置不存在該文件時,纔會進行復制
4. backup:默認取值爲no,如果取值爲yes,那麼在覆蓋之前將原文件進行備份
5. directory_mode:遞歸設定目錄權限,默認爲系統默認權限
6. others:所有file模塊裏的選項都可以在這裏使用

(5)user/group

user模塊請求的是useradd、userdel、usermod這三個指令,group模塊請求的是groupadd、groupdel、groupmod這三個指令。

user/group模塊的使用示例:

# 創建一個用戶
ansible test -m user -a 'name=John comment="John Doe" uid=1239 group=root' -become

# 刪除一個用戶
ansible test -m user -a 'name=John state=absent' -become

# 創建一個用戶,並且產生一對密鑰
ansible test -m user -a 'name=John comment="John Doe" generate_ssh_key=yes ssh_key_bits=2048' -become

# 創建羣組
ansible test -m group -a 'name=ansible state=present gid=1234' -become

# 刪除羣組
ansible test -m group -a 'name=ansible state=absent' -become

user/group模塊重要選項:

1. name:需要操作的用戶名或羣組名
2. comment:用戶的描述信息
3. createhome:創建用戶時,是否創建家目錄,默認爲yes
4. home:指定用戶的家目錄,需要與createhome選項配合使用
5. group:指定用戶的屬組
6. uid:設置用戶的id
7. gid:設置羣組的id
8. password:設置用戶的密碼
9. state:是創建用戶或羣組,還是刪除用戶後羣組,取值包括present和absent
10. expires:用戶的過期時間
11. shell:指定用戶的shell環境

(6)yum

yum模塊可以幫助我們在遠程主機上通過yum源管理軟件包。

yum模塊使用示例:

# 安裝軟件包
ansible test -m yum -a 'name=nginx disable_gpg_check=yes'
ansible test -m yum -a 'name=nginx state=present disable_gpg_check=yes'
ansible test -m yum -a 'name=nginx state=installed disable_gpg_check=yes'
ansible test -m yum -a 'name=nginx state=latest disable_gpg_check=yes'

# 卸載軟件包
ansible test70 -m yum -a 'name=nginx state=absent'
ansible test70 -m yum -a 'name=nginx state=removed'

yum模塊重要選項:

1. name:必須參數,用於指定需要管理的軟件包,比如nginx
2. state:用於指定軟件包的狀態 ,默認值爲present,表示確保軟件包已經安裝,除了present,其他可用值有installed、latest、absent、removed,其中installed與present等效,latest表示安裝yum中最新的版本,absent和removed等效,表示刪除對應的軟件包
3. disable_gpg_check:用於禁用對rpm包的公鑰gpg驗證,默認值爲no,表示不禁用驗證,設置爲yes表示禁用驗證,即不驗證包,直接安裝,在對應的yum源沒有開啓gpg驗證的情況下,需要將此參數的值設置爲yes,否則會報錯而無法進行安裝
4. enablerepo:用於指定安裝軟件包時臨時啓用的yum源,假如你想要從A源中安裝軟件,但是你不確定A源是否啓用了,你可以在安裝軟件包時將此參數的值設置爲yes,即使A源的設置是未啓用,也可以在安裝軟件包時臨時啓用A源
5. disablerepo:用於指定安裝軟件包時臨時禁用的yum源,某些場景下需要此參數,比如,當多個yum源中同時存在要安裝的軟件包時,你可以使用此參數臨時禁用某個源,這樣設置後,在安裝軟件包時則不會從對應的源中選擇安裝包
6. enablerepo參數和disablerepo參數可以同時使用

(7)get_url

從互聯網上下載數據到本地,作用類似於Linux下的curl命令。get_url模塊比curl命令更加靈活,可以控制下載以後的數據所有者、權限以及檢查下載數據的checksum等。

get_url模塊使用示例:

爲了進行get_url測試,使用命令“python -m http.server”啓動一個下載服務器,將下載服務器中的文件地址傳給url選項。

# 下載文件到遠程服務器
ansible test -m get_url -a 'url=http://localhost:8000/data.tar.gz dest=/tmp/data.tar.gz'

# 下載文件到遠程服務器,並且修改文件的權限
ansible test -m get_url -a 'url=http://localhost:8000/data.tar.gz dest=/tmp/data.tar.gz mode=0777'

# 下載文件到遠程服務器,並且檢查文件的MD5校驗是否與控制端的MD5校驗相同
[root@bogon ~]# md5sum s.txt
d41d8cd98f00b204e9800998ecf8427e  s.txt
[root@bogon ~]# ansible 127.0.0.1 -m get_url -a 'url=http://localhost:8000/s.txt dest=/tmp/s.txt checksum=md5:d41d8cd98f00b204e9800998ecf8427e'
127.0.0.1 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum_dest": null,
    "checksum_src": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "dest": "/tmp/s.txt",
    "elapsed": 0,
    "gid": 0,
    "group": "root",
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e",
    "mode": "0644",
    "msg": "OK (0 bytes)",
    "owner": "root",
    "secontext": "unconfined_u:object_r:admin_home_t:s0",
    "size": 0,
    "src": "/root/.ansible/tmp/ansible-tmp-1584171703.8607588-137457225931919/tmpG3otIP",
    "state": "file",
    "status_code": 200,
    "uid": 0,
    "url": "http://localhost:8000/s.txt"
}
[root@bogon ~]# ansible 127.0.0.1 -m get_url -a 'url=http://localhost:8000/s.txt dest=/tmp/s.txt checksum=md5:d41d8cd98f00b204e9800998ecf84270'
127.0.0.1 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "checksum_dest": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "checksum_src": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "dest": "/tmp/s.txt",
    "elapsed": 0,
    "msg": "The checksum for /tmp/s.txt did not match d41d8cd98f00b204e9800998ecf84277e; it was d41d8cd98f00b204e9800998ecf8427e.",
    "src": "/root/.ansible/tmp/ansible-tmp-1584171717.7448506-78799482489470/tmpyczfH3",
    "url": "http://localhost:8000/s.txt"
}

get_url模塊重要選項:

1. dest:必傳選項,指定將文件下載的絕對路徑
2. url:必傳選項,文件的下載地址(網址)
3. url_username: 用於http基本認證的用戶名
4. url_password: 用於http基本認證的密碼
5. validate_certs: 如果否,SSL證書將不會驗證。這隻應在使用自簽名證書的個人控制站點上使用
6. owner: 指定屬主
7. group: 指定屬組
8. mode: 指定權限
9. checksum:文件的校驗碼
10. headers:傳遞給下載服務器的HTTP Headers
11. backup:如果本地已經存在同名文件,備份文件
12. timeout:下載的超時時間

(8)unarchive

unarchive模塊用於解壓文件,其作用類似於Linux下的tar命令。默認情況下,unarchive的作用是將控制節點的壓縮包拷貝到遠程服務器,然後進行解壓。

unarchive模塊使用示例:

# 先創建一個目錄
ansible test - m file -a 'path=/tmp/data state=directory'

# 解壓本地文件
ansible test - m unarchive -a 'src=data.tar.gz dest=/tmp/data list_files=yes'

# 將本地文件拷貝到遠程服務器
ansible test -m copy -a 'src=data.tar.bz2 dest=/tmp/data.tar.bz2'

# 解壓遠程的文件
ansible test -m unarchive -a 'src=/tmp/data.tar.bz2 dest=/tmp remote_src=yes'

unarchive模塊重要選項:

1. remote_src:該選項可以取值爲yes或no,用來表示解壓的文件存在遠程服務器中,還是存在控制節點所在的服務器中。默認取值爲no,表示在解壓文件之前,先將控制節點的文件複製到遠程主機中,然後在進行解壓
2. src:指定壓縮文件的路徑,該選項的取值取決於remote_src的取值。如果remote_src取值爲yes,則src指定的是遠程服務器中壓縮包的地址;如果remote_src的取值爲no,則src指向的是控制節點中的路徑
3. dest:該選項指定的是遠程服務器上的絕對路徑,表示壓縮文件解壓的路徑
4. list_files:默認情況下該選項取值爲no,如果該選項取值爲yes,也會解壓文件,並且在ansible的返回值中列出壓縮包裏的文件
5. exclude:解壓文件時排除exclude選項指定的文件或目錄列表
6. keep_newer:默認取值爲False,如果該選項取值爲True,那麼當目標地址中存在同名的文件,並且文件比壓縮包中的文件更新時,不進行覆蓋
7. owner:文件或目錄解壓以後的所有者
8. group:文件或目錄解壓以後所屬的羣組
9. mode:文件或目錄解壓以後的權限

(9)git

git模塊非常好理解,就是在遠程服務器執行git相關的操作。該模塊一般應用於需要源碼安裝軟件時,從github這樣的源碼託管網站將軟件下載到本地,然後執行命令進行源碼安裝。需要注意的是,該模塊依賴於git軟件,因此在使用該模塊前應該使用yum模塊先安裝git軟件。

git模塊的使用示例:

#將requests克隆到/tmp/requests目錄下
ansible test -m git -a 'repo=https://github.com/psf/requests.git dest=/tmp/requests version=HEAD'

# 從源碼安裝requests
ansible test -a 'python setup.py install chdir=/tmp/requests' -become

# 驗證requests是否安裝成功
ansible test -a "python -c 'import requests'"

git模塊常用選項:

1. repo:遠程git庫的地址,可以是一個git協議、ssh協議或http協議的git庫地址
2. dest:必選選項,git庫clone到本地服務器以後保存的絕對路徑
3. version:克隆遠程git庫的版本,取值可以爲HEAD、分支的名稱、tag的名稱,也可以是一個commit的hash值
4. force:默認取值爲no,當該選項取值爲yes時,如果本地的git庫有修改,將會拋棄本地的修改
5. accept_hostkey:當該選項取值爲yes時,如果git庫的服務器不在know_hosts中,則添加到konw_hosts中,key_file指定克隆遠程git庫地址是使用的私鑰

(10)stat

stat模塊用於獲取遠程服務器上的文件信息,其作用類似於Linux下的stat命令。stat模塊可以獲取atime、ctime、mtime、checksum、size、uid、gid等信息。

stat只有path這一個必選選項,用來指定文件或目錄的路徑。stat模塊的使用方法如下:

# 獲取文件的詳細信息
ansible test -m stat -a 'path=/etc/passwd'

(11)cron

顧名思義,cron是管理Linux下計劃任務的模塊。

cron模塊的使用示例:

# 增加一個crontab任務
ansible test -m cron -a 'backup=yes name="測試計劃任務" minute=*/2 hour=* job="ls /tmp >/dev/null"'

# 進入服務器,查看新增的crontab任務
crontab -l

該模塊包含以下重要選項:

1. backup:取值爲yes或no,默認爲no,表示修改之前先做備份
2. state:取值爲present或absent,用來確認該任務計劃是創建還是刪除
3. name:該任務的描述
4. job:添加或刪除任務,主要取決於state的取值
5. user:操作哪一個用戶的crontab
6. cron_file:如果指定該選項,則用該文件替換遠程主機上cron.d命令下的用戶任務計劃
7. month weekday 打印minute hour:取值與crontab類似。例如:對於minute的取值範圍0~59,也可以選擇“*”表示每分鐘運行,或者“*/5”表示每5分鐘運行

(12)service

service模塊的作用類似於Linux下的service命令,用來啓動、停止、重啓服務。

service模塊的使用示例:

# 安裝Apache,默認情況下,Apache安裝完成以後就會啓動
ansible test -m yum -a 'name=httpd state=present' -become

# 停止Apache
ansible test -m service -a 'name=httpd state=stopped'

# 重啓Apache
ansible 127.0.0.1 -m service -a 'name=httpd state=restarted'

service模塊的常用選項:

1. name:服務的名稱,該選項爲必選項
2. state:可以取值爲started、stopped、restarted和reload。其中,started和stopped是冪等的,也就是說,如果服務已經啓動了,執行started不會執行任何操作
3. sleep:重啓的過程中,先停止服務,然後sleep幾秒在啓動
4. pattern:定義一個模式,ansible首先通過status命令查看服務的狀態,依次判斷服務是否在運行。如果通過status查看服務狀態時沒有響應,ansible會嘗試匹配ps命令的輸出,當匹配到相應模式時,認爲服務已經啓動,否則認爲服務沒有啓動
5. enabled:取值爲yes或no,用來設置服務是否開機啓動

(13)sysctl

該模塊的作用與Linux下的sysctl命令相似,用於控制Linux的內核參數。

sysctl模塊使用示例:

# 設置overcommit_memory參數的值爲1
ansible test -m sysctl -a 'name=vm.overcommit_memory value=1' -become

sysctl模塊的常用選項:

1. name:需要設置的參數
2. value:需要設置的值
3. sysctl_file:sysctl.conf文件的絕對路徑,默認路徑是/etc/sysctl.conf
4. reload:該選項可以取值爲yes或no,默認爲yes,用於表示設置完成以後是否需要執行sysctl -p操作

(14)setup

setup模塊用於收集遠程主機的信息

setup模塊的使用示例:

# 獲取IP地址
ansible test -m setup -a 'filter=ansible_default_ipv4'

# 獲取內存信息
ansible test -m setup -a 'filter=ansible_memory_mb'

# 獲取主機完整信息
ansible test -m setup

(15)mount

在遠程服務器上掛載磁盤,當進行掛盤操作是,如果掛載點指定的路徑不存在,將創建該路徑。

mount模塊使用示例:

# 掛載/dev/vda盤到/mnt/data目錄
ansible test -m mount -a 'name=/mnt/data src=/dev/vda fstype=ext4 state=mounted'

mount模塊常用選項:

1. name:掛載點的路徑
2. state:可以取值爲present、absent、mounted、unmounted,其中,mounted與unmounted用來處理磁盤的掛載和卸載,並且會正確配置fstab文件,present與absent只會設置fstab文件,不會去操作磁盤
3. fstype:指定文件系統類型,當state取值爲present或mounted時,該選項爲必填選項
4. src:掛載的設備

(16)synchronize

synchronize模塊是對rsync命令的封裝,以便對常見的rsync任務進行處理。我們也可以使用command模塊調用rsync命令執行相應的操作。rsync是一個比較複雜的命令,相對來說,使用synchronize簡單一些。

synchronize模塊的使用示例:

#  同步本地目錄到遠程服務器
ansible test -m synchronize -a 'src=test dest=/tmp'

synchronize模塊的常用選項:

1. src:需要同步到遠程服務器的文件和目錄
2. dest:遠程服務器保存數據的路徑
3. archive:默認取值爲yes,相當於同時開啓recursive、links、perms、times、owner、group、-D等選項
4. compress:默認爲yes,表示在文件同步過程中是否啓用壓縮
5. delete:默認爲no,當取值爲yes時,表示刪除dest中存在而src中不存在的文件

4、模塊的返回值

Ansible通過模塊來執行具體的操作,由於模塊的功能千差萬別,所以執行模塊操作後,Ansible會根據不同的需要返回不同的結果。雖然如此,Ansible中也有一些常見的返回值。如下所示:

返回值的名稱 返回值的含義
changed 幾乎所有的Ansible模塊都會返回該變量,表示模塊是否對遠程主機執行了修改操作
failed 如果模塊未能執行完成,將返回failed爲True
msg 模塊執行失敗的原因,常見的錯誤如ssh連接失敗,沒有權限執行模塊等
rc 與命令行工具相關的模塊會返回rc,表示執行Linux命令的返回碼
stdout 與rc類似,返回的是標準輸出的結果
stderr 與rc類似,返回的是錯誤輸出的結果
backup_file 所有存在backup選項的模塊,用來返回備份文件的路徑
results 應用在Playbook中存在循環的情況,返回多個結果
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章