自動化運維工具-----Ansible playbook詳解

目錄

一.Ansible playbook簡介

二.Ansible playbook使用場景

三.Ansible playbook格式

格式簡介

核心元素

基本組件

variables變量

模板templates

條件測試

字典

角色定製


一.Ansible playbook簡介

  • playbook是ansible用於配置,部署,和管理被節點的劇本
  • 通過playbook的詳細描述,執行其中的一些列tasks,可以讓遠端的主機達到預期的狀態。playbook就像ansible控制器給被控節點列出的一系列to-do-list,而且被控節點必須要完成
  • playbook顧名思義,即劇本,現實生活中演員按照劇本表演,在ansible中,這次由被控計算機表演,進行安裝,部署應用,提供對外的服務等,以及組織計算機處理各種各樣的事情。

二.Ansible playbook使用場景

  • 執行一些簡單的任務,使用ad-hoc命令可以方便的解決問題,但是有時一個設施過於複雜,需要大量的操作的時候,執行的ad-hoc命令是不合適的,這時候最好使用playbook。
  • 就像執行shell命令與寫shell腳本一樣,也可以理解爲批處理任務,不過playbook有自己的語法格式
  • 使用playbook可以方便的重複使用這些代碼,可以移植到不同的機器上面,像函數一樣,最大化的利用代碼。在你使用Ansible的過程中,你也會發現,你所處理的大部分操作都是編寫playbook。可以把常見的應用都編寫playbook,之後管理服務器會變得很簡單。

三.Ansible playbook格式

格式簡介

  • playbook由YAML語言編寫。
  • YAML( /ˈjæməl/ )參考了其他多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822,Clark Evans在2001年5月在首次發表了這種語言,另外Ingy döt Net與OrenBen-Kiki也是這語言的共同設計者。
  • YAML格式是類似JSON的文件格式。YAML用於文件的配置編寫,JSON多用於開發設計。
  • YAML的格式如下:

1.文件的第一行應該以“---”(三個連字符)開始,表明YAML文件的開始。

2.在同一行中,#之後的內容表示註釋,類似於shell,python和ruby。

3.YAML中的列表元素以“-”開頭並且跟着一個空格。後面爲元素內容。

4.同一個列表之中的元素應該保持相同的縮進,否則會被當做錯誤處理。

5.play中hosts、variables、roles、tasks等對象的表示方法都是以鍵值中間以“:”分隔表示,並且“:”之後要加一個空格。

  • 安裝並且運行mysql服務,實例如下:

---
- hosts: node1
  remote_user: root
  tasks:

    - name: install mysql-server package
      yum: name=mysql-server state=present
    - name: starting mysqld service
      service: name=msyql state=started

以上面爲例,文件名應該以 .yml 結尾

host部分:使用hosts指示使用哪個主機或者主機組來運行下面的tasks,每個playbooks都必須指定hosts,host也可以使用通配符格式。主機或者主機組在inventorry清單中指定,可以使用系統默認的/etc/ansible/hosts,也可以自己編輯,在運行的時候加上-i 選項指定清單的位置。在運行清單文件的時候, --list-hosts選項會顯示哪些主機將會參與執行task的過程中。

remote_user:指定遠端主機的哪個用戶來登錄遠端系統,在遠端系統執行task的用戶,可以任意指定,也可以使用sudo,但是用戶必須要有執行相應的task權限。

tasks:指定遠端主機將要執行的一系列動作。tasks的核心爲ansible的模塊,前面已經提到模塊的用法,tasks包含name和要執行的模塊,name是可選的,只是爲了便於用戶閱讀,模塊是必須的,同時也要給予模塊相應的參數

  • 使用ansible-playbook運行playbook文件,得到的輸出信息中,信息內容爲JSON格式,並且由不同的顏色組成,便於識別。

  • 綠色代表執行成功,系統保持原樣。黃色代表系統狀態發生改變。紅色代表執行失敗,顯示錯誤輸出。

核心元素

  • Hosts:主機組
  • Tasks:任務列表
  • Variables:變量,設置方式有四種
  • Templates:包含了模塊語法的文本文件
  • Handlers:由特定條件觸發的任務。

基本組件

  • playbooks配置文件的基礎組件
