ansible playbook使用說明及測試demo

ansible 任務執行模式:

Ansible 系統由控制主機對被管節點的操作方式可分爲兩類,即adhoc和playbook:

(一)ad-hoc模式(點對點模式)

使用單個模塊,支持批量執行單條命令。ad-hoc 命令是一種可以快速輸入的命令,而且不需要保存起來的命令。就相當於bash中的一句話shell。

(二)playbook模式

是Ansible主要管理方式,也是Ansible功能強大的關鍵所在。playbook通過多個task集合完成一類功能,如Web服務的安裝部署、數據庫服務器的批量備份等。可以簡單地把playbook理解爲通過組合多條ad-hoc操作的配置文件。

一、YAML介紹

YAML(/ˈjæməl/,尾音類似camel駱駝)是一個可讀性高,用來表達數據序列化的格式。

YAML是"YAML Ain’t a Markup Language"(YAML不是一種標記語言)的遞歸縮寫。在開發的這種語言時,YAML 的意思其實是:“Yet Another Markup Language”(仍是一種標記語言),但爲了強調這種語言以數據做爲中心,而不是以標記語言爲重點,而用反向縮略語重命名。

YAML的語法和其他高級語言類似,並且可以簡單表達清單、散列表,標量等數據形態。它使用空白符號縮進和大量依賴外觀的特色,特別適合用來表達或編輯數據結構、各種配置文件、傾印調試內容、文件大綱(例如:許多電子郵件標題格式和YAML非常接近)。YAML 的配置文件後綴爲 .yml,如:test.yml 。

1.1 YAML基本語法

  • 大小寫敏感
  • 使用縮進表示層級關係
  • 縮進不允許使用tab,只允許空格
  • 縮進的空格數不重要,只要相同層級的元素左對齊即可
  • '#'表示註釋

1.2 YAML數據類型

  • 對象:鍵值對的集合,又稱爲映射(mapping)/ = 哈希(hashes) / 字典(dictionary)
  • 數組:一組按次序排列的值,又稱爲序列(sequence) / 列表(list)
  • 純量(scalars):單個的、不可再分的值
1.2.1 對象
#(1)格式爲key: value,冒號後面加一個空格
url: http://192.168.20.1
#(2)表示server: {host: node1}
server:
    host: node1
#(3)使用縮進表示層級關係
key: 
    key1: value1
    key2: value2
#上面還支持流式(flow)語法表示對象
key: {key1: value1, key2: value2}
1.2.2 數組

使用一個短橫線加一個空格代表一個數組項

#(1)表示server爲[node1,node2,node3]
server:
    - node1
    - node2
    - node3
#(2)表示[[python,java]]
-
    - python
    - java
#(3)表示companies屬性是一個數組,每一個數組元素又是由id,name,price三個屬性構成
note:
    -
        id: 1
        name: book1
        price: 20
    -
        id: 2
        name: book2
        price: 50
#上面數組也可以使用流式(flow)的方式表示:
note: [{id: 1,name: book1,price: 20},{id: 2,name: book2,price: 50}]
1.2.3 常量

常量結構,包括:整數,浮點數,字符串,NULL,日期,布爾,時間

boolean: 
    - TRUE  #true,True都可以
    - FALSE  #false,False都可以
float:
    - 3.14
    - 6.8523015e+5  #可以使用科學計數法
int:
    - 123
    - 0b1010_0111_0100_1010_1110    #二進制表示
null:
    Name: 'node'
    parent: ~  #使用~表示null
string:
    - 測試
    - 'Hello world'  #可以使用雙引號或者單引號包裹特殊字符
    - line1
      line2    #字符串可以拆成多行,每一行會被轉化成一個空格
date:
    - 2020-04-02    #日期必須使用ISO 8601格式,即yyyy-MM-dd
datetime: 
    -  2020-04-02T15:02:31+08:00    #時間使用ISO 8601格式,時間和日期之間使用T連接,最後使用+代表時區
1.2.4 一些特殊符號
# (1)--- YAML可以在同一個文件中,使用---表示一個文檔的開始;也常常使用---來分割不同的內容,比如記錄日誌
---
Time: 2020-04-02T15:02:31+08:00
User: ed
Warning:
     This is an error message for the log file
