Ansible 详解(三):Playbooks
ansible 是一款轻量级自动化运维工具,由的 Python 语言开发,结合了多种自动化运维工具的特性,实现了批量系统配置,批量程序部署,批量命令执行等功能; ansible 是基于模块化实现批量操作的。
一、基础应用
二、重用
1、include&import
区别:
- ansible 在 playbook 解析时间预处理所有静态导入
- 动态包含是在运行时处理
- 动态包优势&限制
优势:与循环一起使用,为循环的每个项目添加任务或角色
限制:
--list-tags 命令不能显示动态包含的 tag
--list-tasks 命令不能显示动态包含的 task
不能使用 notify 触发动态包的 handler(可触发动态包含文件自身 handler)
不能使用 --start-at-task 开始执行动态包含的任务。
静态导入优势&限制
限制:不能与循环结合使用
在导入文件或角色中名称中不能使用 inventory host_vars/group_vars 中的变量
2、playbook
import_playbook:导入 play
——
- import_playbook:webservers.yaml
- import_playbook:database.yaml
task/handler
- include_tasks
- import_tasks
tasks01.yaml
---
- name:task_01
ping:
tasks02.yaml
---
- name:task_02
shell:echo "task_02 {{name}} 'date'" >> /tmp/playbook_v3.log
playbook_v3.yaml
---
- hosts:mytest
task:
-import_tasks:task_01.yaml
-include_tasks:task_01.yaml
name:include
-import_task:task02.yaml
name:import
测试
ansible-playbook playbook_v3.yaml -i hosts --list-tasks
ansible-playbook playbook_v3.yaml -i hosts
3、roles
根据已知的文件结构自动加载 vars,tasks,handlers,并实现功能的共享。
三、变量
1、命名规范
- 数字,大小写英文字母,下划线
- 英文字母开头
2、自定义变量
定义位置
-
inventory
var
host_vars
group_vars - roles
使用语法
- {{ var }}
- {{ var.key }}
- {{ var['key'] }}
- {{ var[0]}}
使用的位置
- inventory
- jinja2 模板
3、facts 变量
通过远程方法获取受控机器的变量数据
命令
ansible all -m setup -i hosts
读取
{{ ansible_nodemame }} 主机名
{{ ansible_default_ipv4.address }} 主机 ip
关闭 facts
在 playbook 中使用 gather_facts:False 关闭
---
- hosts: mytest
gather_facts: False
roles:
- { role: webservers}
受控主机本地 facts
存储目录
/ect/ansible/facts.d/test.fact
文件格式
ini/yaml/json
测试
/ect/ansible/facts.d/test.fact
[name]
from=kk
ansible mytest -m setup -i hosts -a "filter = ansible_local"
使用 {{ ansible_local.test.name.from }} 读取数据
使用 play 更新受控机器本地 facts 后,需要主动调用 setup 模块更新当前执行主机 facts 信息。
4、ansible 版本变量
ansible_version
playbook_v12.yaml
---
- hosts: mytest
tasks:
- debug:
msg: "{{ ansible_version }}"
测试
ansible-playbook playbook_v12.yaml -i hosts
facts 缓存
hostvars
playbook_v13.yaml
---
- hosts: all
gather_facts: False
tasks:
- debug:
msg: "{{ hostvars['mytest']['ansible_nodename'] }}"
测试
ansible-playbook playbook_v13.yaml -i hosts
启用缓存
配置 ansible.cfg
[defaults]
gather=smart
fact_caching=jsonfile
fact_caching_connection=/tmp/ansible/facts/
fact_caching_timeout=86400
测试
ansible all -m setup -i hosts
ansible-playbook playbook_v13.yaml -i hosts
使用场景
定时更新 facts 缓存数据
关闭 playbook 中 gather_facts, 减少 playbook 执行时间
5、注册变量
保存执行命令变量
用法:在 task 中定义 registers 指定结果接受变量名
playbook_v14.yaml
---
- hosts: mytest
gather_facts: False
tasks:
- name: ip addr1
shell: ip addr1
register: result
ignore_errors: True
- debug:
msg: "{{ result.stderr }}"
when: result.rc != 0
测试
ansible-playbook playbook_v14.yaml -i hosts
6、魔术变量
综合信息
hostvars:主机缓存
groups:分组信息
受控机器信息
group_names:当前匹配主机所在组
inventory_hostname:当前匹配主机在 inventory 中定义的名称
ansible_hostname_short
ansible_play_batch
ansible_play_hosts
ansible_playbook_python:当前匹配主机在 Python 执行器
控制机器信息
- inventory_dir:inventory 所在目录
- inventory_file:inventory 文件
- inventory_dir:playbook 所在目录
- role_path:当前 role 路径、只能在 role 中使用
- ansible_check_mode:运行命令是否启用 check
playbook_v15.yaml
---
- hosts: mytest
gather_facts: False
tasks:
- debug:
msg: "{{ group_names }}"
- debug:
msg: "{{ groups }}"
- debug:
msg: "{{ inventory_hostname }}"
- debug:
msg: "{{ ansible_hostname }}"
- debug:
msg: "{{ inventory_hostname_short }}"
- debug:
msg: "{{ ansible_play_batch }}"
- debug:
msg: "{{ ansible_play_hosts }}"
- debug:
msg: "{{ ansible_playbook_python }}"
- debug:
msg: "{{ inventory_dir }}"
- debug:
msg: "{{ inventory_file }}"
- debug:
msg: "{{ playbook_dir }}"
- debug:
msg: "{{ ansible_check_mode }}"
ansible-playbook playbook_v15.yaml -i hosts --check
四、模板(jinja2)
过滤器
格式化
- to_json
- to_yaml
- to_nice_json
- to_nice_yaml
- from_json
- from_yaml
关闭变量是否定义检查:mandatory
为未定义变量设置默认值: default(value)
省略:default(omit)
列表过滤器
- min
- max
- flattern
集合过滤器
- unique
- union(set)
- interset(set)
- defference(set)
- symmentic_difference(set)
随机数:random
随机排序:shuffle
数学
- log
- pow
- root
json 查询:json_query
ip 地址
- ipaddr
- ipv4
- ipv5
测试
- is match
- is search
- is version
- is subset
- is superset
- is all
- is any
- is directory
- is file
- is line
- is exists
- is abs
- is mount
- is same_file
- is failed
- is success
- is skipped
- is succeeded
- is changed
五、条件语句
when:可用于 role,import,include 的控制
loop when:使用 item 接收循环的元素
vars_file + var + list:在 list 中查找第一个存在的文件进行加载
loop-query:找第一个可用的文件
query('first_found', {'file' : [], 'pths' : [] } )
六、循环
playbook_v18.yaml
---
- hosts: mytest
vars:
user_list:
- silence
tasks:
- name: loop
debug:
msg: "{{ item }}"
loop:
- first
- second
- name: loop vars
debug:
msg: "{{ item }}"
loop: "{{ user_list }}"
- name: loop query
debug:
msg: "{{ item }}"
loop: "{{ query('nested', ['a', 'b'], ['x', 'y', 'z']) }}"
- name: loop lookup
debug:
msg: "{{ item }}"
loop: "{{ lookup('nested', ['a', 'b'], ['x', 'y', 'z'], withlist=True) }}"
- name: do-until
command: python -c "import sys,random; sys.exit(random.randint(0, 3));"
ignore_errors: True
register: result
until: result is success
retries: 3
delay: 3
- name: loop register
command: "echo {{ item }}"
loop: "{{ user_list }}"
register: echo
changed_when: echo.stdout != 'kk'
- name: loop register result
debug:
msg: "{{ item.cmd }} is success"
loop: "{{ echo.results }}"
when: item.rc == 0
- name: all host
debug:
msg: "{{ item }}"
loop: "{{ groups['all'] }}"
- name: batch host
debug:
msg: "{{ item }}"
loop: "{{ ansible_play_batch }}"
- name: loop query
debug:
msg: "{{ item }}"
loop: "{{ query('inventory_hostnames', 'all') }}"
- include_tasks: tasks.yaml
loop: [1, 2, 3]
loop_control:
loop_var: outer_item
- name: loop control label
debug:
msg: "{{ item }}"
loop:
- name : kk
age: 30
- name : silence
age: 31
- name: loop control label
debug:
msg: "{{ item }}"
loop:
- name : kk
age: 30
- name : silence
age: 31
loop_control:
label: "{{ item.name }}"
- name: loop control label
debug:
msg: "{{ item.name }}"
loop:
- name : kk
age: 30
- name : silence
age: 31
loop_control:
label: "{{ item.name }}"
- name: loop control pause
debug:
msg: "{{ item }}"
loop: [1, 2, 3]
loop_control:
pause: 3
- name: loop control index
debug:
msg: "{{ index }} : {{ item }}"
loop: [1, 2, 3]
loop_control:
index_var: index
测试
ansible _playbook playbook_v18.yaml -i hosts
七、block
使用场景
- 对任务进行逻辑分组,组内任务共享数据和指令
- 异常处理
playbook_v19.yaml
---
- hosts: all
tasks:
- name: block task
block:
- debug:
msg: 'start'
- ping:
- debug:
msg: 'end'
when: inventory_hostname == 'localhost'
playbook_v20.yaml
---
- hosts: mytest
tasks:
- name: exception
block:
- command: python -c "import sys; sys.exit(1);"
rescue:
- debug:
msg: 'rescue 1'
always:
- debug:
msg: "always 1"
- name: exception
block:
- command: python -c "import sys; sys.exit(0);"