自動化運維—Ansible


一:為什么選擇Ansible

  相對於puppet和saltstack,ansible無需客戶端,更輕量級

  ansible甚至都不用啟動服務,僅僅只是一個工具,可以很輕松的實現分布式擴展

  更強的遠程命令執行操作

  不輸於puppet和saltstack的其他功能

二:Ansible基本架構

 

三:Asible基本組成

  核心:ansible

  核心模塊(Core Modules):這些都是ansible自帶的模塊

  擴展模塊(Custom Modules):如果核心模塊不足以完成某種功能,

  可以添加擴展模塊 插件(Plugins):完成模塊功能的補充

  劇本(Playbooks):ansible的任務配置文件,將多個任務定義在劇本中,由ansible自動執行

  連接插件(Connectior Plugins):ansible基於連接插件連接到各個主機上,雖然ansible是使用ssh連接到各個主機的,但是它還支持其他的連接方法,所以需要有連接插件

  主機群(Host Inventory):定義ansible管理的主機

四:ansible工作原理

 

 

五:ansible安裝 

  Ansible的安裝方式有很多種,常用的安裝方法是基於yum或者源碼,如果是基於yum安裝,需要配置epel源,然后直接執行yum -y install ansible即可。源碼安裝配置如下:

  解決依賴關系:

   yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto

  下載ansible:

#wget https://github.com/ansible/ansible/archive/release1.6.1.zip

  解壓安裝

