運維自動化之ansible

Ansible簡介 

Ansible是一個簡單的自動化運維管理工具,基於Python語言實現,由Paramiko和PyYAML兩個關鍵模塊構建,可用於自動化部署應用、配置、編排task(持續交付、無宕機更新等)。html

主版本大概每2個月發佈一次。 node

  Ansible官網:https://www.ansible.com/
    github地址:https://github.com/Ansible
 Ansible具備以下特色:
部署簡單,只需在主控端部署Ansible環境,被控端無需作任何操做;
默認使用SSH協議對設備進行管理;
主從集中化管理;
配置簡單、功能強大、擴展性強;
支持API及自定義模塊,可經過Python輕鬆擴展;
經過Playbooks來定製強大的配置、狀態管理;
對雲計算平臺、大數據都有很好的支持;
提供一個功能強大、操做性強的Web管理界面和REST API接口——AWX平臺。
Ansible無需在被控主機部署任何客戶端代理,默認直接經過SSH通道進行遠程命令執行或下發配置:具有功能強大、靈活的系統管理、狀態配置,二者都提供豐富的模板及API,對雲計算平臺、大數據都有很好的支持。python

安裝

rpm包安裝:EPEL源linux

yum install ansible

編譯安裝nginx

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

Git方式:git

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


pip安裝: pip是安裝Python包的管理器,相似yumgithub

yum install python-pip python-devel
yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
pip install --upgrade pip
pip install ansible --upgrade
確認安裝: ansible --version

相關文件

配置文件

/etc/ansible/ansible.cfg 主配置文件,配置ansible工做特性
/etc/ansible/hosts 主機清單
/etc/ansible/roles/ 存放角色的目錄

程序web

/usr/bin/ansible 主程序,臨時命令執行工具
/usr/bin/ansible-doc 查看配置文檔,模塊功能查看工具
/usr/bin/ansible-galaxy 下載/上傳優秀代碼或Roles模塊的官網平臺
/usr/bin/ansible-playbook 定製自動化任務,編排劇本工具/usr/bin/ansible-pull 遠程執行命令的工具
/usr/bin/ansible-vault 文件加密工具
/usr/bin/ansible-console 基於Console界面與用戶交互的執行工具

 基本操做

  在ansible的安裝目錄下有兩個比較重要的目錄,bin目錄和examples目錄,bin目錄下存放着全部的可執行命令,examples目錄是配置文件的樣板文件。正則表達式

  一、編輯或建立/etc/ansible/hosts文件,添加可管理主機shell

  [ansibleserver](自定義主機清單)
  192.168.130.6
  [testservers] (自定義主機清單)
  192.168.130.7
  192.168.130.8

  二、配置無密碼登陸  

# ssh-keygen -t rsa  -p  ' ' (-p指定生成密鑰密碼)
# ssh-copy-id 192.168.130.6
# ssh-copy-id 192.168.130.7
# ssh-copy-id 192.168.130.8

主機清單和配置文件

主機清單 Inventory

/etc/ansible/hosts 默認主機清單文件,inventory file能夠有多個,且也能夠經過Dynamic Inventory來動態生成

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

格式1:

  host:[port]

格式2:

  [groupname]

  host1

  host2

  host3

格式3:

  [groupname]

  host[1:3]

配置文件

配置文件/etc/ansible/ansible.cfg (通常保持默認) 

inventory      = /etc/ansible/hosts		#主機清單文件
library        = /usr/share/my_modules/		#庫文件存放目錄
remote_tmp     = ~/.ansible/tmp			#臨時py命令文件存放在遠程主機目錄 
local_tmp      = ~/.ansible/tmp			#本機的臨時命令執行目錄 
forks          = 5  				#默認併發數
sudo_user      = root				#默認sudo用戶
ask_sudo_pass = True				#每次執行ansible命令是否詢問ssh密碼 
remote_port    = 22 				#遠程主機端口號
host_key_checking = False 			#禁用第一次鏈接的key檢查
log_path = /var/log/ansible.log 		#默認ansible不記錄日誌,啓用此項開啓日誌記錄 

Ansible系列命令集

ansible

用法:ansible <host-pattern> [-m module_name] [-a args]

