18.自動運維工具ansible

1 Ansible 介紹和架構

1.1 Ansible介紹

ansible 的名稱來自科幻小說《安德的遊戲》中跨越時空的即時通訊工具,使用它可以在相距數光年的 距離,遠程實時控制前線的艦隊戰鬥。在電腦中ansible則作為一個運維工具,可以實現批量管理主機、使用模組化方式自動安裝複雜軟體如K8s等功能。與ansible類似還有以下工具:

  • Saltstack:python,一般需部署agent,執行效率更高
  • Puppet:ruby, 功能強大,配置複雜,重型,適合大型環境
  • Fabric:python,agentless
  • Chef:ruby,中國應用少
  • Cfengine
  • func

ansible工作方式

在實現主機間基於key驗證之後,ansible執行playbook時會自動連接至被管理主機,並將ansible模組推送到被管理主機上,之後ansible會在被管理主機上執行這些模組,並在執行完畢之後移除這些模組。

官方文檔://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html

1.2 Ansible 特性

  • 模組化:調用特定的模組完成特定任務,支援自定義模組,可使用任何程式語言寫模組
  • Paramiko(python對ssh的實現),PyYAML,Jinja2(模板語言)三個關鍵模組
  • 基於Python語言實現
  • 部署簡單,基於python和SSH(默認已安裝),agentless,無需代理不依賴PKI(無需ssl)
  • 安全,基於OpenSSH
  • 冪等性:一個任務執行1遍和執行n遍效果一樣,不因重複執行帶來意外情況
  • 支援playbook編排任務,YAML格式,編排任務,支援豐富的數據結構
  • 較強大的多層解決方案 role

1.3 Ansible相關概念介紹

控制節點(Control node)

安裝了Ansible的主機,調用命令來管理需要被管理的主機。控制節點不能安裝在Windows上

被管理節點(Managed nodes)

使用Ansible來管理的設備,被管理節點無需安裝Ansible

清單(Inventory)

被管理節點的列表

模組(Modules)

用於實現Ansible功能,類似於命令行中的各種命令,如ls等

任務(TASK)

用於PLAYBOOK中,指定要執行的模組

劇本(PLAYBOOK)

包含了多個順序執行的TASK,還可以在其中定義變數等

2 Ansible 安裝和入門

2.1 Ansible安裝

ansible的安裝方法有多種

2.1.1 EPEL源的安裝方式

#推薦使用該方式安裝
[root@ansible ~]#yum install ansible

2.1.2 pip安裝

#pip默認安裝最新版本
yum install python-pip python-devel
yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
/usr/bin/python -m pip install --upgrade pip
pip install ansible --upgrade

2.1.3 git安裝

git clone git://github.com/ansible/ansible.git --recursive
cd ./ansible
source ./hacking/env-setup

還有很多其他安裝方式,詳細可以參考官方文檔://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html

2.1.4 確認ansible版本

[root@server1 ~]# ansible --version
ansible 2.9.21
  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, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

2.1.5 windows主機配置

參考文檔://docs.ansible.com/ansible/latest/user_guide/windows_setup.html

管理節點
#安裝pywinrm用於連接被管理主機
[root@centos8 Python-3.8.11]# pip3.6 install -i //pypi.tuna.tsinghua.edu.cn/simple pywinrm
#配置主機列表
[root@centos8 Python-3.8.11]# cat /etc/ansible/hosts 
[windows]
172.16.60.90
[windows:vars]
ansible_user="administratorHsykt"
ansible_password="[email protected]"
ansible_connection="winrm"
ansible_winrm_transport="basic"
ansible_port=5985
ansible_winrm_scheme=http
ansible_winrm_server_cert_validation=ignore

被管理節點
Windows機器上的powershell版本5.0,Framework4.0
#查看winrm服務狀態
winrm enumerate winrm/config/listener
#配置winrm服務
winrm quickconfig
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'