---
Time: 2020-04-02T15:05:21+08:00
User: ed
Warning:
    A slightly different error message.

#(2)... 和---配合使用,在一個配置文件中代表一個文件的結束,下面例子相當於在一個yaml文件中連續寫了兩個yaml配置項
---
time: 20:03:20
player: tom
action: run
...
---
time: 20:03:47
player: Lily
action: run
...

#(3)!! YAML中使用!!做類型強行轉換,例如把數字和布爾類型強轉爲字符串
string:
    - !!str 54321
    - !!str true
#將數組解析爲set,簡單理解,轉化的內容就是:[{aaa=58}, {bbb=65}, {ccc=63}],重複的ccc去掉
--- !!set
- bbb: 65
- ccc: 63
- ccc: 63
- aaa: 58

#(4)>在字符串中摺疊換行,| 保留換行符
context: > 
 this is
 a book
stats: |
 today is
 sunday
 #結果是:
context=this is a book #換行符轉化成了空格;每行的文本前一定要有一個空格
 stats= today is
 sunday
 
#(5)引用
#重複的內容在YAML中可以使用&來完成錨點定義,使用*來完成錨點引用
hr:
- aa
- &SS bb
rbi:
- *SS 
- cc
#結果爲:
{rbi=[bb, cc], hr=[aa, bb]}

#(6)合併
test:
  - &SMALL { x: 1, y: 2 }
  - &BIG { r: 10 }
 
exp2:
    << : [ *SMALL, *BIG ]
    other: haha
    
exp3:
    << : [ *SMALL, *BIG ]
    r: 100
#exp2中,<<: [*SMALL, *BIG] 意思是聯合引用{x: 1,y: 2}和{r: 10},並且合併到exp2中,那麼合併的結果爲:exp2={other=haha, x=1, y=2, r=10}

#exp3中,引入了*SMALL, *BIG,還使用了r: 100覆蓋了引入的r: 10,所以exp3值爲:exp3={r=100, y=2, x=1}

二、ansible playbook相關介紹

2.1 ansible palybook的核心元素

  • Hosts 執行的遠程主機列表
  • Tasks 任務,由模板定義的操作列表
  • Variables 內置變量或自定義變量在playbook中調用
  • Templates 模板,即使用模板語法的文件,比如配置文件等
  • Handlers 和notity結合使用,由特定條件觸發的操作,滿足條件方纔執行,否則不執行
  • tags 標籤,指定某條任務執行,用於選擇運行playbook中的部分代碼。
  • Roles:角色

2.2 playbook的基礎組件

- Hosts:運行指定任務的目標主機
- remote_user:在遠程主機上執行任務的用戶
    sudo_user
- tasks:任務列表
    模塊,模塊參數;
    格式:(1)action:module arguments
          (2)module:arguments
    注意:shell和command模塊後面直接跟命令,而非key=value類的參數列表;
1)某任務的狀態在運行後爲changed時,可通過"notify"通知給相應的handlers;
2)任務可以通過"tags"打標籤,而後可在ansible-palybook命令上使用-t指定進行調用;

2.3 hosts和users介紹

---
- hosts: abc                   #可以是一個主機組、主機、多個主機,中間以冒號分隔,也可以用all參數表示所有主機
    remote_user: root          #表示執行的用戶賬號
    become: yes                #2.6版本以後的參數,之前是sudo,意思爲切換用戶運行
    become_user: mysql         #指定sudo用戶爲mysql
become 和become_user 作爲指定遠程主機sudo切換用

2.4 Tasks list 和action介紹

1、Play的主體部分是task列表,task列表中的各任務按次序逐個在hosts中指定的主機上執行,即在所有主機上完成第一個任務後再開始第二個任務。
 
2、在運行playbook時(從上到下執行),如果一個host執行task失敗,整個tasks都會回滾,請修正playbook 中的錯誤,然後重新執行即可。
 
3、每一個task必須有一個名稱name,這樣在運行playbook時,從其輸出的任務執行信息中可以很好的辨別出是屬於哪一個task的。
   如果沒有定義name,‘action’的值將會用作輸出信息中標記特定的task。
    
4、定義一個task,常見的格式:”module: options” 例如:yum: name=httpd
 
5、ansible的自帶模塊中,command模塊和shell模塊無需使用key=value格式

