目錄
參考
介紹
在Playbook
中,使用task
來定義一個子任務,並在任務中指定需要使用的模塊,以及觸發條件等信息。最終一個Playbook
的Yml
文件中可由多個task
組成,按照任務順序對指定主機進行自動化運維
YAML語言
教程
https://www.runoob.com/w3cnote/yaml-intro.html
核心元素
- Hosts 執行的遠程主機列表
- remote_user:指定執行任務時在遠程主機上所用的用戶
- Tasks 任務集
- Variables 內置變量或自定義變量在playbook中調用
- Templates 模板,可替換模板文件中的變量並實現一些簡單邏輯的文件
- Handlers 和 notify 結合使用,由特定條件觸發的操作,滿足條件方纔執行,否則不執行
- tags 標籤 指定某條任務執行,用於選擇運行playbook中的部分代碼。ansible具有冪等性,因此會自動跳過沒有變化的部分,即便如此,有些代碼爲測試其確實沒有發生變化的時間依然會非常地長。此時,如果確信其沒有變化,就可以通過tags跳過此些代碼片斷
注:hosts用於指定要執行指定任務的主機,須事先定義在主機清單中
playbook命令
格式
ansible-playbook <filename.yml> ... [options]
常見選項
-C --check #只檢測可能會發生的改變,但不真正執行操作
--list-hosts #列出運行任務的主機
--list-tags #列出tag
--list-tasks #列出task
--limit 主機列表 #只針對主機列表中的主機執行
-v -vv -vvv #顯示過程
playbook初步
開啓遠程主機mysql
的遠程訪問權限
[root@localhost playbook]# cat config-mysql.yml
---
- hosts: csmp
gather_facts: no
tasks:
- name: Open mysql remote access permissions
replace: path=/etc/my.cnf.d/server.cnf regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
- name: restart mysql
service: name=mysql state=restarted
執行
[root@localhost playbook]# ansible-playbook config-mysql.yml -vv
handlers和notify
作用
只有當關注的資源發生變化時,纔會採取一定的操作。在notify
中列出的操作成爲handler
示例
改寫上面的例子,只有當配置文件修改的時候才重啓mysql
服務
---
- hosts: csmp
gather_facts: no
tasks:
- name: Open mysql remote access permissions
replace: path=/etc/my.cnf.d/server.cnf regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
notify: restart mysql
handlers:
- name: restart mysql
service: name=mysql state=restarted
tags組件
作用
在playbook
中,可以利用tags
組件,爲特定task
指定標籤,當在執行playbook
時,可以只執行特定tags
的tasks
,而非整個playbook
文件
示例
---
- hosts: csmp
gather_facts: no
tasks:
- name: Open mysql remote access permissions
replace: path=/etc/my.cnf.d/server.cnf regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
tags: replace
- name: restart mysql
service: name=mysql state=restarted
tags: effective
此時就可只通過tags
執行其中某一個task
[root@localhost playbook]# ansible-playbook config-mysql.yml --list-tags
playbook: config-mysql.yml
play #1 (csmp): csmp TAGS: []
TASK TAGS: [effective, replace]
# -t TAGS, --tags TAGS only run plays and tasks tagged with these values
[root@localhost playbook]# ansible-playbook -t effective config-mysql.yml
ansible中使用變量
定義
僅能由字母、數字和下劃線組成,且只能以字母開頭
variable=value
調用
通過{ { variable_name }} 調用變量,且變量名前後建議加空格,有時用“{ { variable_name }}”才生效
使用setup
模塊中變量
要求在playbook
中使用,不要用ansible
命令調用
---
#var.yml
- hosts: all
remote_user: root
gather_facts: yes
tasks:
- name: create log file
file: name=/data/{
{
ansible_nodename }}.log state=touch owner=wang mode=600
ansible-playbook var.yml
在playbook命令行中定義變量
通過-e
參數使用
-e EXTRA_VARS, --extra-vars EXTRA_VARS
set additional variables as key=value or YAML/JSON, if
filename prepend with @
示例:
---
- hosts: "{
{ server }}"
gather_facts: no
tasks:
- name: Open mysql remote access permissions
replace: path=/etc/my.cnf.d/server.cnf regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
notify: restart mysql
handlers:
- name: restart mysql
service: name=mysql state=restarted
在執行時通過-e
指定server
變量。
[root@localhost playbook]# ansible-playbook config-mysql.yml -e server=10.47.119.156
在playbook文件中定義變量
vars
中定義變量,在後續直接使用
---
- hosts: "{
{ server }}"
gather_facts: no
vars:
- path: /etc/my.cnf.d/server.cnf
tasks:
- name: Open mysql remote access permissions
replace: path={
{
path }} regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
notify: restart mysql
handlers:
- name: restart mysql
service: name=mysql state=restarted
使用變量文件
可以在一個獨立的playbook文件中定義變量,在另一個playbook文件中引用變量文件中的變量,比playbook中定義的變量優先級高
# 定義變量文件
[root@localhost playbook]# cat config-mysql-var.yml
---
server_conf_path: /etc/my.cnf.d/server.cnf
# playbook文件中引入使用
[root@localhost playbook]# cat config-mysql.yml
---
- hosts: "{
{ server }}"
gather_facts: no
vars_files:
- config-mysql-var.yml
tasks:
- name: Open mysql remote access permissions
replace: path={
{
server_conf_path }} regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
notify: restart mysql
handlers:
- name: restart mysql
service: name=mysql state=restarted
主機清單文件中定義變量
- 主機(普通)變量
在inventory
主機清單文件中爲指定得主機定義變量,以便在playbook
中使用
[root@localhost playbook]# cat /etc/ansible/hosts
[server]
10.47.119.156 server_conf_path=/etc/my.cnf.d/server.cnf
10.47.119.157 server_conf_path=/etc/my.cnf.d/server1.cnf
- 組(公共)變量
在inventory 主機清單文件中賦予給指定組內所有主機上的在playbook中可用的變量,如果和主機變是同名,優先級低於主機變量
[root@localhost playbook]# cat /etc/ansible/hosts
[server]
10.47.119.156
10.47.119.157
[server:vars]
server_conf_path=/etc/my.cnf.d/server.cnf
使用時直接使用變量即可
---
- hosts: "{
{ server }}"
gather_facts: no
tasks:
- name: Open mysql remote access permissions
replace: path={
{
server_conf_path }} regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
notify: restart mysql
handlers:
- name: restart mysql
service: name=mysql state=restarted
template模板
jinja2語言
官網
https://jinja.palletsprojects.com/en/2.11.x/
template
功能
可以根據和參考模塊文件,動態生成相類似的配置文件
要求
template
文件必須存放於templates
目錄下,且命名爲 .j2 結尾
yaml/yml
文件需和templates
目錄平級,目錄結構如下示例:
.
├── config.yml
└── templates
└── nginx.conf.j2
示例
# tree
.
├── config-nginx.yml
└── templates
└── nginx.conf.j2
設置nginx
進程數與ansible_processor_vcpus+1
相等
# cat templates/nginx.conf.j2
...
worker_processes {
{ ansible_processor_vcpus+1 }};
...
playbook
內容
# cat config-nginx.yml
---
- hosts: vm
tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
handlers:
- name: restart nginx
service: name=nginx state=restarted
使用setup
模塊發現ansible_processor_vcpus
值爲4,所以模板文件中對應nginx
子進程數應爲5
# ansible vm -m setup -a 'filter=ansible_processor_vcpus'
10.91.156.205 | SUCCESS => {
"ansible_facts": {
"ansible_processor_vcpus": 4,
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
統計nginx
子進程數目
# ansible vm -m 'shell' -a "ps aux | grep 'nginx: worker process' "
10.91.156.205 | CHANGED | rc=0 >>
nginx 24585 0.0 0.0 105956 3444 ? S 15:05 0:00 nginx: worker process
nginx 24586 0.0 0.0 105956 3444 ? S 15:05 0:00 nginx: worker process
nginx 24587 0.0 0.0 105956 3444 ? S 15:05 0:00 nginx: worker process
nginx 24588 0.0 0.0 105956 3444 ? S 15:05 0:00 nginx: worker process
nginx 24589 0.0 0.0 105956 3448 ? S 15:05 0:00 nginx: worker process
...
流程控制
template中可使用流程控制 for 循環和 if 條件判斷,實現動態生成文件功能
for循環
示例
j2
文件:
...
{% for port in listen_ports %}
server {
listen {
{ port }};
root /usr/share/nginx/html;
location / {
}
}
{% endfor %}
...
playbook
文件中src
指定j2
文件,拷貝到遠程主機後記得要修改名稱
---
- hosts: vm
gather_facts: no
vars:
listen_ports:
- 8888
- 8889
tasks:
- name: template config to remote hosts
template: src=nginx-server.conf.j2 dest=/etc/nginx/nginx.conf backup=true
notify: restart nginx
handlers:
- name: restart nginx
service: name=nginx state=restarted
驗證發現服務器nginx.cnf
中多出了8888,8889兩個server
...
server {
listen 8888;
root /usr/share/nginx/html;
location / {
}
}
server {
listen 8889;
root /usr/share/nginx/html;
location / {
}
}
....
若vars
中變量是字典形式,形如
vars:
nginx_vhosts:
- listen: 8080
server_name: "web1.magedu.com"
root: "/var/www/nginx/web1/"
- listen: 8081
server_name: "web2.magedu.com"
root: "/var/www/nginx/web2/"
jinja2就需要使用如下方式調用
{% for vhost in nginx_vhosts %}
server {
listen {
{ vhost.listen }}
server_name {
{ vhost.server_name }}
root {
{ vhost.root }}
}
{% endfor %}
if 判斷
在模板文件中可通過條件判斷,來決定相關配置得生成信息。例如
# cat if-config.yml
---
- hosts: vm
gather_facts: no
vars:
nginx_vhosts:
- listen: 80
server_name: "server1"
root: "/var/www/nginx/web1"
- listen: 8080
root: "var/www/nginx/web2"
tasks:
- name: template config if exp
template: src=if-config.cnf.j2 dest=/root/if-config.cnf
模板文件
# cat templates/if-config.cnf.j2
{% for vhosts in nginx_vhosts %}
server {
listen {
{ vhosts.listen }}
{% if vhosts.server_name is defined %}
server_name {
{ vhosts.server_name }}
{% endif %}
root {
{ vhosts.root }}
}
{% endfor %}
最終生成結果
#結果
server {
listen 80
server_name server1
root /var/www/nginx/web1
}
server {
listen 8080
root var/www/nginx/web2
}
playbook使用when
when語句,可實現條件測試。如果需要根據變量,facts或此前任務得執行結果來作爲某task執行與否的前提時要用到條件測試。通過在task後添加when子句即可使用條件測試。
示例
如果ansible_os_family
值爲RedHat
則創建/root/redhat
目錄,否則創建/root/others
目錄
---
- hosts: vm
tasks:
- name: mkdir redhat dir
shell: mkdir /root/redhat
when: ansible_os_family == "RedHat"
- name: mkdir other dir
shell: mkdir /root/otherOs
when: ansible_os_family != "RedHat"
迭代with_items
作用
當有需要重複性執行的任務時,可以使用迭代機制。對迭代項的引用,固定變量名爲"item"。要在task
中使用with_items
給定要迭代的元素列表
列表元素格式
- 字符串
---
- hosts: vm
gather_facts: no
tasks:
- name: install tools
yum: name={
{
item }} state=installed
with_items:
- lrzsz
- wget
等同於
---
- hosts: vm
gather_facts: no
tasks:
- name: install lrzsz
yum: name=lrzsz state=installed
- name: install wget
yum: name=wget state=installed
- 字典
---
- hosts: vm
gather_facts: no
tasks:
- name: copy config file
copy: src={
{
item.src }} dest={
{
item.dest }}
with_items:
- {
src: /root/src1.cnf, dest: /root/dest1.txt }
- {
src: /root/src2.cnf, dest: /root/dest2.txt }