天天看點

Ansible playbook 進階文法

主機清單檔案中定義變量

實驗準備

準備一台 CentOS7伺服器,安裝好 ansible,并配置一台被遠端管理的伺服器.前提關閉防火牆和selinux。

這裡用到centos7 absible1主機作為ansible機器。IP:192.168.32.7

被控制機器為centos8 ansible2 主機。IP:192.168.32.8

[[email protected] ~]#ansible --version
ansible 2.9.1
  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, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
  
[[email protected] ~]#ansible all -m ping
192.168.32.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[[email protected] ~]#
           

變量介紹

主機變量:

在inventory 主機清單檔案中為指定的主機定義變量以便于在playbook中使用

範例:

[appsrvs]
192.168.32.8 HOST1=centos7
其中就是把centos7這個值指派給到HOST1
           

組(公共)變量:

在inventory 主機清單檔案中賦予給指定組内所有主機上的在playbook中可用的變量

範例:

[appsrvs]
192.168.32.8 HOST1=centos7

[appsrvs:vars]
HOST2=centos8
在組變量centos8的值賦給HOST2,并且在組appsrvs的成員變量都生效
           

ansible-playbook 中的變量,變量名稱由字母數字和下劃線構成。

使用 setup 子產品,擷取遠端主機定義的變量, 使用雙層大括号調用變量值

變量實驗一

[[email protected] ~]#ansible all -m setup |grep "version"
        "ansible_bios_version": "6.00", 
        "ansible_distribution_major_version": "8",   #版本資訊變量
        "ansible_distribution_version": "8.0", 
        "ansible_kernel_version": "#1 SMP Tue Jun 4 09:19:46 UTC 2019", 
        "ansible_product_version": "None", 
            "version": {
            "version_info": [
        "ansible_python_version": "3.6.8", 

           
[[email protected] ~]#cd /data/ansible/
[[email protected] ansible]#
[[email protected] ansible]#vim vartest.yml
[[email protected] ansible]#
[[email protected] ansible]#cat vartest.yml
---
- hosts: all
  remote_user: root

  tasks:
    - name: playbook var test
      shell: /bin/echo "192.168.32.8 remote CentOS version is {{ ansible_distribution_major_version 
      }}" > /data/ansible/varsion.txt
      # ansible_distribution_major_version為setup中系統變量名稱
[[email protected] ansible]#
[[email protected] ansible]#ansible-playbook -C vartest.yml  #  -C選項 文法檢查

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

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

TASK [playbook var test] ******************************************************************************************
skipping: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.8               : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[[email protected] ansible]#ansible-playbook vartest.yml #運作劇本

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

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

TASK [playbook var test] ******************************************************************************************
changed: [192.168.32.8]

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

[[email protected] ansible]#ansible all -a 'cat /data/ansible/varsion.txt'
192.168.32.8 | CHANGED | rc=0 >>
192.168.32.8 remote CentOS version is 8

[[email protected] ansible]#
[[email protected] ansible]#

           

除了使用 setup 子產品提供的遠端主機變量,我們還可以在 ansible 的 hosts 檔案中定義變量

[[email protected] ansible]#vim /etc/ansible/hosts 

[[email protected] ansible]#cat /etc/ansible/hosts
[appsrvs]
192.168.32.8  NAME=kaivi  LOVER=duanxin

[[email protected] ansible]#vim vartest.yml 

[[email protected] ansible]#cat vartest.yml 
---
- hosts: all
  remote_user: root

  tasks:
    - name: playbook var test
      shell: /bin/echo "As we all know,{{ NAME }} love gril who is {{ LOVER }} " > 
 /data/ansible/kaivi_say.txt

[[email protected] ansible]#ansible-playbook -C vartest.yml 

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

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

TASK [playbook var test] ******************************************************************************************
skipping: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.8               : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[[email protected] ansible]#ansible-playbook  vartest.yml 

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

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

TASK [playbook var test] ******************************************************************************************
changed: [192.168.32.8]

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

[[email protected] ansible]#
[[email protected] ansible]#ansible all -a "cat /data/ansible/kaivi_say.txt"
192.168.32.8 | CHANGED | rc=0 >>
As we all know,kaivi love gril who is duanxin 

           

除了在 hosts 配置檔案的主機 ip 位址後定義變量外,還可以單獨給主機分組定義變量,變量全組有效,如下:

[[email protected] ansible]#vim /etc/ansible/hosts 

[[email protected] ansible]#cat /etc/ansible/hosts
[appsrvs]
192.168.32.8 

