1. 程式人生 > 其它 >Ansible之Playbook詳解

Ansible之Playbook詳解

介紹

簡單命令可以使用ad-hoc(呼叫各種模組,通過命令列來執行命令)命令可以方便的解決問題,但是對於複雜場景或需要大量的操作時候,執行的ad-hoc命令是不適合的,這時最好使用playbook,它類似於Shell,檔案格式是YAML(教程:YAML

Inventory:主機列表,表示劇本中的任務要應用在哪些主機上

Tasks:具體任務,即呼叫哪些模組完成操作,可以配置多個任務

Variables:變數,包含內建變數和自定義變數

Templates:模板,即使用模板語法來靈活變更的配置檔案

Handlers與notify:觸發器,由某事件觸發執行的操作,比如修改配置檔案後自動重啟服務

Playbook的語法要求

1、playbook本質是包含了一個或多個play的YAML配置檔案,通常以.yaml或者.yml結尾

2、在單一的一個playbook檔案中,使用連續的三個中橫線(---)作為每個play的區分

3、縮排必須統一,不能空格和tab混合使用,縮排級別需要一致,同樣的縮排代表同樣的級別

ansible具有冪等性

再次執行的時候ansible會檢測這個task是否已經執行過,如果這個task任務執行過,它不會再次執行task任務,而是直接顯示ok狀態

執行順序

play的主體部分是task list, task list中的各任務按次序逐個在hosts中指定的所有主機上執行,即在所有主機上完成第一個任務後在開始第二個任務,在執行自上而下某個playbook時,如果中途發生錯誤,所有已經執行的任務都會回滾,因此,在更正playbook後重新執行一次即可。

handlers

在關注的資源發生變化時採取一定的操作,會在 playbook 的每一個 task 結束時被觸發,而且即使有多個不同的 task 通知改動的發生, ‘notify’ actions 只會被觸發一次.

- name: template configuration file
  template: src=template.j2 dest=/etc/foo.conf
  notify:
    - restart memcached
    - restart apache

handler是task列表,這些task與前述的task並沒有本質上的區別

handlers:
- name: restart memcached      #名字要和上面notify的 一致
  service: name=memcached state=restarted
- name: restart apache
  service: name=apache state=restarted

執行 playbook

ansible-playbook -t tag_name httpd.yml #-t指定標籤名,多個標籤用逗號分隔
ansible-playbook playbookname.yml --list-task #列出該playbook中的任務
  • --check | -C:只檢測可能會發生的改變,但不真正執行操作
  • --list-hosts:列出執行任務的主機
  • --list-tags:列出playbook檔案中定義的所有tags
  • --list-tasks:列出playbook檔案中定義的所有任務
  • --limit:主機列表 只針對主機列表中的某個主機或者某個組執行
  • -f:指定併發數,預設為5個
  • -t:指定tags執行,執行某一個或者多個tags。前提是playbook中有定義tags

ansible-playbook命令結果說明:

  • ok:已經達到任務要求,無需再次處理
  • changed:經過了ansible的處理,再次執行則會發現這些資訊也變成了ok
  • PLAY RECAP:一個彙總報告

例項2:安裝Httpd

# ansible install httpd 
- hosts:    # 這裡是需要安裝的機器列表, 也可以是ansible配置好的組名
  - 192.168.199.110
  - 192.168.199.180
  tasks:    # 任務塊
    - name: install httpd server   # 描述資訊
      yum:    # ansible 模組
        name: httpd,lrzsz  # 需要安裝的軟體名稱 
        state: installed   # 執行動作
    - name: start httpd server
      service:
        name: httpd
        state: started
        enabled: yes

相關命令

#通過-e引數能給將變數傳入進去
ansible-playbook check_variable.yml  -e "key=hehe"
#-t指定標籤名,多個標籤用逗號分隔
ansible-playbook -t tag_name httpd.yml 

#列出該playbook中的任務
ansible-playbook playbookname.yml --list-task 
#語法檢查
ansible-playbook playbook1.yml --syntax-check  
#列出所有任務
ansible-playbook playbook1.yml --list-tasks

#指定要使用的並行程序數(預設值 = 5)
ansible-playbook playbook1.yml -f 3 

#檢視某一個 Ansible 模組介紹
ansible-doc -l | grep <keywords associated with the module name>
#檢視某一個 Ansible 模組的使用方法
ansible-doc <module>
#按下 “:” 之後再按下 “/” 之後再輸入 <要檢視部分的關鍵字>

變數與引用

在hosts裡定義變數

[root@LeoDevops playb]# grep -vE "(^$|^#)" /etc/ansible/hosts 
192.168.93.132  key=132
192.168.93.137  key=137
[nginx]
192.168.93.132
192.168.93.137
[nginx:vars]
ansible_python_interpreter=/usr/bin/python2.6

playbook引用變數

- hosts: all
  gather_facts: False
  tasks:
    - name: Display Host Variable From Hostfile
      debug: msg="The {{ inventory_hostname  }} Value is {{ key  }}"

在playbook定義變數

- hosts: all
  gather_facts: False  #設定為false,那麼下面的debug模組會生效
  vars:       # 先申明vars這個關鍵字
    key: "Ansible"  #這種方式定義,key: value的形式
  tasks:
    - name: display host variables from hostfile
      debug: msg="The {{ inventory_hostname  }} value is {{ key }}"

或者在playbook裡面引用有變數的檔案

- hosts: all
  gather_facts: False
  vars_files:
    - var.json
  tasks:
    - name: display host variables from hostfile
      debug: msg="The {{ inventory_hostname  }} value is {{ key }}"
[root@LeoDevops playb]# cat var.json 
{"key":"json"}

另一種變數引用, 定義全域性變數

在hosts的nginx裡面定義一個變數key, 不在單獨對每個主機定義key

> grep -vE "(^$|^#)" /etc/ansible/hosts 
[nginx]
192.168.93.132
192.168.93.137
[nginx:vars]
ansible_python_interpreter=/usr/bin/python2.6
key=nginx

playbook保持不變

通過命令列傳輸

  • 通過-e引數能給將變數傳入進去
[root@LeoDevops playb]# ansible-playbook check_variable.yml  -e "key=hehe"
  • -e指定檔案的方式傳入變數
[root@LeoDevops playb]# cat var.json 
{"key":"json"}
[root@LeoDevops playb]# ansible-playbook check_variable.yml -e "@var.json"

register內的變數

ansible playbook內的task之間還可以互相傳遞資料,比如總共有兩個tasks,其中第二個task是否執行是需要判斷第1個task執行後的結果,這個時候就得在task之間傳遞資料,需要把第一個task執行的結果傳遞給第二個task,下面看看簡單的register的方式

- hosts: u12
  tasks:
    - name: register variable
      shell: date
      register: info
    - name: display variable
      debug: msg="the variable is {{ info['stdout'] }}"

使用vars_prompt傳入

ansible 還支援在執行playbook的時候通過互動式的方式給定義好的引數傳入變數值,只需要在playbook中定義vars_prompt 的變數名和互動式提示內容即可。當然ansible還可以對傳入的變數值進行加密處理。加密處理依賴於passlib python庫。請看簡單的 vars_prompt的例子

- hosts: all
  gather_facts: False
  vars_prompt:
    - name: "one"
      prompt: "please input your value"
      private: no
    - name: "two"
      prompt: "please input two value"
      default: 'good'  # 預設顯示一個值
      private: yes  #置為yes的話,那麼就是看不見自己輸入的什麼了
  tasks:
     - name: display one value
       debug: msg="one value is {{ one }}"
     - name: display two value
       debug: msg="two value is {{ two }}"

例項

playbook示例

---
- hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
  - name: write the apache config file
    template: src=/srv/httpd.j2 dest=/etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running
    service: name=httpd state=started
  handlers:
    - name: restart apache
      service: name=httpd state=restarted

此action可用於在每個play的最後被觸發,這樣可以避免多次有改變發生時每次都執行指定的操作,僅在所有的變化發生完成最後一次性地執行指定操作。在notify中列出的操作稱為handler,也即notify中呼叫handler中定義的操作。

vim hello_world.yml

---                       #固定格式
- hosts: 192.168.1.31     #定義需要執行的主機或主機組
  remote_user: root       #遠端使用者
  vars:                   #定義變數
    http_port: 8088       #變數
  tasks:                  #定義一個任務
    - name: create new file          #定義任務的名稱
      file: name=/tmp/playtest.txt state=touch   #呼叫模組,具體要做的事情
    - name: install package
      yum: name=httpd
    - name: config httpd
      template: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
      notify:   #觸發器,當條件觸發後需要做的操作,配合handlers使用
        - restart apache  #需要引用的handlers的名字
    - name: copy index.html
      copy: src=/var/www/html/index.html dest=/var/www/html/index.html
    - name: start httpd
      service: name=httpd state=started
  handlers:   #notify定義的觸發執行相應的處理動作
    - name: restart apache                     #要與notify定義的內容相同
      service: name=httpd state=restarted      #觸發要執行的動作

hosts:指定遠端主機(多個主機用逗號分隔)或主機組

remote_user:指定執行任務的使用者(也可單獨給每個task定義),通常是root使用者,也可指定非root使用者使用sudo方式執行任務

執行

 ansible-playbook hello_world.yml
---
- hosts: 192.168.1.31
  remote_user: root  #定義全域性使用者
  tasks: 
  - name: run df -h
    remote_user: test  #單獨為task定義使用者
    shell: name=df -h

sudo(可省略):如果設定為yes,那麼sudo_user指定的使用者在執行任務時會獲得root許可權

sudo_user(可省略):指定需要使用sudo執行操作的使用者

tasks: 
  - name: run df -h
    sudo_user: test
    sudo: yes
    shell: name=df -h

connection(可省略):通過什麼方式連線到遠端主機,預設為SSH

gather_facts(可省略):如果明確不需要通過setup模組來獲取遠端主機facts資訊,可以使用這個選項

---
#安裝mysql
- hosts: db_hosts   #主機或主機組
  remote_user: root     #指定遠端主機的執行使用者
  var: dar     #變數,引用方式為{{ var }}
    http_port: 80
    db_port: 3306
  tasks: #指定遠端主機將要執行的一系列動作
    - name: Install MySQL-server package  #不是必須,但建議加上
      yum: name=mysql-server state=present  #模組
    - name: Starting mysqld service
      service: name=mysqld state=started
      notify: 

    handlers:
      - name: restart apache
        service: name=httpd state=restarted

第一個示例

vim /root/first.yml

- hosts: all
  remote_user: root
  vars: httpd_port=80
  
  tasks:
  - name: install httpd
    yum: name=httpd state=present
  - name: install php
    yum: name=php state=present
  - name: start httpd
    service: name=httpd state=started enabled=true

hosts 定義單個主機或組,vars定義變數,remote_user定義執行命令的遠端使用者,tasks定義執行哪些命令,handlers定義呼叫哪些處理器

vars(變數)

  • 變數命名: 字母數字下劃線組成,只能以字母開頭

變數種類:

  1. facts(內建變數)

由遠端主機發回的主機屬性資訊,這些資訊被儲存在ansible變數當中

例如:ansible 192.168.238.170 -m setup 來獲取遠端主機上的屬性資訊,這些屬性資訊儲存在facts中

通過命令列傳遞:ansible-playbook test.yml --extra-vars “host=www user=tom“(如果劇本中已有此處定義的變數則會被覆蓋)

  1. 通過roles傳遞

    主機變數 , 在/etc/ansible/hosts中定義

[web1]
192.168.1.1 name=haha

組變數

[group_name:vars]
foo=bar

hosts :

/etc/abible/hosts 中指定的遠端主機,並用指定的屬性進行連線

ansible_ssh_port 連線遠端主機使用的埠

ansible_ssh_user 連線遠端主機使用的使用者

ansible_ssh_pass 連線遠端主機使用的密碼

cat /etc/ansible/hosts

[web1]
web1.hostname ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123
web2.hostname

第二個示例

vim /root/second.yml

- hosts: web1
  remote_user: root
  vars:
    username: bob
    password: 123
    
  tasks:
  - name: add user
    user: name={{ username }} state=present
    when: ansible_os_family == "Debian"
  - name: set password
    shell: echo {{ password }} |passwd --stdin {{ username }}
  - name: install httpd php
    yum: name={{ item }} state=present
    with_items:
      - httpd
      - php
  - name: add two users
    user: name={{ item }} state=present groups={{ item.groups }}
    with_items:
    - { name: 'user1', groups: 'group1'}
    - { name: 'user2', groups: 'group2'}
  • 在playbook中呼叫變數的方式為{{ variable }}
  • when語句用來條件測試
  • ansible_os_family 是facts中內建的屬性資訊 ansible_os_family的資訊可以使用ansible all -m setup | grep ansible_os_family 檢視
  • 在task中呼叫內建的item變數;在某task後面使用with_items語句來定義元素列表

第三個示例

vim /root/third.yml

- hosts: web1
  remote_user: root
  vars: 
    httpd_port=80
  
  tasks:
  - name: install httpd
    yum: name=httpd state=present
  - name: install php
    yum: name=php state=present
  - name: copy config file
    copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify: restart httpd
  - name: start httpd
    service: name=httpd state=started enabled=true
    
  handlers:
  - name: restart httpd
    service: name=httpd state=restarted

上面的意思是copy中複製過去的檔案跟遠端主機上的檔案不同,就通過notify呼叫handlers,即重啟httpd服務。

handler是重啟服務是最通用的用法

第四個示例

vim /etc/ansible/hosts
[web1]
192.168.1.1 http_port=80

vim /root/httpd.conf
……
Listen {{ http_port }}
……

vim /root/fourth.yml

- hosts: web1
  remote_user: root
  vars: 
    httpd_port=80
  
  tasks:
  - name: install httpd
    yum: name=httpd state=present
  - name: copy config file
    template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify: restart httpd
  - name: start httpd
    service: name=httpd state=started enabled=true
    
  handlers:
  - name: restart httpd
    service: name=httpd state=restarted

templates:用於生成文字檔案(配置檔案)

模板檔案中可使用jinja2表示式,表示式要定義在{{ }},也可以簡單地僅執行變數替換

第五個示例

roles:roles用於實現“程式碼複用”,roles以特定的層次型格式組織起來的playbook元素(variables, tasks, templates,handlers);可被playbook以role的名字直接進行呼叫

roles的檔案結構:

  • files/:此角色中用到的所有檔案均放置於此目錄中
  • templates/: Jinja2模板檔案存放位置
  • tasks/:任務列表檔案;可以有多個,但至少有一個叫做main.yml的檔案
  • handlers/:處理器列表檔案;可以有多個,但至少有一個叫做main.yml的檔案
  • vars/:變數字典檔案;可以有多個,但至少有一個叫做main.yml的檔案
  • meta/:此角色的特殊設定及依賴關係
mkdir /root/roles
cd /root/roles
mkdir -p web1/{files, templayes, tasks, handlers, vars, meta}

vim web1/vars/main.yml
user: tom
group: tom
http_port: 8080

vim web1/tasks/main.yml

- name: install httpd
  yum: name=httpd state=present
- name: copy config file
  template: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
  notify: restart httpd
  tags: conf
- name: start httpd
  service: name=httpd state=started enabled=true
 
#這裡的template指的是相對路徑-->web1/templates
#tags可以在執行時指定標籤任務

vim web1/handlers/main.yml

handlers:
- name: restart httpd
  service: name=httpd state=restarted

vim web1/templates/httpd.conf

……
Listen {{ http_port }}
……

定義一個呼叫roles檔案

vim /root/web1.yml

- hosts: web1
  remote_user: root
  roles:
    - web1
    - { role:web2, http_port:8080 }
  • hosts:web1 指在/etc/ansible/hosts中定義的組,上面有定義
    • roles: web1 指的是當前目錄下的web1目錄,也可通過role傳遞變數, 也可呼叫多個role。這樣只需更改hosts的主機就可以實現不同主機的程式碼重用了

執行

ansible-playbook web1.yml
#指定執行任務:
ansible-playbook -t conf web1.yml

ansible任務的非同步執行

ansible方便在於能批量下發,並返回結果和呈現。簡單、高效。
但有的任務執行起來卻不那麼直接,可能會花比較長的時間,甚至可能會比ssh的超時時間還要長。這種情況任務是不是沒法執行了?
ansible考慮到了這種情況,官方文件介紹了這個問題的解決方法,就是讓下發的任務執行的連線變為非同步:任務下發之後,長連線不再保持,而是每隔一段時間輪詢結果,直到任務結束。
他們在playbook的任務中加入兩個引數:async和poll。

async引數值代表了這個任務執行時間的上限值。即任務執行所用時間如果超出這個時間,則認為任務失敗。此引數若未設定,則為同步執行。

poll引數值代表了任務非同步執行時輪詢的時間間隔。 官方給出例子:

hosts: all
remote_user: root
tasks:
  - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
    command: /bin/sleep 15
    async: 45
    poll: 5

這時候已經不怕任務超時了。可以執行一個45s的任務,當然也可以根據需要自己設定。另外,如果poll為0,就相當於一個不關心結果的任務。

如果還想要更方便地看輪詢結果,ansible還提供了這個模組async_status。


# Requires ansible 1.8+
- name: 'YUM - fire and forget task'
  yum: name=docker-io state=installed
  async: 1000
  poll: 0
  register: yum_sleeper

- name: 'YUM - check on fire and forget task'
  async_status: jid={{ yum_sleeper.ansible_job_id }}
  register: job_result
  until: job_result.finished
  retries: 30

第一個job執行非同步任務,並且註冊了一個名字叫yum_sleeper,用於提供給第二個job作為輪詢物件,並且poll設為0,它自己不再輪詢。
第二個job使用async_status模組,進行輪詢並返回輪詢結果。準備檢查30次。結果如下:

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [cloudlab001]

TASK [YUM - fire and forget task] **********************************************
ok: [cloudlab001]

TASK [YUM - check on fire and forget task] *************************************
FAILED - RETRYING: TASK: YUM - check on fire and forget task (29 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (28 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (27 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (26 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (25 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (24 retries left).
changed: [cloudlab001]

PLAY RECAP *********************************************************************
cloudlab001 : ok=3 changed=1 unreachable=0 failed=0

playbook安裝zabbix

定義hosts

shell > vim /etc/ansible/hosts

[mini]

129.139.153.78:16283
155.139.190.94:12573

定義入口檔案install_zabbix_agent.yml

shell > vim /etc/ansible/install_zabbix_agent.yml

---
- hosts: mini
  roles:
  - install_zabbix_agent

## 可以看到將要安裝的主機組為 mini 組,角色為 install_zabbix_agent

定義角色 install_zabbix_agent

shell > tree /etc/ansible/roles/install_zabbix_agent/

├── files
│    └── zabbix-2.4.5.tar.gz
├── tasks
│    └── main.yml
├── templates
│    ├── zabbix_agentd
│    └── zabbix_agentd.conf
└── vars
      └── main.yml

## 建立 files     目錄,存放編譯安裝過的 zabbix_agent 目錄的壓縮檔案,用於拷貝到遠端主機
## 建立 tasks     目錄,用於編寫將要執行的任務
## 建立 templates 目錄,用於存放可變的模板檔案
## 建立 vars      目錄,用於存放變數資訊

建立tasks主檔案

shell > cat /etc/ansible/roles/install_zabbix_agent/tasks/main.yml

---
  - name: Install Software
    yum: name={{ item }} state=latest
    with_items:
      - libcurl-devel
  - name: Create Zabbix User
    user: name={{ zabbix_user }} state=present createhome=no shell=/sbin/nologin
  - name: Copy Zabbix.tar.gz
    copy: src=zabbix-{{ zabbix_version }}.tar.gz dest={{ zabbix_dir }}/src/zabbix-{{ zabbix_version }}.tar.gz owner=root group=root
  - name: Uncompression Zabbix.tar.gz
    shell: tar zxf {{ zabbix_dir }}/src/zabbix-{{ zabbix_version }}.tar.gz -C {{ zabbix_dir }}/
  - name: Copy Zabbix Start Script
    template: src=zabbix_agentd dest=/etc/init.d/zabbix_agentd owner=root group=root mode=0755
  - name: Copy Zabbix Config File
    template: src=zabbix_agentd.conf dest={{ zabbix_dir }}/zabbix/etc/zabbix_agentd.conf owner={{ zabbix_user }} group={{ zabbix_user }} mode=0644
  - name: Modify Zabbix Dir Permisson
    file: path={{ zabbix_dir }}/zabbix owner={{ zabbix_user }} group={{ zabbix_user }} mode=0755 recurse=yes
  - name: Start Zabbix Service
    shell: /etc/init.d/zabbix_agentd start
  - name: Add Boot Start Zabbix Service
    shell: chkconfig --level 35 zabbix_agentd on

建立主變數檔案

shell > cat /etc/ansible/roles/install_zabbix_agent/vars/main.yml

zabbix_dir: /usr/local
zabbix_version: 2.4.5
zabbix_user: zabbix
zabbix_port: 10050
zabbix_server_ip: 131.142.101.120

建立模板檔案

shell > cat /etc/ansible/roles/install_zabbix_agent/templates/zabbix_agentd

#!/bin/bash

. /etc/init.d/functions


        # Zabbix-Directory
        BASEDIR={{ zabbix_dir }}/zabbix

        # Binary File
        BINARY_NAME=zabbix_agentd

        # Full Binary File Call
        FULLPATH=$BASEDIR/sbin/$BINARY_NAME

        # PID file
        PIDFILE=/tmp/$BINARY_NAME.pid

        # Establish args
        ERROR=0
        STOPPING=0

if [ -f $PIDFILE  ] && [ -s $PIDFILE ]
        then
        PID=`cat $PIDFILE`

        if [ "x$PID" != "x" ] && kill -0 $PID 2>/dev/null && [ $BINARY_NAME == `ps -e | grep $PID | awk '{print $4}'` ]
        then
                STATUS="$BINARY_NAME (pid `pidof $APP`) running.."
                RUNNING=1
        else
                rm -f $PIDFILE
                STATUS="$BINARY_NAME (pid file existed ($PID) and now removed) not running.."
                RUNNING=0
        fi
else
        if [ `ps -e | grep $BINARY_NAME | head -1 | awk '{ print $1 }'` ]
                then
                STATUS="$BINARY_NAME (pid `pidof $APP`, but no pid file) running.."
        else
                STATUS="$BINARY_NAME (no pid file) not running"
        fi
        RUNNING=0
fi

# functions
start() {
        if [ $RUNNING -eq 1 ]
                then
                echo "$0 $ARG: $BINARY_NAME (pid $PID) already running"
        else
                action $"Starting $BINARY_NAME: " $FULLPATH
                touch /var/lock/subsys/$BINARY_NAME
        fi
}

stop() {
        echo -n $"Shutting down $BINARY_NAME: "
        killproc $BINARY_NAME
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$BINARY_NAME
        RUNNING=0
}


# logic
case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        status)
                status $BINARY_NAME
                ;;
        restart)
                stop
                sleep 10
                start
                ;;
        help|*)
                echo $"Usage: $0 {start|stop|status|restart|help}"
                cat <<EOF

                        start           - start $BINARY_NAME
                        stop            - stop $BINARY_NAME
                        status          - show current status of $BINARY_NAME
                        restart         - restart $BINARY_NAME if running by sending a SIGHUP or start if not running
                        help            - this screen

EOF
        exit 1
        ;;
esac

exit 0

shell > cat /etc/ansible/roles/install_zabbix_agent/templates/zabbix_agentd.conf

LogFile=/tmp/zabbix_agentd.log

Server={{ zabbix_server_ip }}

ListenPort={{ zabbix_port }}

Hostname={{ ansible_all_ipv4_addresses[1] }}

Timeout=20

UnsafeUserParameters=1

安裝

shell > ansible-playbook /etc/ansible/install_zabbix_agent.yml

PLAY [mini] *******************************************************************

GATHERING FACTS ***************************************************************
ok: [129.139.153.78]
ok: [155.139.190.94]

TASK: [install_zabbix_agent | Install Software] *******************************
changed: [155.139.190.94] => (item=libcurl-devel)
changed: [129.139.153.78] => (item=libcurl-devel)

TASK: [install_zabbix_agent | Create Zabbix User] *****************************
changed: [129.139.153.78]
changed: [155.139.190.94]

TASK: [install_zabbix_agent | Copy Zabbix.tar.gz] *****************************
changed: [129.139.153.78]
changed: [155.139.190.94]

TASK: [install_zabbix_agent | Uncompression Zabbix.tar.gz] ********************
changed: [129.139.153.78]
changed: [155.139.190.94]

TASK: [install_zabbix_agent | Copy Zabbix Start Script] ***********************
changed: [155.139.190.94]
changed: [129.139.153.78]

TASK: [install_zabbix_agent | Copy Zabbix Config File] ************************
changed: [129.139.153.78]
changed: [155.139.190.94]

TASK: [install_zabbix_agent | Modify Zabbix Dir Permisson] ********************
changed: [155.139.190.94]
changed: [129.139.153.78]

TASK: [install_zabbix_agent | Start Zabbix Service] ***************************
changed: [129.139.153.78]
changed: [155.139.190.94]

TASK: [install_zabbix_agent | Add Boot Start Zabbix Service] ******************
changed: [129.139.153.78]
changed: [155.139.190.94]

PLAY RECAP ********************************************************************
155.139.190.94               : ok=10   changed=9    unreachable=0    failed=0
129.139.153.78               : ok=10   changed=9    unreachable=0    failed=0

## 關注一下,啟動指令碼跟配置檔案中變數的引用。
## 完成安裝,可以去客戶機檢查效果了 !

模組

模組詳解 官方模組

ping模組

功能:檢測

 #測試連線可通性,沒有引數。通的話返回pong
 ansible all -m ping 

setup模組

功能:獲取主機資訊(綠色,紅色)

--tree :#將所有主機的輸出資訊儲存到/tmp/目錄下,以/etc/ansible/hosts裡的主機名為檔名
filter :#過濾關鍵字
ansible all -m setup -a 'filter=ansible_distribution_version' --tree /tmp/xx

#企業需求
1.根據不同主機'不同IP'建立對應IP的目錄
2.根據不同主機不同'主機名'建立對應主機名的目錄
3.自動化運維平臺需要自動獲取到主機的'IP地址,記憶體資訊,磁碟資訊,主機名'...等
4.如果安裝資料庫,分配記憶體為實體記憶體的80%,此時有3臺不同實體記憶體的機器2G、4G、16G
寫一個playbook的情況下,我需要獲取到對應主機的記憶體並作出計算,寫判斷。

#檢視主機所有詳細資訊(命令列和劇本中獲取的格式不同)
[root@m01 ~]# ansible web01 -m setup
#獲取ip
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_default_ipv4'
#獲取主機名
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_fqdn'
#獲取記憶體資訊
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_memory_mb'
#獲取磁碟資訊
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_devices'

#其他資訊引數
ansible_all_ipv4_addresses:'僅顯示ipv4的資訊'。
ansible_devices:僅顯示磁碟裝置資訊。
ansible_distribution:'顯示是什麼系統',例:centos,suse等。
ansible_distribution_major_version:顯示是系統主版本。
ansible_distribution_version:僅顯示系統版本。
ansible_machine:顯示系統型別,例:32位,還是64位。
ansible_eth0:'僅顯示eth0的資訊'。
ansible_hostname:'僅顯示主機名。
ansible_kernel:僅顯示核心版本。
ansible_lvm:顯示lvm相關資訊。
ansible_memtotal_mb:'顯示系統總記憶體'。
ansible_memfree_mb:顯示可用系統記憶體。
ansible_memory_mb:詳細顯示記憶體情況。
ansible_swaptotal_mb:顯示總的swap記憶體。
ansible_swapfree_mb:顯示swap記憶體的可用記憶體。
ansible_mounts:'顯示系統磁碟掛載情況'。
ansible_processor:'顯示cpu個數(具體顯示每個cpu的型號)''。
ansible_processor_vcpus:顯示cpu個數(只顯示總的個數)

#取ip
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_default_ipv4'|awk -F '["]' '/"address"/{print $4}'
10.0.0.7
[root@m01 ~]# ansible web_group -m setup -a 'filter=ansible_default_ipv4'|awk -F '["]' '/"address"/{print $4}'
10.0.0.7
10.0.0.9
10.0.0.8

#取主機名
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_fqdn'|awk -F '["]' '/fqdn/{print $4}'
web01

command模組

command模組

功能:遠端執行簡單的命令

#預設模組(可省略不指定)
#作用:執行系統命令(linux windows),不支援變數,"<",">","|",";","&"等符號
 
[root@m01 ~]# ansible web_group -a 'ls'
[root@m01 ~]# ansible web_group -a 'df -h'

cron模組

cron模組

功能:新增定時任務

#使用crontab之前最好同步時間(注意單引號和雙引號的作用)(*有時候需要加'')
[root@m01 ~]# ansible '*' -m cron -a "name=同步時間 minute=*/5 job='/usr/sbin/ntpdate time1.aliyun.com &>/dev/null'"

ansible-doc cron
ansible db -m cron -a 'minute=""  hour="" day="" month="" weekday="" job="" name="(必須填寫)" state='

#    1、定時設定指定值的寫入即可,沒有設定的要刪除
#    2、name必須寫(建立定時任務或者刪除定時任務的 標誌,不能修改註釋)(這一點和yum倉庫名一樣)
#    3、state有兩個狀態:present(新增(預設值))or absent(移除)
   
#新增定時任務
	ansible db -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job" state="present"'
#檢視定時任務	
ansible db -a "crontab -l"

#修改定時任務
	ansible db -m cron -a 'minute="*/5" job="/bin/echo hello" name="test cron job" state="present"'

#移除定時任務(根據name來刪除)
	ansible db -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job" state="absent"'
	ansible all -m cron -a "name=test state=absent"
檢視定時任務	
ansible db -a "crontab -l"
# 註釋相應定時任務,使定時任務失效
 	ansible web_group -m cron -a "name='ansible cron01' minute=0 hour=0 job='/bin/sh /server/scripts/test.sh' disabled=yes"

ansible yml語法(playbook)

注意:yml語法很嚴格,不能多,漏空格,不能使用TAB

在不同的主機上,建立以主機名命名的目錄

[root@m01 ~]# vim 2.yml 
- hosts: web_group
  tasks:
    - name: 233
      file:
        path: /root/{{ ansible_fqdn }}
        state: directory
        owner: root
        group: root
        mode: 0755
[root@m01 ~]# ansible-playbook 2.yml

[root@web01 ~]# ll
total 8
drwxr-xr-x  2 root root    6 Jun  1 00:41 web01

#檢視ansiable-playbook命令
[root@m01 ~]# ll /usr/bin/ansible	#TAB
ansible               ansible-console-2.7 

copy模組

copy模組

拷貝, 修改檔案或目錄, 修改已經存在的目錄的許可權

使用content可以直接在遠端建立檔案,同時指定檔案內容

使用backup=yes備份配置檔案,可以實現配置檔案的修改或回滾

該模組可以直接拷貝連結

[root@m01 ~]# ansible-doc copy	#檢視copy模組用法
    src: 	#原始檔或目錄,要複製到遠端主機的檔案在本地的地址,可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,它將遞迴複製。在這種情況下,如果路徑使用"/"來結尾,則只複製目錄裡的內容,如果沒有使用"/"來結尾,則包含目錄在內的整個內容全部複製,類似於rsync(#)。(src為空目錄是時候是不會拷貝的,一致顯示綠色)
    content:用於替代"src",可以在命令列直接設定指定檔案的值 
    dest: 			#目標目錄
    owner: foo		#屬主
    group: foo		#屬組(不能使用gid指定)
    mode: '0644'	#許可權,數字(3位|4位),字母,UGO   
    backup: yes		#當出現同名的檔案,直接覆蓋,因為預設是no,指定yes後(檔案內容不同會以當前時間戳備份該檔案)
    force:如果目標主機包含該檔案,但內容不同,如果設定為yes,則強制覆蓋,如果為no,則只有當目標主機的目標位置不存在該檔案時,才複製。預設為yes(force=no和state=backup可以二選一)
	remote_src:			
		yes			#受控端自己玩(可以做批量回滾)
		no			#預設
--------------------------------------------------  
#遠端批量拷貝,相當於scp,rsync
#目標目錄下檔案存在的話會報錯,被控端主機使用者不存在會報錯(但是它把能做的都做了)
[root@m01 ~]# ansible 'web_group' -m copy -a 'src=/root/hosts dest=/root owner=www group=www mode=0644'
--------------------------------------------
[root@web01 /]# yum install -y httpd
[root@web01 ~]# systemctl start httpd
[root@web01 ~]# echo 233 > /var/www/html/index.html
#瀏覽器訪問
------------------------------------------------------------
#遠端拷貝檔案,並且將原來的同名檔案備份,如果檔名和檔案內容,屬主屬組和許可權都一樣就不做拷貝了(綠),backup=no可以省略,屬主屬組是root的時候可以不寫(目的地檔案1.同名 2.內容不同 才備份),當dest不存在時,原始檔改名
[root@m01 /]# ansible 'web_group' -m copy -a 'src=/root/hosts dest=/root owner=www group=www mode=0644 backup=yes'

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

#簡單的檔案直接可以直接使用content在命令列copy,不需要copy檔案(記得在末尾加\n)
[root@m01 ~]# ansible 'nfs_group' -m copy -a 'content="/data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)\n" dest=/etc/exports'

--------------------------------------------------------------------------
#遠端的源拷貝到遠端指定的位置
[root@m01 ~]# ansible 'web_group' -m copy -a 'src=/etc/passwd dest=/tmp remote_src=yes'
#配置檔案回滾
[root@m01 ~]# ansible web01 -m copy -a 'src=/root/passwd.1811.2020-06-09@18:16:13~ dest=/root/passwd remote_src=yes'

file模組

官文

功能:建立檔案或目錄,修改已經存在的目錄的許可權,建立軟硬連線

  file:
    path: /etc/foo.conf		#指定建立的目錄或檔案
    state:
    	touch			#建立檔案
    	directory		#建立目錄
    	absent			#刪除目錄或檔案
    	link			#做軟連結
    owner: foo			#屬主
    group: foo			#屬組
    mode: '0644'		#許可權
    recurse				#遞迴

#1 force:需要在兩種情況下強制建立軟連結,一種是原始檔不存在但之後會建立的情況下;另一種是目標軟連結已存在,需要先取消之前的軟鏈,然後建立新的軟鏈,有兩個選項:yes|no 
#2 group:定義檔案/目錄的屬組 
#3 mode:定義檔案/目錄的許可權( 1.一次建立多個目錄的時候才會遞迴授權, 									 2.recurse=yes也會遞迴授權)
#4 owner:定義檔案/目錄的屬主
#5 path:必選項,定義檔案/目錄的路徑(不存在的話可以直接建立)#
#6 recurse:'遞迴'的設定檔案的屬性,只對'目錄'有效(指定recurce的話,可以修改已經存在的檔案或者目錄的許可權,預設關閉)(需要配合mode owner group一起使用)
#7 src:要被連結的原始檔的路徑,只應用於state=link的情況
#8 dest:被連結到的路徑,只應用於state=link的情況 
#9 state:  
	directory:如果目錄不存在,建立目錄 
	file:只能修改檔案或目錄的時間 (配合modification_time access_time)
	link:建立軟連結 
	hard:建立硬連結 
	touch:如果檔案不存在,則會建立一個新的檔案,如果檔案或目錄已存在,則更新其最後修改時間 (不能在不存在的目錄下建立檔案,這一點和touch命令一樣)
absent:刪除目錄、檔案或者取消連結檔案

#遠端批量建立目錄
	不指定屬主屬組,預設是root(當前使用者),不指定mode,那麼許可權為預設
[root@lb01 /code]# ansible 'web_group' -m file -a 'path=/backup state=directory owner=adm group=adm mode=0000'
#建立目錄,同時遞迴授權(不能針對檔案)
[root@m01 ~]# ansible 'web01' -m file -a 'path=/1/2/3  state=directory mode=000 recurse=yes'
#當state=touch mode=000同時指定,建立的都是目錄,只指定touch才會建立檔案 3
[root@m01 ~]# ansible web01 -m file -a 'path=/1/2/3 state=touch mode=000'

#遠端批量建立檔案(上級目錄必須存在)
[root@lb01 /code]# ansible 'web_group' -m file -a 'path=/backup state=touch owner=adm group=adm mode=0000'
--------------------------------------------------------------------
#遠端批量刪除目錄或檔案
[root@lb01 ~]# ansible 'web_group' -m file -a 'path=/backup state=absent'
-----------------------------------------------------------------------
#遠端建立軟連結,(不指定許可權的話,屬主屬組為root,連結檔案許可權是777)
[root@lb01 /code]# ansible 'web_group' -m file -a 'src=/backup/a.txt dest=/b.txt state=link owner=adm group=adm mode=0000'

#遠端建立硬連結(可通過ll -i 檢視inode號,判斷是否為硬連結關係)
[root@lb01 /code]# ansible 'web_group' -m file -a 'src=/backup/a.txt dest=/b.txt state=hard owner=adm group=adm mode=0000'

yum模組

yum模組

功能:遠端下載

name			#包名,用等於號表示(指定要安裝的軟體包的名稱)
	file://		#指定本地安裝路徑,=yum localinstall -y
	http://		#指定yum倉庫
	
state					#指定動作,用等於號表示
	present				#安裝軟體包(預設)(=install)
	absent				#刪除軟體包(=remove)
	latest				#安裝最新版本的軟體包或,升級
	
	disable_gpg_check	#預設值為 no,表示不禁用驗證,設定為 yes 表示禁用驗證,即不驗證包,直接安裝。
	enablerepo			#臨時啟用源(無論此源是否開啟)
	disablerepo			#臨時禁用某個源,這樣設定後,在安裝軟體包時則不會從對應的源中選擇安裝包。

	download_only=true              #只下載不安裝 yum install [d]
-------------------------------------------------------------
#下載安裝,使用被控端的源安裝軟體包
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=vsftpd'
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=vsftpd state=present'

#下載安裝,指定源的rpm包,相當於wget+localinstall,可以指定包名和協議
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-agent-5.0.0-1.el7.x86_64.rpm state=present'

#安裝,前提是客戶端指定目錄下有這個rpm包(相當於yum localinstall)
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=/root/zabbix-agent-5.0.0-1.el7.x86_64.rpm state=present'
--------------------------------------------------------------
#解除安裝
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=zabbix-agent-5.0.0-1.el7.x86_64 state=absent'
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=zabbix state=absent'
-----------------------------------------------------------------------
#擴充套件
[root@localhost ~]# ansible all -m yum -a "name=httpd state=latest disable_gpg_check=yes enablerepo=epel"

#升級所有軟體包,排除httpd
[root@Ansible ~]# ansible all -m yum -a "state=latest name='*' exclude='httpd'"

shell模組

shell模組

功能:執行復雜的命令

#尤其是用到複雜命令時(如帶管道符等等),但是shell模組不能做mysql的主從複製,但是nginx編譯安裝的時候只能使用shell模組(一般不用shell模組,因為還要指定模組...)
#企業中一般不讓使用shell模組

#使用ansible批量操作叢集的主機
[root@m01 ~]# ansible 'web_group' -m shell -a 'free -m'
[root@m01 ~]# ansible 'web_group' -m conmand -a 'free -m'
[root@m01 ~]# ansible web01 -m shell -a "ps -ef|grep httpd"

#命令的最後也可以加 -f number ,表示使用的併發程序數目,預設是5個
ansible webserver -a 'netstat -ulntp' -f 15

#/usr/bin/ansible 預設使用當前ansible 伺服器登陸的使用者來進行管理,如果你不喜歡這樣,也可以使用 -u username 的方式來指定使用者
[root@docker ~]# ansible webserver -a "ls" -u zhangsan -f 9

script模組

功能:作用:將本地指令碼複製到遠端主機,並執行。(不需要給指令碼新增執行許可權)

#編輯指令碼(只需要放在m01就好)
vim /root/dir.sh
mkdir syy

#執行
absible 'web01' -m script -a '/root/dir.sh'

synchronize模組

功能:基於rsync命令工具同步目錄和檔案

由於synchronize模組會呼叫rsync命令,因此首先要記得提前安裝好rsync軟體包

	1 archive: 歸檔,相當於同時開啟recursive(遞迴)、links、perms、times、owner、group、-D選項都為yes ,預設該項為開啟(#保證原始檔和目標檔案屬性一致)
 	2 checksum: 是否檢測sum值,預設關閉
 	3 compress:是否開啟壓縮(預設開啟)
 	4 copy_links:同步的時候是否複製連結,預設為no ,注意後面還有一個links引數
 		links:同步連結檔案
 	5 delete: 刪除不存在的檔案,delete=yes 使兩邊的內容一樣(即以推送方為主),預設no
 	6 dest:目錄路徑(絕對路徑或者相對路徑)
 	7 dest_port:目標主機上的埠 ,預設是22,走的ssh協議
 	8 dirs:傳送目錄不進行遞迴,預設為no,即進行目錄遞迴(#一般不用指定)
	9 rsync_opts:通過傳遞陣列來指定其他rsync選項。	#
		--exclude=*.txt  #排除
	10 set_remote_user:主要用於ansible預設使用的使用者與rsync使用的'使用者不同的情況
	11 mode: push(預設)或pull 模組,push模的話,'一般用於從本機向遠端主機上傳檔案,pull 模式用於從遠端主機上取檔案'
	12 src: 要同步到目的地的源主機上的路徑; 路徑可以是絕對的或相對的。如果路徑使用”/”來結尾,則只複製目錄裡的內容,如果沒有使用”/”來結尾,則包含目錄在內的整個內容全部複製 
ansible 172.25.70.2 -m synchronize -a ' '
#同步目錄(前提是遠端伺服器上有rsync這個命令)
src=some/relative/path dest=/some/absolute/path rsync_path="sudo rsync"
#排除(#由於這個是rsync命令的引數,所以必須和rsync_opts一起使用)
src=/tmp/helloworld dest=/var/www/helloword rsync_opts=--exclude=.log 

mount模組

功能:掛載

mount模組控制/etc/fstab中的活動和配置掛載點

檔案系統的型別:C7(xfs),C6(ext4), C5(ext3)

	#1 fstype:必選項,掛載檔案的型別 (nfs檔案共享 fstype=nfs)
	#2 name:必選項,'哪個檔案掛載' (可以使用path指定)
	#3 opts:傳遞給mount命令的引數(rw,ro)
	#4 src:必選項,'掛載到哪的目錄' (nfs)
	#5 state:必選項 
		present:把指定的掛載寫入到fastab中,不會立即掛載,(綠色)
		mounted	 :即寫入檔案,又直接掛載(自動建立掛載點並掛載之)(#推薦)
		absent:刪除掛載點 (會清理fastab中的開機掛載)(#推薦)
		unmounted:解除安裝(不會清理fastab中的開機掛載)
--------------------------------------------------------------------		
1.#服務端和客戶端安裝nfs
[root@m01 ~]# ansible web_group  -a 'yum -y install nfs-utils'
[root@m01 ~]# ansible nfs_group  -a 'yum -y install nfs-utils'

2.#編輯nfs配置檔案
[root@m01 ~]# ansible 'nfs_group' -m copy -a 'content="/data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)\n" dest=/etc/exports'

3.建立
[root@m01 ~]# ansible nfs_group -a 'mkdir /data'
[root@m01 ~]# ansible nfs_group -m systemd -a 'name=nfs state=started'

4.啟動並設定開機自啟
[root@m01 ~]# ansible web_group -m systemd -a 'name=nfs state=started'
[root@m01 ~]# ansible web_group -m systemd -a 'name=nfs enabled=yes'
[root@m01 ~]# ansible nfs_group -m systemd -a 'name=nfs enabled=yes'

5.掛載
[root@m01 ~]# ansible web01 -m mount -a ''
path=/mnt src=172.16.1.31:/data fstype=nfs state=mounted

name=/mnt/dvd src=/dev/sr0 fstype=iso9660 opts=ro state=present
name=/srv/disk src='LABEL=SOME_LABEL' state=present
name=/home src='UUID=b3e48f45-f933-4c8e-a700-22a159ec9077' opts=noatime state=present
ansible test -a 'dd if=/dev/zero of=/disk.img bs=4k count=1024'
ansible test -a 'losetup /dev/loop0 /disk.img'
ansible test -m filesystem 'fstype=ext4 force=yes opts=-F dev=/dev/loop0'
ansible test -m mount 'name=/mnt src=/dev/loop0 fstype=ext4 state=mounted opts=rw'	

6.取消掛載
[root@m01 ~]# ansible web_group -m mount -a 'path=/mnt src=172.16.1.31:/data fstype=nfs state=unmounted'

7.清理/etc/fstab檔案

#UUID就是磁碟的身份證號,不會重複(一般使用UUID的方式掛載)
[root@web ~]# blkid /dev/sda1	檢視UUID(xfs檔案系統)
/dev/sda1: UUID="12722517-ff26-416b-b535-073a95a7a00e" TYPE="xfs" 
[root@web ~]# cat /etc/fstab 
UUID=5bf16417-9cb6-40eb-80b9-8cc2f715f79f / (根目錄的UUID)                      xfs     defaults        0 0
UUID=12722517-ff26-416b-b535-073a95a7a00e /boot (/bbot目錄的UUID)                   xfs     defaults        0 0

#把本地的磁碟掛載到遠端主機上
[root@Ansible ~]# ansible all -m mount -a "name=/mnt src=/dev/sda3 fstype=xfs state=mounted opts=rw"

#格式化磁碟:
ansible all -m filesystem -a "fstype=ext4 dev=/dev/sdb1"

get_url模組

功能:下載

[root@m01 ~]# ansible-doc get_url								
    url: http://example.com/path/file.conf	#自定下載檔案的URL
    dest: /etc/foo.conf						#指定下載的目錄
    mode: '0440'						#指定下載後的許可權
    owner
    group
    force_basic_auth: yes		#檔名相同直接覆蓋(預設)
	checksum				#預設關閉
		md5					#md5校驗
		sha256				#sha校驗
          
      
#遠端連線並下載(序列,速度慢)
[root@m01 ~]# ansible 'web_group' -m get_url -a 'url=http://test.driverzeng.com/Nginx_Code/wordpress-4.9.4-zh_CN.tar.gz dest=/root mode=000'

#校驗MD5並下載(小心等於號,阿里雲不使用md5sum校驗,)
[root@m01 ~]# ansible 'web_group' -m get_url -a 'url=http://test.driverzeng.com/Nginx_Code/wordpress-4.9.4-zh_CN.tar.gz dest=/root mode=000 checksum= md5:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'

yum_repository模組

功能:新增,刪除,修改yum源

[root@m01 ~]#  ansible-doc yum_repository
  yum_repository:			
    name: epel		#不能省略,指定倉庫檔名和倉庫名,自動新增.repo
    description: 	#相當於倉庫內的name註釋
    baseurl: https://download.fedoraproject.org/pub/epel/$releasever/$basearch/
    
    file:		#指定倉庫檔名(優先順序高),不指定的話倉庫檔名和倉庫名一樣,不能同時在同一個倉庫檔案內新增多個倉庫名不同的倉庫,同時指定的話file=倉庫檔名,name=倉庫名
        
    gpgcheck	#是否開啟校驗
        yes
        no
    enabled		#是否啟用yum倉庫
        yes
        no
  	state   
      	present		#建立yum倉庫(預設)  
    	absent		#刪除yum倉庫
--------------------------------------------------------
#批量新增yum倉庫,不能一次在某一主機新增多個倉庫檔案和倉庫,功能有限
[root@m01 ~]# ansible 'web_group' -m yum_repository -a 'name=syy_add_epel description=EEE baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=no enabled=yes file=zdy'

#在客戶端已存在的倉庫檔案內新增倉庫(1.指定倉庫檔案。2.指定倉庫名,存在即修改,不存在即新增)
[root@m01 ~]# ansible 'web_group' -m yum_repository -a 'name=syy2_add_epel description=EEE baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=no enabled=yes file=zdy'
--------------------------------------------------------------
#批量刪除yum倉庫,只能一個一個刪除倉庫檔案(也就是說不能只指定name來批量刪除),file優先順序高,可以只指定name,也可以同時指定(視情況而定)
(倉庫檔名和倉庫名要對應,最好都寫上)
[root@m01 ~]# ansible 'web_group' -m yum_repository -a 'name=syy_add_epel file=zdy state=absent'
--------------------------------------------------------------
#修改
不能修改倉庫檔名,也不能修改倉庫名,可以修改URL,gpg,enabled
[root@m01 ~]# ansible 'web_group' -m yum_repository -a 'name=syy_add_epelllll description=EEE baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=no enabled=yes file=1'

也可以修改gpgcheck和enable
[root@m01 ~]# ansible 'web_group' -m yum_repository -a 'name=syy_add_epel description=EEE baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=no enabled=no file=1'

#使用playbook執行yml指令碼,可以實現更精確的操作

ansible服務模組--systemd模組

功能:遠端啟停,過載服務,

[root@m01 ~]# ansible-doc systemd
  systemd:				#模組
    state: started 		#啟動
    name: httpd				#指定服務名稱
    state: stopped		#停止
    state: restarted	#重啟
    state: reloaded		#過載配置檔案
    enabled=yes		#設定開機自啟
    daemon_reload		# 讀取配置檔案,每次修改了檔案,最好都執行一次,確保應用了(systemd)
    masked:			#是否將服務設定為masked狀態,被mask的服務是無法啟動的(systemd),(yes|no)預設為no
----------------------------------------------------------------
#遠端停止服務
[root@m01 ~]# ansible 'web_group' -m systemd -a 'name=nginx state=stopped '

#遠端啟動服務(並設定開機自啟動)
[root@m01 ~]# ansible 'web_group' -m systemd -a 'name=nginx state=started enabled=yes '
-------------------------------------------------------------
# 先將服務停止
[root@Ansible ~]# ansible web -m systemd -a "name=httpd state=stopped"
#設定masked
[root@Ansible ~]# ansible web -m systemd -a "name=httpd masked=yes"
# 服務已無法啟動
[root@Ansible ~]# ansible web -m systemd -a "name=httpd state=started"
# 撤銷mask
[root@Ansible ~]# ansible web -m systemd -a "name=httpd masked=no"
# 可以啟動成功
[root@Ansible ~]# ansible web -m systemd -a "name=httpd state=started"

service模組

service模組

遠端啟停,過載服務

service模組(可以跨平臺,跨系統) 與systemd模組作用類似,使用命令類似

	#1 arguments:給命令列提供一些選項 	#
	#2 enabled:是否開機啟動 yes|no(預設是no)
	#3 name:必選項,服務名稱 
	#4 pattern:定義一個模式,如果通過status指令來檢視服務的狀態時,沒有響應,就會通過ps指令在程序中根據該模式進行查詢,如果匹配到,則認為該服務依然在執行		#
	#5 runlevel:執行級別		#
	#6 sleep:如果執行了restarted,在則stop和start之間沉睡幾秒鐘
	#7 state:對當前服務執行啟動,停止、重啟、重新載入等操作(started,stopped,restarted,reloaded)
	
#保持服務啟動並設定為開機自啟
 ansible web_group -m service -a 'enabled=yes name=httpd state=started'

ansible使用者組管理模組

group模組

功能:建立使用者組

[root@m01 ~]# ansible-doc group
    name: somegroup		#指定組名
    state: present 		#建立(預設,課省略)
    state: absent 		#刪除
	gid					#指定建立的組的gid
	
#遠端建立組
[root@m01 ~]# ansible 'web_group' -m group -a 'name=dd gid=233 state=present'

#遠端刪除組
[root@m01 ~]# ansible 'web_group' -m group -a 'name=dd gid=233 state=absent'

ansible使用者管理模組

user模組

使用yml語法修改使用者密碼

多種加密方式獲取加密密碼

功能:管理遠端主機上的使用者,比如建立使用者、修改使用者、刪除使用者、為使用者建立金鑰對等操作

#user模組是請求的是useradd, userdel, usermod三個指令,goup模組請求的是groupadd, groupdel, groupmod 三個指令。

groups:			#修改附加組為
    	append=no			#預設,覆蓋(相當於usermod -G)
    	append=yes			#追加(相當於usermod -aG)
uid:			#指定用的uid
group:			#指定主組
password:		#明文密碼進行雜湊後的字串,你可以在 python 的命令提示符下輸入如下命令,生成明文密碼對應的加密字串 "import crypt; crypt.crypt('666666')"
update_password:
    always:		#只有當密碼不相同時才會生效,即修改密碼(預設)		#
    on_create:	#只為新使用者設定密碼
name:			#指定使用者名稱
system:			#是否為系統使用者 yes|no(預設是no)
remove:			#當state=absent時,remove=yes則表示連同家目錄,郵件目錄一起刪除,等價於userdel -r(預設是no)
state:
    absent				#刪除使用者
    	remove=no		#預設,刪除使用者時,不會刪除使用者的家目錄等資訊
    	remove=yes		#刪除使用者的同時,會刪除使用者的家目錄,郵件目錄
    present				#建立使用者(預設)
shell:			#指定使用者的shell環境(預設是/bin/bash)
expires:		#設定使用者的過期時間,值是一個時間戳(轉化命令:date -d 2018-12-31 +%s,命令列設定 expires=)
comment:		#建立使用者的時候新增一段註釋
generate_ssh_key: yes		#建立公鑰(預設)
ssh_key_bits: 2048			#指定公鑰長度
ssh_key_file: .ssh/id_rsa	#建立私鑰(建立使用者的家目錄下)
create_home=false				#是否建立家目錄(預設建立true)
------------------------------------------------------------------------
#建立使用者,修改使用者
ansible 'web_group' -m user -a ' '
	name=ll
	name=hh comment="zhushi" uid=1040 group=adm		#該組必須存在
	name=hh shell=/bin/bash groups=adm,lp append=yes
	name=hh state=absent remove=yes
	name=hh expires=1422403387
	name=hh generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa
	name="testops" password="$6$0lwTSmqKOkL.ktgl$OnBexXC7haBf0FRHVMIZM2edDeFWBbpKJ2r9cxVwNvY.vh3IIUzwFz8n7jFglc0CrtQSY12ziDonVL6e71Og2."
--------------------------------------------------------------	
#生成金鑰時,只會生成公鑰檔案和私鑰檔案,和直接使用ssh-keygen指令效果相同,不會生成authorized_keys檔案。複製id_rsa.pub貼上為authorized_keys檔案即可使用
	name=test generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=~/.ssh/id_rsa
-----------------------------------------------------------------------
	
#指定password引數時,不能使用後面這一串密碼會被直接傳送到被管理主機的/etc/shadow檔案中,所以需要先將密碼字串進行加密處理。然後將得到的字串放到password中即可。
#1.加密
[root@ansible-manager ~]# python
>>> import crypt;crypt.crypt('666666')
'$6$ziT/sb5KRtUaxoq7$ulfHVLqVgXfmfFUYY7FppzqBQMUYd.2GLDyQwmKv4dYAd0zpgtt5JDheoO/OvvTvY53x9UShX.PtHykJEvsmG0'
#2.建立使用者指定密碼 或 修改使用者密碼
------------------------------------------------------------------
#刪除使用者
#注意該使用者下不能有任何程序,否則會報錯(但是能刪除的都刪除了)
ansible 'web_group' -m user -a ' '
	name=ll state=absent remove=yes

fetch

fetch模組

[root@m01 ~]# ansible web01 -m fetch -a "src=/root/lol.txt dest=/root"

壓縮解壓unarchive模組

官方文件

功能:解壓縮

1、解壓ansible管理機上的壓縮檔案到遠端主機:
ansible all -m unarchive -a "src=/tmp/install/zabbix-3.0.4.tar.gz dest=/tmp/ mode=0755 copy=yes"

2、解壓遠端主機上的檔案到目錄:
#ansible all -m unarchive -a "src=/tmp/install/zabbix-3.0.4.tar.gz dest=/tmp/ mode=0755 copy=no"

#copy:預設為yes,當copy=yes,那麼拷貝的檔案是從ansible主機複製到遠端主機上的,如果設定為copy=no,那麼會在遠端主機上尋找src原始檔

#src:源路徑,可以是ansible主機上的路徑,也可以是遠端主機上的路徑,如果是遠端主機上的路徑,則需要設定copy=no
#dest:遠端主機上的目標路徑

selinux

功能:管理selinux

C6想要使用這種方式關閉selinux的話,需要安裝 libselinux-python(改過要重啟生效)

不能使用systemd service模組來管理selinux systemd

state:
	enforcing		#永久開啟
	permissive		#臨時開啟(預設)
	disabled		#禁用
	

#修改配置檔案關閉selinux(永久關閉),必須重啟
[root@m01 ~]# ansible web_group -m selinux -a 'state=disabled' -i ./hosts

#臨時關閉
[root@m01 ~]# ansible web_group -m shell -a 'setenforce 0' -i ./hosts

#檢視
[root@m01 ~]# ansible web_group -m shell -a 'getenforce' -i ./hosts
#	如果修改了/etc/selinux/config檔案的話,需要重啟,如果你只是臨時修改的話,不需要重啟
#	使用setenforce 可以臨時改變selinux的狀態,不需要重啟系統。但是系統重啟後,配置失效,因為系統重啟後,是根據/var/selinux/config的配置內容進行功能設定的

firewalld

功能:管理firewalld

開啟才能關閉

service                 #指定開放或關閉的服務名稱(http https)
port                    #指定開放或關閉的埠(-)
permanent               #是否新增永久生效(permanent=no即為臨時生效)		#
immediate               #臨時生效
state                   
    enabled				#永久開啟
    disabled			#永久關閉

zone                    #指定配置某個區域
rich_rule               #配置輔規則
masquerade              #開啟地址偽裝
source                  #指定來源IP

#service指定服務(需要提前開啟防火牆)
[root@m01 ~]# ansible web_group -m firewalld -a 'service=http permanent=yes state=enabled' -i ./hosts
[root@m01 ~]# ansible web_group -m firewalld -a "service=https permanent=yes state=enabled" -i ./hosts

#service指定埠(某些服務系統自動開啟)
[root@m01 ~]# ansible web_group -m firewalld -a "port=8080-8090/tcp  permanent=yes state=enabled" -i ./hosts

lineinfile

功能:lineinfile模組用於確保一個特定的行在一個檔案中,或使用一個正則表示式替換現有的行

如果想要改變檔案中相似的多行,可以使用replace模組。如果想要插入、更新、刪除一個行塊,可以使用blockinfile模組

#(1)文字替換
#將/etc/selinux/config檔案中所有匹配^SELINUX=正則表示式的行中的最後一行使用SELINUX=disabled替換
#如果regexp不匹配檔案中的任何一行,則將line所指定的行插入到檔案的末尾
[root@Ansible ~]# ansible web -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled'"

#(2)刪除行
#將/tmp/test.sh檔案中所有匹配^pwd的行刪除
[root@Ansible ~]# ansible web -m lineinfile -a "path=/tmp/test.sh regexp='^pwd' state=absent"

#(3)替換行並設定檔案許可權
[root@Ansible ~]# ansible web -m lineinfile -a "path=/etc/hosts regexp='^127.0.0.1' line='127.0.0.1 localhost' owner=root group=root mode=0644"

stat模組

功能:stat模組獲取遠端檔案狀態資訊,包括atime、ctime、mtime、md5、uid、gid等

#(1)顯示檔案的所有資訊
[root@Ansible ~]# ansible web -m stat -a "path=/etc/sysctl.conf"

#(2)顯示MD5值
[root@Ansible ~]# ansible web -m stat -a "path=/etc/sysctl.conf get_md5=yes"

mysql_user模組

mysql_user

功能:主控端對被控端mysql伺服器 新增刪除使用者,授權遠端使用者登入,訪問

mysql_user模組引數
login_host=“localhost” 指定本地root使用者登入本機mysql
login_password=“123.com” root使用者的登入密碼		#登入密碼
login_user=“root” 為root使用者或者mysql使用者			#登入使用者
login_port=“3306” 資料庫埠號
name="" 指定grant授權使用者			#建立使用者的名字或是已存在的使用者
password="" grant授權使用者密碼		#給新使用者設定密碼,或者修改密碼
priv="" 庫名.SQL語句許可權,GRANT    #資料庫.資料表:許可權1,許可權2(要用")
host="" 授權遠端登入的IP地址,一般為 網段.% 或者直接 %
state=“present” 建立授權使用者
state=“absent” 刪除授權使用者
ahdoc模式寫法建立授權使用者,驗證模組正確時使用

[root@localhost ansible]# ansible mysql -m mysql_user -a "login_host=% login_password=123.com login_user=root login_port=3306 name=ty_user password=1 priv=".:ALL,GRANT" host='%' state=present"
playbook劇本寫法建立授權使用者,執行自動化部署時使用
- hosts: mysql_group
  remote_user: root
  tasks:
    - name: grant mysql user
      mysql_user:
      	login_host: "localhost"
      	login_user: "root"
     	login_password: "123.com"
     	login_port: "3306"
      	name: "ty"
      	password: "123.com"
      	host: "%"
      	priv: "*.*:ALL,GRANT"
      	state: "present"

mysql_db模組

mysql_db

功能:用於建立、刪除、匯入和匯出資料庫

#建立資料庫
  hosts: mysql_group
  tasks:
  - name: create a database
    mysql_db:
      login_host: "127.0.0.1"
      login_user: "root"
      login_password: "mysql@123"
      login_port: "3306"
      name: "mezz"
      encoding: "utf8"
      state: "present"
      
#刪除資料庫
  hosts: mysql_group
  tasks:
  - name: delete a database
    mysql_db:
      login_host: "127.0.0.1"
      login_user: "root"
      login_password: "mysql@123"
      login_port: "3306"
      name: "mezz"
      state: "absent"
      
#匯出資料庫
  hosts: mysql_group
  tasks:
  - name: dump a database
    mysql_db:
      login_host: "127.0.0.1"
      login_user: "root"
      login_password: "mysql@123"
      login_port: "3306"
      name: "mezz"
      target: "/tmp/mezz.gz"
      state: "dump"
      
#匯入資料庫
  hosts: mysql_group
  tasks:
  - name: import a database
    mysql_db:
      login_host: "127.0.0.1"
      login_user: "root"
      login_password: "mysql@123"
      login_port: "3306"
      name: "mezz"
      target: "/tmp/mezz.gz"
      state: "import"

template模組

template模組使用了Jinjia2模版語言,進行文件內變數的替換的模組。

該模組只能在playbook中執行,不能使用命令列

功能:該模組和copy模組作用基本一樣,都是把某個檔案複製到遠端主機上,但是區別在於template模組可以獲取變數的值,而copy則是原封不動的把檔案內容複製過去

改變數的呼叫依賴於facts,關閉fascs的話,該模組作用將於copy模組相同

#問題:由於每臺伺服器cpu數量不一樣,沒辦法來靈活配置Nginx最大程序數

– backup: 如果原目標檔案存在,則先備份目標檔案 
– src:在ansible控制器上的Jinja2格式化模板的路徑。 這可以是相對或絕對的路徑。 
– dest:將模板渲染到遠端機器上的位置。 
force:是否強制覆蓋,預設為yes 
– owner:目標檔案屬主 
– group:目標檔案屬組 
– mode:目標檔案的許可權模式

# Example from Ansible Playbooks
- template:
    src: /mytemplates/foo.j2
    dest: /etc/file.conf
    owner: bin
    group: wheel
    mode: 0644

pam_limits模組

功能:修改檔案描述符

#為使用者joe新增或修改nofile軟限制
- pam_limits:
    domain: joe
    limit_type: soft
    limit_item: nofile
    value: 64000

# 為使用者smith新增或修改硬限制。保持或設定最大值。
- pam_limits:
    domain: smith
    limit_type: hard
    limit_item: fsize
    value: 1000000
    use_max: yes

#為使用者james新增或修改memlock,包括軟硬限制和註釋。
- pam_limits:
    domain: james
    limit_type: '-'
    limit_item: memlock
    value: unlimited
    comment: unlimited memory lock for james

參考

http://www.linuxe.cn/post-275.html Ansible教程(3)playbook的基本使用

Ansible中文權威指南

https://www.fdevops.com/2020/03/08/ansible-quick-tutorial Ansible中Playbook的光速教程

https://juejin.cn/post/6844903631066513421 ansible自動化運維詳細教程及playbook詳解