選項:

  • --version:查看版本相關信息
  • -m module:指定模塊,默認爲command
  • -v|–vv|-vvv:詳細過程
  • —list|--list-hosts:顯示主機列表
  • -k|--ask-pass:提示鏈接密碼,默認Key驗證
  • -K|--ask-become-pass:提示輸入sudo
  • -C|--check:檢查執行,並非真正執行
  • -T|--timeout=TIMEOUT:執行命令的超時時間,默認10s
  • -u|--user=REMOTE_USER:執行遠程執行的用戶
  • -b|--become:代替舊版的sudo切換

host-pattern:

  • all:表示主機清單中全部的主機
  • groupname:表示組中的全部主機
  • host:指定某臺主機,可是此主機必須在主機清單中
  • 支持通配符(*)、邏輯與(:&)或(:)非(:!)和正則表達式(~)

ansible-doc

用法:ansible-doc [options] [module...]

選項:

  • -a 顯示全部模塊的文檔
  • -l, --list 列出可用模塊
  • -s, --snippet 顯示指定模塊的playbook片斷

ansible-galaxy

從網站上下載對應的roles(https://galaxy.ansible.com)

  • install 安裝roles 
  • list 列出全部roles 
  • remove 刪除roles 

ansible-playbook

執行.yml劇本文件

  • -C | --check 檢查執行,不真正執行
  • -t tags 執行指定的標籤
  • --list-tags 列出劇本中的全部的標籤
  • --list-tasks 列出劇本中全部的任務
  • --list-hosts 列出劇本中全部的主機
  • --limit host_group_name 只針對主機列表中的主機執行
  • -v | -vv | -vvv 顯示詳細信息
  • -e 'var=value' 自定義變量賦值

ansible-vault

管理加密解密yml文件

  • encrypt 加密
  • decrypt 解密
  • view 查看
  • edit 編輯加密文件
  • rekey 修改口令
  • create 建立新文件

ansible-console

ansible的交互式終端,root@all (3)[f:5]$:執行用戶@當前操做的主機組 (當前組的主機數量)[f:併發數]$ 

  • forks #:設置併發數
  • cd:切換主機組或主機
  • list:列出當前主機列表
  • help:獲取幫助

ansible-pull

推送命令至遠程,支持直接從git下載playbook執行,須要遵循其規定的目錄格式,用處不是特別大

經常使用模塊

1)command 不支持管道、變量和管道,只支持簡單功能,須要使用shell模塊

removes=/path/file 若是文件不存在則不執行

creates=/path/file 若是文件存在則不執行

chdir=/path/file 進入指定文件夾

~]# ansible all -a 'df -h'
~]# ansible all -m command -a 'chdir=/data ls' 

2)shell 和command模塊用法相同,可是支持管道、變量和管道等複雜命令

~]# ansible all -m shell -a 'echo $HOSTNAME'

3)script 在遠程主機上執行本地腳本

--some-arguments 1234 指定參數

~]# ansible all -m script -a '/root/ansible/host.sh'

4)copy 將本地文件複製至遠程主機

backup 複製覆蓋時先備份

content 指定一些內容當文件複製

dest 目標路徑

mode 權限

owner 全部者

src 源路徑

~]# ansible all -m copy -a 'src=/root/ansible/selinux dest=/etc/selinux/config backup=yes'
~]# ansible all -m copy -a 'content="hello world" dest=/data/f1'

5)fetch 從遠程主機文件複製到本地,必須是一個文件,在本地目錄下會生成主機名對應的文件夾,文件存放於文件夾中按遠程主機上的目錄結構

dest 本地的一個目錄

src 遠程主機系統上的一個文件(必須)

~]# ansible all -m fetch -a 'src=/var/log/messages dest=/data'

6)archive 打包文件

7)unarchive 解包文件

8)file 建立,刪除,設置文件屬性

state= directory | touch | link | hard | absent 目錄,空文件,軟連接,硬連接,遞歸刪除

dest | name | path= 路徑

src= 建立軟連接時的原文件

mode= 權限

owner= 所屬者

~]# ansible all -m file -a 'name=/data/testfile.ans state=touch'
~]# ansible all -m file -a 'name=/data/dir1 state=directory'
~]# ansible all -m file -a 'src=/etc/fstab dest=/data/f2 state=link'