[appsrvs:vars]
name=kaivi
address=beijing


[[email protected] ansible]#vim vartest.yml 
[[email protected] ansible]#cat vartest.yml
---
- hosts: all
  remote_user: root

  tasks:
    - name: playbook var test
      shell: /bin/echo "who are you? is where now?  I am {{ name }} ,here is {{ address }}! " > 
      /data/ansible/ask_answer.txt
[[email protected] ansible]#ansible-playbook -C vartest.yml 

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

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

TASK [playbook var test] ******************************************************************************************
skipping: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.8               : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[[email protected] ansible]#ansible-playbook vartest.yml 

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

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

TASK [playbook var test] ******************************************************************************************
changed: [192.168.32.8]

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

[[email protected] ansible]#ansible all -a 'cat /data/ansible/ask_answer.txt'
192.168.32.8 | CHANGED | rc=0 >>
who are you? is where now?  I am kaivi ,here is beijing! 

[[email protected] ansible]#

           

在被管理的主機192.168.32.8上面檢視

[[email protected] ~]#ll /data/ansible/* |grep "txt"
-rw-r--r-- 1 root root        58 Dec  6 19:58 /data/ansible/ask_answer.txt
-rw-r--r-- 1 root root        47 Dec  6 19:47 /data/ansible/kaivi_say.txt
-rw-r--r-- 1 root root        40 Dec  6 19:36 /data/ansible/varsion.txt

           

在運作 ansible-playbook 指令時可以直接使用 -e 選項定義變量,優先級最高:

[[email protected] ansible]#cat vartest.yml 
---
- hosts: all
  remote_user: root

  tasks:
    - name: playbook var test
      shell: /bin/echo "who are you? is where now?  I am {{ name }} ,here is {{ address }}! " > /data/ansible/ask_answer.txt

[[email protected] ansible]#ansible-playbook -e name=duanxin address=shanghai vartest.yml 
ERROR! the playbook: address=shanghai could not be found
[[email protected] ansible]#ansible-playbook -e name=duanxin -e address=shanghai vartest.yml 
或者:
[[email protected] ansible]#ansible-playbook -e "name=duanxin address=tianjin" vartest.yml 

[WARNING]: Found variable using reserved name: name


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

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

TASK [playbook var test] ******************************************************************************************
changed: [192.168.32.8]

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

[[email protected] ansible]#ansible all -a 'cat /data/ansible/ask_answer.txt'
192.168.32.8 | CHANGED | rc=0 >>
who are you? is where now?  I am duanxin ,here is shanghai! 

           

[WARNING]: Found variable using reserved name: name這個警告是因為在之前的hosts配置檔案中組變量中以及存在一個同名的變量導緻,删除即可。

在 playbook 檔案中直接定義變量,然後使用:

[[email protected] ansible]#vim /etc/ansible/hosts 
[[email protected] ansible]#cat /etc/ansible/hosts
[appsrvs]
192.168.32.8 


[[email protected] ansible]#vim vartest2.yml
[[email protected] ansible]#
[[email protected] ansible]#cat vartest2.yml 
---
- hosts: all
  vars: 
    - username: duanxin
    - usergroup: kaivi
  tasks: 
    - name: create group
      group: name={{ usergroup }} state=present
    - name: create user
      user: name={{ username }} group={{ usergroup }} state=present
[[email protected] ansible]#

[[email protected] ansible]#ansible-playbook -C vartest2.yml 

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

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

TASK [create group] ***********************************************************************************************
ok: [192.168.32.8]

TASK [create user] ************************************************************************************************
changed: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.8               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[[email protected] ansible]#ansible-playbook  vartest2.yml 

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

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

TASK [create group] ***********************************************************************************************
ok: [192.168.32.8]

TASK [create user] ************************************************************************************************
changed: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.8               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[[email protected] ansible]#ansible all -a 'id duanxin'
192.168.32.8 | CHANGED | rc=0 >>
uid=1001(duanxin) gid=1000(kaivi) groups=1000(kaivi)


           

在 playbook 中定義變量過多,編輯和管理起來會很不友善,我們可以單獨建立定義變量的 yml 檔案,然後再 playbook 中引入即可

[[email protected] ansible]#cat vartest2.yml 
---
- hosts: all
  vars: 
    - username: duanxin
    - usergroup: kaivi
  tasks: 
    - name: create group
      group: name={{ usergroup }} state=present
    - name: create user
      user: name={{ username }} group={{ usergroup }} state=present