Hosts:運行指定任務的目標主機
remoute_user:在遠程主機上執行任務的用戶;
sudo_user:
tasks:任務列表

tasks的具體格式:

tasks:
  - name: TASK_NAME
    module: arguments
    notify: HANDLER_NAME
    handlers:
  - name: HANDLER_NAME
    module: arguments

##模塊,模塊參數:
格式如下:
    (1)action: module arguments
     (2) module: arguments
注意:shell和command模塊後直接加命令,而不是key=value類的參數列表


handlers:任務,在特定條件下觸發;接受到其他任務的通知時被觸發;
  • 在某個任務的狀態在運行之後爲changed時,可以通過“notify”通知相應的handlers;

  • 任務可以通過“tags”打標籤,而後可以在ansible-playbook命令上使用-t指定進行調用;

定義一個安裝nginx的playbook

  • 定義playbook

[root@ansible ~]# cd /etc/ansible/
[root@ansible ansible]# ls
ansible.cfg  hosts  nginx.yml  roles
[root@ansible ansible]# cat nginx.yml 
---
- hosts: web
  remote_user: root
  tasks:
  
    - name: install nginx        ##安裝模塊,需要在被控主機里加上nginx的源
      yum: name=nginx state=present
    - name: copy nginx.conf    ##複製nginx的配置文件過去,需要在本機的/tmp目錄下編輯nginx.conf
      copy: src=/tmp/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
      notify: reload    #當nginx.conf發生改變時,通知給相應的handlers
      tags: reloadnginx    #打標籤
    - name: start nginx service    #服務啓動模塊
      service: name=nginx state=started
      tags: startnginx    #打標籤

  handlers:
    - name: reload
      service: name=nginx state=restarted
[root@ansible ansible]# 
  • 測試運行結果

[root@ansible ansible]# ansible-playbook nginx.yml 

PLAY [web] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.43.110]
ok: [192.168.43.109]

TASK [install nginx] ***********************************************************
changed: [192.168.43.109]
changed: [192.168.43.110]

TASK [copy nginx.conf] *********************************************************
ok: [192.168.43.110]
ok: [192.168.43.109]

TASK [start nginx service] *****************************************************
changed: [192.168.43.110]
changed: [192.168.43.109]

PLAY RECAP *********************************************************************
192.168.43.109             : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.43.110             : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

##查看被控主機上的nginx服務
[root@ansible ansible]# ansible web -m shell -a 'netstat -natp | grep nginx'
192.168.43.110 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      2720/nginx: master  
192.168.43.109 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      2776/nginx: master  
[root@ansible ansible]# 
  • 測試標籤,我們在nginx.yml中已經打了標籤,所以可以直接應用標籤,但是需要先將服務關閉,在運行劇本並且引用標籤

#關閉被控節點的nginx服務
[root@ansible ansible]# 
[root@ansible ansible]# ansible web -m shell -a 'systemctl stop nginx'
192.168.43.110 | CHANGED | rc=0 >>

192.168.43.109 | CHANGED | rc=0 >>



#重新加載劇本並且應用標籤
[root@ansible ansible]# ansible-playbook nginx.yml -t startnginx

PLAY [web] ************************************************************************

TASK [Gathering Facts] ************************************************************
ok: [192.168.43.109]
ok: [192.168.43.110]

TASK [start nginx service] ********************************************************
changed: [192.168.43.109]
changed: [192.168.43.110]

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

[root@ansible ansible]# 


  • 測試notify,在nginx.yml中做了一個notify,當配置文件改變時,條件就被戳發,我們修改一下/tem/nginx.conf的監聽端口

##使用reloadnginx標籤,重新加載劇本
[root@ansible ansible]# ansible-playbook nginx.yml -t reloadnginx

PLAY [web] **************************************************************************************************

TASK [Gathering Facts] **************************************************************************************
ok: [192.168.43.109]
ok: [192.168.43.110]

TASK [copy nginx.conf] **************************************************************************************
changed: [192.168.43.109]
changed: [192.168.43.110]

RUNNING HANDLER [reload] ************************************************************************************
changed: [192.168.43.110]
changed: [192.168.43.109]

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

[root@ansible ansible]# ansible web -m shell -a 'netstat -natp | grep nginx'
192.168.43.109 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      38417/nginx: master 
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      38417/nginx: master 
192.168.43.110 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      38281/nginx: master 
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      38281/nginx: master 
[root@ansible ansible]# 