9)hostname 設置主機名,當即生效而且同步至配置文件

name= 主機名

~]# ansible 192.168.130.11 -m hostname -a 'name=node1'

10)cron 任務計劃

name 名稱

job 做業

disabled=true | false 禁用|啓用

state=absent 刪除

day 天

hour 小時

minute 分鐘

month 月

weekday 星期

~]# ansible all -m cron -a 'minute=* weekday=1,3,5 job="/usr/bin/wall FBI warning" name=warningcron'
~]# ansible all -m cron -a 'disabled=true job="/usr/bin/wall FBI warning" name=warningcron'

11)yum 管理軟件包模塊

list=installed 列出已安裝的軟件包

name= 包名稱

state= present | absent latest 安裝 | 卸載 | 安裝最新版

disable_gpg_check=yes 臨時禁用gpg檢查

update_cache=yes 更新yum緩存

~]# ansible all -m yum -a 'name=vsftpd state=latest'

12)service 管理服務模塊

name 服務名

enabled=yes 開機啓動

state=started | stopped | restarted | reloaded 啓動 | 中止 | 重啓 | 重讀配置文件

~]# ansible all -m service -a 'name=vsftpd state=started enabled=yes'

13)user 用戶管理模塊

name= 用戶名

password= 密碼

remove= 刪除用戶及家目錄

system=yes 建立系統用戶

shell= 設置默認shell

~]# ansible all -m user -a 'name=nginx shell=/sbin/nologin system=yes home=/var/nginx groups=root,bin uid=80 comment="nginx service"' 
~]# ansible all -m user -a 'name=nginx state=absent remove=yes'

14)group 組管理模塊

15)setup 獲取遠程主機的系統信息

filter=var 過濾查看變量參數

劇本(Playbook)

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

YAML簡介

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

YAML Ain't Markup Language,即YAML不是XML。不過,在開發的這種語言時,YAML的意思實際上是:"Yet Another Markup Language"(還是一種標記語言) http://www.yaml.org

基本格式:

  1. --- :表示一個檔案
  2. ... :表示檔案結尾
  3. # :註釋
  4. : :分割k/v(鍵/值)
  5. 縮進必須是統一的,不能空格和tab混用,通常習慣建議2個空格縮進
  6. 縮進的級別也必須是一致的,一樣的縮進表明一樣的級別,程序判別配置的級別是經過縮進結合換行來實現的
  7. k/v(鍵/值)的值均需大小寫敏感
  8. v(值)能夠是字符串,也能夠是嵌套另外一個列表
  9. 文件的後綴一般爲yml或yaml
  10. - :列表
  11. Dictionary:字典由多個key與value構成 

組成playbook的核心元素

一、主機列表:Hosts

playbook中的每個play的目的都是爲了讓某個或某些主機以某個指定的用戶身份執行任務。hosts用於指定要執行指定任務的主機,須事先定義在主機清單中。

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

---
- hosts: all
  remote_user: root

  tasks:
    - name: see hostname
      command: hostname
...

二、任務集:Tasks和action

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

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

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

格式:module: arguments ,可是command模塊和shell模塊後直接寫命令

---
- hosts: websrvs
remote_user: root
tasks:                   #任務 - name: install httpd package    #action yum: name=httpd           #調用yum模塊,並向yum模塊傳遞name=httpd的參數 - name: copy configuration file for httpd copy: src=files/httpd.conf dest=/etc/httpd/conf/httpd.conf - name: start httpd service service: name=httpd state=started ...

若是命令或腳本的退出碼不爲零,使用 ignore_errors:True 來忽略錯誤信息

三、變量:Variables

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

內建變量:facts,setup模塊到主機上收集的全部信息保存爲變量,能夠直接引用,列如 ansible_fqdn 變量用來保存主機名

# ansible all -m setup |grep ansible_fqdn         
        "ansible_fqdn": "node1", 
        "ansible_fqdn": "node2", 
        "ansible_fqdn": "node3", 

自定義變量賦值:

3.1.命令行直接賦值

ansible-playbook -e 'var=value'

3.2.在playbook中定義變量

vars:

  - varname: value

3.3.在主機清單中定義變量

主機變量,直接在主機後定義,只對定義主機有效,優先級高於公共變量

host var=value