[[email protected] ansible]#
[[email protected] ansible]#vim vars.yml
[[email protected] ansible]#cat vars.yml 
username: likai
usergroup: GNU
[[email protected] ansible]#
[[email protected] ansible]#vim vartest2.yml 
[[email protected] ansible]#cat vartest2.yml 
---
- hosts: all
  vars_files:                    #ansible程式會自動在上級目錄找對應的檔案
    - vars.yml              
  tasks: 
    - name: create group
      group: name={{ usergroup }} state=present
    - name: create user
      user: name={{ username }} group={{ usergroup }} state=present

[[email protected] ansible]#ansible-playbook -C vartest2.yml 

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

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

TASK [create group] ***********************************************************************************************
changed: [192.168.32.8]

TASK [create user] ************************************************************************************************
changed: [192.168.32.8]

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

[[email protected] ansible]#ansible-playbook  vartest2.yml 

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

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

TASK [create group] ***********************************************************************************************
changed: [192.168.32.8]

TASK [create user] ************************************************************************************************
changed: [192.168.32.8]

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

[[email protected] ansible]#ansible all -a 'id likai'
192.168.32.8 | CHANGED | rc=0 >>
uid=1002(likai) gid=1001(GNU) groups=1001(GNU)

[[email protected] ansible]#

           

template 模闆

模闆介紹

模闆是一個文本檔案,可以做為生成檔案的模版,并且模闆檔案中還可嵌套jinja文法

jinja2語言

jinja2 語言使用字面量,有下面形式:

字元串:使用單引号或雙引号

數字:整數,浮點數

清單:[item1, item2, …]

元組:(item1, item2, …)

字典:{key1:value1, key2:value2, …}

布爾型:true/false

算術運算:+, -, *, /, //, %, **

比較操作:==, !=, >, >=, <, <=

邏輯運算:and,or,not

流表達式:For,If,When Jinja2相關

字面量:
表達式最簡單的形式就是字面量。字面量表示諸如字元串和數值的 Python 對象。如“Hello World” 雙引
号或單引号中間的一切都是字元串。無論何時你需要在模闆中使用一個字元串(比如函數調用、過濾器
或隻是包含或繼承一個模闆的參數),如42,42.23 數值可以為整數和浮點數。如果有小數點,則為浮
點數,否則為整數。在 Python 裡, 42 和 42.0 是不一樣的
           
算術運算:
Jinja 允許用計算值。支援下面的運算符 +:把兩個對象加到一起。通常對象是素質,但是如果兩者是字
符串或清單,你可以用這 種方式來銜接它們。無論如何這不是首選的連接配接字元串的方式!連接配接字元串見
~ 運算符。 {{ 1 + 1 }} 等于 2 -:用第一個數減去第二個數。 {{ 3 - 2 }} 等于 1 /:對兩個數做除法。傳回
值會是一個浮點數。 {{ 1 / 2 }} 等于 {{ 0.5 }} //:對兩個數做除法,傳回整數商。 {{ 20 // 7 }} 等于 2
%:計算整數除法的餘數。 {{ 11 % 7 }} 等于 4 
* :用右邊的數乘左邊的操作數。 {{ 2 * 2 }} 會傳回 4 。
也可以用于重 複一個字元串多次。 {{ ‘=’ * 80 }} 會列印 80 個等号的橫條\ **:取左操作數的右操作數
次幂。 {{ 2**3 }} 會傳回 8
           
比較操作符
 == 比較兩個對象是否相等 != 比較兩個對象是否不等
> 如果左邊大于右邊,傳回 true >= 如果左邊大于等于右邊,傳回 true < 如果左邊小于右邊,傳回 true
<= 如果左邊小于等于右邊,傳回 true
           
邏輯運算符 
對于 if 語句,在 for 過濾或 if 表達式中,它可以用于聯合多個表達式 and 如果左操作數和
右操作數同為真,傳回 true or 如果左操作數和右操作數有一個為真,傳回 true not 對一個表達式取反
(expr)表達式組 true / false true 永遠是 true ,而 false 始終是 false
           

模闆具體示例

template功能:

可以根據和參考子產品檔案,動态生成相類似的配置檔案 template檔案必須存放于

templates目錄下,且命名為 .j2 結尾 yaml/yml 檔案需和templates目錄平級,目錄結構如下: ./

├── temnginx.yml └── templates └── nginx.conf.j2

範例:利用template 同步nginx配置檔案