注意事項
1.powershell和Framework版本要滿足官方要求
2.管理節點要安裝pywinrm

2.2 Ansible主要文件

2.2.1 配置文件

Ansible 的配置文件 /etc/ansible/ansible.cfg

[defaults]
#inventory     = /etc/ansible/hosts # 主機列表配置文件
#library = /usr/share/my_modules/ # 庫文件存放目錄
#remote_tmp = $HOME/.ansible/tmp #臨時py命令文件存放在遠程主機目錄
#local_tmp     = $HOME/.ansible/tmp # 本機的臨時命令執行目錄
#forks         = 5   # 默認並發數
#sudo_user     = root # 默認sudo 用戶
#ask_sudo_pass = True #每次執行ansible命令是否詢問ssh密碼
#ask_pass     = True  
#remote_port   = 22
#host_key_checking = False # 檢查對應伺服器的host_key,建議取消注釋
#log_path=/var/log/ansible.log #日誌文件,建議啟用
#module_name = command   #默認模組,可以修改為shell模組

2.2.2 Inventory設備清單文件

默認的inventory file為 /etc/ansible/hosts,主要用於指定要執行Ansible模組的主機

範例:

#如若目標主機使用了非默認的SSH埠,還可以在主機名稱之後使用冒號加埠號來標明
[webservers]
www1.123.com:2222
www2.321.com

[websrvs]
www[1:100].example.com

[appsrvs]
10.0.0.[1:100]

2.2.3 roles

默認位於/etc/ansible/roles/ ,主要用來存放角色

[root@server1 ~]# ll /etc/ansible/roles/ -d
drwxr-xr-x 2 root root 6 5月   5 04:39 /etc/ansible/roles/

2.3 Ansible的常用工具

  • /usr/bin/ansible 主程式,臨時命令執行工具

  • /usr/bin/ansible-doc 查看配置文檔,模組功能查看工具,相當於man

  • /usr/bin/ansible-playbook 訂製自動化任務,編排劇本工具,相當於腳本

  • /usr/bin/ansible-pull 遠程執行命令的工具

  • /usr/bin/ansible-vault 文件加密工具

  • /usr/bin/ansible-console 基於Console介面與用戶交互的執行工具

  • /usr/bin/ansible-galaxy 下載/上傳優秀程式碼或Roles模組的官網平台

利用ansible實現管理的主要方式:

  • Ad-Hoc 即利用ansible命令,主要用於臨時命令使用場景
  • Ansible-playbook 主要用於長期規劃好的,大型項目的場景,需要有前期的規划過程

2.3.1 ansible-doc

顯示模組的幫助資訊

格式:

ansible-doc [options] [module...]
-l, --list       #列出可用模組
-s, --snippet #顯示指定模組的playbook片段

2.3.2 ansible

針對設置的主機執行單個任務playbook

格式:

ansible <host-pattern> [-m module_name] [-a "<module options>"]

選項:

  • –version #顯示版本
  • -m module #指定模組,默認為command
  • -v #詳細過程 –vv -vvv更詳細
  • –list-hosts #顯示主機列表,可簡寫 –list
  • -k, –ask-pass #提示輸入ssh連接密碼,默認Key驗證
  • -C, –check #檢查,並不執行
  • -T, –timeout=TIMEOUT #執行命令的超時時間,默認10s
  • -u, –user=REMOTE_USER #執行遠程執行的用戶
  • -b, –become #代替舊版的sudo 切換
  • –become-user=USERNAME #指定sudo的runas用戶,默認為root
  • -K, –ask-become-pass #提示輸入sudo時的口令

pattern的用法

表格中列出了常用的pattern

Description Pattern(s) Targets
All hosts all (or *)
One host host1
Multiple hosts host1:host2 (or host1,host2)
One group webservers
Multiple groups webservers:dbservers all hosts in webservers plus all hosts in dbservers
Excluding groups webservers:!atlanta all hosts in webservers except those in atlanta
Intersection of groups webservers:&staging any hosts in webservers that are also in staging

