ansible 基礎(chǔ)學(xué)習(xí)

[TOC]

** 部分內(nèi)容源于網(wǎng)絡(luò)盛险,文檔是個人學(xué)習(xí)筆記與記錄**

什么是ansible?

Ansible is Simple IT Automation——簡單的自動化IT工具汁果,可以實現(xiàn) 批量系統(tǒng)配置、批量程序部署窖剑、批量運行命令等功能麻车,簡而言之汉矿,就是 <span style='color:red'> 分布式集中管理工具</span>, 通俗的講就是批量在遠端服務(wù)器上執(zhí)行命令宿百。其實趁仙,ansible自身不具備部署能力的,只是提供框架垦页,其核心為模塊

ansible架構(gòu)圖

ansible架構(gòu).JPG
五大部分 功能
connection plugins 遠程連接插件
hosts 定義管理主機或主機組
modules 包含各個核心模塊及自定義模塊
Plugin 完成模塊功能的補充雀费,如日志插件、郵件插件等
Playbook ansible的任務(wù)配置文件痊焊,將多個任務(wù)定義在劇本中進行管理

?

?

?

ansible 的工作流程

ansible流程.JPG

?

?

?

安裝ansible

#配置源  ansible默認(rèn)不在yum倉庫中
rpm -iUvh http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel//7/x86_64/e/epel-release-7-9.noarch.rpm

#此源主要是為了安裝PyYAML
wget http://mirrors.163.com/.help/CentOS7-Base-163.repo          
mv CentOS7-Base-163.repo /etc/yum.repos.d/

yum -y install ansible

ansible --version
#可查看當(dāng)前ansible版本

配置登錄

ansible 使用ssh登錄盏袄,所以主奴之間要配置密鑰進行認(rèn)證,這樣才能開始正常工作

ssh-keygen -t rsa #回車
#將會生成密鑰/root/.ssh/id_rsa.pub

ssh-copy-id -i root@ipaddress 
#公鑰將會被cp到各個ipaddress節(jié)點

#至此 已經(jīng)實現(xiàn)了master與各節(jié)點的連接

定義Ansible的節(jié)點清單

vim /etc/ansible/hosts
[testgroup]-----#服務(wù)器組的名字薄啥,方便統(tǒng)一管理辕羽,劃分和命名要有規(guī)劃
192.168.1.XX----#組內(nèi)節(jié)點的地址
192.168.1.XXX
等等

[websever]
....
[DBserver]
....

簡單的遠程操作

通過執(zhí)行who,查看服務(wù)器登錄信息

ansible testgroup -m command -a 'who' #組
ansible all -m command -a 'who'     # 所有
ansible 192.168.1.XX -m command -a 'who'  #單個ip

##
192.168.247.152 | SUCCESS | rc=0 >>
root     :0           2017-02-15 22:33 (:0)
root     pts/0        2017-02-15 22:34 (:0)
root     pts/1        2017-02-18 13:08 (192.168.247.1)
root     pts/2        2017-03-07 22:52 (:0)
root     pts/3        2017-03-07 22:54 (192.168.247.156)


# 以ashin用戶身份ping .134
ansible 192.168.1.134 -m ping -u zili

# 以用戶zili身份使用sudo來ping 組testgroup
# -K是輸入root密碼
ansible v1 -m ping -u zili --sudo -K

定義變量

定義主機變量
    [web]
    192.168.247.152  http_port=80
    ...............  http_port=303
    [mysql]
    192.168.247.152
    ...
    
    #組名以及ip根本自己需求定義
    #主機指定變量垄惧,以便后面供palybooks配置使用刁愿。
    #定義兩臺web服務(wù)器的apache參數(shù)http_port,可以讓兩臺服務(wù)器產(chǎn)生的apache配置文件httpd.conf差異化
    
定義組變量
    [web]
    192.168.247.152
    [web:vars]
    http_port=80
    
    #組變量的作用域是覆蓋組所有成員到逊,通過定義一個新塊铣口,塊名由組名+ ":vars"組成。
嵌套組
    [web]
    192.168.247.152
    [mysql]
    192.168.247.152
    ...
    [nested:children]
    web
    mysql
    [nested:vars]
    ntp_server=s1b.time.edu.cn   
    
##
嵌套組定義一個新塊蕾管,塊名由 組名+":chilren" 組成枷踏。
同是嵌套組也可以定義組變量,作用域是嵌套組里的所有組,  
嵌套組只能在/usr/bin/ansible-playbook中掰曾,
在/usr/bin/ansible中不起作用旭蠕,下面會介紹playbook
分離主機和組特定數(shù)據(jù)

為更好的規(guī)范定義的主機與組變量,我們實際是不會在hosts里直接寫的var旷坦,將定義的主機名與組變量單獨剝離出來放到指定的文件中掏熬,將采用YAML格式存放
全局的變量放在group_vars/all中,局部變量放在group_vars/x中秒梅,特定的host使用特定的變量可以使用host_vars/x旗芬,子group中的變量會覆蓋上級變量,hosts變量總是覆蓋groups變量
存放位置規(guī)定:"/etc/ansible/group_vars/名"和"/etc/ansible/host_vars/主機名"分別存放指定組名或主機名定義的變量捆蜀,如
/etc/ansible/group\_vars/mysql.yml
/etc/ansible/host\_vars/192.168.11.1.yml
使用變量要用jinja語法去引用

