一:為什么選擇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.異步模式
async: 45 不指定則為同步
poll: 5 默認輪詢時間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:解壓文件