同時還支援通配符和正則表達式

#通配符
ansible "*" -m ping
ansible 192.168.1.* -m ping
ansible "srvs" -m ping

#正則表達式
ansible "websrvs:dbsrvs" –m ping
ansible "~(web|db).*\.magedu\.com" –m ping

這裡值得說明的是執行完成後會有不同顏色的返回結果,下面簡單進行一個說明

  • 綠色:執行成功並且不需要做改變的操作
  • 黃色:執行成功並且對目標主機做變更
  • 紅色:執行失敗

在配置文件中可以進行自定義

[root@server1 ~]# grep -A 14 '\[colors\]' /etc/ansible/ansible.cfg
[colors]
#highlight = white
#verbose = blue
#warn = bright purple
#error = red
#debug = dark gray
#deprecate = purple
#skip = cyan
#unreachable = red
#ok = green
#changed = yellow
#diff_add = green
#diff_remove = red
#diff_lines = cyan

2.4 Ansible常用模組

Ansible雖然模組眾多,但最常用的模組也就2,30個而已,針對特定業務只用10幾個模組。

官方文檔://docs.ansible.com/ansible/latest/collections/index.html

2.4.1 Command 模組

功能:在遠程主機執行命令,此為默認模組,所以可忽略-m選項

注意:variables like $HOSTNAME and operations like "*", "<", ">", "|", ";" and "&" will not work,所以一般會使用shell模組來代替Command 模組

範例:

[root@server1 ~]# ansible lvyou -a 'ls /data'
172.16.60.218 | CHANGED | rc=0 >>
123.txt

2.4.2 shell 模組

功能:和command相似,用shell執行命令(推薦)

範例:

[root@centos8 .ssh]# ansible innet -m shell -a 'ls /root'
172.16.222.101 | CHANGED | rc=0 >>
anaconda-ks.cfg
172.16.111.100 | CHANGED | rc=0 >>
anaconda-ks.cfg

[root@centos8 .ssh]# ansible innet -m shell -a 'echo $HOSTNAME'
172.16.222.101 | CHANGED | rc=0 >>
centos8
172.16.111.100 | CHANGED | rc=0 >>
centos8.1

將shell設置為默認模組

[root@ansible ~]#vim /etc/ansible/ansible.cfg
#修改下面一行
module_name = shell

2.4.3 Script 模組

功能:在遠程主機上運行ansible伺服器上的腳本(無需執行許可權)

範例:

ansible inint -m script -a /data/test.sh

2.4.4 Copy 模組

功能:從ansible伺服器主控端複製文件到遠程主機

範例:

#如目標存在,默認覆蓋,此處指定先備份,注意文件內容不一致時才會產生備份文件
[root@centos8 .ssh]# ansible innet -m copy -a "src=/root/123.txt dest=/data backup=yes"

#將指定內容,直接生成目標文件
[root@centos8 .ssh]# ansible innet -m copy -a "content='123\nab' dest=/data/test.txt"

#複製/etc目錄自身,注意/etc/後面沒有/,此時會將/etc整個目錄拷貝過去,dest目錄如果沒有會自動創建
[root@centos8 .ssh]# ansible innet -m copy -a "src=/etc dest=/backup"

2.4.5 File模組

功能:創建文件指定文件屬性

範例:

#創建空文件
[root@centos8 .ssh]# ansible innet -m file  -a 'path=/data/test1.txt state=touch'

#刪除文件
[root@centos8 .ssh]# ansible innet -m file  -a 'path=/data/test1.txt state=absent'

#創建目錄
ansible all -m file -a "path=/data/mysql state=directory owner=mysql group=mysql"

#創建軟鏈接
ansible all -m file -a 'src=/data/testfile dest=/data/testfile-link state=link'

2.4.6 unarchive 模組

功能:解包解壓縮