#準備templates/nginx.conf.j2檔案
vim temnginx.yml
---
  - hosts: websrvs
  remote_user: root
  tasks:
	- name: template config to remote hosts
 	 template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
ansible-playbook temnginx.yml
           

template變更替換

範例:

#修改檔案nginx.conf.j2
vim templates/nginx.conf.j2
worker_processes {{ ansible_processor_vcpus }};
vim temnginx2.yml
---
- hosts: websrvs
  remote_user: root
  tasks:
	- name: template config to remote hosts
	  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
ansible-playbook temnginx2.yml
           

template算術運算

範例:

vim nginx.conf.j2
worker_processes {{ ansible_processor_vcpus**2 }};
worker_processes {{ ansible_processor_vcpus+2 }};
           

template中使用流程控制 for 和 if

template中也可以使用流程控制for循環和if條件判斷,實作動态生成檔案功能

範例

#temnginx1.yml
---
- hosts: websrvs
  remote_user: root
  vars:
	nginx_vhosts:
	  - listen: 8080
tasks:
  - name: config file
    template: src=nginx2.conf.j2 dest=/data/nginx2.conf
#templates/nginx.conf1.j2
{% for vhost in nginx_vhosts %}
server {
  listen {{ vhost.listen }}
}
{% endfor %}
#生成的結果
server {
  listen 8080
}
           

範例:

#temnginx2.yml
---
- hosts: websrvs
  remote_user: root
  vars:
	nginx_vhosts:
	  - 81
	  - 82
	  - 83
tasks:
  - name: template config
	template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
#templates/nginx.conf2.j2
{% for vhost in nginx_vhosts %}
server {
	listen {{ vhost }}
}
{% endfor %}
#生成的結果:
server {
	listen 81
}
server {
	listen 82
}
server {
	listen 83
}
           

if

在模版檔案中還可以使用if條件判斷,決定是否生成相關的配置資訊

範例:

#temnginx4.yml
- hosts: websrvs
  remote_user: root
  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.conf.j4 dest=/etc/nginx/nginx.conf


#templates/nginx.conf4.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 %}

#生成的結果
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/
}
           

when

playbook使用 when

when語句,可以實作條件測試。如果需要根據變量、facts或此前任務的執行結果來做為某task執行與

否的前提時要用到條件測試,通過在task後添加when子句即可使用條件測試,jinja2的文法格式

範例:

---
- hosts: websrvs
  remote_user: root
  tasks:
	- name: "shutdown RedHat flavored systems"
	  command: /sbin/shutdown -h now
	  when: ansible_os_family == "RedHat"
           

範例:

---
- hosts: websrvs
  remote_user: root
  tasks:
	- name: install conf file to centos7
	  template: src=nginx.conf.c7.j2 dest=/etc/nginx/nginx.conf
	  when: ansible_distribution_major_version == "7"
    - name: install conf file to centos8
	  template: src=nginx.conf.c8.j2 dest=/etc/nginx/nginx.conf
	  when: ansible_distribution_major_version == "8"
           

with_items

playbook 使用疊代 with_items

疊代:當有需要重複性執行的任務時,可以使用疊代機制

對疊代項的引用,固定變量名為”item“

要在task中使用with_items給定要疊代的元素清單

清單元素格式:

字元串

字典

範例:

---
- hosts: websrvs
  remote_user: root
  tasks:
	- name: add several users
	  user: name={{ item }} state=present groups=wheel
	  with_items:
 		- testuser1
		- testuser2
#上面語句的功能等同于下面的語句
- name: add user testuser1
	user: name=testuser1 state=present groups=wheel
- name: add user testuser2
	user: name=testuser2 state=present groups=wheel
           

範例:

---
#remove mariadb server
- hosts: appsrvs:!192.168.38.8
  remote_user: root
  tasks:
	- name: stop service
	  shell: /etc/init.d/mysqld stop
	- name: delete files and dir
	  file: path={{item}} state=absent
	  with_items:
		- /usr/local/mysql
		- /usr/local/mariadb-10.2.27-linux-x86_64
		- /etc/init.d/mysqld
		- /etc/profile.d/mysql.sh
		- /etc/my.cnf
		- /data/mysql
  - name: delete user
	user: name=mysql state=absent remove=yes
           

疊代嵌套子變量:在疊代中,還可以嵌套子變量,關聯多個變量在一起使用

示例:

---
- hosts: websrvs
  remote_user: root
  tasks:
	- name: add some groups
	  group: name={{ item }} state=present
	  with_items:
	  - nginx
	  - mysql
	  - apache
  - name: add some users
    user: name={{ item.name }} group={{ item.group }} state=present
	with_items:
	  - { name: 'nginx', group: 'nginx' }
	  - { name: 'mysql', group: 'mysql' }
	  - { name: 'apache', group: 'apache' }
           

模闆實驗二

實驗二準備

準備一台 CentOS7伺服器,安裝好 ansible,并配置一台被遠端管理的伺服器.前提關閉防火牆和selinux。

這裡用到centos7 absible1主機作為ansible機器。IP:192.168.32.7

被控制機器為centos8 ansible2 主機。IP:192.168.32.8

被控制機器為centos6 ansible3 主機。IP:192.168.32.6

[[email protected] ~]#
[[email protected] ~]#ansible --version
ansible 2.9.1
  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, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
[[email protected] ~]#ansible all -m ping 
192.168.32.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.32.6 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[[email protected] ~]#

           

playbook 使用條件判斷 when

編寫一個 install_server.yml 的 playbook 實作根據不同的 CentOS 版本,安裝不同的軟體

[[email protected] ~]#
[[email protected] ~]#cd /data/ansible/
[[email protected] ansible]#vim install_server.yml
[[email protected] ansible]#cat install_server.yml 
---
- hosts: all
  remote_user: root

  tasks: 
    - name: install nginx server in centos 6
      yum: name=nginx state=present
      when: ansible_distribution_major_version=="6"

    - name: install mariadb server in centos 8
      yum: name=mariadb-server state=present
      when: ansible_distribution_major_version=="8"


[[email protected] ansible]#
[[email protected] ansible]#ansible-playbook -C install_server.yml 

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

TASK [Gathering Facts] ********************************************************************************************
ok: [192.168.32.6]
ok: [192.168.32.8]

TASK [install nginx server in centos 6] ***************************************************************************
skipping: [192.168.32.8]
changed: [192.168.32.6]

TASK [install mariadb server in centos 8] *************************************************************************
skipping: [192.168.32.6]
changed: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.6               : ok=2    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
192.168.32.8               : ok=2    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[[email protected] ansible]#ansible-playbook  install_server.yml 

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

TASK [Gathering Facts] ********************************************************************************************
ok: [192.168.32.6]
ok: [192.168.32.8]

TASK [install nginx server in centos 6] ***************************************************************************
skipping: [192.168.32.8]
changed: [192.168.32.6]

TASK [install mariadb server in centos 8] *************************************************************************
skipping: [192.168.32.6]
changed: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.6               : ok=2    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
192.168.32.8               : ok=2    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[[email protected] ansible]#ansible 192.168.32.6 -m shell -a "yum install nginx"
[WARNING]: Consider using the yum module rather than running 'yum'.  If you need to use command because yum is
insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get
rid of this message.

192.168.32.6 | CHANGED | rc=0 >>
Loaded plugins: fastestmirror, refresh-packagekit, security
Setting up Install Process
Loading mirror speeds from cached hostfile
Package nginx-1.10.3-1.el6.x86_64 already installed and latest version
Nothing to do

[[email protected] ansible]#ansible 192.168.32.8 -m shell -a "yum install mariadb-server"
[WARNING]: Consider using the yum module rather than running 'yum'.  If you need to use command because yum is
insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get
rid of this message.

192.168.32.8 | CHANGED | rc=0 >>
Last metadata expiration check: 0:35:46 ago on Fri 06 Dec 2019 09:19:23 PM CST.
Package mariadb-server-3:10.3.11-2.module_el8.0.0+35+6f2527ed.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!

[[email protected] ansible]#

           

playbook 使用循環 with_items

使用循環結構多次執行同一個 task 任務

[[email protected] ansible]#vim adduser.yml 

[[email protected] ansible]#cat adduser.yml
---
- hosts: 192.168.32.8
  remote_user: root

  tasks: 
    - name: add some group
      group: name={{ item }} state=present
      with_items:
        - mysql1
        - nginx1
        - likai1

    - name: add some user
      user: name={{ item.username }} group={{ item.usergroup }} state=present
      with_items:
        - {username: "mysql",   usergroup: "mysql1"}
        - {username: "nginx",   usergroup: "nginx1"}
        - {username: "duanxin", usergroup: "likai1"}

[[email protected] ansible]#
[[email protected] ansible]#ansible-playbook -C adduser.yml 

PLAY [192.168.32.8] ***********************************************************************************************

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