cat mysql.yml

   ---
    ntp_server: s1b.time.edu.cn
    database_server: 192.168.247.152

##
規(guī)范變量名字疮丛,是因為,ansible會自動加載這目錄下的變量辆它,
否則無法調(diào)用誊薄,當(dāng)然也有解決不放此目錄的方法

例如

[root@master ansible]# tree
├── create_user.yml
├── group_vars
│   └── t1.yml
├── hosts

[root@master ansible]# cat hosts
[t1]
10.1.27.24

所以
├── group_vars
│   └── t1.yml  #他的內(nèi)容就是t1的變量

[root@master ansible]# cat group_vars/t1.yml 
---
user: ansibleTest1

[root@master ansible]# cat create_user.yml 
# create user
---
- name: create user
  hosts: t1
  user: root
  tasks:
  - name: useradd {{ user }}  #引用t1變量
    user: name="{{ user }}"

返回結(jié)果如下
[root@master ansible]# ansible-playbook create_user.yml 

PLAY [create user] ***********************************************************************************************************

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

TASK [useradd ansibleTest1] **************************************************************************************************
changed: [10.1.27.24]

PLAY RECAP *******************************************************************************************************************
10.1.27.24                 : ok=2    changed=1    unreachable=0    failed=0   

命令參數(shù)

ansible <host-pattern> [options]

    -m MODULE_NAME, --module-name=MODULE_NAME     要執(zhí)行的模塊,默認(rèn)為 command  
    -a MODULE_ARGS, --args=MODULE_ARGS      模塊的參數(shù)  
    -u REMOTE_USER, --user=REMOTE_USER ssh      連接的用戶名锰茉,默認(rèn)用 root呢蔫,ansible.cfg 中可以配置
    -k, --ask-pass      提示輸入 ssh 登錄密碼,當(dāng)使用密碼驗證登錄的時候用     
    -s, --sudo      sudo 運行
    -U SUDO_USER, --sudo-user=SUDO_USER     sudo 到哪個用戶飒筑,默認(rèn)為 root
    -K, --ask-sudo-pass     提示輸入 sudo 密碼片吊,當(dāng)不是 NOPASSWD 模式時使用
    -B SECONDS, --background=SECONDS       run asynchronously, failing after X seconds(default=N/A)
    -P POLL_INTERVAL, --poll=POLL_INTERVAL      set the poll interval if using
    -B (default=15)
    -C, --check     只是測試一下會改變什么內(nèi)容绽昏,不會真正去執(zhí)行
    -c CONNECTION   連接類型(default=smart)
    -f FORKS, --forks=FORKS     fork 多少個進程并發(fā)處理,默認(rèn) 5
    -i INVENTORY, --inventory-file=INVENTORY      指定hosts文件路徑默認(rèn) default =/etc/ansible/hosts
    -l SUBSET, --limit=SUBSET       指定一個 pattern俏脊,對<host_pattern>已經(jīng)匹配的主機中再過濾一次
    --list-hosts        只打印有哪些主機會執(zhí)行這個 playbook 文件:不是實際執(zhí)行該 playbook
    -M MODULE_PATH, --module-path=MODULE_PATH       要執(zhí)行的模塊的路徑全谤,默認(rèn)為/usr/share/ansible/
    -o, --one-line      壓縮輸出,摘要輸出
    --private-key=PRIVATE_KEY_FILE      私鑰路徑
    -T TIMEOUT, --timeout=TIMEOUT   ssh 連接超時時間联予,默認(rèn) 10 秒
    -t TREE, --tree=TREE            日志輸出到該目錄啼县,日志文件名會以主機名命名
    -v, --verbose   verbose mode (-vvv for more, -vvvv to enable connection debugging)

Pattern

可以直接指定ip或hosts中的組名,同時指定多個組或者多個ip使用:分割

ansible group1:group2 -m ping
ansible ip1:ip2 -m ping

#all  或者 *  代表全部
ansible all -m ping

# 感嘆號 ! 表示非
g1:!g2   #表示在g1分組中沸久,但是不在g2中的hosts

# &符號表示交集
g1:&g2  #表示在g1分組中季眷,也在g2中的hosts

#使用下標(biāo)
g1[2]  #組的第三個
g1[0:3] #組的前四個

常用模塊

copy模塊
目的:把主控端/root目錄下的a.sh文件拷貝到到指定節(jié)點上  
命令:ansible 192.168.247.152 -m copy -a 'src=/root/a.sh dest=/tmp/ owner=root group=root mode=0755'
file模塊
目的:更改指定節(jié)點上/tmp/t.sh的權(quán)限為755,屬主和屬組為root  
命令:ansible all -m file -a "dest=/tmp/t.sh mode=755 owner=root group=root"
cron模塊
    目的:在指定節(jié)點上定義一個計劃任務(wù)卷胯,每隔3分鐘到主控端更新一次時間  
    命令:ansible all -m cron -a 'name="custom job" minute=*/3 hour=* day=* month=* weekday=* job="/usr/sbin/ntpdate 192.168.247.152"'