2.5 ansible playbook常用命令

# ansible-playbook first.yml --syntax-check    #檢查yaml文件的語法是否正確
# ansible-playbook first.yml --list-task       #檢查tasks任務
# ansible-playbook first.yml --list-hosts      #檢查生效的主機
# ansible-playbook first.yml --start-at-task='Copy Nginx.conf'     #指定從某個task開始運行
# ansible-playbook first.yml -k      #用來交互輸入ssh密碼
# ansible-playbook first.yml -K      #用來交互輸入sudo密碼
# ansible-playbook first.yml -u      #指定用戶

ansible playbook執行參數說明

執行方式:ansible-playbook playbook.yml [options]

-u REMOTE_USER, --user=REMOTE_USER 
# ssh連接的用戶名
 
 -k, --ask-pass   
#ssh登錄認證密碼
 
 -s, --sudo          
#sudo 到root用戶相當於Linux系統下的sudo命令
 
 -U SUDO_USER, --sudo-user=SUDO_USER   
#sudo到對應的用戶
 
 -K, --ask-sudo-pass    
#用戶的密碼(—sudo時使用)
 
 -T TIMEOUT, --timeout=TIMEOUT
# ssh連接超時,默認10秒
 
 -C, --check     
# 指定該參數後,執行playbook文件不會真正去執行,而是模擬執行一遍,然後輸出本次執行會對遠程主機造成的修改
 
 -e EXTRA_VARS, --extra-vars=EXTRA_VARS   
# 設置額外的變量如:key=value形式或者 YAML or JSON,以空格分隔變量,或用多個-e
 
 -f FORKS, --forks=FORKS   
# 進程併發處理,默認5
 
 -i INVENTORY, --inventory-file=INVENTORY  
# 指定 hosts 文件路徑,默認 default=/etc/ansible/hosts
 
 -l SUBSET, --limit=SUBSET   
# 指定一個pattern,對-hosts:匹配到的主機再過濾一次
 
 --list-hosts 
# 只打印有哪些主機會執行這個playbook文件,不是實際執行該playbook
 
 --list-tasks  
# 列出該playbook中會被執行的task
 
 --private-key=PRIVATE_KEY_FILE  
# 私鑰路徑
 
 --step   
# 同一時間只執行一個task,每個task 執行前都會提示確認一遍
 
 --syntax-check 
# 只檢測playbook文件語法是否有問題,不會執行該playbook
 
 -t TAGS, --tags=TAGS  
#當play和task的tag爲該參數指定的值時才執行,多個tag以逗號分隔
 
 --skip-tags=SKIP_TAGS  
# 當play和task的tag不匹配該參數指定的值時,才執行
 
 -v, --verbose  
#輸出更詳細的執行過程信息,-vvv可得到所有執行過程信息。

2.6 運行playbook的方式

2.6.1 測試
#只檢測可能會發生的改變,但不真正執行操作
ansible-playbook --check
#列出運行任務的主機
ansible-playbook --list-hosts
2.6.2 運行playbook
[root@localhost playbooks]# cat first.yaml 
- hosts: all
  remote_user: root
  tasks:
  - name: install redis
    yum: name=redis state=latest
  - name: start redis
    service: name=redis state=started enabled=true

#語法檢測
[root@localhost playbooks]# ansible-playbook --syntax-check first.yaml 

playbook: first.yaml

#列出運行任務的主機
[root@localhost playbooks]# ansible-playbook --list-hosts first.yaml 

playbook: first.yaml

  play #1 (all): all	TAGS: []
    pattern: [u'all']
    hosts (1):
      192.168.75.128

#列出任務和主機
[root@localhost playbooks]# ansible-playbook --list-hosts --list-tasks first.yaml 

playbook: first.yaml

  play #1 (all): all	TAGS: []
    pattern: [u'all']
    hosts (1):
      192.168.75.128
    tasks:
      install redis	TAGS: []
      start redis	TAGS: []

#執行playbook文件不會真正去執行,而是模擬執行一遍,然後輸出本次執行會對遠程主機造成的修改
[root@localhost playbooks]# ansible-playbook -C first.yaml  
#開始運行YAML文件,按任務逐個執行
[root@localhost playbooks]# ansible-playbook  first.yaml 

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

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