variables變量

  • variables變量有四種定義方法。如下:

facts:可以直接調用

  • ansible中有setup模塊,這個模塊就是通過facts組件來實現的。這裏的variables也可以直接調用facts組件的facters我們可以使用setup模塊來獲取,然後直接放入我們的劇本之中調用即可

用戶自定義變量

  • 自定義變量有兩種方式
  • 通過命令行傳入
ansible-playbook命令行中的 -e VARS,--extra-vars=VARS,這樣就可以直接把自定義的變量傳入
  • 在playbook中定義變量
##在playbook中定義變量如下:
vars:
  - var1: value1
  -- var2: value2

​​​​​​​使用playbook定義變量,實例如下

  • 定義劇本,將ngixn替換成變量
[root@ansible ansible]# ls
ansible.cfg  hosts  nginx.yml  roles
[root@ansible ansible]# cat nginx.yml 
---
- hosts: web
  remote_user: root
  tasks:
  
    - name: install {{ rpmname }}
      yum: name={{ rpmname }} state=present
    - name: copy {{ rpmname }}.conf
      copy: src=/tmp/{{ rpmname }}.conf dest=/etc/{{ rpmname }}/{{ rpmname }}.conf backup=yes
      notify: reload
      tags: reload{{ rpmname }}
    - name: start {{ rpmname }} service
      service: name={{ rpmname }} state=started
      tags: start{{ rpmname }}

  handlers:
    - name: reload
      service: name={{ rpmname }} state=restarted
[root@ansible ansible]# 
  • 拷貝配置文件
#因爲我們要安裝keepalived服務,所以將keepalived的配置文件拷貝到/tmp目錄下
#可以在本機上下載keepalived服務

[root@server ansible]# cp /etc/keepalived/keepalived.conf /tmp/keepalived.conf
  • 運行劇本,變量有命令行傳入
[root@ansible ansible]# ls
ansible.cfg  hosts  nginx.yml  roles

##-e表示編輯yml內部變量
[root@ansible ansible]# ansible-playbook nginx.yml -e rpmname=keepalived

PLAY [web] ************************************************************************

TASK [Gathering Facts] ************************************************************
ok: [192.168.43.110]
ok: [192.168.43.109]

TASK [install keepalived] *********************************************************
changed: [192.168.43.109]
changed: [192.168.43.110]

TASK [copy keepalived.conf] *******************************************************
ok: [192.168.43.109]
ok: [192.168.43.110]

TASK [start keepalived service] ***************************************************
changed: [192.168.43.110]
changed: [192.168.43.109]

PLAY RECAP ************************************************************************
192.168.43.109             : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.43.110             : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible ansible]# 
  • 修改劇本直接定義變量,同樣我們可以直接在劇本中定義好變量,這樣就不需要再通過命令行傳入。以後想要俺咋混給不同的服務,直接在劇本內部修改變量即可

  • 運行定義過變量的劇本

通過roles傳遞變量

  • 當說到roles時具體說明

Host Inventory

  • 我們也可以在主機清單中定義,方法如下:
#向不同的主機傳遞不同的變量
IP/HOSTNAME varaiable=value var2=value2

#向組中的主機傳遞相同的變量
[groupname:vars]
variable=value

模板templates

  • 模板是一個文本文件,嵌套有腳本(使用模板編程語言編寫)
  • Jinja2是python的一種模板語言,以Django的模板語言爲原本
  • 該模板支持:

 字符串:使用單引號或雙引號;
  數字:整數,浮點數;
  列表:[item1, item2, ...]
  元組:(item1, item2, ...)
  字典:{key1:value1, key2:value2, ...}
  布爾型:true/false
  算術運算:
    +, -, *, /, //, %, **
  比較操作:
    ==, !=, >, >=, <, <=
  邏輯運算:
    and, or, not

  • 通常模板都是通過引用變量來運用的

實例如下

  • 定義模板
[root@ansible ansible]# mv /tmp/nginx.conf /tmp/nginx.conf.j2
[root@ansible ansible]# vi /tmp/nginx.conf.j2 
ddworker_processes {{ ansible_processor_vcpus }};
listen {{ nginxport }};

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
server {

listen 8888;
}
  • 修改劇本,如下兩個地方

  • 運行劇本