group模塊
目的:在所有節(jié)點上創(chuàng)建一個組名為nolinux子刮,gid為2014的組  
命令:ansible all -m group -a 'gid=2014 name=nolinux'
uesr模塊
目的:在所有節(jié)點上創(chuàng)建一個用戶名為nolinux,組為nolinux的用戶  
命令:ansible all -m user -a 'name=nolinux groups=nolinux state=present'
刪除用戶  
命令:ansible all -m user -a 'name=nolinux state=absent remove=yes'
yum模塊
目的:在指定節(jié)點上安裝 apache 服務(wù)  
命令:ansible all -m yum -a "state=present name=httpd"
#state=latest 安裝最新版本
shell模塊
目的:在指定節(jié)點上安裝 apache 服務(wù)  
命令:ansible testgroup -m shell -a 'yum -y install httpd'
command模塊
目的:在指定節(jié)點上運行hostname命令
命令:ansible 192.168.247.152 -m command -a 'hostname'
raw模塊
目的:在192.168.247.152節(jié)點上運行ifconfig命令
命令:ansible 192.168.247.152 -m raw-a 'ifconfig|eth0'
script模塊
目的:在指定節(jié)點上執(zhí)行/root/a.sh腳本(該腳本是在ansible主控端)  
命令:ansible 10.1.1.113 -m script -a '/root/a.sh'
command,script,shell,raw的區(qū)別

思考:四者有何區(qū)別窑睁?

command模塊 [執(zhí)行遠程命令]

ansible client -m command -a "uname -n" -s

script模塊 [在遠程主機執(zhí)行主控端的shell/python腳本]

ansible client -m script -a "/soft/ntpdate.py" -s

shell模塊 [執(zhí)行遠程主機的shell/python腳本]

ansible client -m shell -a "/soft/file.py" -s

raw模塊 [類似于command模塊挺峡、支持管道傳遞]

ansible client -m raw -a "ifconfig eth0|sed -n 2p|awk '{print \$2}'" -s
service模塊
目的:啟動指定節(jié)點上的 httpd 服務(wù),并讓其開機自啟動  
命令:ansible 192.168.247.152 -m service -a 'name=httpd state=restarted enabled=yes'
ping模塊
目的:檢查指定節(jié)點機器是否還能連通  
命令:ansible 192.168.247.152 -m ping
get_url
目的:下載百度下的圖標(biāo)文件到節(jié)點的/tmp文件下
命令:ansible testgroup -m get_url -a 'url=https://www.baidu.com/favicon dest=/tmp'
#結(jié)果為error.html担钮,但是證明了模塊是可用的
stat模塊
目的:獲取遠程文件狀態(tài)信息橱赠,包括atime、ctime箫津、mtime狭姨、md5、uid苏遥、gid等信息
ansible web -m stat -a 'path=/etc/sysctl.conf'
template模塊
template使用了Jinja2格式作為文件模版饼拍,進行文檔內(nèi)變量的替換的模塊。它的每次使用都會被ansible標(biāo)記為”changed”狀態(tài)田炭。

模塊參數(shù)

參數(shù)名 是否必須 默認(rèn)值 選項 說明
backup no no yes/no 建立個包括timestamp在內(nèi)的文件備份师抄,以備不時之需.
dest yes 遠程節(jié)點上的絕對路徑,用于放置template文件教硫。
group no 設(shè)置遠程節(jié)點上的的template文件的所屬用戶組
mode no 設(shè)置遠程節(jié)點上的template文件權(quán)限叨吮。類似Linuxchmod的用法
owner no 設(shè)置遠程節(jié)點上的template文件所屬用戶
src yes 本地Jinjia2模版的template文件位置

模塊參數(shù)案例

把/mytemplates/foo.j2文件經(jīng)過填寫參數(shù)后,復(fù)制到遠程節(jié)點的/etc/file.conf瞬矩,文件權(quán)限相關(guān)略過

 - template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode=0644

跟上面一樣的效果挤安,不一樣的文件權(quán)限設(shè)置方式

 - template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode="u=rw,g=r,o=r"
#詳細(xì)說明 
roles/templates/server.xml中的template文件關(guān)鍵部分如下:
<user username="{{ admin_username }}" password="{{ admin_password }}" roles="manager-gui" />
#當(dāng)這個文件還沒被template執(zhí)行的時候,本地的admin_username及admin_password 都是變量狀態(tài)丧鸯。 
#當(dāng)playbook執(zhí)行完template的時候,遠程的admin_username*及admin_password 會變成變量所對應(yīng)的值嫩絮。

#例 
#前面的那個Playbook,如果我們在tomcat-servers設(shè)置了這兩個變量如下:
dmin_username: admin
admin_password: adminsecret