unzip release1.6.1
cd ansible-release1.6.1
python setup.py build
python setup.py install
mkdir /etc/ansible
cp -r examples/* /etc/ansible  

六:主機清單

6.1簡單的主機和組

  中括號中的名字代表組名,可以根據自己的需求將龐大的主機分成具有標識的組,如上面分了兩個組webservers和dbservers組;

  主機(hosts)部分可以使用域名、主機名、IP地址表示;當然使用前兩者時,也需要主機能反解析到相應的IP地址,一般此類配置中多使用IP地址;

mail.yanruogu.com
[webservers]
web1.yanruogu.com
web2.yanruogu.com 
[dbservers]
db1.yanruogu.com
db2.yanruogu.com

6.2端口與別名

  如果某些主機的SSH運行在自定義的端口上,ansible使用Paramiko進行ssh連接時,不會使用你SSH配置文件中列出的端口,但是如果修改ansible使用openssh進行ssh連接時將會使用:

192.168.1.1:3091

  假如你想要為某些靜態IP設置一些別名,可以這樣做:

web1 ansible_ssh_port = 3333 ansible_ssh_host = 192.168.1.2

  上面的 web1別名就指代了IP為192.168.1.2,ssh連接端口為3333的主機。

6.3指定主機范圍

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

上面指定了從web1到web50,webservers組共計50台主機;databases組有db-a到db-f共6台主機。

6.4使用主機變量

  以下是Hosts部分中經常用到的變量部分:

ansible_ssh_host     #用於指定被管理的主機的真實IP
ansible_ssh_port     #用於指定連接到被管理主機的ssh端口號,默認是22
ansible_ssh_user     #ssh連接時默認使用的用戶名
ansible_ssh_pass     #ssh連接時的密碼
ansible_sudo_pass     #使用sudo連接用戶時的密碼
ansible_sudo_exec     #如果sudo命令不在默認路徑,需要指定sudo命令路徑
ansible_ssh_private_key_file     #秘鑰文件路徑,秘鑰文件如果不想使用ssh-agent管理時可以使用此選項
ansible_shell_type     #目標系統的shell的類型,默認sh
ansible_connection     #SSH 連接的類型: local , ssh , paramiko,在 ansible 1.2 之前默認是 paramiko ,后來智能選擇,優先使用基於 ControlPersist 的 ssh (支持的前提)
ansible_python_interpreter     #用來指定python解釋器的路徑,默認為/usr/bin/python 同樣可以指定ruby 、perl 的路徑
ansible_*_interpreter     #其他解釋器路徑,用法與ansible_python_interpreter類似,這里"*"可以是ruby或才perl等其他語言

  示例如下:

[test]
192.168.1.1 ansible_ssh_user=root ansible_ssh_pass='P@ssw0rd'
192.168.1.2 ansible_ssh_user=breeze ansible_ssh_pass='123456'
192.168.1.3 ansible_ssh_user=bernie ansible_ssh_port=3055 ansible_ssh_pass='456789'

  

  上面的示例中指定了三台主機,三台主機的用密碼分別是P@ssw0rd、123456、45789,指定的ssh連接的用戶名分別為root、breeze、bernie,ssh 端口分別為22、22、3055 ,這樣在ansible命令執行的時候就不用再指令用戶和密碼等了。

6.5組內變量

變量也可以通過組名,應用到組內的所有成員:

 [test]
 host1
 host2
 [test:vars]
 ntp_server=192.168.1.10
 proxy=192.168.1.20

  

上面test組中包含兩台主機,通過對test組指定vars變更,相應的host1和host2相當於相應的指定了ntp_server和proxy變量參數值 。

6.6組的包含與組內變量

  上面的示例中,指定了武漢組有web1、web2;隨州組有web3、web4主機;又指定了一個湖北組,同時包含武漢和隨州;同時為該組內的所有主機指定了2個vars變量。設定了一個組中國組,包含湖北、湖南。

  注:vars變量在ansible ad-hoc部分中基本用不到,主要用在ansible-playbook中。

   [wuhan]
   web1
   web2
   [suizhou]
   web4
   web3
   [hubei:children]
   wuhan
   suizhou
   [hubei:vars]
   ntp_server=192.168.1.10
   zabbix_server=192.168.1.10
   [china:children]
   hubei
   hunan

6.7Patterns(主機與組正則匹配部分)

  把Patterns 直接理解為正則實際是不完全准確的,正常的理解為patterns意味着在ansible中管理哪些主機,也可以理解為,要與哪台主機進行通信。在探討這個問題之前我們先看下ansible的用法:

  ansible <pattern_goes_here> -m <module_name> -a <arguments>

  直接上一個示例:

  ansible webservers -m service -a "name=httpd state=restarted"

  這里是對webservers 組或主機重啟httpd服務 ,其中webservers 就是Pattern部分。而之所以上面說Pattern(模式)可以理解為正則,主要針對下面經常用到的用法而言的。

1、表示所有的主機可以使用all 或 * 

2、通配符與邏輯或

利用通配符還可以指定一組具有規則特征的主機或主機名,冒號表示or---邏輯或

   web1.yanruogu.com
   web1.yanruogu.com:web2.yanruogu.com
   192.168.1.1
   192.168.1.*

  

當然,這里的*通配符也可以用在前面,如:

   *.yanruogu.com
   *.com    
   webservers1[0]     #表示匹配 webservers1 組的第 1 個主機    webservers1[0:25]  #表示匹配 webservers1 組的第 1 個到第 25 個主機(官網文檔是":"表示范圍,測試發現應該使用"-",注意不要和匹配多個主機組混淆)

  

上面的用法,在多個組之間同樣適用 ,如:

   webservers
   webservers:dbservers  #表示兩個組中所有的主機

  

3、邏輯非與邏輯and

非的表達式,如,目標主機必須在組webservers但不在phoenix組中

    webserver:!phoenix

  

交集的表達式,如,目標主機必須即在組webservers中又在組staging中

    webservers:&staging

  

一個更復雜的示例:

    webserver:dbservers:&staging:!phoenix

  

上面這個復雜的表達式最后表示的目標主機必須滿足:在webservers或者dbservers組中,必須還存在於staging組中,但是不在phoenix組中 。

4、混合高級用法

    *.yanruogu.com:*.org

  

還可以在開頭的地方使用”~”,用來表示這是一個正則表達式:

    ~(web|db).*\.yanruogu\.com

  

給兩個ansible-playbook中具體可能用的用法:

a、在ansible-palybook命令中,你也可以使用變量來組成這樣的表達式,但是你必須使用“-e”的選項來指定這個表達式(通常我們不這樣用):

    ansible-palybook -e webservers:!`excluded`:&`required`

  

b、在ansible和ansible-playbook中,還可以通過一個參數”--limit”來明確指定排除某些主機或組:

    ansible-playbook site.yml --limit datacenter2

  

c、從Ansible1.2開始,如果想排除一個文件中的主機可以使用"@":
    ansible-playbook site.yml --limit @retry_hosts.txt

  

七:ansible.cfg配置說明

  Ansible默認安裝好后有一個配置文件/etc/ansible/ansible.cfg,該配置文件中定義了ansible的主機的默認配置部分,如默認是否需要輸入密碼、是否開啟sudo認證、action_plugins插件的位置、hosts主機組的位置、是否開啟log功能、默認端口、key文件位置等等

7.1配置讀取順序

  1.環境變量

  2.當前目錄中的ansible.cfg

  3.家目錄中的ansible.cfg

  4./etc/ansible/ansible.cfg

 

7.2配置詳解

具體如下:

  [defaults]
   # some basic default values...
   hostfile       = /etc/ansible/hosts   \\指定默認hosts配置的位置
   # library_path = /usr/share/my_modules/
   remote_tmp     = $HOME/.ansible/tmp   \\
   sudo_exe=sudo                \\如果在其他遠程主機上使用另一種方式執行sudo操作, sudo程序的路徑可以用這個參數更換,使用命令行標簽來擬合標准sudo
   roles_path =/opt/mysite/roles\\roles 路徑指的是’roles/’下的額外目錄,多條的路徑可以用冒號分隔
   remote_user = root           \\ansible使用/usr/bin/ansible-playbook鏈接的默認用戶名. 注意如果不指定,/usr/bin/ansible默認使用當前用戶名稱
   inventory =/etc/ansible/hosts\\默認庫文件位置,腳本,或者存放可通信主機的目錄
   command_warnings = False     \\當shell和命令行模塊被默認模塊簡化的時,Ansible 將默認發出警告. 可以通過在命令行末尾添加 warn=yes 或者 warn=no選項來控制是否開啟警告提示
   deprecation_warnings = True  \\允許在ansible-playbook輸出結果中禁用“不建議使用”警告
   display_skipped_hosts = True \\跳過的任務狀態是否顯示,默認不顯示
   error_on_undefined_vars= True\\如果所引用的變量名稱錯誤的話, 將會導致ansible在執行步驟上失敗
   executable = /bin/bash       \\可以在sudo環境下產生一個shell交互接口. 用戶只在/bin/bash的或者sudo限制的一些場景中需要修改.大部分情況下不需要修改
   force_color = 1              \\到沒有使用TTY終端的時候,這個選項當用來強制顏色模式
   force_handlers = True        \\即便這個用戶崩潰,這個選項仍可以繼續運行這個用戶
   module_name = command        \\這個是/usr/bin/ansible的默認模塊名(-m). 默認是’command’模塊
   library = /usr/share/ansible \\Ansible默認搜尋模塊的位置
   nocolor=0                    \\默認ansible會為輸出結果加上顏色,用來更好的區分狀態信息和失敗信息.如果你想關閉這一功能,可以把’nocolor’設置為‘1’
   pattern        = *           \\playbook要通信的默認主機組.默認值是對所有主機通信,
   vault_password_file= /path/to/vault_password_file \\設置密碼文件,也可以通過命令行指定``–vault-password-file``
   timeout  = 10                \\SSH鏈接嘗試超市時間
   jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n \\允許開啟Jinja2拓展模塊
   private_key_file=/path/to/file.pem \\如果你是用pem密鑰文件而不是SSH 客戶端或密鑰認證的話,你可以設置這里的默認值,來避免每一次提醒設置密鑰文件位置``–ansible-private-keyfile``
   forks          = 5           \\這個選項設置在與主機通信時的默認並行進程數
   poll_interval  = 15          \\當具體的poll interval 沒有定義時,多少時間回查一下這些任務的狀態, 默認值是一個折中選擇15秒鍾
   sudo_user      = root  \\遠程sudo用戶,默認為root
   ask_sudo_pass = True   \\Ansible playbook 在執行sudo之前是否詢問sudo密碼.默認為no
   ask_pass      = True   \\Ansible 劇本playbook 是否會自動默認彈出彈出密碼.默認為no
   transport      = smart
   remote_port    = 22    \\設置是系統默認的遠程SSH端口,如果不指定,默認為22號端口
   module_lang    = C     \\這是默認模塊和系統之間通信的計算機語言,默認為’C’語言
   gathering = implicit   \\這個設置控制默認facts收集(遠程系統變量)
   host_key_checking = False    \\是否檢測主機密鑰
   log_path    = /var/log/ansible.log \\登陸日志,需要時可以自行添加。chown -R root:root ansible.log
   system_warnings = False    \\關閉運行ansible時系統的提示信息,一般為提示升級
   # set plugin path directories here, separate with colons
   action_plugins     = /usr/share/ansible_plugins/action_plugins       \\用來激活一些事件,例如執行一個模塊,一個模版,等等
   callback_plugins   = /usr/share/ansible_plugins/callback_plugins     #
   connection_plugins = /usr/share/ansible_plugins/connection_plugins   \\連接插件允許拓展ansible拓展通訊信道,用來傳輸命令或者文件.
   lookup_plugins     = /usr/share/ansible_plugins/lookup_plugins       \\允許模塊插件在不同區域被加載
   vars_plugins       = /usr/share/ansible_plugins/vars_plugins
   filter_plugins     = /usr/share/ansible_plugins/filter_plugins       \\過濾器是一種特殊的函數,用來拓展模版系統
[accelerate]
   accelerate_port = 5099    //急速模式下使用的端口
   accelerate_timeout = 30   //控制從客戶機獲取數據的超時時間.如果在這段時間內沒有數據傳輸,套接字連接會被關閉
   accelerate_connect_timeout = 5.0  //設置空着套接字調用的超時時間.這個應該設置相對比較短.這個和`accelerate_port`連接在回滾到ssh或者paramiko連接方式之前會嘗試三次開始遠程加速daemon守護進程.默認設置為1.0秒
   accelerate_daemon_timeout = 30    //控制加速daemon守護進程的超時時間,用分鍾來衡量.默認為30分鍾:
[paramiko]
   record_host_keys=True        //默認設置會記錄並驗證通過在用戶hostfile中新發現的的主機
[ssh_connection]
   ssh_args = -o ControlMaster=auto -o ControlPersist=60s  //ssh參數
   control_path=%(directory)s/ansible-ssh-%%h-%%p-%%r      //保存ControlPath套接字的位置
   scp_if_ssh=False                                        //.如果這個設置為True,scp將代替用來為遠程主機傳輸文件
   pipelining=False                                        //默認這個選項為了保證與sudoers requiretty的設置的兼容性是禁用的. 但是為了提高性能強烈建議開啟這個設置.

  如果在對之前未連接的主機進行連結時報錯如下:

ansible test -a 'uptime'
   192.168.1.1| FAILED =>Using a SSH password instead of a key is not possible because HostKeychecking is enabled and sshpass does not support this.Please add this host's fingerprint to your known_hosts file to manage this host.
   192.168.1.2 | FAILED => Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host.

  

  是由於在本機的~/.ssh/known_hosts文件中並有fingerprint key串,ssh第一次連接的時候一般會提示輸入yes 進行確認為將key字符串加入到  ~/.ssh/known_hosts 文件中。

方法1:

在進行ssh連接時,可以使用-o參數將StrictHostKeyChecking設置為no,使用ssh連接時避免首次連接時讓輸入yes/no部分的提示。通過查看ansible.cfg配置文件,發現如下行:

[ssh_connection]
# ssh arguments to use
# Leaving off ControlPersist will result in poor performance, so use
# paramiko on older platforms rather than removing it
#ssh_args = -o ControlMaster=auto -o ControlPersist=60s

可以啟用ssh_args 部分,使用下面的配置,避免上面出現的錯誤:

ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no

方法2:

在ansible.cfg配置文件中,也會找到如下配置:

# uncomment this to disable SSH key host checking
host_key_checking = False

  

默認host_key_checking部分是注釋的,通過找開該行的注釋,同樣也可以實現跳過ssh 首次連接提示驗證部分。但在實際測試中,似乎並沒有效果,建議使用方法1.

其他部分

默認ansible 執行的時候,並不會輸出日志到文件,不過在ansible.cfg 配置文件中有如下行:

log_path = /var/log/ansible.log

默認log_path這行是注釋的,打開該行的注釋,所有的命令執行后,都會將日志輸出到/var/log/ansible.log文件

 八:Ad-hoc與命令執行模塊

Ad-Hoc 是指ansible下臨時執行的一條命令,並且不需要保存的命令,對於復雜的命令會使用playbook。Ad-hoc的執行依賴於模塊,ansible官方提供了大量的模塊。 如:command、raw、shell、file、cron等,具體可以通過ansible-doc -l 進行查看 。可以使用ansible-doc -s module來查看某個模塊的參數,也可以使用ansible-doc help module來查看該模塊更詳細的信息。

8.1Ad-hoc 

1、命令說明

一個ad-hoc命令的執行,需要按以下格式進行執行:

    ansible 主機或組 -m 模塊名 -a '模塊參數'  ansible參數
  • 主機和組,是在/etc/ansible/hosts 里進行指定的部分,當然動態Inventory 使用的是腳本從外部應用里獲取的主機;

  • 模塊名,可以通過ansible-doc -l 查看目前安裝的模塊,默認不指定時,使用的是command模塊,具體可以查看/etc/ansible/ansible.cfg 的“#module_name = command ” 部分,默認模塊可以在該配置文件中進行修改;

  • 模塊參數,可以通過 “ansible-doc -s 模塊名” 查看具體的用法及后面的參數

  • ansible參數,可以通過ansible命令的幫助信息里查看到,這里有很多參數可以供選擇,如是否需要輸入密碼、是否sudo等。

2、后台執行

當命令執行時間比較長時,也可以放到后台執行,使用-B、-P參數,如下:

   ansible all -B 3600 -a "/usr/bin/long_running_operation --do-stuff" #后台執行命令3600s,-B 表示后台執行的時間
   ansible all -m async_status -a "jid=123456789"  #檢查任務的狀態
   ansible all -B 1800 -P 60 -a "/usr/bin/long_running_operation --do-stuff" #后台執行命令最大時間是1800s即30分鍾,-P 每60s檢查下狀態,默認15s
 
        

8.2命令執行模塊

命令執行模塊包含如下 四個模塊:

  • command模塊:該模塊通過-a跟上要執行的命令可以直接執行,不過命令里如果有帶有如下字符部分則執行不成功 “  "<", ">", "|",  "&" ;

  • shell 模塊:用法基本和command一樣,不過其是通過/bin/sh進行執行,所以shell 模塊可以執行任何命令,就像在本機執行一樣;

  • raw模塊:用法和shell 模塊一樣 ,其也可以執行任意命令,就像在本機執行一樣;

  • script模塊:其是將管理端的shell 在被管理主機上執行,其原理是先將shell 復制到遠程主機,再在遠程主機上執行,原理類似於raw模塊。

注:raw模塊和comand、shell 模塊不同的是其沒有chdir、creates、removes參數,chdir參數的作用就是先切到chdir指定的目錄后,再執行后面的命令,這在后面很多模塊里都會有該參數 。

command模塊包含如下選項: 

  • creates:一個文件名,當該文件存在,則該命令不執行 

  • free_form:要執行的linux指令 

  • chdir:在執行指令之前,先切換到該指定的目錄 

  • removes:一個文件名,當該文件不存在,則該選項不執行

  • executable:切換shell來執行指令,該執行路徑必須是一個絕對路徑

 

使用chdir的示例:

ansible 127.0.0.1 -m command -a 'chdir=/tmp/test.txt touch test.file'
ansible 127.0.0.1 -m shell -a 'chdir=/tmp/test.txt touch test2.file'
ansible 127.0.0.1 -m raw -a 'chdir=/tmp/text.txt touch test3.file'

三個命令都會返回執行成功的狀態。不過實際上只有前兩個文件會被創建成功。使用raw模塊的執行的結果文件事實上也被正常創建了,不過不是在chdir指定的目錄,而是在當前執行用戶的家目錄。

creates與removes示例:

ansible 192.168.1.1 -a 'creates=/tmp/server.txt uptime'         #當/tmp/server.txt文件存在時,則不執行uptime指令

ansible 192.168.1.1 -a 'removes=/tmp/server.txt uptime'       #當/tmp/server.txt文件不存在時,則不執行uptime指令

   

script模塊示例:

要執行的腳本文件script.sh內容如下:
#/bin/bash
ls /
執行ansible指令:
#ansible 10.212.52.252 -m script -a 'script.sh' |egrep '>>|stdout'
127.0.0.1 | SUCCESS => {
    "changed": true,
    "rc": 0,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "bin\nboot\ndata\ndev\netc\nhome\ninitrd.img\nlib\nlib64\nlost+found\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nsnap\nsrv\nsys\ntmp\nusr\nvar\nvmlinuz\n",
    "stdout_lines": [
        "bin",
        "boot",
        "data",
        "dev",
        "etc",
        "home",
        "initrd.img",
        "lib",
        "lib64",
        "lost+found",
        "media",
        "mnt",
        "opt",
        "proc",
        "root",
        "run",
        "sbin",
        "snap",
        "srv",
        "sys",
        "tmp",
        "usr",
        "var",
        "vmlinuz"
    ]
}

  

九:ansible常用模塊

  file:用於配置文件屬性

  yum:用於安裝軟件包

  cron:配置計划任務

  copy:復制文件到遠程主機

  command:在遠程主機上執行命令

  raw:類似於command模塊,支持管道

  user:配置用戶 group:配置用戶組

  service:用於管理服務

  ping:用於檢測遠程主機是否存活

  setup:查看遠程主機的基本信息

  mount:配置掛載點

 展示所有模塊

ansible-doc -l 

 查看某模塊相關參數

ansible-doc -s user

 調用某模塊,某個參數

#-m調用某個模塊
#-a調用該模塊下某個參數
ansible all -m command -a 'ls /home'

9.1setup模塊

    查看遠程主機的基本信息

    setup模塊,主要用於獲取主機信息,在playbooks里經常會用到的一個參數gather_facts就與該模塊相關。setup模塊下經常使用的一個參數是filter參數,具體使用示例如下:

ansible 10.212.52.252 -m setup -a 'filter=ansible_*_mb'   //查看主機內存信息
ansible 10.212.52.252 -m setup -a 'filter=ansible_eth[0-2]'   //查看地接口為eth0-2的網卡信息
ansible all -m setup --tree /tmp/facts   //將所有主機的信息輸入到/tmp/facts目錄下,每台主機的信息輸入到主機名文件中(/etc/ansible/hosts里的主機名)

  

9.2ping

       測試主機是否是通的,用法很簡單,不涉及參數:

ansible test -m ping

9.3file  

   file模塊主要用於遠程主機上的文件操作,file模塊包含如下選項: 

  • force:需要在兩種情況下強制創建軟鏈接,一種是源文件不存在但之后會建立的情況下;另一種是目標軟鏈接已存在,需要先取消之前的軟鏈,然后創建新的軟鏈,有兩個選項:yes|no 

  • group:定義文件/目錄的屬組 

  • mode:定義文件/目錄的權限

  • owner:定義文件/目錄的屬主

  • path:必選項,定義文件/目錄的路徑

  • recurse:遞歸的設置文件的屬性,只對目錄有效

  • src:要被鏈接的源文件的路徑,只應用於state=link的情況

  • dest:被鏈接到的路徑,只應用於state=link的情況 

  • state:  

    • directory:如果目錄不存在,創建目錄

    • file:即使文件不存在,也不會被創建

    • link:創建軟鏈接

    • hard:創建硬鏈接

    • touch:如果文件不存在,則會創建一個新的文件,如果文件或目錄已存在,則更新其最后修改時間

    • absent:刪除目錄、文件或者取消鏈接文件

使用示例:

ansible test -m file -a "src=/etc/fstab dest=/tmp/fstab state=link"    
ansible test -m file -a "path=/tmp/fstab state=absent"
ansible test -m file -a "path=/tmp/test state=touch"

  

9.4copy模塊

復制文件到遠程主機,copy模塊包含如下選項:

  • backup:在覆蓋之前將原文件備份,備份文件包含時間信息。有兩個選項:yes|no 

  • content:用於替代"src",可以直接設定指定文件的值 

  • dest:必選項。要將源文件復制到的遠程主機的絕對路徑,如果源文件是一個目錄,那么該路徑也必須是個目錄 

  • directory_mode:遞歸的設定目錄的權限,默認為系統默認權限

  • force:如果目標主機包含該文件,但內容不同,如果設置為yes,則強制覆蓋,如果為no,則只有當目標主機的目標位置不存在該文件時,才復制。默認為yes

  • others:所有的file模塊里的選項都可以在這里使用

  • src:要復制到遠程主機的文件在本地的地址,可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,它將遞歸復制。在這種情況下,如果路徑使用"/"來結尾,則只復制目錄里的內容,如果沒有使用"/"來結尾,則包含目錄在內的整個內容全部復制,類似於rsync。 

  • validate :The validation command to run before copying into place. The path to the file to validate is passed in via '%s' which must be present as in the visudo example below.

示例如下:

ansible test -m copy -a "src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode=0644"
ansible test -m copy -a "src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes"
ansible test -m copy -a "src=/mine/sudoers dest=/etc/sudoers validate='visudo -cf %s'"

  

9.5cron模塊

用於管理計划任務包含如下選項: 

  • backup:對遠程主機上的原任務計划內容修改之前做備份 

  • cron_file:如果指定該選項,則用該文件替換遠程主機上的cron.d目錄下的用戶的任務計划 

  • day:日(1-31,*,*/2,……) 

  • hour:小時(0-23,*,*/2,……)  

  • minute:分鍾(0-59,*,*/2,……) 

  • month:月(1-12,*,*/2,……) 

  • weekday:周(0-7,*,……)

  • job:要執行的任務,依賴於state=present 

  • name:該任務的描述 

  • special_time:指定什么時候執行,參數:reboot,yearly,annually,monthly,weekly,daily,hourly 

  • state:確認該任務計划是創建還是刪除 

  • user:以哪個用戶的身份執行