[root@ansible ansible]# ansible-playbook nginx.yml -t reloadnginx

PLAY [web] ***********************************************************************************

TASK [Gathering Facts] ***********************************************************************
ok: [192.168.43.109]
ok: [192.168.43.110]

TASK [copy nginx.conf] ***********************************************************************
ok: [192.168.43.109]
ok: [192.168.43.110]

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

[root@ansible ansible]# 

條件測試

  • when語句:在task中使用,jinja2的語法格式
tasks:
- name: install conf file to centos7
  template: src=files/nginx.conf.c7.j2
  when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
  template: src=files/nginx.conf.c6.j2
  when: ansible_distribution_major_version == "6"
  • 循環:迭代,需要重複執行的任務,對於迭代項的引用,固定變量名爲“item”,而後在task中使用with_items給定的迭代的元素列表
tasks:
- name: unstall web packages
  yum: name={{ item }} state=absent
  with_items:
  - httpd
  - php
  - php-mysql

字典

  • ansible playbook也支持字典功能,舉例如下:
- name: install some packages
  yum: name={{ item }} state=present
  with_items:
    - nginx
    - memcached
    - php-fpm
- name: add some groups
  group: name={{ item }} state=present
  with_items:
    - group11
    - group12
    - group13
- name: add some users
  user: name={{ item.name }} group={{ item.group }} state=present
  with_items:
    - { name: 'user11', group: 'group11' }
    - { name: 'user12', group: 'group12' }
    - { name: 'user13', group: 'group13' }

角色定製

簡介

  • 對於以上所有方式有個缺點就是無法實現同時部署web、database、keepalived等不同服務或者不同服務器組合不同的應用就需要寫多個yaml文件,很難實現靈活的調用
  • roles用於層次性,結構化地組織playbook。roles能夠根據層次結果自動裝載變量文件、tasks以及handlers等。
  • 要使用roles只需要在playbook中使用include指令即可。
  • 簡單來講,roles就是通過分別將變量(vars)、文件(files)、任務(tasks)、模塊(modules)以及處理器(handlers)放置於單獨的目錄中,並且可以便捷的include它們地一種機制。
  • 角色一般用於基於主機構建服務的場景中,但是也可以用於構建守護進程等場景中。

角色集合

​​​​​​​roles/

mysql/:mysql服務的yml文件

httpd/:apached服務的yml文件

nginx/:nginx服務的yml文件

files/:存儲由copy或者script等模塊調用的文件或者腳本;

tasks/:此目錄中至少應該有一個名爲main.yml的文件,用於定義各個task;其他文件需要由main.yml進行包含調用;

handlers/:此目錄中至少應該有一個名爲main.yml的文件,用於定義各個handler;其他文件需要由main.yml進行包含調用;

vars/:此目錄至少應該有一個名爲main,yml的文件,用於定義各個variable;其他的文件需要由main.yml進行包含調用;

templates/:存儲由templates模塊調用的模板文件;

meta/:此目錄中至少應該有一個名爲main.yml的文件,定義當前角色的特殊設定以及依賴關係,其他文件需要由main.yml進行包含調用;

default/:此目錄至少應該有一個名爲main.yml的文件,用於設定默認變量;

角色定製實例

  • 在roles目錄下生成對應的目錄結構
[root@ansible ansible]# ls
ansible.cfg  hosts  nginx.yml  roles
[root@ansible ansible]# cd roles/
[root@ansible roles]# ls
[root@ansible roles]# mkdir -pv ./{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default}
[root@ansible roles]# yum install tree -y &> /dev/null
[root@ansible roles]# tree 
.
├── httpd
│   ├── default
│   ├── files
│   ├── handlers
│   ├── meta
│   ├── tasks
│   ├── templates
│   └── vars
├── mysql
│   ├── default
│   ├── files
│   ├── handlers
│   ├── meta
│   ├── tasks
│   ├── templates
│   └── vars
└── nginx
    ├── default
    ├── files
    ├── handlers
    ├── meta
    ├── tasks
    ├── templates
    └── vars

24 directories, 0 files
[root@ansible roles]# 
  • 定義配置文件