#那么在執(zhí)行這個Playbook前丛肢,對應(yīng)的那個template文件(俗稱模版)围肥,
將在本地保持{{ admin_username }}及{{ admin_password }}的狀態(tài)。
在Ansible調(diào)用template模版執(zhí)行的時候蜂怎,這里將由Jinjia2從”tomcat-servers”讀取對應(yīng)的值穆刻,
然后替換掉模版里的變量,然后把這個替換變量值后的文件拷貝到遠程節(jié)點杠步。
#這個就是template的意義所在氢伟。
更多模塊

ansible-doc -l 查詢


playbook的配置和使用

配置文件后綴名為.yml

官網(wǎng)demo說明
#這個是你選擇的主機
- hosts: webservers
#這個是變量
  vars:
    http_port: 80
    max_clients: 200
#遠端的執(zhí)行權(quán)限
  remote_user: root
  tasks:
#利用yum模塊來操作
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
  - name: write the apache config file
    template: src=/srv/httpd.j2 dest=/etc/httpd.conf
#觸發(fā)重啟服務(wù)器
    notify:
    - restart apache
  - name: ensure apache is running
    service: name=httpd state=started
#這里的restart apache 和上面的觸發(fā)是配對的。這就是handlers的作用幽歼。相當(dāng)于tag
  handlers:
    - name: restart apache
      service: name=httpd state=restarted
#有的系統(tǒng)做了sudo限制朵锣,所以需要在playbook中開啟權(quán)限,如下
- hosts: web
  remote_user: vic
  tasks:
    - service: name=nginx state=started
      sudo: yes
腳本實例
#create_user.yml
- name: create user
  hosts: testgroup
  user: root
  ##facts可以調(diào)用client的變量來使用甸私,后面變量里會詳細(xì)介紹
  gather_facts: false
  vars:
  - user: "usertest1"
  tasks:
  - name: create {{ user }}
    user: name="{{ user }}"
    
#返回結(jié)果如下
[root/] ]$ansible-playbook create_user.yml

PLAY [create user] *************************************************************

TASK [create usertest1] ********************************************************
ok: [192.168.247.152]

PLAY RECAP *********************************************************************
192.168.247.152            : ok=1    changed=0    unreachable=0    failed=0
給腳本添加service的調(diào)用
#create_user.yml
- name: create user
  hosts: testgroup
  user: root
  gather_facts: false
  vars:
  - user: "usertest1"
  tasks:
  - name: create {{ user }}
    user: name={{ user }}
  - name: start httpd
    service: name=httpd state=startd
  #添加了httpd服務(wù)的開啟
  
  #返回結(jié)果如下 
PLAY [create user] *************************************************************

TASK [create usertest2] ********************************************************
ok: [192.168.247.152]
#可以注意到 TASK [service]顯示已經(jīng)開啟了
TASK [service] *****************************************************************
changed: [192.168.247.152]

PLAY RECAP *********************************************************************
192.168.247.152            : ok=2    changed=1    unreachable=0    failed=0

給腳本添加copy模塊的調(diào)用
#create_user.yml
- name: create user
  hosts: testgroup
  user: root
  gather_facts: false
  vars:
  - user: "usertest1"
  tasks:
  - name: create {{ user }}
    user: name={{ user }}
  - name: start httpd
    service: name=httpd state=startd
   #添加了httpd服務(wù)的開啟
  - name: Copy file to client
    copy: src=/tmp/test.test dest=/tmp/
    #添加了copy服務(wù)的開啟
    
 #返回結(jié)果如下
[root/ansible_yml] ]$ansible-playbook create_user.yml

PLAY [create user] ************************************************************

TASK [create usertest2] *******************************************************
ok: [192.168.247.152]

TASK [service] ****************************************************************
ok: [192.168.247.152]
#可以注意到 TASK [copy file to clent]已成功
TASK [copy file to clent] *****************************************************
changed: [192.168.247.152]

PLAY RECAP ********************************************************************
192.168.247.152            : ok=3    changed=1    unreachable=0    failed=0

copy傳送的時候诚些,可能報錯

afewbug | FAILED >> {
    "checksum": "4ee72f7427050dcd97068734d35ca7b2c651bc88", 
    "failed": true, 
    "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren‘t installed!"
    
是因為ansible需要libselinux-python包。(被控端需要安裝libselinux-python**)  
可以在copy前先調(diào)用yum模塊皇型,安裝libselinux-python
template模板(支持jinja2)
#create_user.yml
- name: create user
  hosts: testgroup
  user: root
  gather_facts: false
  vars:
  - user: "usertest1"
  - temp: temptest
  tasks:
  - name: create {{ user }}
    user: name={{ user }}
  - name: start httpd
    service: name=httpd state=startd
   #添加了httpd服務(wù)的開啟
  - name: Copy file to client
    copy: src=/tmp/test.test dest=/tmp/
    #添加了copy服務(wù)的開啟
  - name: template test
    template: src=/tmp/temp dest=/tmp/{{temp}} #{{temp}}變量來自vars
    #添加了template模板使用
    
#返回結(jié)果
[root/ansible_yml] ]$ansible-playbook create_user.yml

PLAY [create user] *************************************************************

TASK [create usertest2] ********************************************************
ok: [192.168.247.152]

TASK [start httpd] *************************************************************
ok: [192.168.247.152]

TASK [copy file to clent] ******************************************************
ok: [192.168.247.152]
#可以注意到 返回結(jié)果顯示成功诬烹,去client相關(guān)目錄即可看到文件
TASK [template test] ***********************************************************
changed: [192.168.247.152]

PLAY RECAP *********************************************************************
192.168.247.152            : ok=4    changed=1    unreachable=0    failed=0


##
#template模塊可以引用變量到源文件
/tmp/temp
{{user}}
{{temp}}

#執(zhí)行yml后

[root/ansible_yml] ]$ansible testgroup -m command -a 'cat /tmp/temptest'
192.168.247.152 | SUCCESS | rc=0 >>
##client返回的就是主機源文件中引入的變量
usertest1
temptest

執(zhí)行外部命令的模塊
#create_user.yml
- name: create user
  hosts: testgroup
  user: root
  gather_facts: false
  vars:
  - user: "usertest1"
  - temp: temptest
  tasks:
  - name: create {{ user }}
    user: name={{ user }}
  - name: start httpd
    service: name=httpd state=startd
   #添加了httpd服務(wù)的開啟
  - name: Copy file to client
    copy: src=/tmp/test.test dest=/tmp/
    #添加了copy服務(wù)的開啟
  - name: template test
    template: src=/tmp/temp dest=/tmp/{{temp}} #{{temp}}變量來自vars
    #添加了template模板使用
  - name: run shell
    shell: /usr/bin/ls /tmp/ || /bin/true
    #/bin/true 防中斷
  - name: run  command
    command: mkdir /tmp/command-test
    #添加了兩個執(zhí)行外部命令模塊shell和command

#返回結(jié)果如下
[root/ansible_yml] ]$ansible-playbook create_user.yml

PLAY [create user] *************************************************************

TASK [create usertest2] ********************************************************
ok: [192.168.247.152]

TASK [start httpd] *************************************************************
ok: [192.168.247.152]

TASK [copy file to client] *****************************************************
changed: [192.168.247.152]

TASK [template test] ***********************************************************
changed: [192.168.247.152]

TASK [shell~] ******************************************************************
changed: [192.168.247.152]

TASK [run this command] ********************************************************
changed: [192.168.247.152]
 [WARNING]: Consider using file module with state=directory rather than running
mkdir


PLAY RECAP *********************************************************************
192.168.247.152            : ok=6    changed=4    unreachable=0    failed=0


###
#1./usr/bin/...||/bin/true  前面失敗的話/bin/true:返回true。防止中斷弃鸦,繼續(xù)執(zhí)行绞吁。類似的判斷還有chenge_when參數(shù)

變量功能

facts

一個常用的組件,可實現(xiàn)對遠程自己系統(tǒng)信息的獲取唬格,比如:主機名家破,IP地址,操作系統(tǒng)西轩,分區(qū)情況员舵,硬件信息等,配合playbook使用藕畔,更加的靈活和個性化定制

ansible ip/group -m setup可以獲取clients的facts信息

[root~] ]$ansible testgroup -m setup
192.168.247.152 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.122.1",
            "192.168.247.152"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::20c:29ff:feb5:6e6"
        ],
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "07/02/2015",
        "ansible_bios_version": "6.00",
        
        ......

腳本中開啟Facts功能

#create_user.yml
- name: create user
  hosts: testgroup
  user: root
  gather_facts: false #開啟facts
  tasks:
  - name: template test
    template: src=/tmp/temp dest=/tmp/{{temp}} #{{temp}}變量來自vars

#返回結(jié)果马僻,
[root/ansible_yml] ]$ansible-playbook create_user.yml

PLAY [create user] *************************************************************

TASK [setup] *******************************************************************
ok: [192.168.247.152]

TASK [template test] ***********************************************************
changed: [192.168.247.152]

PLAY RECAP *********************************************************************
192.168.247.152            : ok=2    changed=1    unreachable=0    failed=0

#查看
[root/ansible_yml] ]$ansible testgroup -m raw -a "ls /tmp | grep 192*"
192.168.247.152 | SUCCESS | rc=0 >>
[u'192.168.122.1', u'192.168.247.152']
Shared connection to 192.168.247.152 closed.
#IP地址有兩個所以文件名很奇怪

當(dāng)然,我們也可以在主機的/tmp/temp下調(diào)用facts變量

#修改/tmp/temp文件
test
{{ansible_all_ipv4_addresses}}

#create_user.yml
- name: create user
  hosts: testgroup
  user: root
  gather_facts: false #開啟facts
  tasks:
  - name: template test
    template: src=/tmp/temp dest=/tmp/factstest

#結(jié)果如下
[root/ansible_yml] ]$ansible-playbook create_user.yml

PLAY [create user] *************************************************************

TASK [setup] *******************************************************************
ok: [192.168.247.152]

TASK [template test] ***********************************************************
changed: [192.168.247.152]

PLAY RECAP *********************************************************************
192.168.247.152            : ok=2    changed=1    unreachable=0    failed=0

[root/ansible_yml] ]$ansible testgroup -m raw -a "cat /tmp/factstest"
192.168.247.152 | SUCCESS | rc=0 >>
test
[u'192.168.122.1', u'192.168.247.152']
Shared connection to 192.168.247.152 closed.
自定義變量

如何facts的變量并不能滿足需求的注服,就可以自定義facts模板來實現(xiàn)

另外可以通過本地facts來實現(xiàn)韭邓,只需在client的/etc/ansible/facts.d目錄定義JSON,INI或可執(zhí)行的JSON輸出,后綴名一定要用.fact溶弟,那么這些文件就可以作為本地的facts

在client定義變量女淑,供ansible主機使用
[root@test1 ~]# mkdir /etc/ansible/facts.d -p
[root@test1 ~]# cd /etc/ansible/facts.d/
[root@test1 facts.d]# cat client.fact
[general]
name=zili

ansible主機

[root/ansible_yml] ]$ansible 192.168.247.152 -m setup -a "filter=ansible_local" 192.168.247.152 | SUCCESS => {
    "ansible_facts": {
        "ansible_local": {          #本地facts
            "client": {             #文件名
                "general": {         #節(jié)點名
                    "name": "zili"    #key-value
                }
            }
        }
    },
    "changed": false
}

那么就可以通過如下方式去調(diào)用自定義的facts變量

{{ansible_local.client.general.name}}

[root/ansible_yml] ]$ansible-playbook create_user.yml

PLAY [create user] *************************************************************

TASK [setup] *******************************************************************
ok: [192.168.247.152]

TASK [template test] ***********************************************************
changed: [192.168.247.152]

PLAY RECAP *********************************************************************
192.168.247.152            : ok=2    changed=1    unreachable=0    failed=0
#調(diào)用成功,并可看到client內(nèi)容已變化
[root/ansible_yml] ]$ansible testgroup -m raw -a "cat /tmp/factstest2"          192.168.247.152 | SUCCESS | rc=0 >>
zili #
Shared connection to 192.168.247.152 closed.

在操作主機定義變量辜御,來控制client

思路就是在執(zhí)行playbook的時候?qū)⒈镜氐膄acts推送到client相關(guān)目錄下

      - name: create directory for ansible custom facts
        file: state=directory recurse=yes path=/etc/ansible/facts.d
      - name: install custom facts
        copy: src=/etc/ansible/host.fact dest=/etc/ansible/facts.d
      - name: re-read facts after adding custom fact
        setup: filter=ansible_local
  #如此相當(dāng)于批量在client創(chuàng)建了facts變量
  #然后就可以主機調(diào)用了!
注冊變量

變量可以將一條命令的返回值進行保存鸭你,然后提供給playbook使用

[root@ansible ansible]# cat user1.yml
- hosts: testgroup
  remote_user: root
  tasks:
  - shell: /usr/bin/foo
    register: z         #注冊了一個foo\_resul變量,變量值為shell: /usr/bin/foo的運行結(jié)果;  
    ignore_errors: True  #ignore\_errors: True為忽略錯誤
  - shell: touch /tmp/LLL #當(dāng)變量注冊完成后,就可以在后面的playbook中使用了
    when: z.rc == 5 
#當(dāng)條件語句when: z.rc == 5成立時袱巨,shell: touch /tmp/LLL命令才會執(zhí)行  
#可以注意到command是skipping的阁谆。因為返回值是127,所以client肯定還是沒有創(chuàng)建LLL的
[root/ansible_yml] ]$ansible-playbook user1.yml

PLAY [testgroup] ***************************************************************

TASK [setup] *******************************************************************
ok: [192.168.247.152]

TASK [command] *****************************************************************
fatal: [192.168.247.152]: FAILED! => {"changed": true, "cmd": "/usr/bin/foo", "delta": "0:00:00.003488", "end": "2017-03-11 13:08:45.996549", "failed": true, "rc": 127, "start": "2017-03-11 13:08:45.993061", "stderr": "/bin/sh: /usr/bin/foo: No such file or directory", "stdout": "", "stdout_lines": [], "warnings": []}
...ignoring

TASK [command] *****************************************************************
skipping: [192.168.247.152]

PLAY RECAP *********************************************************************
192.168.247.152            : ok=2    changed=1    unreachable=0    failed=0

##所以我門修改z.rc的返回值為127在執(zhí)行
#以為返回值是對的愉老,所以執(zhí)行了touch场绿,warning是友情提示,最好用線管模塊進行文件的操作
[root/ansible_yml] ]$ansible-playbook user1.yml

PLAY [testgroup] ***************************************************************

TASK [setup] *******************************************************************
ok: [192.168.247.152]

TASK [command] *****************************************************************
fatal: [192.168.247.152]: FAILED! => {"changed": true, "cmd": "/usr/bin/foo", "delta": "0:00:00.003539", "end": "2017-03-11 13:11:01.955975", "failed": true, "rc": 127, "start": "2017-03-11 13:11:01.952436", "stderr": "/bin/sh: /usr/bin/foo: No such file or directory", "stdout": "", "stdout_lines": [], "warnings": []}
...ignoring

TASK [command] *****************************************************************
changed: [192.168.247.152]
 [WARNING]: Consider using file module with state=touch rather than running touch


PLAY RECAP *********************************************************************
192.168.247.152            : ok=3    changed=2    unreachable=0    failed=0

[root/ansible_yml] ]$


語句

條件語句

playbook的執(zhí)行結(jié)果取決于變量嫉入,不管是facts還是tasks結(jié)果賦值的焰盗,而變量的值可以依賴于其他變量,當(dāng)然一會印象ansible的執(zhí)行

有時候我們咒林,想要跳過某些主機的執(zhí)行步驟熬拒,比如,某些client不安裝某個軟件包映九,不清理垃圾等等

就要使用判斷了

when
- name: when
  hosts: testgroup
  remote_user: root
  gather_facts: true
  tasks:
  - name: shutdown centos
    command: /sbin/shutdown -t now
    when: ansible_hostname == 'test1'
#when返回bool值梦湘,為true是執(zhí)行,false則不執(zhí)行

when 針對不同分支的二級處理

- name: when
  hosts: web
  remote_user: root
  gather_facts: true
  tasks:
  - command: /sbin/ip a
    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: result|success"的意思為當(dāng)變量result執(zhí)行結(jié)果為成功
#將執(zhí)行/bin/something_else命令件甥,其他同理捌议。
#其中success為Ansible內(nèi)部過濾器方法,返回True代表命令運行成功引有。
循環(huán)語句
- name: whell
  hosts: testgroup
  remote_user: root
  gather_facts: true
  tasks:
  - name: "add user"
    user: name={{ item }} state=present groups=wheel
    with_items:
    - tiger1
    - tiger2
    
#創(chuàng)建用戶的瓣颅。with_items會自動循環(huán)執(zhí)行上面的語句"user: name={{ item }} state=present groups=wheel",循環(huán)的次數(shù)為with_items的元素個數(shù)譬正。這里有2個元素宫补,分別為tiger1、tiger2曾我,會分別替換{{ item }}項
#等同于
- name: whell
  hosts: testgroup
  remote_user: root
  gather_facts: true
  tasks:
  - name: "add user tiger1"
    user: name=tiger1 state=present groups=wheel
  - name: "add user tiger2"
    user: name=tiger2 state=present groups=wheel
循環(huán)元素支持列表
#首先定義好列表 list.yml
packages_base:
  - [ 'vsftpd', 'vim' ]
packages_apps:
  - [[ 'mysql',httpd' ]]

#然后引入使用
- name: whell
  hosts: testgroup
  remote_user: root
  gather_facts: true
  var_files: 
  - /etc/ansible/list.yml
  tasks:
  - name: "install rpm"
    yum: name={{ item }} state=installed
    with_flattened: #此語句 用來循環(huán)定義好的列表
    - packages_base
    - packages_apps
handlers 和 include

當(dāng)多個playbook涉及復(fù)用的任務(wù)列表時粉怕,可以將復(fù)用的內(nèi)容剝離出來,寫到獨立的文件里抒巢,需要的地方include進來即可

除了tasks之外贫贝,還有一個handlers的命令,handlers是在執(zhí)行tasks之后服務(wù)器發(fā)生變化之后可供調(diào)用的handler

- name: write the httpd config file
  hosts: testgroup
  remote_user: root
  gather_facts: true
  tasks:
  - name: write the httpd.conf to client
    template: src=/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
    notify:    # 如果copy執(zhí)行完之后/etc/httpd/conf/httpd.conf文件發(fā)送了變化蛉谜,則執(zhí)行
    - restart httpd  # 調(diào)用handler
    - include: playbook/tasks/httpd.yml
    
    handlers:
    - name: restart httpd #此處的標(biāo)識必須和notify一樣才可以引起觸發(fā)
      service: name=httpd state=restarted
      
 #注意上面使用的- include: playbook/tasks/httpd.yml稚晚,看一下這個文件的內(nèi)容
- name: ensure httpd is running
  service: name=httpd state=started

notify這個action可用于在每個play的最后被觸發(fā),這樣可以避免多次有改變發(fā)生時每次都執(zhí)行指定的操作型诚,取而代之客燕,僅在所有的變化發(fā)生完成后一次性地執(zhí)行指定操作。

Handlers 是由通知者進行 notify, 如果沒有被 notify,handlers 不會執(zhí)行狰贯。

Handlers 最佳的應(yīng)用場景是用來重啟服務(wù),或者觸發(fā)系統(tǒng)重啟操作.除此以外很少用到了也搓。

roles 使用

前面的所有都在一個文件內(nèi).還有一種方法可以進行更好的組織架構(gòu)
使用roles

[root@master roles]# tree
.
├── test
│   └── tasks
│       └── main.yml
└── test.yml
test.yml為入口文件,每次執(zhí)行它即可.他的內(nèi)容如下

[root@master roles]# cat test.yml 
---
- hosts: all
  roles:
    - role: test
定義了主機/主機組,然后定義了要使用的roles,(也就是roles下的文件夾的名字)

test文件夾下定義了tasks,內(nèi)有 **main.yml**  這個命名是規(guī)定好的.必須是main


main.yml 書寫了tasks的任務(wù).
[root@master roles]# cat test/tasks/main.yml 
---
- name: test role ping
  ping:

[root@master roles]# 

結(jié)果如下:

[root@master roles]# ansible-playbook test.yml 

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

TASK [Gathering Facts] ************************************************************************
ok: [10.1.27.28]
ok: [10.1.27.24]

TASK [test : test role ping] ******************************************************************
ok: [10.1.27.28]
ok: [10.1.27.24]

PLAY RECAP ************************************************************************************
10.1.27.24                 : ok=2    changed=0    unreachable=0    failed=0   
10.1.27.28                 : ok=2    changed=0    unreachable=0    failed=0   

roles有很多結(jié)構(gòu),ansible可以根據(jù)其進行解析.

├── defaults
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars

如果roles/x/tasks/main.yml存在,則自動將里面的tasks添加到play中赏廓。
如果roles/x/handlers/main.yml存在,則自動將里面的handlers添加到play中。
如果roles/x/vars/main.yml存在, 則自動將其中的variables添加到play中还绘。
如果roles/x/meta/main.yml存在,則添加role的依賴關(guān)系roles中楚昭。
任何copy任務(wù)、script任務(wù)都可以引用roles/x/files中的文件拍顷,無論是使用絕對或相對路徑都可以。
任何template任務(wù)都可以引用roles/x/templates中的文件塘幅,無論絕對或相對路徑昔案。
任何include任務(wù)都可以引用roles/x/tasks/中的文件,無論相對或絕對路徑

具體可以參見文檔:http://docs.ansible.com/playbooks_intro.html

(1)files/:存放copy或script模塊等調(diào)用的文件

(2)templates/:templates查找所需要模塊文件的目錄电媳;

(3)tasks/:(必須要有)至少應(yīng)該包含一個名為main.yml的文件踏揣,其他的文件需要在此文件中通過include進行包含;

(4)handlers/:至少應(yīng)該包含一個名為main.yml的文件匾乓,其他的文件需要在此文件中通過include進行包含捞稿;

(5)vars/:定義的是變量,至少應(yīng)該包含一個名為main.yml的文件拼缝,其他的文件需要在此文件中通過include進行包含娱局;

(6)meta/:定義此當(dāng)前角色的特殊設(shè)定及其他依賴關(guān)系,至少應(yīng)該包含一個名為main.yml的文件咧七,其他的文件需要在此文件中通過include進行包含衰齐;

(7)default/:為當(dāng)前角色設(shè)定默認(rèn)變量時使用目錄中的main.yml文件

ansible和saltstack的對比

1、salt要安裝agent , ansible通過ssh連接继阻。

2耻涛、salt在server端要啟進程;ansible不需要瘟檩。

3抹缕、salt與ansible都有模塊,可使用任意語言開發(fā)模塊墨辛。

4卓研、salt與ansible都使用yaml語言格式編寫劇本。

ansible走的是ssh,所以它有認(rèn)證以及加密碼的過程背蟆,使得ansible非常慢鉴分,不適用于大規(guī)模環(huán)境(指上千臺)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市带膀,隨后出現(xiàn)的幾起案子志珍,更是在濱河造成了極大的恐慌,老刑警劉巖垛叨,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伦糯,死亡現(xiàn)場離奇詭異柜某,居然都是意外死亡,警方通過查閱死者的電腦和手機敛纲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門喂击,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人淤翔,你說我怎么就攤上這事翰绊。” “怎么了旁壮?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵监嗜,是天一觀的道長。 經(jīng)常有香客問我抡谐,道長裁奇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任麦撵,我火速辦了婚禮刽肠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘免胃。我一直安慰自己音五,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布杜秸。 她就那樣靜靜地躺著放仗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪撬碟。 梳的紋絲不亂的頭發(fā)上诞挨,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天,我揣著相機與錄音呢蛤,去河邊找鬼惶傻。 笑死,一個胖子當(dāng)著我的面吹牛其障,可吹牛的內(nèi)容都是我干的银室。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼励翼,長吁一口氣:“原來是場噩夢啊……” “哼蜈敢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起汽抚,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤抓狭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后造烁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體否过,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡午笛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了苗桂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片药磺。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖煤伟,靈堂內(nèi)的尸體忽然破棺而出癌佩,到底是詐尸還是另有隱情,我是刑警寧澤便锨,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布驼卖,位于F島的核電站,受9級特大地震影響鸿秆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜怎囚,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一卿叽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恳守,春花似錦考婴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至伊群,卻和暖如春考杉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背舰始。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工崇棠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人丸卷。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓枕稀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谜嫉。 傳聞我的和親對象是個殘疾皇子萎坷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容