常見參數:

  • copy:默認為yes,當copy=yes,拷貝的文件是從ansible主機複製到遠程主機上,如果設置為 copy=no,會在遠程主機上尋找src源文件
  • remote_src:和copy功能一樣且互斥,yes表示在遠程主機,不在ansible主機,no表示文件在 ansible主機上
  • src:源路徑,可以是ansible主機上的路徑,也可以是遠程主機(被管理端或者第三方主機)上的路 徑,如果是遠程主機上的路徑,則需要設置copy=no
  • dest:遠程主機上的目標路徑
  • mode:設置解壓縮後的文件許可權

範例:

ansible all -m unarchive -a 'src=/data/foo.tgz dest=/var/lib/foo'
ansible all -m unarchive -a 'src=//example.com/example.zip dest=/data copy=no'

2.4.7 Archive 模組

功能:管理主機名

範例:

ansible websrvs -m archive  -a 'path=/var/log/ dest=/data/log.tar.bz2 format=bz2'

2.4.8 Cron 模組

功能:實現計劃任務

範例:

#創建計劃任務
ansible 10.0.0.8 -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql"
job=/root/mysql_backup.sh'

#禁用計劃任務
ansible websrvs   -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1
&>/dev/null' name=Synctime disabled=yes"

#啟用計劃任務
ansible websrvs   -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1
&>/dev/null' name=Synctime disabled=no"

#刪除計劃任務
ansible websrvs -m cron -a "name='backup mysql' state=absent"
ansible websrvs -m cron -a 'state=absent name=Synctime'

2.4.9 Yum 模組

功能:管理軟體包,只支援RHEL,CentOS,fedora,不支援Ubuntu其它版本

範例:

ansible innet -m yum -a 'name=httpd state=present'  #安裝
ansible innet -m yum -a 'name=httpd state=absent'   #刪除

2.4.10 Setup 模組

功能: setup 模組來收集主機的系統資訊,這些 facts 資訊可以直接以變數的形式使用,但是如果主機 較多,會影響執行速度,可以使用 gather_facts: no 來禁止 Ansible 收集 facts 資訊

範例:

#收集全部資訊
[root@centos8 .ssh]# ansible innet -m setup

#收集指定主機資訊
[root@centos8 .ssh]# ansible innet -m setup -a 'filter=ansible_python_version'

3 Playbook

3.1 Plyabook介紹

playbook 劇本是由一個或多個”play”組成

play的主要功能在於將預定義的一組主機,裝扮成事先通過ansible中的task定義好的角色。Task實際是 調用ansible的一個module,將多個play組織在一個playbook中,即可以讓它們聯合起來,按事先編排的機制執行預定義的動作,從而完成複雜的主機管理功能

3.2 YAML

3.2.1 YAML簡介

由於Playbook 文件是採用YAML語言編寫的,所以下面對YAML進行簡單的介紹

YAML是一種和XML、JSON類似的語言,JSON主要用於進行網路中數據交換,YAML則通常用來配置。XML既可以用於數據交換也能配置,不過語法比前兩種繁瑣。

可以用工具互相轉換

//www.json2yaml.com/

//www.bejson.com/json/json2yaml/

3.2.2 YAML特點

  • 易讀性較強
  • 交互性較好
  • 易於實現
  • 表達能力強,擴展好
  • 有一個一致的資訊模型

3.2.3 YAML語法簡介

  • 在單一文件第一行,用連續三個連字號”-” 開始(也可以省略),還有選擇性的連續三個點號( … )用來表示文件的結尾
  • 次行開始正常寫Playbook的內容,一般建議寫明該Playbook的功能
  • 使用#號注釋程式碼
  • 縮進必須統一,TAB和空格不能混用
  • 縮進的級別也必須一致
  • key/value可同行也可換行寫,同行使用,進行分隔
  • 一般YAML文件擴展名為yml或yaml

List列表

列表由多個元素組成,每個元素放在不同行,且元素前均使用”-“打頭,並且 – 後有一個空格, 或者將所 有元素用 [ ] 括起來放在同一行