示例:

ansible test -m cron -a 'name="a job for reboot" special_time=reboot job="/some/job.sh"'
ansible test -m cron -a 'name="yum autoupdate" weekday="2" minute=0 hour=12 user="root
ansible test -m cron  -a 'backup="True" name="test" minute="0" hour="5,2" job="ls -alh > /dev/null"'
ansilbe test -m cron -a 'cron_file=ansible_yum-autoupdate state=absent'

  

9.6yum模塊

使用yum包管理器來管理軟件包,其選項有: 

  • config_file:yum的配置文件 

  • disable_gpg_check:關閉gpg_check 

  • disablerepo:不啟用某個源 

  • enablerepo:啟用某個源

  • name:要進行操作的軟件包的名字,也可以傳遞一個url或者一個本地的rpm包的路徑 

  • state:狀態(present【安裝】,absent【卸載】,latest)

示例如下:

ansible test -m yum -a 'name=httpd state=latest'
ansible test -m yum -a 'name="@Development tools" state=present'
ansible test -m yum -a 'name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present'

  

9.7user模塊與group模塊

user模塊是請求的是useradd, userdel, usermod三個指令,goup模塊請求的是groupadd, groupdel, groupmod 三個指令。

9.7.1user模塊

  • home:指定用戶的家目錄,需要與createhome配合使用

  • groups:指定用戶的屬組

  • uid:指定用的uid

  • password:指定用戶的密碼

  • name:指定用戶名

  • createhome:是否創建家目錄 yes|no

  • system:是否為系統用戶

  • remove:當state=absent時,remove=yes則表示連同家目錄一起刪除,等價於userdel -r

  • state:是創建還是刪除

  • shell:指定用戶的shell環境

