相关文章推荐
魁梧的茴香  ·  How to fix 415 ...·  11 月前    · 
谦虚好学的鸵鸟  ·  Oops!!! - 简书·  1 年前    · 
俊逸的铅笔  ·  ruby - Rails server ...·  1 年前    · 
Ansible 详解(三):Playbooks

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);"