運維自動化工具之Ansible

一、簡介

    ansible是新出現的自動化運維工具,基於Python開發,集合了衆多運維工具(puppet、cfengine、chef、func、fabric)的優點,實現了批量系統配置、批量程序部署、批量運行命令等功能。

ansible是基於模塊工作的,本身沒有批量部署的能力。真正具有批量部署的是ansible所運行的模塊,ansible只是提供一種框架。主要包括:

(1)、連接插件connection plugins:負責和被監控端實現通信;

(2)、host inventory:指定操作的主機,是一個配置文件裏面定義監控的主機;

(3)、各種模塊核心模塊、command模塊、自定義模塊;

(4)、藉助於插件完成記錄日誌郵件等功能;

(5)、playbook:劇本執行多個任務時,非必需可以讓節點一次性運行多個任務。

二、安裝Ansible

ansible依賴於Python 2.6或更高的版本、paramiko、PyYAML及Jinja2。所以,安裝ansible之前要先解決以上依賴關係。(http://www.rpmfind.net/)找到相應的版本下載之。

# yum install python-paramiko-1.7.5-2.1.el6.noarch.rpm PyYAML-3.10-3.1.el6.x86_64.rpm python-jinja2-26-2.6-3.el6.noarch.rpm
 python-crypto2.6-2.6.1-2.el6.x86_64.rpm python-babel-0.9.4-5.1.el6.noarch.rpm

2.1 編譯安裝

# yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
# tar xf ansible-1.5.4.tar.gz
# cd ansible-1.5.4
# python setup.py build
# python setup.py install
# mkdir /etc/ansible
# cp -r examples/* /etc/ansible

2.2 rpm包安裝

# yum install ansible-2.2.1.0-1.el6.noarch.rpm

  1. yum install http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm
    yum install anisble

注意:不同版本的ansible的功能差異可能較大。

三、簡單應用

ansible通過ssh實現配置管理、應用部署、任務執行等功能,因此,需要事先配置ansible端能基於密鑰認證的方式聯繫各被管理節點。

參考:配置Linux主機SSH無密碼訪問

ansible <host-pattern> [-f forks] [-m module_name] [-a args]

-m module:默認爲command

ansible-doc: Show Ansible module documentation

 -l, --list            List available modules

  -s, --snippet         Show playbook snippet for specified module(s)

四、YAML

4.1 YAML介紹

YAML是一個可讀性高的用來表達資料序列的格式。YAML參考了其他多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822等。Clark Evans在2001年在首次發表了這種語言,另外Ingy dt Net與Oren Ben-Kiki也是這語言的共同設計者。

YAML Ain't Markup Language,即YAML不是XML。不過,在開發的這種語言時,YAML的意思其實是:"Yet Another Markup Language"(仍是一種標記語言)。其特性:

YAML的可讀性好

YAML和腳本語言的交互性好

YAML使用實現語言的數據類型

YAML有一個一致的信息模型

YAML易於實現

YAML可以基於流來處理

YAML表達能力強,擴展性好

更多的內容及規範參見http://www.yaml.org。

4.2 YAML語法

YAML的語法和其他高階語言類似,並且可以簡單表達清單、散列表、標量等數據結構。其結構(Structure)通過空格來展示,序列(Sequence)裏的項用"-"來代表,Map裏的鍵值對用":"分隔。下面是一個示例。

name: John Smith

age: 41

gender: Male

spouse:

    name: Jane Smith

    age: 37

    gender: Female

children:

    -   name: Jimmy Smith

        age: 17

        gender: Male

    -   name: Jenny Smith

        age 13

        gender: Female

YAML文件擴展名通常爲.yaml,如example.yaml。

4.2.1 list

列表的所有元素均使用“-”打頭,例如:

# A list of tasty fruits

- Apple

- Orange

- Strawberry

- Mango

4.2.2 dictionary

字典通過key與valuef進行標識,例如:

---

# An employee record

name: Example Developer

job: Developer

skill: Elite

也可以將key:value放置於{}中進行表示,例如:

---

# An employee record

{name: Example Developer, job: Developer, skill: Elite}

五、Ansible基礎元素

5.1 變量

5.1.1 變量命名

變量名僅能由字母、數字和下劃線組成,且只能以字母開頭。

5.1.2 facts

facts是由正在通信的遠程目標主機發回的信息,這些信息被保存在ansible變量中。要獲取指定的遠程主機所支持的所有facts,可使用如下命令進行:

# ansible hostname -m setup

5.1.3 register

把任務的輸出定義爲變量,然後用於其他任務,示例如下:

tasks:
     - shell: /usr/bin/foo
       register: foo_result
       ignore_errors: True

5.1.4 通過命令行傳遞變量

在運行playbook的時候也可以傳遞一些變量供playbook使用,示例如下:

ansible-playbook test.yml --extra-vars "hosts=www user=bovin"

5.1.5 通過roles傳遞變量

當給一個主機應用角色的時候可以傳遞變量,然後在角色內使用這些變量,示例如下:

- hosts: webservers
  roles:
    - common
    - { role: foo_app_instance, dir: '/web/htdocs/a.com',  port: 8080 }

5.2 Inventory

ansible的主要功用在於批量主機操作,爲了便捷地使用其中的部分主機,可以在inventory file中將其分組命名。默認的inventory file爲/etc/ansible/hosts。

inventory file可以有多個,且也可以通過Dynamic Inventory來動態生成。

5.2.1 inventory文件格式

inventory文件遵循INI文件風格,中括號中的字符爲組名。可以將同一個主機同時歸併到多個不同的組中;此外,當如若目標主機使用了非默認的SSH端口,還可以在主機名稱之後使用冒號加端口號來標明。

mail.example.com
[webservers]
foo.example.com:8888
bar.example.com
[dbservers]
one.example.com
two.example.com
three.example.com

方括號[]中是組名,用於對系統進行分類,便於對不同系統進行個別的管理.

一個系統可以屬於不同的組,比如一臺服務器可以同時屬於 webserver組 和 dbserver組.這時屬於兩個組的變量都可以爲這臺主機所用.

如果有主機的SSH端口不是標準的22端口,可在主機名之後加上端口號,用冒號分隔.SSH 配置文件中列出的端口號不會在 paramiko 連接中使用,會在 openssh 連接中使用.

端口號不是默認設置時,可明確的表示爲:

badwolf.example.com:5309

假設你有一些靜態IP地址,希望設置一些別名,但不是在系統的 host 文件中設置,又或者你是通過隧道在連接,那麼可以設置如下:

jumper ansible_ssh_port=5555 ansible_ssh_host=192.168.1.50

在這個例子中,通過 “jumper” 別名,會連接 192.168.1.50:5555.記住,這是通過 inventory 文件的特×××設置的變量. 一般而言,這不是設置變量(描述你的系統策略的變量)的最好方式.後面會說到這個問題.


如果主機名稱遵循相似的命名模式,還可以使用列表的方式標識各主機,例如:

[webservers]
www[01:50].example.com
[databases]
db-[a:f].example.com

對於每一個 host,你還可以選擇連接類型和連接用戶名:

[targets]
localhost           ansible_connection=local
other1.example.com     ansible_connection=ssh        ansible_ssh_user=mpdehaan
other2.example.com     ansible_connection=ssh        ansible_ssh_user=mdehaan

5.2.2 主機變量

可以在inventory中定義主機時爲其添加主機變量以便於在playbook中使用。例如:

[webservers]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

5.2.3 組變量

組變量是指賦予給指定組內所有主機上的在playbook中可用的變量。例如:

[webservers]
host1
host2
[webserver:vars]
ntp_server=ntp.webservers.example.com
nfs_server=nfs.webservers.example.com

5.2.4 組嵌套

inventory中,組還可以包含其它的組,並且也可以向組中的主機指定變量。不過,這些變量只能在ansible-playbook中使用,而ansible不支持。例如:

[apache]
httpd1.centos.com
httpd2.centos.com
[nginx]
ngx1.centos.com
ngx2.centos.com
[webservers:children]
apache
nginx
[webservers:vars]
ntp_server=ntp.centos.com

5.2.5 inventory參數

ansible基於ssh連接inventory中指定的遠程主機時,還可以通過參數指定其交互方式;這些參數如下所示:

ansible_ssh_host
      將要連接的遠程主機名.與你想要設定的主機的別名不同的話,可通過此變量設置.
ansible_ssh_port
      ssh端口號.如果不是默認的端口號,通過此變量設置.
ansible_ssh_user
      默認的 ssh 用戶名
ansible_ssh_pass
      ssh 密碼(這種方式並不安全,我們強烈建議使用 --ask-pass 或 SSH 密鑰)
ansible_sudo_pass
      sudo 密碼(這種方式並不安全,我們強烈建議使用 --ask-sudo-pass)
ansible_sudo_exe (new in version 1.8)
      sudo 命令路徑(適用於1.8及以上版本)
ansible_connection
      與主機的連接類型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默認使用 paramiko.1.2 以後默認使用 'smart','smart' 方式會根據是否支持 ControlPersist, 來判斷'ssh' 
方式是否可行.
ansible_ssh_private_key_file
      ssh 使用的私鑰文件.適用於有多個密鑰,而你不想使用 SSH 代理的情況.
ansible_shell_type
      目標系統的shell類型.默認情況下,命令的執行使用 'sh' 語法,可設置爲 'csh' 或 'fish'.
ansible_python_interpreter
      目標主機的 python 路徑.適用於的情況: 系統中有多個 Python, 或者命令路徑不是"/usr/bin/python",比如  \*BSD, 或者 /usr/bin/python
      不是 2.X 版本的 Python.我們不使用 "/usr/bin/env" 機制,因爲這要求遠程用戶的路徑設置正確,且要求 "python" 可執行程序名不可爲 python以外的名字(實際有可能名爲
python26).
      與 ansible_python_interpreter 的工作方式相同,可設定如 ruby 或 perl 的路徑....

5.3 條件測試

如果需要根據變量、facts或此前任務的執行結果來做爲某task執行與否的前提時要用到條件測試。

5.3.1 when語句

在task後添加when子句即可使用條件測試;when語句支持Jinja2表達式語法。例如:

tasks
  - name: "shutdown Debian flavored systems"
    command: /sbin/shutdown -h now
    when: ansible_os_family == "Debian"

when語句中還可以使用Jinja2的大多“filter”,例如要忽略此前某語句的錯誤並基於其結果(failed或者sucess)運行後面指定的語句,可使用類似如下形式:

tasks:
  - command: /bin/false
    register: result
    ignore_errors: True
  - command: /bin/something
    when: result|failed
  - command: /bin/something_else
    when: result|success
  - command: /bin/still/something_else
    when: result|skipped

此外,when語句中還可以使用facts或playbook中定義的變量。

5.4 迭代

當有需要重複性執行的任務時,可以使用迭代機制。其使用格式爲將需要迭代的內容定義爲item變量引用,並通過with_items語句來指明迭代的元素列表即可。例如:

- 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

事實上,with_items中可以使用元素還可爲hashes,例如:

- name: add several users
  user: name={{ item.name }} state=present groups={{ item.groups }}
  with_items:
    - { name: 'testuser1', groups: 'wheel' }
    - { name: 'testuser2', groups: 'root' }

ansible的循環機制還有更多的高級功能,具體請參見官方文檔(http://docs.ansible.com/playbooks_loops.html)。

六、Ansible的基本使用

1.

[root@Centos ansible]# rpm -ql ansible | head
/etc/ansible   
/etc/ansible/ansible.cfg  --ansible的主配置文件
/etc/ansible/hosts        --ansible的host inventory文件
/etc/ansible/roles
/usr/bin/ansible          --ansible的命令,實現批量部署的命令
/usr/bin/ansible-console
/usr/bin/ansible-doc      --ansible模塊相關命令,可以獲取相關幫助
/usr/bin/ansible-galaxy
/usr/bin/ansible-playbook --playbook相關命令
/usr/bin/ansible-pull

2、定義Host Inventory  

# vim /etc/ansible/hosts 
[webserver]
192.168.1.101 ansible_ssh_user=root ansible_ssh_pass=fanshine
192.168.1.102 ansible_ssh_user=root ansible_ssh_pass=fanshine
[dbserver]
192.168.1.110

解釋 :

#ansible_ssh_user=root 是ssh登陸用戶  

#ansible_ssh_pass=fanshine是ssh登陸密碼

# 注意每個模塊的用法可以使用 ansible-doc MOD 來查看例如ansible-doc copy  

ansible命令最常用的用法:

ansible <host-pattern> [-f forks] [-m module_name] [-a args]
    args:
         key=value

注意:command模塊要執行命令無須爲key=value格式,而是直接給出要執行的命令即可;

ansible常用模塊:

command
        -a 'COMMAND'
user
        -a 'name= state={present|absent} system= uid='
group
        -a 'name= gid= state= system='
cron
        -a 'name= minute= hour= day= month= weekday= job= user= state='
copy
        -a 'dest= src= mode= owner= group='
file
        -a 'path= mode= owner= group= state={directory|link|present|absent} src='
ping
        沒有參數
yum
        -a 'name= state={present|latest|absent}'
service
        -a 'name= state={started|stopped|restarted} enabled='
shell
        -a 'COMMAND'
script
        -a '/path/to/script'
setup

所支持的模塊可以使用ansible-doc -l來查看.

Ansible簡單實例:

1.使用command模塊,查看客戶機上的網卡信息:

wKiom1kZZryyQ5SXAABVR6eDP3M482.png-wh_50

2使用user模塊進行添加用戶。

wKiom1kZaW-RbBJdAAA9FWaje2w962.png-wh_50

3.使用copy模塊進行復制。

wKiom1kZbqOSxVNFAABmCCzp8K0874.png-wh_50

在使用copy模塊,出現以下錯誤:

192.168.1.102 | FAILED! => {
    "changed": false, 
    "checksum": "8a7d578b4e911043538f101eae8291c428c67605", 
    "failed": true, 
    "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"
}
192.168.1.101 | FAILED! => {
    "changed": false, 
    "checksum": "8a7d578b4e911043538f101eae8291c428c67605", 
    "failed": true, 
    "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"
}

錯誤: "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"
解決: yum install -y libselinux-python

4.使用commad模塊,安裝軟件或者服務。

wKioL1kZa1zAXDKPAABaxH6EN0k073.png-wh_50

5、支持管道的命令。raw模塊,類似於shell模塊

wKiom1kZb8bSPXnGAAAZHPUrjKE464.png-wh_50

6.使用file模塊,創建目錄。

wKioL1kZcw7h-9pLAAA5v0kipI4378.png-wh_50

7.使用yum模塊進行安裝服務。

wKioL1kZfqyDgrbjAABraGkMPhA303.png-wh_50

8.使用service模塊,啓動,停止,重啓服務。

wKioL1kZfwCg4uHUAAA3o-e6Ivs435.png-wh_50

9.簡單的Ping命令進行各主機檢查。

wKioL1kZeOeR0r0gAAAX3NZ7b1M884.png-wh_50

10.使用shell模塊,完成更多操作。

wKiom1kZeiuySqU7AAAp0p-fBn8315.png-wh_50

七、ansible playbooks

playbook是由一個或多個“play”組成的列表。play的主要功能在於將事先歸併爲一組的主機裝扮成事先通過ansible中的task定義好的角色。從根本上來講,所謂task無非是調用ansible的一個module。將多個play組織在一個playbook中,即可以讓它們聯同起來按事先編排的機制同唱一臺大戲。下面是一個簡單示例。

- hosts: webnodes

 vars:

   http_port: 80

   max_clients: 256

 remote_user: root

 tasks:

 - name: ensure apache is at the latest version

   yum: name=httpd state=latest

 - name: ensure apache is running

   service: name=httpd state=started

 handlers:

   - name: restart apache

     service: name=httpd state=restarted

7.1 playbook基礎組件

7.1.1 Hosts和Users

playbook中的每一個play的目的都是爲了讓某個或某些主機以某個指定的用戶身份執行任務。hosts用於指定要執行指定任務的主機,其可以是一個或多個由冒號分隔主機組;remote_user則用於指定遠程主機上的執行任務的用戶。如上面示例中的

-hosts: webnodes

remote_user: root

不過,remote_user也可用於各task中。也可以通過指定其通過sudo的方式在遠程主機上執行任務,其可用於play全局或某任務;此外,甚至可以在sudo時使用sudo_user指定sudo時切換的用戶。

- hosts: webnodes

 remote_user: centos

 tasks:

   - name: test connection

     ping:

     remote_user: centos

     sudo: yes

7.1.2 任務列表和action

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

task的目的是使用指定的參數執行模塊,而在模塊參數中可以使用變量。模塊執行是冪等的,這意味着多次執行是安全的,因爲其結果均一致。

每個task都應該有其name,用於playbook的執行結果輸出,建議其內容儘可能清晰地描述任務執行步驟。如果未提供name,則action的結果將用於輸出。

定義task的可以使用“action: module options”或“module: options”的格式,推薦使用後者以實現向後兼容。如果action一行的內容過多,也中使用在行首使用幾個空白字符進行換行。

tasks:

 - name: make sure apache is running

   service: name=httpd state=running

在衆多模塊中,只有command和shell模塊僅需要給定一個列表而無需使用“key=value”格式,例如:

tasks:

 - name: disable selinux

   command: /sbin/setenforce 0

如果命令或腳本的退出碼不爲零,可以使用如下方式替代:

tasks:

 - name: run this command and ignore the result

   shell: /usr/bin/somecommand || /bin/true

或者使用ignore_errors來忽略錯誤信息:

tasks:

 - name: run this command and ignore the result

   shell: /usr/bin/somecommand

   ignore_errors: True

7.1.3 handlers

用於當關注的資源發生變化時採取一定的操作。

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

- name: template configuration file

 template: src=template.j2 dest=/etc/foo.conf

 notify:

    - restart memcached

    - restart apache

handler是task列表,這些task與前述的task並沒有本質上的不同。

handlers:

   - name: restart memcached

     service:  name=memcached state=restarted

   - name: restart apache

     service: name=apache state=restarted

案例:

heartbeat.yaml
- hosts: hbhosts
  remote_user: root
  tasks:
    - name: ensure heartbeat latest version
      yum: name=heartbeat state=present
    - name: authkeys configure file
      copy: src=/root/hb_conf/authkeys dest=/etc/ha.d/authkeys
    - name: authkeys mode 600
      file: path=/etc/ha.d/authkeys mode=600
      notify:
        - restart heartbeat
    - name: ha.cf configure file
      copy: src=/root/hb_conf/ha.cf dest=/etc/ha.d/ha.cf
      notify: 
       - restart heartbeat
  handlers:
  - name: restart heartbeat
    service: name=heartbeat state=restarted

八、roles

ansilbe自1.2版本引入的新特性,用於層次性、結構化地組織playbook。roles能夠根據層次型結構自動裝載變量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。簡單來講,roles就是通過分別將變量、文件、任務、模塊及處理器放置於單獨的目錄中,並可以便捷地include它們的一種機制。角色一般用於基於主機構建服務的場景中,但也可以是用於構建守護進程等場景中。

一個roles的案例如下所示:

site.yml
webservers.yml
fooservers.yml
roles/
   common/
     files/
     templates/
     tasks/
     handlers/
     vars/
     meta/
   webservers/
     files/
     templates/
     tasks/
     handlers/
     vars/
     meta/

而在playbook中,可以這樣使用roles:

---

- hosts: webservers

 roles:

    - common

    - webservers


也可以向roles傳遞參數,例如:

---

- hosts: webservers

 roles:

   - common

   - { role: foo_app_instance, dir: '/opt/a',  port: 5000 }

   - { role: foo_app_instance, dir: '/opt/b',  port: 5001 }

甚至也可以條件式地使用roles,例如:

---

- hosts: webservers

 roles:

   - { role: some_role, when: "ansible_os_family == 'RedHat'" }

8.1 創建role的步驟

(1) 創建以roles命名的目錄;

(2) 在roles目錄中分別創建以各角色名稱命名的目錄,如webservers等;

(3) 在每個角色命名的目錄中分別創建files、handlers、meta、tasks、templates和vars目錄;用不到的目錄可以創建爲空目錄,也可以不創建;

(4) 在playbook文件中,調用各角色;

8.2 role內各目錄中可用的文件

tasks目錄:至少應該包含一個名爲main.yml的文件,其定義了此角色的任務列表;此文件可以使用include包含其它的位於此目錄中的task文件;

files目錄:存放由copy或script等模塊調用的文件;

templates目錄:template模塊會自動在此目錄中尋找Jinja2模板文件;

handlers目錄:此目錄中應當包含一個main.yml文件,用於定義此角色用到的各handler;在handler中使用include包含的其它的handler文件也應該位於此目錄中;

vars目錄:應當包含一個main.yml文件,用於定義此角色用到的變量;

meta目錄:應當包含一個main.yml文件,用於定義此角色的特殊設定及其依賴關係;ansible 1.3及其以後的版本才支持;

default目錄:爲當前角色設定默認變量時使用此目錄;應當包含一個main.yml文件;

九、Tags

tags用於讓用戶選擇運行或路過playbook中的部分代碼。ansible具有冪等性,因此會自動跳過沒有變化的部分,即便如此,有些代碼爲測試其確實沒有發生變化的時間依然會非常地長。此時,如果確信其沒有變化,就可以通過tags跳過此些代碼片斷。

十、Jinja2相關

10.1 字面量

表達式最簡單的形式就是字面量。字面量表示諸如字符串和數值的 Python 對象。下面 的字面量是可用的:

“Hello World”:

雙引號或單引號中間的一切都是字符串。無論何時你需要在模板中使用一個字 符串(比如函數調用、過濾器或只是包含或繼承一個模板的參數),它們都是 有用的。

42 / 42.23:

直接寫下數值就可以創建整數和浮點數。如果有小數點,則爲浮點數,否則爲 整數。記住在 Python 裏, 42 和 42.0 是不一樣的。

[‘list’, ‘of’, ‘objects’]:

一對中括號括起來的東西是一個列表。列表用於存儲和迭代序列化的數據。例如 你可以容易地在 for 循環中用列表和元組創建一個鏈接的列表:

<ul>

{% for href, caption in [('index.html', 'Index'), ('about.html', 'About'),

                        ('downloads.html', 'Downloads')] %}

   <li><a href="` href `">` caption `</a></li>

{% endfor %}

</ul>

(‘tuple’, ‘of’, ‘values’):

元組與列表類似,只是你不能修改元組。如果元組中只有一個項,你需要以逗號 結尾它。元組通常用於表示兩個或更多元素的項。更多細節見上面的例子。

{‘dict’: ‘of’, ‘key’: ‘and’, ‘value’: ‘pairs’}:

Python 中的字典是一種關聯鍵和值的結構。鍵必須是唯一的,並且鍵必須只有一個 值。字典在模板中很少使用,罕用於諸如 xmlattr() 過濾器之類。

true / false:

true 永遠是 true ,而 false 始終是 false 。

10.2 算術運算

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 。

10.3 比較操作符

==

比較兩個對象是否相等。

!=

比較兩個對象是否不等。

>

如果左邊大於右邊,返回 true 。

>=

如果左邊大於等於右邊,返回 true 。

<

如果左邊小於右邊,返回 true 。

<=

如果左邊小於等於右邊,返回 true 。

10.4 邏輯運算符

對於 if 語句,在 for 過濾或 if 表達式中,它可以用於聯合多個表達式:

        and

如果左操作數和右操作數同爲真,返回 true 。

or

如果左操作數和右操作數有一個爲真,返回 true 。

not

對一個表達式取反(見下)。

(expr)

表達式組。


(二)ansible自動安裝nginx


學習資料:

http://www.ansible.com.cn/index.html

https://github.com/ansible/ansible-examples

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