使用示例:
ansible test -m user -a 'createhome=yes home=/home/user1 password=123123 name=user2 state=present shell=/bin/bash'
user: name=johnd comment="John Doe" uid=1040 group=admin
user: name=james shell=/bin/bash groups=admins,developers append=yes user: name=johnd state=absent remove=yes
user: name=james18 shell=/bin/zsh groups=developers expires=1422403387
user: name=test generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa    #生成密鑰時,只會生成公鑰文件和私鑰文件,和直接使用ssh-keygen指令效果相同,不會生成authorized_keys文件。

  

注:指定password參數時,不能使用明文密碼,因為后面這一串密碼會被直接傳送到被管理主機的/etc/shadow文件中,所以需要先將密碼字符串進行加密處理。然后將得到的字符串放到password中即可。

echo "123456" | openssl passwd -1 -salt $(< /dev/urandom tr -dc '[:alnum:]' | head -c 32) -stdin
$1$4P4PlFuE$ur9ObJiT5iHNrb9QnjaIB0
#使用上面的密碼創建用戶
ansible all -m user -a 'name=foo password="$1$4P4PlFuE$ur9ObJiT5iHNrb9QnjaIB0"'

  

不同的發行版默認使用的加密方式可能會有區別,具體可以查看/etc/login.defs文件確認,centos 6.5版本使用的是SHA512加密算法。

 