範例:

#不同行,行以-開頭,後面有一個空格
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango

#同一行
[Apple,Orange,Strawberry,Mango]

Dictionary字典

字典由多個key與value構成,key和value之間用 :分隔, 並且 : 後面有一個空格,所有k/v可以放在一 行,或者每個 k/v 分別放在不同行

範例:

#不同行
# An employee record
name: Example Developer
job: Developer
skill: Elite

#同一行,也可以將ke
y:value放置於{}中進行表示,用,分隔多個key:value
# An employee record
{name: "Example Developer", job: "Developer", skill: "Elite"}

3.3 Playbook 核心組件

常見組件類型如下:

  • Hosts 執行的遠程主機列表
  • Tasks 任務集,由多個task的元素組成的列表實現,每個task是一個字典
  • Variables 內置變數或自定義變數在playbook中調用
  • Templates 模板,可替換模板文件中的變數並實現一些簡單邏輯的文件
  • Handlers 和 notify 結合使用,由特定條件觸發的操作,滿足條件方才執行,否則不執行
  • tags 標籤 指定某條任務執行,用於選擇運行playbook中的部分程式碼。ansible具有冪等性,因此 會自動跳過沒有變化的部分,即便如此,有些程式碼為測試其確實沒有發生變化的時間依然會非常地 長。此時,如果確信其沒有變化,就可以通過tags跳過此些程式碼片斷
  • 一個完整的程式碼塊功能需最少元素需包括 name 和 task,一個name只能包括一個task

更多組件和詳細的組件說明可以參看官方文檔://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html

下面分別用shell和palybook實現httpd安裝

範例:

#SHELL腳本實現
#!/bin/bash
# 安裝Apache
yum install --quiet -y httpd
# 複製配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp/tmp/vhosts.conf /etc/httpd/conf.d/
# 啟動Apache,並設置開機啟動
systemctl enable --now httpd

#Playbook實現
---
- hosts: websrvs
 remote_user: root
 tasks:
   - name: "安裝Apache"
     yum: name=httpd
   - name: "複製配置文件"
     copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
   - name: "複製配置文件"
     copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
   - name: "啟動Apache,並設置開機啟動"
     service: name=httpd state=started enabled=yes

3.4 playbook命令

格式:

ansible-playbook <filename.yml> ... [options]

常用選項:

  • -C –check #只檢測可能會發生的改變,但不真正執行操作
  • –list-hosts #列出運行任務的主機
  • –list-tags #列出tag
  • –list-tasks #列出task
  • –limit 主機列表 #只針對主機列表中的特定主機執行
  • -v -vv -vvv #顯示過程

範例:

[root@centos8 data]# cat hello.yml 
---
- hosts: innet
  tasks:
    - name: hello
      command: echo "hello ansible"
      
[root@centos8 data]# ansible-playbook -C hello.yml
[root@centos8 data]# ansible-playbook hello.yml

3.5 Playbook初步

3.5.1 Playbook使用handlers和notify

Handlers本質是task list,其作用類似一個動作,當task執行完畢時使用notify觸發才會執行。

範例:當配置文件發生改變,對服務進行重啟操作

---
- hosts: websrvs
 remote_user: root
 gather_facts: no
 tasks:
    - name: Install httpd
     yum: name=httpd state=present
    - name: Install configure file
     copy: src=files/httpd.conf dest=/etc/httpd/conf/
     notify: restart httpd
    - name: ensure apache is running
      service: name=httpd state=started enabled=yes
  
 handlers:
    - name: restart httpd
      service: name=httpd state=restarted

3.5.2 Playbook中使用tags組件

在playbook文件中,可以利用tags組件,為特定 task 指定標籤,當在執行playbook時,可以只執行特 定tags的task,而非整個playbook文件

範例:

# tags example
- hosts: websrvs
 remote_user: root
 gather_facts: no
  
 tasks:
    - name: Install httpd
     yum: name=httpd state=present
    - name: Install configure file
     copy: src=files/httpd.conf dest=/etc/httpd/conf/
     tags: conf
    - name: start httpd service
     tags: service
      service: name=httpd state=started enabled=yes
      
[root@centos8 data]#ansible-playbook –t conf,service httpd.yml

3.6 Playbook中變數的使用

變數的調用:

通過{{ variable_name }} 調用變數,且變數名前後建議加空格,有時用”{{ variable_name }}”才生效

調用較為簡單,這裡主要介紹幾種定義變數的方式

3.6.1 使用setup模組中的變數

本模組自動在playbook調用,不要用ansible命令調用

範例:

[root@centos8 data]# cat var1.yml 
---
#var1.yml
- hosts: innet
  
  tasks:
    - name: create log file
      file: name=/data/{{ ansible_nodename }}.log state=touch 

3.6.2 在命令行中定義變數

範例:

[root@centos8 data]# cat var2.yml 
---
- hosts: innet

  tasks:
    - name: touch file
      file: name=/data/{{ file }}.log state=touch

[root@centos8 data]# ansible-playbook -e file=test var2.yml

3.6.3 在playbook文件中定義變數

範例:

[root@centos8 data]# cat va3.yml 
---
- hosts: innet
  remote_user: root
  vars:
    collect_info: "/data/{{ansible_nodename}}/"
  tasks:
    - name: create IP directory
      file: name="{{collect_info}}" state=directory
       
[root@centos8 data]# ansible-playbook -e file=test var3.yml

3.6.4 使用變數文件

可以在一個獨立的playbook文件中定義變數,在另一個playbook文件中引用變數文件中的變數,比 playbook中定義的變數優化級高

範例:

vim vars.yml
---
# variables file
package_name: mariadb-server
service_name: mariadb
vim var5.yml
---
#install package and start service
- hosts: dbsrvs
 remote_user: root
 vars_files:
    - vars.yml
 tasks:
    - name: install package
     yum: name={{ package_name }}
     tags: install
    - name: start service
      service: name={{ service_name }} state=started enabled=yes

3.6.5 主機清單文件中定義變數

主機變數

為指定的主機定義變數

範例:

[websrvs]
www1.hello.com http_port=80 maxRequestsPerChild=808
www2.hello.com http_port=8080 maxRequestsPerChild=909

組(公共)變數

給指定組內所有主機上的在playbook中可用的變數,如果和主機變是 同名,優先順序低於主機變數

範例:

[websrvs]
www1.hello.com http_port=8080
www2.hello.com
[websrvs:vars]
http_port=80
ntp_server=ntp.magedu.com
nfs_server=nfs.magedu.com

3.7 template 模板

模板是一個文本文件,可以做為生成文件的模版,並且模板文件中還可嵌套jinja語法

3.7.1 jinja2語言

官方文檔://jinja.palletsprojects.com/en/3.0.x/

中文版本://docs.jinkan.org/docs/jinja2/#

3.7.2 template

官方介紹://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html

範例:

使用 if條件判斷,決定是否生成相關的配置資訊
#yml文件
[root@centos8 data]# cat temp5.yml 
---
- hosts: innet
  vars:
    nginx_vhosts:
     - web1:
       listen: 8080
       root: "/var/www/nginx/web1/"
     - web2:
       listen: 8080
       server_name: "web2.magedu.com"
       root: "/var/www/nginx/web2/"
     - web3:
       listen: 8080
       server_name: "web3.magedu.com"
       root: "/var/www/nginx/web3/"
  tasks:
     - name: template config to
       template: src=nginx.conf5.j2 dest=/data/nginx5.conf #也可以寫絕對路徑,使用此處寫法將模板文件放在同級目錄也可以執行