TASK [add some group] *********************************************************************************************
changed: [192.168.32.8] => (item=mysql1)
changed: [192.168.32.8] => (item=nginx1)
changed: [192.168.32.8] => (item=likai1)

TASK [add some user] **********************************************************************************************
failed: [192.168.32.8] (item={u'username': u'mysql', u'usergroup': u'mysql1'}) => {"ansible_loop_var": "item", 
"changed": false, "item": {"usergroup": "mysql1", "username": "mysql"}, "msg": "Group mysql1 does not exist"}
failed: [192.168.32.8] (item={u'username': u'nginx', u'usergroup': u'nginx1'}) => {"ansible_loop_var": "item",
 "changed": false, "item": {"usergroup": "nginx1", "username": "nginx"}, "msg": "Group nginx1 does not exist"}
failed: [192.168.32.8] (item={u'username': u'duanxin', u'usergroup': u'likai1'}) => {"ansible_loop_var": "item", 
"changed": false, "item": {"usergroup": "likai1", "username": "duanxin"}, "msg": "Group likai1 does not exist"}


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

#這裡報錯的原因是由于隻是檢測文法和運作,實際上并沒有真正執行,也是就是這個組還沒有建立。
[[email protected] ansible]#ansible-playbook  adduser.yml 

PLAY [192.168.32.8] ***********************************************************************************************

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

TASK [add some group] *********************************************************************************************
changed: [192.168.32.8] => (item=mysql1)
changed: [192.168.32.8] => (item=nginx1)
changed: [192.168.32.8] => (item=likai1)

TASK [add some user] **********************************************************************************************
changed: [192.168.32.8] => (item={u'username': u'mysql', u'usergroup': u'mysql1'})
changed: [192.168.32.8] => (item={u'username': u'nginx', u'usergroup': u'nginx1'})
changed: [192.168.32.8] => (item={u'username': u'duanxin', u'usergroup': u'likai1'})

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

[[email protected] ansible]#ansible 192.168.32.8 -m shell -a "cat /etc/passwd |tail -5"
192.168.32.8 | CHANGED | rc=0 >>
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
nginx:x:977:1003:Nginx web server:/var/lib/nginx:/sbin/nologin
duanxin:x:1001:1004::/home/duanxin:/bin/bash
likai:x:1002:1001::/home/likai:/bin/bash
mysql:x:27:1002:MySQL Server:/var/lib/mysql:/sbin/nologin

           

playbook 使用 templates 模闆

[[email protected] ansible]#cat /etc/ansible/hosts |grep -Ev "^#|^$"
[appsrvs]
192.168.32.8 
192.168.32.6
[[email protected] ansible]#vim httpd-install.yml

[[email protected] ansible]#cat httpd-install.yml 
---
- hosts: 192.168.32.8
  remote_user: root

  tasks: 
    - name: install httpd
      yum: name=httpd
    - name: config httpd service
      template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf 
      notify: restart httpd service

    - name: copy default index.html
      copy: src=/data/ansible/index.html dest=/usr/share/httpd/noindex/index.html

    - name: manage httpd service
      service: name=httpd state=started enabled=yes

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

[[email protected] ansible]#

[[email protected] ansible]#vim index.html 

[[email protected] ansible]#cat index.html 
<h1>I'am kaivi , who are you ? </h1>

[[email protected] ansible]#
[[email protected] ansible]#mkdir -pv templates
mkdir: created directory ‘templates’
[[email protected] ansible]#ll
total 7
-rw-r--r-- 1 root root 503 Dec  7 09:43 httpd-install.yml
-rw-r--r-- 1 root root  38 Dec  7 09:45 index.html
drwxr-xr-x 2 root root   6 Dec  7 09:46 template

[[email protected] ~]#cp -p /etc/httpd/conf/httpd.conf /data/ansible/templates/
#在已經有http的機器上面拷貝模闆檔案
[[email protected] ansible]#cd templates/
[[email protected] templates]#mv httpd.conf httpd.conf.j2   #修改名稱和劇本對應

[[email protected] templates]#vim httpd.conf.j2 

[[email protected] templates]#cat httpd.conf.j2 |grep "Listen"
# Listen: Allows you to bind Apache to specific IP addresses and/or
# Change this to Listen on specific IP addresses as shown below to 
#Listen 12.34.56.78:80
#Listen 80
Listen 9527    #把預設端口80改為端口9527

[[email protected] templates]#cd ../  #傳回上一級目錄

[[email protected] ansible]#ansible-playbook -C httpd-install.yml 

PLAY [192.168.32.8] ***********************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
^C [ERROR]: User interrupted execution