公共變量,對主機組內全部主機有效

[groupname:vars] 爲指定主機組自定義變量,vars爲關鍵字

varname=value

3.4.roles中變量在 ansible/roles/object/vars/main.yml 文件中直接定義

var:value
var2:value2

3.5.在.yml文件中直接定義,使用vars_files 關鍵字引用,例如:

# vim vars.yml
var1: httpd
var2: vstfpd

# vim testvar.yml
---
- hosts: all
  remote_user: root
  vars_files:
    - vars.yml
  tasks:
    - name: install package
      yum: name={{ var1 }} state=present
    - name: create file
      file: name=/data/{{ var2 }}.log state=touch
...

變量引用:命令行中定義的變量優先級最高

{{ varname }}

---
- hosts: websrvs
  remote_user: root
  vars:
    - package_name: httpd

  tasks:
    - name: install httpd package
      yum: name={{ package_name }}
    - name: copy configuration file for httpd
      copy: src=files/httpd.conf dest=/etc/httpd/conf/httpd.conf
    - name: start httpd service
      service: name={{ package_name }} state=started
...

四、模板:Templates

咱們爲了對不一樣配置的主機配置不一樣的配置,咱們不可能每次都要修改配置文件,全部就出現了模板技術,這樣咱們只要定義好一份模板,之後推送配置文件時會自動將配置文件模板中的變量替換爲目標主機的參數

templates功能:根據模塊文件動態生成對應的配置文件,ansible中模板使用jinja2語言編寫,第七節有關於jinja2的介紹

要求:

  1. templates文件必須存放於templates目錄下且命名爲 .j2 結尾
  2. yaml/yml 文件需和templates目錄平級
  3. 在playbook中使用template關鍵字調用模板
[root@centos7 ansible]# vim templates/httpd.conf.j2
ServerRoot "/etc/httpd"
Listen 80
Include conf.modules.d/*.conf
User apache
Group apache
ServerAdmin root@localhost
ServerName {{ ansible_fqdn }}:80
[root@centos7 ansible]# vim temp_httpd.yml 
---
- hosts: all
  remote_user: root
  vars:
  - package_name: httpd
  - service_name: httpd

  tasks:
    - name: install package
      yum: name={{ package_name }}
    - name: copy config file
      template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
      notify: restart service
    - name: start service
      service: name={{ service_name }} state=started

  handlers:
    - name: restart service
      service: name={{ service_name }} state=started
...
[root@centos7 ansible]# tree 
.
├── temp_httpd.yml
└── templates
    └── httpd.conf.j2

  ansible_fqdn 變量表明主機名,是setup模塊返回的變量,能夠直接使用

五、觸發器:Handlers和notify

Handlers是task列表,這些task與前述的task並無本質上的不一樣,用於當關注的資源發生變化時,纔會採起必定的操做;

notify這個action可用於在每一個play的最後被觸發,這樣能夠避免屢次有改變發生時每次都執行指定的操做,僅在全部的變化發生完成後一次性地執行指定操做。在notify中列出的操做稱爲handler,也即notify中調用handler中定義的操做。

---
- hosts: websrvs
remote_user: root tasks: - name: install httpd package yum: name=httpd - name: copy configuration file for httpd copy: src=files/httpd.conf dest=/etc/httpd/conf/httpd.conf notify: restart service - name: start httpd service service: name=httpd state=started handlers: - name: restart service service: name=httpd state=restarted ...

當copy的配置文件發生改變時則執行重啓服務的功能,這是必須的

六、標籤:Tags

爲action打上一個標籤,可使用ansible-playbook -t 來指定標籤名,用來只執行單個action

---
- hosts: websrvs
remote_user: root tasks: - name: install httpd package yum: name=httpd - name: copy configuration file for httpd copy: src=files/httpd.conf dest=/etc/httpd/conf/httpd.conf tags: put_config_file - name: start httpd service service: name=httpd state=started tags: start_service ...

使用 ansible-playbook --list-tags httpd.yml 命令查看playbook中的標籤

角色(Roles)

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

建立role的步驟:

1) 建立以roles命名的目錄;

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

3) 在每一個角色命名的目錄中分別建立files、handlers、tasks、templates和vars目錄;用不到的目錄能夠建立爲空目錄,也能夠不建立;

4) 在playbook文件中,經過Includes調用各角色。

[root@centos7 ansible3]# mkdir -p roles/project/{tasks,files,vars,templates,handlers,default,meta}
[root@centos7 ansible3]# tree
.
└── roles
    └── project
        ├── default
        ├── files
        ├── handlers
        ├── meta
        ├── tasks
        ├── templates
        └── vars

9 directories, 0 files

  各目錄做用介紹:

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

示例:簡單的構建一個role

  1)建立目錄框架

[root@centos7 ansible]# mkdir -p roles/httpd/{tasks,templates,files,handlers}
[root@centos7 ansible]# tree
.
└── roles
    └── httpd
        ├── files
        ├── handlers
        ├── tasks
        └── templates

  2)編寫任務

[root@centos7 ansible]# vim roles/httpd/tasks/yum.yml
- name: install httpd
  yum: name=httpd state=present

[root@centos7 ansible]# vim roles/httpd/tasks/copy.yml
- name: copy config file
  template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  notify: restart service
- name: copy index.html
  copy: src=index.html dest=/var/www/html/ owner=apache

[root@centos7 ansible]# vim roles/httpd/tasks/start.yml
- name: start httpd
  service: name=httpd state=started

[root@centos7 ansible]# vim roles/httpd/tasks/main.yml
- include: yum.yml
- include: copy.yml
- include: start.yml

  3)配置模板和主頁測試文件

[root@centos7 ansible]# cp /etc/httpd/conf/httpd.conf roles/httpd/templates/httpd.conf.j2
[root@centos7 ansible]# vim roles/httpd/templates/httpd.conf.j2
ServerName www.{{ ansible_fqdn }}.com:80
[root@centos7 ansible]# vim roles/httpd/files/index.html
<h1>The is a test website.</h1>

  4)定義handlers,使得配置文件模板改變後能夠重啓服務

[root@centos7 ansible]# vim roles/httpd/handlers/main.yml              
- name: restart service
  service: name=httpd state=restarted
[root@centos7 ansible]# tree
.
└── roles
    └── httpd
        ├── files
        │   └── index.html
        ├── handlers
        │   └── main.yml
        ├── tasks
        │   ├── copy.yml
        │   ├── main.yml
        │   ├── start.yml
        │   └── yum.yml
        └── templates
            └── httpd.conf.j2

  5)角色已經編寫完成,咱們只須要在roles目錄的同級目錄下編寫playbook,在playbook中直接使用角色所定義的任務

[root@centos7 ansible]# vim httpd.yml
---
- hosts: websvrs
  remote_user: root
  
  roles:
    - httpd
...

  6)最後,一個簡單的角色就定義完成了,接下來咱們去測試

[root@centos7 ansible]# ansible-playbook -C httpd.yml #先空跑一下,沒有問題再實際執行
[root@centos7 ansible]# ansible-playbook httpd.yml
[root@centos7 ansible]# curl 192.168.130.10
<h1>The is a test website.</h1>
[root@centos7 ansible4]# curl 192.168.130.11
<h1>The is a test website.</h1>

   # 和咱們所預期的操做同樣,那麼之後能夠向這個角色中添加更爲豐富的功能

jinja2語法

字符串:使用單引號或雙引號

列表:[ item1, item2, ... ]

元組:( item1, item2, ... )

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

算術運算

+	把兩個對象加到一塊兒。一般對象是素質,可是若是二者是字符串或列表,你能夠用這 種方式來銜接它們。不管如何這不是首選的鏈接字符串的方式!鏈接字符串見 ~ 運算符。 {{ 1 + 1 }} 等於 2 
-	用第一個數減去第二個數。 {{ 3 - 2 }} 等於 1 
/	對兩個數作除法。返回值會是一個浮點數。 {{ 1 / 2 }} 等於 {{ 0.5 }} 
//	對兩個數作除法,返回整數商。 {{ 20 // 7 }} 等於 2 
%	計算整數除法的餘數。 {{ 11 % 7 }} 等於 4 
*	用右邊的數乘左邊的操做數。 {{ 2 * 2 }} 會返回 4 。也能夠用於重 復一個字符串屢次。 {{ ‘=’ * 80 }} 會打印 80 個等號的橫條
 worker_processes {{ ansible_processor_vcpus*2 }};    #被控端的cpu核心數*2

比較操做符

==	比較兩個對象是否相等
!=	比較兩個對象是否不等
>	若是左邊大於右邊,返回 true 
>=	若是左邊大於等於右邊,返回 true 
<	若是左邊小於右邊,返回 true 
<=	若是左邊小於等於右邊,返回 true 

邏輯運算符

and	若是左操做數和右操做數同爲真,返回 true 
or	若是左操做數和右操做數有一個爲真,返回 true 
not	對一個表達式取反(見下)
(expr)	表達式組

條件測試:when

  條件測試:若是須要根據變量、facts或此前任務的執行結果來作爲某task執行與否的前提時要用到條件測試,經過when語句實現,在task中使用

---
- hosts: all
  remote_user: root
  vars:
  - package_name: httpd
  - service_name: httpd

  tasks:
    - name: install package
      yum: name={{ package_name }}
    - name: copy config file
      template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
      notify: restart service
    - name: start service
      service: name={{ service_name }} state=started
      when: ansible_fqdn == "node2"  #只有主機名是 node2 的節點啓動web服務

  handlers:
    - name: restart service
      service: name={{ service_name }} state=started

迭代:with_items

  當有須要重複性執行的任務時,可使用迭代機制,要在task中使用with_items給定要迭代的元素列表。使用item變量引用列表中的變量

---
- hosts: all
  remote_user: root

  tasks:
    - name: create some files
      file: name=/data/{{ item }} state=touch
      with_items:
        - file1
        - file2
        - file3
    - name: install some package
      yum: name={{ item }}
      with_items:
        - httpd
        - vsftpd
        - htop
        - dstat
        - iftop
        - sl
        - iotop
        - hping3
...   

  迭代中嵌套子變量

- hosts: all
  remote_user: root

  tasks:
    - name: create some groups
      group: name={{item}}
      with_items:
        - g1
        - g2
        - g3
    - name: ceate some users
      user: name={{item.name}} group={{item.group}}
      with_items:
        - { name: 'user1', group: 'g1' }
        - { name: 'user2', group: 'g2' }
        - { name: 'user3', group: 'g3' }
...

for循環

  for語句在templates文件中使用

[root@centos7 ansible]# vim testfor.yml 
---
- hosts: all
  remote_user: root
  vars:
    ports:
      - 81
      - 82
      - 83

  tasks:
    - name: copy config file
      template: src=for1.conf.j2 dest=/data/for1.conf
...

[root@centos7 ansible]# vim templates/for.conf.j2 
{% for p in ports %}
server{
    listen {{ p }}
}
{% endfor %}

  也可使用for來遍歷列表

[root@centos7 ansible]# vim testfor2.yml 
---
- hosts: all
  remote_user: root
  vars:
    ports:
      - http_port: 81
      - http_port: 82
      - http_port: 83

  tasks:
    - name: copy config file
      template: src=for2.conf.j2 dest=/data/for2.conf
...

[root@centos7 ansible]# vim templates/for2.conf.j2 
{% for p in ports %}
server{
    listen {{ p.http_port }}
}
{% endfor %}

  以上的模板生成的結果:

server{
        listen 81
}
server{
        listen 82
}
server{
        listen 83
}

if判斷

  if語句在templates文件中使用

[root@centos7 ansible]# cat testif.yml 
---
- hosts: all
  remote_user: root
  vars:
    ports:
      - web1:
        port: 81
        name: web1.test.com
        rootdir: /data/website1
      - web1:
        port: 82
        name: web2.test.com
        rootdir: /data/website2
      - web1:
        #port: 83
        name: web3.test.com
        rootdir: /data/website3

  tasks:
    - name: copy config file
      template: src=if.conf.j2 dest=/data/if.conf
...

[root@centos7 ansible]# cat templates/if.conf.j2 
{% for i in ports %}
server{
{% if i.port is defined %}  #這個判斷的意思是若是變量i.port,也就是ports中的port變量,沒有配置,則這個語句塊則不生效
        Listen {{ i.port }}
{% endif %}
        ServerName {{ i.name }}
        Documentroot {{ i.rootdir }}
}
{% endfor %}
相關文章
相關標籤/搜索