#模板文件位置
[root@centos8 data]# cat ./templates/nginx.conf5.j2 
{% for vhost in nginx_vhosts %}
server {
   listen {{ vhost.listen }}
   {% if vhost.server_name is defined %}
server_name {{ vhost.server_name }}
   {% endif %}
root  {{ vhost.root }}
}
{% endfor %}

#生成的文件
[root@centos8 data]# cat nginx5.conf 
server {
   listen 8080
   root  /var/www/nginx/web1/
}
server {
   listen 8080
   server_name web2.magedu.com
   root  /var/www/nginx/web2/
}
server {
   listen 8080
   server_name web3.magedu.com
   root  /var/www/nginx/web3/
}

4 roles角色

roles就是通過分別將變數、文件、任務、模板及處理器放置於單獨的目錄中,並可以便 捷地include它們的一種機制。將任務拆分成多個模組,適用於較為複雜的場景,提高程式碼復用性。

官方文檔://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

4.1 roles結構

roles目錄結構如下

# playbooks
site.yml
webservers.yml
fooservers.yml
roles/
    common/
        tasks/
        handlers/
        library/
        files/
        templates/
        vars/
        defaults/
        meta/
    webservers/
        tasks/
        defaults/
        meta/

默認情況Ansible會去查找角色每個目錄下的main.yml文件中內容

  • tasks/main.yml – the main list of tasks that the role executes.
  • handlers/main.yml – handlers, which may be used within or outside this role.
  • library/my_module.py – modules, which may be used within this role
  • defaults/main.yml – 設定默認變數時使用此目錄中的main.yml文件,比vars的優先順序低
  • vars/main.yml – other variables for the role.
  • files/main.yml – 存放由copy或script模組等調用的文件
  • templates/main.yml – templates that the role deploys.
  • meta/main.yml – metadata for the role, including role dependencies.

4.2 role使用

調用role步驟

1 創建以roles命名的目錄
2 在roles目錄中分別創建以各角色名稱命名的目錄,如webservers等
3 在每個角色命名的目錄中分別創建files、handlers、meta、tasks、templates和vars目錄;用不到
的目錄可以創建為空目錄,也可以不創建
4 在playbook文件中,調用各角色

在playbook中調用role方法

範例:

---
- hosts: websrvs
 remote_user: root
 roles:
 - mysql
 - memcached
 - nginx 
 
#鍵role用於指定角色名稱,後續的k/v用於傳遞變數給角色
---
- hosts: all
 remote_user: root
 roles:
    - mysql
    - { role: nginx, username: nginx }
    
#還可基於條件測試實現角色調用
---
- hosts: all
 remote_user: root
 roles:
   - { role: nginx, username: nginx, when: ansible_distribution_major_version
== '7' }

roles 中使用 tags

#nginx-role.yml
---
- hosts: websrvs
 remote_user: root
 roles:
    - { role: nginx ,tags: [ 'nginx', 'web' ] ,when:
ansible_distribution_major_version == "6" }
    - { role: httpd ,tags: [ 'httpd', 'web' ] }
    - { role: mysql ,tags: [ 'mysql', 'db' ] }
    - { role: mariadb ,tags: [ 'mariadb', 'db' ] }
ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml

4.3 實戰案例

4.3.1 roles實現zabbix-agent批量部署

[root@centos8 data]# tree roles/
roles/
└── zabbix
    ├── tasks
    │   ├── main.yml
    │   └── zabbixconf.yml
    └── templates
        └── zabbix.conf.j2

[root@centos8 data]# cat roles/zabbix/tasks/main.yml 
- include: zabbixconf.yml
[root@centos8 data]# cat roles/zabbix/tasks/zabbixconf.yml 
---
- name: zabbix host set
  template: src=zabbix.conf.j2 dest=/data/zabbix.conf

[root@centos8 data]# cat roles/zabbix/templates/zabbix.conf.j2 
hostname {{ ansible_nodename }};

5 ansible相關鏈接

ansible模組共享社區://galaxy.ansible.com/home