[root@ansible nginx]# pwd
/etc/ansible/roles/nginx
[root@ansible nginx]# ls
default  files  handlers  meta  tasks  templates  vars
[root@ansible nginx]# ls tasks/
main.yml
[root@ansible nginx]# cat tasks/main.yml 
- name: cp
  copy: src=nginx-1.18.0-1.el7.ngx.x86_64.rpm dest=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm
- name: install
  yum: name=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm state=latest
- name: conf
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  tags: nginxconf
  notify: new conf to reload
- name: start service
  service: name=nginx state=started enabled=true
[root@ansible nginx]# 
  • 放置需要的文件到指定目錄下

[root@ansible ]# cp /var/cache/yum/x86_64/7/nginx/packages/nginx-1.18.0-1.el7.ngx.x86_64.rpm /etc/ansible/roles/nginx/files/
[root@ansible ]# cp /tmp/nginx.conf.j2 /etc/ansible/roles//nginx/templates/
[root@ansible nginx]# tree
.
├── default
├── files
│   └── nginx-1.18.0-1.el7.ngx.x86_64.rpm
├── handlers
├── meta
├── tasks
│   └── main.yml
├── templates
│   └── nginx.conf.j2
└── vars

7 directories, 3 files
[root@ansible nginx]# 
  • 修改變量文件
[root@ansible nginx]# ls
default  files  handlers  meta  tasks  templates  vars
[root@ansible nginx]# cat vars/main.yml 
nginxport: 9999
[root@ansible nginx]# 
  • 定義handlers文件
[root@ansible nginx]# cat handlers/main.yml 
- name: new conf to reload
  service: name=nginx state=restarted
[root@ansible nginx]# 
  • 定義劇本文件
[root@ansible ansible]# pwd
/etc/ansible
[root@ansible ansible]# cat roles.yml 
- hosts: web
  remote_user: root
  roles:
    - nginx
[root@ansible ansible]# 
  • 啓動服務
[root@ansible ansible]# ansible-playbook roles.yml 

PLAY [web] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.43.110]
ok: [192.168.43.109]

TASK [nginx : cp] **************************************************************
changed: [192.168.43.110]
changed: [192.168.43.109]

TASK [nginx : install] *********************************************************
ok: [192.168.43.110]
ok: [192.168.43.109]

TASK [nginx : conf] ************************************************************
changed: [192.168.43.110]
changed: [192.168.43.109]

TASK [nginx : start service] ***************************************************
changed: [192.168.43.109]
changed: [192.168.43.110]

RUNNING HANDLER [nginx : new conf to reload] ***********************************
changed: [192.168.43.110]
changed: [192.168.43.109]

PLAY RECAP *********************************************************************
192.168.43.109             : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.43.110             : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible ansible]# ansible web -m shell -a 'netstat -natp | grep nginx'
192.168.43.110 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:9999            0.0.0.0:*               LISTEN      43345/nginx: master 
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      43345/nginx: master 
192.168.43.109 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:9999            0.0.0.0:*               LISTEN      46442/nginx: master 
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      46442/nginx: master 
[root@ansible ansible]# 
[root@ansible nginx]# pwd
/etc/ansible/roles/nginx
[root@ansible nginx]# tree
.
├── default
├── files
│   └── nginx-1.18.0-1.el7.ngx.x86_64.rpm
├── handlers
│   └── main.yml
├── meta
├── tasks
│   └── main.yml
├── templates
│   └── nginx.conf.j2
└── vars
    └── main.yml

7 directories, 5 files
[root@ansible nginx]# cat handlers/main.yml 
- name: new conf to reload
  service: name=nginx state=restarted
[root@ansible nginx]# cat tasks/main.yml 
- name: cp
  copy: src=nginx-1.18.0-1.el7.ngx.x86_64.rpm dest=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm
- name: install
  yum: name=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm state=latest
- name: conf
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  tags: nginxconf
  notify: new conf to reload
- name: start service
  service: name=nginx state=started enabled=true
[root@ansible nginx]# cat templates/nginx.conf.j2 

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
server {

listen  {{ nginxport }};
}

    include /etc/nginx/conf.d/*.conf;
}
[root@ansible nginx]# cat vars/main.yml 
nginxport: 9999
[root@ansible nginx]# 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章