9.7.2group示例

ansible all -m group -a 'name=somegroup state=present'

  

9.8synchronize模塊

使用rsync同步文件,其參數如下:

  • archive: 歸檔,相當於同時開啟recursive(遞歸)、links、perms、times、owner、group、-D選項都為yes ,默認該項為開啟

  • checksum: 跳過檢測sum值,默認關閉

  • compress:是否開啟壓縮

  • copy_links:復制鏈接文件,默認為no ,注意后面還有一個links參數

  • delete: 刪除不存在的文件,默認no

  • dest:目錄路徑

  • dest_port:默認目錄主機上的端口 ,默認是22,走的ssh協議

  • dirs:傳速目錄不進行遞歸,默認為no,即進行目錄遞歸

  • rsync_opts:rsync參數部分

  • set_remote_user:主要用於/etc/ansible/hosts中定義或默認使用的用戶與rsync使用的用戶不同的情況

  • mode: push或pull 模塊,push模的話,一般用於從本機向遠程主機上傳文件,pull 模式用於從遠程主機上取文件

使用示例:

src=some/relative/path dest=/some/absolute/path rsync_path="sudo rsync"
src=some/relative/path dest=/some/absolute/path archive=no links=yes
src=some/relative/path dest=/some/absolute/path checksum=yes times=no
src=/tmp/helloworld dest=/var/www/helloword rsync_opts=--no-motd,--exclude=.git mode=pull

  

9.9filesystem模塊

在塊設備上創建文件系統
選項: 

  • dev:目標塊設備

  • force:在一個已有文件系統 的設備上強制創建

  • fstype:文件系統的類型

  • opts:傳遞給mkfs命令的選項

示例:

ansible test -m filesystem -a 'fstype=ext2 dev=/dev/sdb1 force=yes'

ansible test -m filesystem -a 'fstype=ext4 dev=/dev/sdb1 opts="-cc"'

  

9.10mount模塊

配置掛載點
選項: 

  • dump

  • fstype:必選項,掛載文件的類型 

  • name:必選項,掛載點 

  • opts:傳遞給mount命令的參數

    src:必選項,要掛載的文件 

    state:必選項 

    present:只處理fstab中的配置 
    absent:刪除掛載點 
    mounted:自動創建掛載點並掛載之 
    umounted:卸載

示例:

name=/mnt/dvd src=/dev/sr0 fstype=iso9660 opts=ro state=present
name=/srv/disk src='LABEL=SOME_LABEL' state=present
name=/home src='UUID=b3e48f45-f933-4c8e-a700-22a159ec9077' opts=noatime state=present
ansible test -a 'dd if=/dev/zero of=/disk.img bs=4k count=1024'
ansible test -a 'losetup /dev/loop0 /disk.img'
ansible test -m filesystem 'fstype=ext4 force=yes opts=-F dev=/dev/loop0'
ansible test -m mount 'name=/mnt src=/dev/loop0 fstype=ext4 state=mounted opts=rw'

  

9.11get_url 模塊

該模塊主要用於從http、ftp、https服務器上下載文件(類似於wget),主要有如下選項:

  • sha256sum:下載完成后進行sha256 check;

  • timeout:下載超時時間,默認10s

  • url:下載的URL

  • url_password、url_username:主要用於需要用戶名密碼進行驗證的情況

  • use_proxy:是事使用代理,代理需事先在環境變更中定義

示例:

 get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf mode=0440
 get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf sha256sum=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c

  

 
        

9.12unarchive模塊