[[email protected] ansible]#ansible-playbook -C httpd-install.yml    #文法檢測

PLAY [192.168.32.8] ***********************************************************************************************

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

TASK [install httpd] **********************************************************************************************
changed: [192.168.32.8]

TASK [config httpd service] ***************************************************************************************
changed: [192.168.32.8]

TASK [copy default index.html] ************************************************************************************
changed: [192.168.32.8]

TASK [manage httpd service] ***************************************************************************************
changed: [192.168.32.8]

RUNNING HANDLER [restart httpd service] ***************************************************************************
changed: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.8               : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


[[email protected] ansible]#ansible-playbook  httpd-install.yml 

PLAY [192.168.32.8] ***********************************************************************************************

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

TASK [install httpd] **********************************************************************************************
changed: [192.168.32.8]

TASK [config httpd service] ***************************************************************************************
changed: [192.168.32.8]

TASK [copy default index.html] ************************************************************************************
changed: [192.168.32.8]

TASK [manage httpd service] ***************************************************************************************
changed: [192.168.32.8]

RUNNING HANDLER [restart httpd service] ***************************************************************************
changed: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.8               : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[[email protected] ansible]#ansible 192.168.32.8 -a "ss -ntl"
192.168.32.8 | CHANGED | rc=0 >>
State    Recv-Q    Send-Q        Local Address:Port        Peer Address:Port    
LISTEN   0         32            192.168.122.1:53               0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:22               0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:9527             0.0.0.0:* 

           

通路下網頁看看是否成功:

Ansible playbook 進階文法

變量運算

變量除了可以直接引用外,還可以進行變量運算

[[email protected] ansible]#cat /etc/ansible/hosts |grep -Ev "^#|^$"
[appsrvs]
192.168.32.8 
192.168.32.6
[[email protected] ansible]#vim /etc/ansible/hosts 
[[email protected] ansible]#cat /etc/ansible/hosts |grep -Ev "^#|^$"
[appsrvs]
192.168.32.8  httpd_port=77 
[[email protected] ansible]#
[[email protected] ansible]#vim templates/httpd.conf.j2 
[[email protected] ansible]#cat templates/httpd.conf.j2 |grep "Listen"
# Listen: Allows you to bind Apache to specific IP addresses and/or
# Change this to Listen on specific IP addresses as shown below to 
#Listen 12.34.56.78:80
#Listen 80
#Listen 9527
Listen {{httpd_port*2}}
[[email protected] ansible]#
[[email protected] ansible]#ansible-playbook -C httpd-install.yml 

PLAY [192.168.32.8] ***********************************************************************************************

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

TASK [install httpd] **********************************************************************************************
changed: [192.168.32.8]

TASK [config httpd service] ***************************************************************************************
changed: [192.168.32.8]

TASK [copy default index.html] ************************************************************************************
changed: [192.168.32.8]

TASK [manage httpd service] ***************************************************************************************
changed: [192.168.32.8]

RUNNING HANDLER [restart httpd service] ***************************************************************************
changed: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.8               : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[[email protected] ansible]#ansible-playbook httpd-install.yml 

PLAY [192.168.32.8] ***********************************************************************************************

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

TASK [install httpd] **********************************************************************************************
changed: [192.168.32.8]

TASK [config httpd service] ***************************************************************************************
changed: [192.168.32.8]

TASK [copy default index.html] ************************************************************************************
changed: [192.168.32.8]

TASK [manage httpd service] ***************************************************************************************
changed: [192.168.32.8]

RUNNING HANDLER [restart httpd service] ***************************************************************************
changed: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.8               : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[[email protected] ansible]#ansible 192.168.32.8 -a "ss -ntl"
192.168.32.8 | CHANGED | rc=0 >>
State    Recv-Q    Send-Q        Local Address:Port        Peer Address:Port    
LISTEN   0         32            192.168.122.1:53               0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:22               0.0.0.0:*       
LISTEN   0         5                 127.0.0.1:631              0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:154              0.0.0.0:*       

           

通路下網頁看看是否成功:

Ansible playbook 進階文法

循環結構動态

模闆中還可以使用循環結構動态生成内容:

[[email protected] ansible]#vim /etc/ansible/hosts

[[email protected] ansible]#cat /etc/ansible/hosts |grep -Ev "^#|^$"
[appsrvs]
192.168.32.8 

[[email protected] ansible]#vim httpd-install.yml 
---
- hosts: 192.168.32.8
  remote_user: root
  vars:
    httpd_vhosts:
      - web01:
        listen: 8080
        documentroot: '/data/web01'

      - web02:
        listen: 9527
        documentroot: '/data/web02'  
 
#  tasks: 
#    - name: install httpd
#      yum: name=httpd
#    - name: config httpd service
#      template: src=vhostport.conf.j2 dest=/etc/httpd/conf.d/vhostport.conf
#      notify: restart httpd service
#
#    - name: copy default index.html
#      copy: src=/data/ansible/index.html dest=/usr/share/httpd/noindex/index.html
#
#    - name: manage httpd service
#      service: name=httpd state=started enabled=yes
#
#  handlers: i
#    - name: restart httpd service
#      service: name=httpd state=restarted

  tasks:
    - name: install httpd 
      yum: name=httpd

    - name: config httpd serivce
      template: src=vhostport.conf.j2 dest=/etc/httpd/conf.d/vhostport.conf
      notify: restart httpd service

    - name: copy default index.html
      copy: src=/data/ansible/index.html dest=/usr/share/httpd/noindex/index.html

    - name: manage httpd service
      service: name=httpd state=started enabled=yes

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


[[email protected] ansible]#vim vhostport.conf.j2 

[[email protected] ansible]#cat vhostport.conf.j2 
{% for vhost in httpd_vhosts %}
listen {{vhost.listen}}
{% endfor %}


{% for vhost in httpd_vhosts %}
<virtualhost *:{{vhost.listen}}>
	documentroot {{vhost.documentroot}}
	<directory {vhost.documentroot}>
		require all granted
	</directory>
</virtualhost>
{% endfor %}

[[email protected] ansible]#vim index.html
[[email protected] ansible]#cat index.html 
<h1>I am kaivi , who are you ? </h1>

<h1> 模闆中使用循環結構動态生成内容測試 </h1>

[[email protected] ansible]#ansible-playbook -C httpd-install.yml 

PLAY [192.168.32.8] ***********************************************************************************************

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

TASK [install httpd] **********************************************************************************************
ok: [192.168.32.8]

TASK [config httpd serivce] ***************************************************************************************
ok: [192.168.32.8]

TASK [copy default index.html] ************************************************************************************
ok: [192.168.32.8]

TASK [manage httpd service] ***************************************************************************************
ok: [192.168.32.8]

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


[[email protected] ansible]#ansible-playbook  httpd-install.yml 

PLAY [192.168.32.8] ***********************************************************************************************

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

TASK [install httpd] **********************************************************************************************
ok: [192.168.32.8]

TASK [config httpd serivce] ***************************************************************************************
changed: [192.168.32.8]

TASK [copy default index.html] ************************************************************************************
ok: [192.168.32.8]

TASK [manage httpd service] ***************************************************************************************
changed: [192.168.32.8]

RUNNING HANDLER [restart httpd service] ***************************************************************************
changed: [192.168.32.8]

PLAY RECAP ********************************************************************************************************
192.168.32.8               : ok=6    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

#檢視預設端口80 指定端口8080 9527是否全部打開
[[email protected] ansible]#ansible 192.168.32.8 -a "ss -ntl"
192.168.32.8 | CHANGED | rc=0 >>
State    Recv-Q    Send-Q        Local Address:Port        Peer Address:Port    
LISTEN   0         32            192.168.122.1:53               0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:22               0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:9527             0.0.0.0:*       
LISTEN   0         5                 127.0.0.1:631              0.0.0.0:*       
LISTEN   0         128               127.0.0.1:6010             0.0.0.0:*       
LISTEN   0         128               127.0.0.1:6011             0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:45475            0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:111              0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:8080             0.0.0.0:*       
LISTEN   0         128                 0.0.0.0:80               0.0.0.0:*       

[[email protected] ansible]#curl 192.168.32.8
<h1>I am kaivi , who are you ? </h1>

<h1> 模闆中使用循環結構動态生成内容測試 </h1>

[[email protected] ansible]#curl 192.168.32.8:9527
<h1>I am kaivi , who are you ? </h1>

<h1> 模闆中使用循環結構動态生成内容測試 </h1>

[[email protected] ansible]#curl 192.168.32.8:8080
<h1>I'am kaivi , who are you ? </h1>

<h1> 模闆中使用循環結構動态生成内容測試 </h1>

[[email protected] ansible]#
[[email protected] ansible]#

           

通路下網頁看看是否成功:

Ansible playbook 進階文法
Ansible playbook 進階文法
Ansible playbook 進階文法