TASK [install redis] ****************************************************************
changed: [192.168.75.128]

TASK [start redis] ******************************************************************
changed: [192.168.75.128]

PLAY RECAP **************************************************************************
192.168.75.128             : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

#查看備機已啓動
[root@localhost ~]# ps -ef | grep redis
redis     73031      1  0 03:17 ?        00:00:08 /usr/bin/redis-server 127.0.0.1:6379
root      74017  73983  0 04:36 pts/0    00:00:00 grep --color=autoredis

處理遠程服務器的redis相關配置

#將遠程主機的配置文件複製到本地
[root@localhost playbooks]# ansible 192.168.75.128 -m fetch -a "src=/etc/redis.conf dest=./"
#修改配置文件redis.conf內容
[root@localhost playbooks]# ls
192.168.75.128  file1.yml  first.yaml
[root@localhost playbooks]# mv 192.168.75.128/etc/redis.conf ./
[root@localhost playbooks]# rm -rf 192.168.75.128
#更改redis.conf
bind 0.0.0.0
requirepass changecan

#更改yaml,將已修改配置文件傳到遠程主機
[root@localhost playbooks]# cat first.yaml 
- hosts: all
  remote_user: root
  tasks:
  - name: install redis
    yum: name=redis state=latest
  - name: copy config file
    copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=redis
  - name: start redis
    service: name=redis state=started enabled=true
[root@localhost playbooks]# ansible-playbook --syntax-check first.yaml
[root@localhost playbooks]# ansible-playbook -C first.yaml
[root@localhost playbooks]# ansible-playbook first.yaml #結果顯示:只執行了傳配置文件這一項

2.7 playbooks組件:handlers對特定條件觸發任務

#當redis.conf內容複製發生改變,則執行重啓
[root@localhost playbooks]# cat second.yaml 
- hosts: all
  remote_user: root
  tasks:
  - name: install redis
    yum: name=redis state=latest
  - name: copy config file
    copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=redis
    notify: restart redis
    tags: configfile
  - name: start redis
    service: name=redis state=started enabled=true
  handlers:
  - name: restart redis
    service: name=redis state=restarted
#更改redis.conf再測試執行,會觸發restart重啓redis操作。若redis.conf內容不變,則不會觸發重啓
[root@localhost playbooks]# ansible-playbook second.yaml

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

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

TASK [install redis] ***********************************************************
ok: [192.168.75.128]

TASK [copy config file] ********************************************************
changed: [192.168.75.128]

TASK [start redis] *************************************************************
ok: [192.168.75.128]

RUNNING HANDLER [restart redis] ************************************************
changed: [192.168.75.128]

PLAY RECAP *********************************************************************
192.168.75.128             : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

#只執行指定標籤tags:名爲configfile標記的任務
[root@localhost playbooks]# ansible-playbook -t configfile second.yaml 

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

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

TASK [copy config file] ********************************************************
ok: [192.168.75.128]

PLAY RECAP *********************************************************************
192.168.75.128             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

2.8 playbook組件:Variables 內置變量或自定義變量

(1)facts:可直接調用
    注意:可使用setup模塊直接獲取目標主機的facters;
     ansible-playbook -m setup
(2)用戶自定義變量:
    (a)ansible-playbook命令的命令行中的自定義變量;
        -e VARS, --extra-vars=VARS
    
    (b)在playbook中定義變量的方法:
        vars:
        - var1: value1
        - var2: value2
    變量引用:{{ variable }}
    
(3)通過roles傳遞變量;
(4)Host Inventory主機清單
    (a)用戶自定義變量
    (i)向不同的主機傳遞不同的變量;
        IP/HOSTNAME variable=value var2=value2
    (ii)向組中的主機傳遞相同的變量;
        [groupname:vars]
        variable=value
    (b)invertory參數
    用於定義ansible遠程連接目標主機時使用的參數,而非傳遞給playbook的變量;
        ansible_ssh_host
        ansible_ssh_port
        ansible_ssh_user
        ansible_ssh_pass
        ansible_sudo_pass

2.8.1 (1)facts:可直接調用

注意:可使用setup模塊直接獲取目標主機的facters;

ansible-playbook -m setup
#例如:調用ansible_env變量獲取遠程主機信息
[root@localhost playbooks]# cat third.yaml 
- hosts: 192.168.75.128
  remote_user: root
  tasks:
  - name: copy file
    copy: content={{ ansible_env }} dest=/tmp/ansible.env
[root@localhost playbooks]# ansible-playbook --syntax-check third.yaml
[root@localhost playbooks]# ansible-playbook third.yaml
[root@128 ~]# cat /tmp/ansible.env 
{"LANG": "en_US.UTF-8", "TERM": "xterm", "SHELL": "/bin/bash", "XDG_RUNTIME_DIR": "/run/user/0", "MAIL": "/var/mail/root", "SHLVL": "2", "SSH_TTY": "/dev/pts/1", "SSH_CLIENT": "192.168.75.129 40590 22", "LESSOPEN": "||/usr/bin/lesspipe.sh %s", "PWD": "/root", "SELINUX_USE_CURRENT_RANGE": "", "LOGNAME": "root", "USER": "root", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", "HOME": "/root", "SELINUX_LEVEL_REQUESTED": "", "XDG_SESSION_ID": "177", "SELINUX_ROLE_REQUESTED": "", "_": "/usr/bin/python", "SSH_CONNECTION": "192.168.75.129 40590 192.168.75.128 22"}
2.8.2 (2)ansible-playbook用戶自定義變量;
    (a)ansible-playbook命令的命令行中的自定義變量;
        -e VARS, --extra-vars=VARS
    
    (b)在playbook中定義變量的方法:
        vars:
        - var1: value1
        - var2: value2
    變量引用:{{ variable }}
#安裝包使用變量表示
[root@localhost playbooks]# cat forth.yaml 
- hosts: all
  remote_user: root
  tasks:
  - name: install {{ pkgname }}
    yum: name={{ pkgname }} state=latest
#安裝nginx
[root@localhost playbooks]# ansible-playbook -e pkgname=nginx forth.yaml 

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

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

TASK [install nginx] ***********************************************************
changed: [192.168.75.128]

PLAY RECAP *********************************************************************
192.168.75.128             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
2.8.3 (4)Host Inventory主機清單
    (a)用戶自定義變量
    (i)向不同的主機傳遞不同的變量;
        IP/HOSTNAME variable=value var2=value2
    (ii)向組中的主機傳遞相同的變量;
        [groupname:vars]
        variable=value
    (b)invertory參數
    用於定義ansible遠程連接目標主機時使用的參數,而非傳遞給playbook的變量;
        ansible_ssh_host
        ansible_ssh_port
        ansible_ssh_user
        ansible_ssh_pass
        ansible_sudo_pass

(i)向不同的主機傳遞不同的變量

#測試:添加用戶changecan
[root@localhost playbooks]# cat users.yaml 
- hosts: all
  remote_user: root
  tasks:
  - name: add user
    user: name=changecan system=no state=present
  - name: set password
    shell: echo changecan | passwd --stdin changecan
[root@localhost playbooks]# ansible-playbook users.yaml
#測試用戶添加成功
[root@localhost playbooks]# ssh -l changecan 192.168.75.128
[email protected]'s password: 
[changecan@128 ~]$

#更改主機清單的配置
[root@localhost playbooks]# cat /etc/ansible/hosts 
[websrvs]
192.168.75.128 ansible_ssh_user=changecan ansible_ssh_pass=changecan

#測試主機清單普通用戶使用權限
[root@localhost playbooks]# ansible websrvs --list-hosts
  hosts (1):
    192.168.75.128
[root@localhost playbooks]# ansible websrvs -m ping
[root@localhost playbooks]# ansible websrvs -m command -a "whoami"
192.168.75.128 | CHANGED | rc=0 >>
changecan

(ii)向組中的主機傳遞相同的變量

[root@localhost playbooks]# cat /etc/ansible/hosts
[websrvs]
192.168.75.128 

[websrvs:vars]
http_port=8080
[root@localhost playbooks]# cat vars.yaml 
- hosts: websrvs
  remote_user: root
  vars:
  - pbvar: playbook variable testing
  tasks:
  - name: command line variable
    copy: content={{ cmdvar }} dest=/tmp/cmd.var
  - name: playbook variables
    copy: content={{ pbvar }} dest=/tmp/pb.var
  - name: host iventory variables
    copy: content={{ http_port }} dest=/tmp/hi.var
[root@localhost playbooks]# ansible-playbook -e cmdvar="command" vars.yaml

PLAY [websrvs] *****************************************************************

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

TASK [command line variable] ***************************************************
changed: [192.168.75.128]

TASK [playbook variables] ******************************************************
changed: [192.168.75.128]

TASK [host iventory variables] *************************************************
changed: [192.168.75.128]

PLAY RECAP *********************************************************************
192.168.75.128             : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@128 ~]# cat /tmp/cmd.var 
command[root@128 ~]# cat /tmp/pb.var 
playbook variable testing[root@128 ~]# cat /tmp/hi.var 
8080

2.9 Templates 模板,即使用模板語法的文件,比如配置文件等

基於模板方式生成一個文件複製到遠程主機

*src=
*dest=
owner=
group=
mode=
2.9.1 Jinja2
字面量:
    字符串:使用單引號或雙引號;
    數字:整數,浮點數;
    列表:[item1, item2, ...]
    元組:(item1 item2, ...)
    字典:{key1:value1, key2:value2, ...}
    布爾型:true/false
算數運算:
    +, -, *, /, //, %, **
比較操作:
    ==, !=, >, >=,<, <=
邏輯運算:
    and, or, not
2.9.2 示例1 redis監聽本服務器IP

通過已修改的配置文件bind {{ ansible_eno16777736.ipv4.address }}去獲取遠程主機ip地址進行參數傳遞

[root@localhost playbooks]# cat /root/playbooks/redis.conf.j2 | grep -v "^$" | grep -v "^#"
bind {{ ansible_eno16777736.ipv4.address }}
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
requirepass changecan
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

[root@localhost playbooks]# cat template.yaml
- hosts: 192.168.75.128
  remote_user: root
  tasks:
  - name: install config file
    template: src=/root/playbooks/redis.conf.j2 dest=/tmp/redis.conf

[root@localhost playbooks]# ansible-playbook template.yaml
執行yaml後,查看遠程主機的IP地址正常傳遞到配置文件了
2.9.3 示例2 httpd新增監聽端口

修改httpd配置,將主機清單/etc/ansible/hosts裏面的變量傳遞到配置文件,使得遠程主機httpd增加監聽端口8080

[root@localhost ~]# cat /etc/ansible/hosts
[websrvs]
192.168.75.128

[websrvs:vars]
http_port=8080
[root@localhost playbooks]# cat mylisten.conf 
Listen {{ http_port }}
[root@localhost playbooks]# cat httpd.yaml 
- hosts: websrvs
  remote_user: root
  tasks:
  - name: install httpd
    yum: name=httpd state=latest
  - name: install config file
    template: src=/root/playbooks/mylisten.conf dest=/etc/httpd/conf.d/mylisten.conf
  - name: start httpd
    service: name=httpd state=started
[root@localhost playbooks]# ansible-playbook httpd.yaml
2.9.3 示例3 nginx配置調整
#從setup模塊中取遠程主機參數:
CPU內核數:"ansible_processor_cores": 2, 
CPU顆數:"ansible_processor_count": 2,
#模板配置文件:files/nginx.conf.j2
worker_processes {{ ansible_processor_vcpus }};
listen {{ http_port }};
#yaml文件
- hosts: websrvs
  remote_user: root
  tasks:
  - name: install nginx
    yum: name=nginx state=present
  - name: install conf file
    template: src=files/nginx.conf.j2 dest=/etc/nginx/nginx.conf
    notify: restart nginx
    tags: instconf
    - name: start nginx service
    service: name=nginx state=started
    handlers:
    - name: restart nginx
    service: name=nginx state=restarted

2.10 條件測試

when語句:在task中使用,jinja2的語法格式
例如:當操作系統爲redhat安裝httpd,當爲Debian則安裝apache2

- hosts: websrvs
  remote_user: root
  tasks:
  - name: install httpd
    yum: name=httpd state=latest
    when: ansible_os_family == "Redhat"
  - name: install apache2
    apt: name=apache2 state=latest
    when: ansible_os_family == "Debian"

2.11 循環:迭代,需要重複執行的任務

對迭代項的引用,固定變量名爲"item".
而後,要在task中使用with_items給定要迭代的元素列表

列表方法:字符串、字典

(下面例子:yum一次性安裝多個模塊的問題)

- hosts: websrvs
  remote_user: root
  tasks:
  - name: install {{ item }} package
    yum: name={{ item }} state=latest
    with_items:
    - nginx
    - tomcat
    - mariadb-server
    - redis
#新版本的ansible-playbook已經不支持在yum安裝多個模塊裏使用的方式。
#這麼寫在老版本還OK,但是在2.8以後,還這麼寫就會有錯誤:
[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: ['nginx', 'tomcat', 
'mariadb-server', 'redis']` 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.
#[棄用警告]:只在通過squash_actions使用循環時調用“yum”一次是不贊成的。而不是如果使用循環提供多個項目並指定' name: ['nginx', 'tomcat', 'mariadb-server', 'redis']',請使用' name: "{{ item }}"' '並刪除循環。這個特性將在2.11版本中刪除。棄用的警告可以通過在ansible.cfg中設置deprecation_warnings=False來禁用。


#【更改】上面的報錯可以通過變量來傳遞(把item該爲packages,並通過變量賦值來傳遞參數):
- hosts: websrvs
  remote_user: root
  vars:
    packages:
      - nginx
      - tomcat
      - mariadb-server
      - redis
  tasks:
  - name: install "{{ packages }}" package
    yum: name={{ packages }} state=latest
    with_items: "{{ packages }}"

三、ansible roles角色

3.1 roles角色相關說明

roles默認存放路徑:

#在/etc/ansible/ansible.cfg裏面進行配置
roles_path    = /etc/ansible/roles

角色集合:

roles/
    mysql/
    httpd/
    nginx/
    memcached/

每個角色,以特定的層級目錄結構進行組織:

mysql/
    files/:     存放copy或script模塊等調用的文件;
    templates/: template模塊查找所需要的模板文件的目錄;
    tasks/:     至少應該包含一個名爲main.yaml的文件,其他的文件需要在此文件中通過include進行包含;
    handlers/: 至少應該包含一個名爲main.yaml的文件,其他的文件需要在此文件中通過include進行包含;
    vars/:      至少應該包含一個名爲main.yaml的文件,其他的文件需要在此文件中通過include進行包含;
    meta/:      至少應該包含一個名爲main.yaml的文件,定義當前角色的特殊設定及其依賴關係,其他的文件需要在此文件中通過include進行包含;
    default/:   設定默認變量時使用此目錄中的main.yaml文件。

3.2 roles示例1:

安裝nginx並啓動服務,並修改配置文件後重啓服務,配置默認index.html

[root@localhost ~]# mkdir -pv /etc/ansible/roles/nginx/{files,templates,tasks,vars,handlers,meta,default}
[root@localhost ~]# cat /etc/ansible/roles/nginx/tasks/main.yaml 
- name: install nginx
  yum: name=nginx state=latest
  when: ansible_os_family == "RedHat"
- name: install conf
  template: src=vhost1.conf.j2 dest=/etc/nginx/conf.d/vhost1.conf
  tags: conf
  notify: restart nginx
- name: install site home diretory
  file: path={{ ngxroot }} state=directory
- name: install index page
  copy: src=index.html dest={{ ngxroot }}/
- name: start nginx
  service: name=nginx state=started

[root@localhost ~]# cat /etc/ansible/roles/nginx/templates/vhost1.conf.j2 
server {
	listen 8080;
	server_name {{ ansible_fqdn }};
	location / {
		root "/ngxdata/vhost1";
	}
}

[root@localhost ~]# cat /etc/ansible/roles/nginx/handlers/main.yaml 
- name: restart nginx
  service: name=nginx state=restarted

[root@localhost ~]# cat /etc/ansible/roles/nginx/vars/main.yaml 
ngxroot: /ngxdata/vhost1

[root@localhost ~]# cat /etc/ansible/roles/nginx/files/index.html 
<h1>Vhost1</h1>

[root@localhost ~]# cat nginx.yaml 
- hosts: websrvs
  remote_user: root
  roles:
  - nginx
[root@localhost ~]# ansible-playbook --syntax-check nginx.yaml
[root@localhost ~]# ansible-playbook -C nginx.yaml
[root@localhost ~]# ansible-playbook nginx.yaml
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章