用於解壓文件,模塊包含如下選項:

  • copy:在解壓文件之前,是否先將文件復制到遠程主機,默認為yes。若為no,則要求目標主機上壓縮包必須存在。

  • creates:指定一個文件名,當該文件存在時,則解壓指令不執行

  • dest:遠程主機上的一個路徑,即文件解壓的路徑 

  • grop:解壓后的目錄或文件的屬組

  • list_files:如果為yes,則會列出壓縮包里的文件,默認為no,2.0版本新增的選項

  • mode:解決后文件的權限

  • src:如果copy為yes,則需要指定壓縮文件的源路徑 

  • owner:解壓后文件或目錄的屬主

示例如下:

- unarchive: src=foo.tgz dest=/var/lib/foo
- unarchive: src=/tmp/foo.zip dest=/usr/local/bin copy=no
- unarchive: src=https://example.com/example.zip dest=/usr/local/bin copy=no

十:playbooks

10.1.playbooks基礎

  playbooks 是一種簡單的配置管理系統與多機器部署系統的基礎.與現有的其他系統有不同之處,且非常適合於復雜應用的部署.

       Playbooks 的格式是YAML(詳見:YAML 語法),語法做到最小化,意在避免 playbooks 成為一種編程語言或是腳本,但它也並不是一個配置模型或過程的模型.

  playbook 由一個或多個 ‘plays’ 組成.它的內容是一個以 ‘plays’ 為元素的列表.

       在 play 之中,一組機器被映射為定義好的角色.在 ansible 中,play 的內容,被稱為 tasks,即任務.在基本層次的應用中,一個任務是一個對 ansible 模塊的調用.

1.用戶組

###自定義遠程用戶
---
- hosts: webservers
  remote_user: root
  tasks:
    - name: test connetion
      ping: 
      remote_user: yh

###sudo執行
---
- hosts: webservers
  remote_user: root
  sudo: yes


###單個tasks用sudo執行
---
- hosts: webserver
  remote_user: root
  tasks:
    - service: name=nginx state=stared
      sudo: yes
      sudo_user: yh
 
 

2.Tasks列表

  每一個play包含一個task列表,每一個task在其所對應的主機上執行完畢后,下一個task才會執行,

3.Handlers 

  Handlers 最佳的應用場景是用來重啟服務,或者觸發系統重啟操作.除此以外很少用到了。

handlers:
    - name: restart memcached
      service:  name=memcached state=restarted
    - name: restart apache
      service: name=apache state=restarted

10.2.playbook之Role、Include

  假如你希望在多個 play 或者多個 playbook 中重用同一個 task 列表,你可以使用 include files 做到這一點。

tasks
  - include: tasks/foo.yml

  Roles 基於一個已知的文件結構,去自動的加載某些 vars_files,tasks 以及 handlers。基於 roles 對內容進行分組,使得我們可以容易地與其他用戶分享 roles 。

  這個 playbook 為一個角色 ‘x’ 指定了如下的行為:

  • 如果 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 存在, 其中列出的 “角色依賴” 將被添加到 roles 列表中 (1.3 and later)
  • 所有 copy tasks 可以引用 roles/x/files/ 中的文件,不需要指明文件的路徑。
  • 所有 script tasks 可以引用 roles/x/files/ 中的腳本,不需要指明文件的路徑。
  • 所有 template tasks 可以引用 roles/x/templates/ 中的文件,不需要指明文件的路徑。
  • 所有 include tasks 可以引用 roles/x/tasks/ 中的文件,不需要指明文件的路徑。
---

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

10.3.Variables

  YAML語法要求如果值以{{ foo }}開頭的話我們需要將整行用雙引號包起來.這是為了確認你不是想聲明一個YAML字典.

- hosts: app_servers
  vars:
       app_path: "{{ base_path }}/22"

  獲取遠程主機的IP地址或者操作系統是什么,以及硬盤類型、主機名等都可以從中獲取。

ansibel  hostname   -m setup

有些提供的facts,比如網絡信息等,是一個嵌套的數據結構.訪問它們使用簡單的 {{ foo }} 語法並不夠用,當仍然很容易.如下所示:

{{ ansible_eth0["ipv4"]["address"] }}

或者這樣寫:

{{ ansible_eth0.ipv4.address }}

相似的,以下代碼展示了我們如何訪問數組的第一個元素:

{{ foo[0] }}

  Ansible會自動提供給你一些變量,即使你並沒有定義過它們.這些變量中重要的有 ‘hostvars’,’group_names’,和 ‘groups’.由於這些變量名是預留的,所以用戶不應當覆蓋它們. ‘environmen’ 也是預留的. hostvars可以讓你訪問其它主機的變量,包括哪些主機中獲取到的facts.

  group_names 是當前主機所在所有群組的列表(數組).所以可以使用Jinja2語法在模板中根據該主機所在群組關系(或角色)來產生變化:

{% if 'webserver' in group_names %}
   # some part of a configuration file that only applies to webservers
{% endif %}

  groups 是inventory中所有群組(主機)的列表.可用於枚舉群組中的所有主機.例如:

{% for host in groups['app_servers'] %}
   # something that applies to all app servers.
{% endfor %}

變量文件分割

  把playbook置於源代碼管理之下是個很好的注意,當你可能會想把playbook源碼公開之余還想保持某些重要的變量私有.有時你也想把某些信息放置在不同的文件中,遠離主playbook文件

你可以使用外部的變量文件來實現:

---

- hosts: all
  remote_user: root
  vars:
    favcolor: blue
  vars_files:
    - /vars/external_vars.yml

  tasks:

  - name: this is just a placeholder
    command: /bin/echo foo

這可以保證你共享playbook源碼時隔離敏感數據的風險.

每個變量文件的內容是一個簡單的YAML文件,如下所示:

---
# in the above example, this would be vars/external_vars.yml
somevar: somevalue
password: magic

命令行中傳參

  除了`vars_prompt`和`vars_files`也可以通過Ansible命令行發送變量.如果你想編寫一個通用的發布playbook時則特別有用,你可以傳遞應用的版本以便部署:

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"

  

其它場景中也很有用,比如為playbook設置主機群組或用戶.

Example:

---

- hosts: '{{ hosts }}'
  remote_user: '{{ user }}'

  tasks:
     - ...

ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"

 

10.4.條件選擇

1.when

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

  

tasks:
  - shell: echo "only on Red Hat 6, derivatives, and later"
    when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6

  如果一個變量不存在,你可以使用Jinja2的`defined`命令跳過或略過.例如:

tasks:
    - shell: echo "I've got '{{ foo }}' and am not afraid to use it!"
      when: foo is defined

    - fail: msg="Bailing out. this play requires 'bar'"
      when: bar is not defined

2.條件導入

  舉個例子,名字叫做Apache的包,在CentOS 和 Debian系統中也許不同, 但是這個問題可以一些簡單的語法就可以被Ansible Playbook解決:

---
- hosts: all
  remote_user: root
  vars_files:
    - "vars/common.yml"
    - [ "vars/{{ ansible_os_family }}.yml", "vars/os_defaults.yml" ]
  tasks:
  - name: make sure apache is running
    service: name={{ apache }} state=running

3.基於變量選擇文件或者模板

  有時候,你想要復制一個配置文件,或者一個基於參數的模版. 下面的結構選載選第一個宿主給予的變量文件,這些可以比把很多if選擇放在模版里要簡單的多. 下面的例子展示怎樣根據不同的系統,例如CentOS,Debian制作一個配置文件的模版:

- name: template a file
   template: src={{ item }} dest=/etc/myapp/foo.conf
   with_first_found:
     - files:
        - {{ ansible_distribution }}.conf
        - default.conf
       paths:
        - search_location_one/somedir/
        - /opt/other_location/somedir/

4.注冊變量

   ‘register’ 關鍵詞決定了把結果存儲在哪個變量中.結果參數可以用在模版中,動作條目,或者 when 語句. 像這樣(這是一個淺顯的例子):

- name: test play
  hosts: all

  tasks:

      - shell: cat /etc/motd
        register: motd_contents

      - shell: echo "motd contains the word hi"
        when: motd_contents.stdout.find('hi') != -1

  

10.5.循環

(1)標准循環:with_items

(2)嵌套循環:with_nested

(3)哈希列表循環:with_dict                         【編譯一個集合中的key和value】

(4)文件列表循環:with_fileglob                   【遍歷一個目錄下所有文件】

(5)並行數據使用循環:with_together          【將兩個數組一對一遍歷成集合】

(6)對子元素進行循環:with_subelements   【用來加載一個yml文件中的各元素以及子元素】

(7)對整數序列采用循環:with_sequence    【循環某段整數之間的數字】

(8)生成隨機數字:random_choice

(9)Do_until循環:until                                  【通過設定循環次數和循環時間等待服務達到某種狀態】

(10)查找第一個匹配的文件:with_fist_found

(11)使用索引循環列表:with_indexd_items  【循環列表的同時可以換取索引所在位置】

(12)循環匹配文件:with_ini                          【ini插件可以使用正則表達式來獲取一組鍵值對】

(13)扁平化列表:with_flattened                   【循環迭代多層嵌套列表】

(14)循環中使用注冊器:with_items              【循環獲取registry的results】

1.標准循環

為了保持簡潔,重復的任務可以用以下簡寫的方式:

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

如果你在變量文件中或者 ‘vars’ 區域定義了一組YAML列表,你也可以這樣做:

with_items: "{{somelist}}"

以上寫法與下面是完全等同的:

- name: add user testuser1
  user: name=testuser1 state=present groups=wheel
- name: add user testuser2
  user: name=testuser2 state=present groups=wheel

  

使用 ‘with_items’ 用於迭代的條目類型不僅僅支持簡單的字符串列表.如果你有一個哈希列表,那么你可以用以下方式來引用子項:

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

2.嵌套循環

循環也可以嵌套:

- name: give users access to multiple databases
  mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
  with_nested:
    - [ 'alice', 'bob' ]
    - [ 'clientdb', 'employeedb', 'providerdb' ]

和以上介紹的’with_items’一樣,你也可以使用預定義變量.:

- name: here, 'users' contains the above list of employees
  mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
  with_nested:
    - "{{users}}"
    - [ 'clientdb', 'employeedb', 'providerdb' ]

3.對哈希表使用循環

假如你有以下變量:

---
users:
  alice:
    name: Alice Appleworth
    telephone: 123-456-7890
  bob:
    name: Bob Bananarama
    telephone: 987-654-3210

  

你想打印出每個用戶的名稱和電話號碼.你可以使用 with_dict 來循環哈希表中的元素:

tasks:
  - name: Print phone records
    debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
    with_dict: "{{users}}"

   

4.對文件列表使用循環

with_fileglob 可以以非遞歸的方式來模式匹配單個目錄中的文件.如下面所示:

---
- hosts: all

  tasks:

    # first ensure our target directory exists
    - file: dest=/etc/fooapp state=directory

    # copy each file over that matches the given pattern
    - copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600
      with_fileglob:
        - /playbooks/files/fooapp/*

5.對並行數據采用循環

假設你通過某種方式加載了以下變量數據:

---
alpha: [ 'a', 'b', 'c', 'd' ]
numbers:  [ 1, 2, 3, 4 ]

如果你想得到’(a, 1)’和’(b, 2)’之類的集合.可以使用’with_together’:

tasks:
    - debug: msg="{{ item.0 }} and {{ item.1 }}"
      with_together:
        - "{{alpha}}"
        - "{{numbers}}"

7.對子元素進行循環

假設你想對一組用戶做一些動作,比如創建這些用戶,並且允許它們使用一組SSH key來登錄.

如何實現那? 先假設你有按以下方式定義的數據,可以通過”vars_files”或”group_vars/all”文件加載:

---
users:
  - name: alice
    authorized:
      - /tmp/alice/onekey.pub
      - /tmp/alice/twokey.pub
    mysql:
        password: mysql-password
        hosts:
          - "%"
          - "127.0.0.1"
          - "::1"
          - "localhost"
        privs:
          - "*.*:SELECT"
          - "DB1.*:ALL"
  - name: bob
    authorized:
      - /tmp/bob/id_rsa.pub
    mysql:
        password: other-mysql-password
        hosts:
          - "db1"
        privs:
          - "*.*:SELECT"
          - "DB2.*:ALL"

  

那么可以這樣實現:

- user: name={{ item.name }} state=present generate_ssh_key=yes
  with_items: "{{users}}"

- authorized_key: "user={{ item.0.name }} key='{{ lookup('file', item.1) }}'"
  with_subelements:
     - users
     - authorized

  

根據mysql hosts以及預先給定的privs subkey列表,我們也可以在嵌套的subkey中迭代列表:

- name: Setup MySQL users
  mysql_user: name={{ item.0.user }} password={{ item.0.mysql.password }} host={{ item.1 }} priv={{ item.0.mysql.privs | join('/') }}
  with_subelements:
    - users
    - mysql.hosts

8.對整數序列進行循環

with_sequence 可以以升序數字順序生成一組序列.你可以指定起始值、終止值,以及一個可選的步長值.

指定參數時也可以使用key=value這種鍵值對的方式.如果采用這種方式,’format’是一個可打印的字符串.

數字值可以被指定為10進制,16進制(0x3f8)或者八進制(0600).負數則不受支持.請看以下示例:

---
- hosts: all

  tasks:

    # create groups
    - group: name=evens state=present
    - group: name=odds state=present

    # create some test users
    - user: name={{ item }} state=present groups=evens
      with_sequence: start=0 end=32 format=testuser%02x

    # create a series of directories with even numbers for some reason
    - file: dest=/var/stuff/{{ item }} state=directory
      with_sequence: start=4 end=16 stride=2

    # a simpler way to use the sequence plugin
    # create 4 groups
    - group: name=group{{ item }} state=present
      with_sequence: count=4
 

9.隨機選擇

  ‘random_choice’功能可以用來隨機獲取一些值.它並不是負載均衡器(已經有相關的模塊了).它有時可以用作一個簡化版的負載均衡器,比如作為條件判斷:

- debug: msg={{ item }}
  with_random_choice:
     - "go through the door"
     - "drink from the goblet"
     - "press the red button"
     - "do nothing"

  提供的字符串中的其中一個會被隨機選中.

10.Do-Until循環

     有時你想重試一個任務直到達到某個條件.比如下面這個例子:

- action: shell /usr/bin/foo
  register: result
  until: result.stdout.find("all systems go") != -1
  retries: 5
  delay: 10

  

  上面的例子遞歸運行shell模塊,直到模塊結果中的stdout輸出中包含”all systems go”字符串,或者該任務按照10秒的延遲重試超過5次.”retries”和”delay”的默認值分別是3和5.

  該任務返回最后一個任務返回的結果.單次重試的結果可以使用-vv選項來查看. 被注冊的變量會有一個新的屬性’attempts’,值為該任務重試的次數.

11.查找第一個匹配文件

  這其實不是一個循環,但和循環很相似.如果你想引用一個文件,而該文件是從一組文件中根據給定條件匹配出來的.這組文件中部分文件名由變量拼接而成.針對該場景你可以這樣做:

- name: INTERFACES | Create Ansible header for /etc/network/interfaces
  template: src={{ item }} dest=/etc/foo.conf
  with_first_found:
    - "{{ansible_virtualization_type}}_foo.conf"
    - "default_foo.conf"

  該功能還有一個更完整的版本,可以配置搜索路徑.請看以下示例:

- name: some configuration template
  template: src={{ item }} dest=/etc/file.cfg mode=0444 owner=root group=root
  with_first_found:
    - files:
       - "{{inventory_hostname}}/etc/file.cfg"
      paths:
       - ../../../templates.overwrites
       - ../../../templates
    - files:
        - etc/file.cfg
      paths:
        - templates

  

12.迭代程序的執行結果

13.使用索引循環列表

14.扁平化列表

15.循環中使用注冊器

16.自定義迭代

 

  當對處於循環中的某個數據結構使用 register 來注冊變量時,結果包含一個 results 屬性,這是從模塊中得到的所有響應的一個列表.

  以下是在 with_items 中使用 register 的示例:

- shell: echo "{{ item }}"
  with_items:
    - one
    - two
  register: echo 

  返回的數據結構如下,與非循環結構中使用 register 的返回結果是不同的:

{
    "changed": true,
    "msg": "All items completed",
    "results": [
        {
            "changed": true,
            "cmd": "echo \"one\" ",
            "delta": "0:00:00.003110",
            "end": "2013-12-19 12:00:05.187153",
            "invocation": {
                "module_args": "echo \"one\"",
                "module_name": "shell"
            },
            "item": "one",
            "rc": 0,
            "start": "2013-12-19 12:00:05.184043",
            "stderr": "",
            "stdout": "one"
        },
        {
            "changed": true,
            "cmd": "echo \"two\" ",
            "delta": "0:00:00.002920",
            "end": "2013-12-19 12:00:05.245502",
            "invocation": {
                "module_args": "echo \"two\"",
                "module_name": "shell"
            },
            "item": "two",
            "rc": 0,
            "start": "2013-12-19 12:00:05.242582",
            "stderr": "",
            "stdout": "two"
        }
    ]
}

  隨后的任務可以用以下方式來循環注冊變量,用來檢查結果值:

- name: Fail if return code is not 0
  fail:
    msg: "The command ({{ item.cmd }}) did not have a 0 return code"
  when: item.rc != 0
  with_items: "{{echo.results}}"

  

 十一:重要點總結

1.Variables

(1)合法變量名:變量名可以為字母,數字以及下划線.變量始終應該以字母開頭.

(2)playbook中定義變量:

  vars:
    http_port: 80

(3) 值以{{ foo }}開頭的話我們需要將整行用雙引號包起來

(4)使用facts獲取信息:ansible  hostname  -m setup

2.條件選擇

(1)when

(2)注冊變量:register:  變量名

                     {{ 變量名.stdout.find() }}

                    {{ 變量名.ipv4.address }}

3.循環

(1)標准循環:with_items

(2)嵌套循環:with_nested

(3)哈希列表循環:with_dict                         【編譯一個集合中的key和value】

(4)文件列表循環:with_fileglob                   【遍歷一個目錄下所有文件】

(5)並行數據使用循環:with_together          【將兩個數組一對一遍歷成集合】

(6)對子元素進行循環:with_subelements   【用來加載一個yml文件中的各元素以及子元素】

(7)對整數序列采用循環:with_sequence    【循環某段整數之間的數字】

(8)生成隨機數字:random_choice

(9)Do_until循環:until                                  【通過設定循環次數和循環時間等待服務達到某種狀態】

(10)查找第一個匹配的文件:with_fist_found

(11)使用索引循環列表:with_indexd_items  【循環列表的同時可以換取索引所在位置】

(12)循環匹配文件:with_ini                          【ini插件可以使用正則表達式來獲取一組鍵值對】

(13)扁平化列表:with_flattened                   【循環迭代多層嵌套列表】

(14)循環中使用注冊器:with_items              【循環獲取registry的results】

4.Special Topics

(1)異步和輪詢

    對於耗時長的任務可以采取,1.同時進行多個任務 2.異步模式

    async45  不指定則為同步

    poll5       默認輪詢時間10s

(2)check mode

(3)錯誤處理:

忽略錯誤命令:ignore_errors: yes
控制對失敗的定義:failed_when: "'FAILED' in command_result.stderr"
覆蓋結果:changed_when: False

(4)標簽:tags運行指定標簽部分

(5)vault:加密和解密文件

(6)start-at-task:從指定階段開始運行

(7)step:在每個任務前會自動停止,並詢問是否應該執行該任務

5.模塊

1.setup:獲取主機的基本信息

2.ping:測試主機是否是通的

3.file:用於遠程主機上的文件操作

4.copy:復制文件到遠程主機

5.yum:管理軟件包

6.user/group:管理用戶組

7.mount:掛載模塊

8.get_url:用於從http、ftp、https服務器上下載文件(類似於wget)

9.unarchive:解壓文件

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM