跳转到内容

Ansible 面试题

40 道题
分类
DevOps
题目数
40 道
已阅读 0 / 40 题
1 Ansible 核心架构组件

答案:

Ansible 采用无代理架构,由 Control Node 控制节点下发指令,通过 SSH 或 WinRM 协议远程执行任务,无需在 Managed Node 上安装代理程序。

组件职责
Control Node运行 ansible/ansible-playbook 命令的节点,支持 Linux/Unix/macOS
Managed Node被管理的目标主机,通过 SSH/WinRM 接受指令
Inventory定义受管主机的清单文件,支持静态和动态两种模式
Module执行具体任务的独立代码单元(如 copy/shell/yum)
PlaybookYAML 格式的任务编排文件,定义主机与任务映射关系
Plugin扩展 Ansible 功能的组件(连接/回调/过滤器等)
GalaxyRole 共享社区仓库,支持依赖管理与版本控制

Control Node 将 Playbook 解析为 Task 列表,逐个调用对应 Module,Module 推送到 Managed Node 临时执行后返回 JSON 结果。

2 无代理架构与 SSH/WinRM 连接机制

答案:

Ansible 的 Agentless 架构消除了在目标主机上预装代理的必要性,降低了维护成本和攻击面。

  • SSH 连接(Linux/Unix):默认使用 OpenSSH,支持连接复用(ControlPersist)、密钥认证、跳板机(ProxyJump)。参数化连接配置通过 ansible_ssh_common_args 传递。
  • WinRM 连接(Windows):通过 pywinrm 库实现,支持 HTTP/HTTPS、Kerberos/NTLM/CredSSP 认证。需在 Windows 主机上执行 winrm quickconfig 初始化。
  • 连接参数:ansible_connection=ssh/winrm/local,ansible_user,ansible_password,ansible_port,ansible_private_key_file。
  • Pipelining:启用 ssh_args = -o ControlMaster=auto -o ControlPersist=60s 减少 SSH 连接次数,提升大规模执行性能。
# inventory 连接配置示例
[webservers]
web1 ansible_host=192.168.1.10 ansible_user=deploy ansible_ssh_private_key_file=/path/to/key
web2 ansible_host=192.168.1.11 ansible_connection=winrm ansible_winrm_transport=credssp
3 Inventory 静态管理与动态管理

答案:

Inventory 定义 Ansible 可管理的主机集合,支持静态文件与动态脚本两种模式。

  • 静态 Inventory:INI 或 YAML 格式文件,手工定义主机和组。
    • 组嵌套:[parent:children] 声明子组关系
    • 主机变量:通过 host_vars/ 目录或 ansible_host 等内联变量
    • 组变量:通过 group_vars/ 目录或 [group:vars] 段落
# INI 格式示例
[web]
web1 ansible_host=10.0.0.1
web2 ansible_host=10.0.0.2

[db]
db1 ansible_host=10.0.0.10

[all:vars]
ansible_user=admin
ansible_ssh_private_key_file=/home/admin/.ssh/id_rsa
# YAML 格式示例
all:
  children:
    web:
      hosts:
        web1:
          ansible_host: 10.0.0.1
    db:
      hosts:
        db1:
          ansible_host: 10.0.0.10
  vars:
    ansible_user: admin
  • 动态 Inventory:可执行脚本或插件从外部系统(AWS EC2、GCP、OpenStack、vCenter)获取主机列表。Ansible 内置 aws_ec2gcp_compute 等插件,支持缓存机制减少 API 调用。
# aws_ec2.yml 动态 inventory 插件配置
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
filters:
  tag:Environment: production
hostnames:
  - ip-address
keyed_groups:
  - prefix: tag
    key: tags.Name
4 Playbook 语法结构与执行流程

答案:

Playbook 是 Ansible 的核心编排文件,以 YAML 格式描述受管主机与待执行任务的映射关系。

- name: Deploy web application
  hosts: webservers
  become: yes
  vars:
    app_port: 8080
  tasks:
    - name: Install Nginx
      ansible.builtin.yum:
        name: nginx
        state: present
    - name: Deploy config file
      ansible.builtin.template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: restart nginx
  handlers:
    - name: restart nginx
      ansible.builtin.systemd:
        name: nginx
        state: restarted
  • 顶层键:name(描述)、hosts(目标组)、become(提权)、vars(变量)、tasks(任务列表)、handlers(通知处理器)。
  • Task 结构:name + module + module_args。支持 when 条件、loop 循环、notify 触发器。
  • 执行阶段:Gathering Facts -> Tasks -> Handlers(仅在 Task 变更时触发)。
  • 幂等性:Module 实现状态检查与目标状态的差异驱动,确保重复执行结果一致。
5 Module 类型划分

答案:

Ansible Module 根据来源与管理范围分为三类:

类型来源特点示例
Core ModuleAnsible 核心仓库内置维护,稳定可靠copy、file、yum、service、command
Community ModuleAnsible Galaxy 社区贡献覆盖广泛生态场景community.docker、community.general
Custom Module自主开发满足特定业务需求任意语言实现,遵循 Module 协议
  • Module 返回值规范:必须返回 JSON 格式,包含 changed/failed/msg 等字段。
  • 文档规范:Module 需包含 DOCUMENTATION 和 EXAMPLES 字符串(Python docstring 格式)。
  • 执行模式:Push 模式,Control Node 将 Module 复制到 Managed Node 执行后清理。
6 变量作用域与优先级

答案:

Ansible 变量遵循严格的优先级规则,高优先级变量覆盖低优先级变量。

优先级从高到低(前五项)

  1. extra vars(-e 命令行参数)
  2. 任务级变量(vars: 任务内联)
  3. Block 级变量
  4. Role 级变量(defaults/main.yml 优先级最低的 role 变量除外)
  5. Include/Import 参数变量
  6. Play 级变量(vars: 字段)
  7. Host facts 和 inventory 变量
  8. Playbook vars_files
  9. Group vars(group_vars/
  10. Role defaults(roles/xxx/defaults/main.yml

变量引用方式

  • {{ variable_name }} Jinja2 表达式
  • {{ ansible_facts['os_family'] }} Fact 变量
  • {{ hostvars['host1']['ansible_default_ipv4']['address'] }} 跨主机变量

注册变量:通过 register 关键字将 Task 执行结果赋给变量,供后续任务使用。

- name: Check disk usage
  ansible.builtin.shell: df -h /
  register: disk_result

- name: Show disk info
  ansible.builtin.debug:
    msg: "XQOPEN disk_result.stdout_lines XQCLOSE"
7 Fact 系统与 Fact 缓存

答案:

Fact 是 Ansible 在 Playbook 执行开始时自动采集的远程主机信息,通过 setup module 实现。

常见 Fact 分类

  • 网络ansible_default_ipv4ansible_all_ipv4_addressesansible_interfaces
  • 系统ansible_os_familyansible_distribution_versionansible_kernel
  • 硬件ansible_processor_coresansible_memtotal_mbansible_architecture
  • 磁盘ansible_devicesansible_mounts

Fact 缓存机制

  • 启用缓存减少多次执行时的采集开销
  • 支持 JSON 文件、Redis、Memcached 等缓存后端
# ansible.cfg
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 3600

自定义 Fact:在 Managed Node 的 /etc/ansible/facts.d/*.fact 文件中定义,Ansible 自动采集。

8 Jinja2 模板引擎

答案:

Ansible 集成 Jinja2 作为模板引擎,通过 template module 将模板文件渲染后推送至远程主机。

模板文件后缀.j2

核心特性

  • 变量插值{{ variable }} 替换变量
  • 过滤器{{ name | upper }}{{ list | join(",") }}{{ default_value | default("fallback") }}
  • 控制结构{% for item in list %}...{% endfor %}{% if condition %}...{% endif %}
  • 模板继承{% block %}...{% endblock %}
  • 数学运算{{ total | int * 1.2 }}
# nginx.conf.j2
server {
    listen XQOPEN http_port | default(80) XQCLOSE;
    server_name XQOPEN server_name XQCLOSE;

    location / {
        proxy_pass http://XQOPEN upstream_host XQCLOSE:XQOPEN upstream_port XQCLOSE;
        {% if enable_cache %}
        proxy_cache my_cache;
        proxy_cache_valid 200 1h;
        {% endif %}
    }
}

Playbook 调用

- name: Render and deploy template
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
  notify: reload nginx
9 Role 结构与 Ansible Galaxy 集成

答案:

Role 是 Playbook 的模块化封装单元,将变量、任务、模板、文件按约定目录结构组织,实现复用与共享。

Role 目录结构

roles/
  common/
    defaults/     # 默认变量(最低优先级)
      main.yml
    vars/         # 内部变量(高优先级)
      main.yml
    tasks/        # 主任务列表
      main.yml
    handlers/     # 通知处理器
      main.yml
    templates/    # Jinja2 模板文件
    files/        # 静态文件
    meta/         # 依赖关系和元数据
      main.yml

角色引用方式

# playbook.yml
- hosts: webservers
  roles:
    - role: nginx
      vars:
        http_port: 8080
    - role: common

Ansible Galaxy:社区 Role 仓库,支持命令行搜索、安装和管理。

# 安装角色
ansible-galaxy role install geerlingguy.nginx

# 创建角色骨架
ansible-galaxy role init my_custom_role

# requirements.yml 管理依赖
ansible-galaxy role install -r requirements.yml
# requirements.yml
roles:
  - src: geerlingguy.nginx
    version: 3.1.0
  - src: https://github.com/user/repo.git
    name: custom_role
    version: v1.2

Role 依赖:在 meta/main.yml 中声明,自动递归加载。

# meta/main.yml
dependencies:
  - role: common
  - role: geerlingguy.docker
10 任务控制:Conditional 条件判断

答案:

when 关键字基于表达式结果控制任务是否执行,支持 Jinja2 条件语法。

- name: Install Apache on RedHat
  ansible.builtin.yum:
    name: httpd
    state: present
  when: ansible_os_family == "RedHat"

- name: Install Apache on Debian
  ansible.builtin.apt:
    name: apache2
    state: present
  when: ansible_os_family == "Debian"

条件组合

- name: Restart service on configuration change
  ansible.builtin.systemd:
    name: myapp
    state: restarted
  when:
    - config_changed
    - ansible_distribution_version is version('7', '>=')

内置测试is definedis undefinedis noneis failedis succeeded

11 任务控制:Loop 循环迭代

答案:

Ansible 支持多种循环模式遍历数组、哈希和范围数据。

循环语法演进

  • 旧语法:with_itemswith_dictwith_fileglob
  • 新语法:loop 通用关键字 + lookup/query 插件
# 列表循环
- name: Create multiple users
  ansible.builtin.user:
    name: "XQOPEN item XQCLOSE"
    state: present
  loop:
    - alice
    - bob
    - charlie

# 字典循环
- name: Configure services
  ansible.builtin.template:
    src: "XQOPEN item.key XQCLOSE.conf.j2"
    dest: "/etc/XQOPEN item.key XQCLOSE/XQOPEN item.key XQCLOSE.conf"
  loop: "XQOPEN lookup('dict', services) XQCLOSE"
  vars:
    services:
      nginx: { port: 80 }
      redis: { port: 6379 }

# 带索引的循环
- name: List items with index
  ansible.builtin.debug:
    msg: "Index XQOPEN ansible_loop.index XQCLOSE: XQOPEN item XQCLOSE"
  loop: "XQOPEN ['a', 'b', 'c'] XQCLOSE"

Loop 控制loop_control 子选项支持 index_varpauselabel

12 Block 任务分组与错误处理

答案:

Block 将多个任务组合为逻辑单元,统一应用条件判断和错误处理策略。

- name: Database deployment block
  block:
    - name: Create database
      community.mysql.mysql_db:
        name: myapp
        state: present

    - name: Create database user
      community.mysql.mysql_user:
        name: myapp_user
        password: "XQOPEN db_password XQCLOSE"
        priv: "myapp.*:ALL"

    - name: Import initial schema
      community.mysql.mysql_db:
        name: myapp
        state: import
        target: /tmp/schema.sql

  rescue:
    - name: Rollback - remove database on failure
      community.mysql.mysql_db:
        name: myapp
        state: absent

    - name: Notify failure
      ansible.builtin.debug:
        msg: "Database deployment failed, rollback executed"

  always:
    - name: Cleanup temp files
      ansible.builtin.file:
        path: /tmp/schema.sql
        state: absent
  • block:正常执行的任务组
  • rescue:block 中任意任务失败时的恢复逻辑
  • always:不论成功或失败均执行的清理任务
13 Tag 标签与任务选择执行

答案:

Tag 机制为 Playbook 中的任务添加标签,支持按标签筛选执行范围,提升调试和运维效率。

- name: Full application setup
  hosts: all

  tasks:
    - name: Install dependencies
      ansible.builtin.yum:
        name: "XQOPEN item XQCLOSE"
        state: present
      loop:
        - git
        - curl
      tags:
        - packages
        - dependencies

    - name: Configure firewall
      ansible.builtin.firewalld:
        port: "XQOPEN item XQCLOSE/tcp"
        permanent: yes
        state: enabled
      loop:
        - 80
        - 443
      tags:
        - firewall
        - security

    - name: Deploy application
      ansible.builtin.copy:
        src: app.tar.gz
        dest: /opt/
      tags:
        - deploy

执行筛选

# 仅执行 firewall 标签任务
ansible-playbook site.yml --tags firewall

# 跳过 packages 标签任务
ansible-playbook site.yml --skip-tags packages

# 列出所有标签
ansible-playbook site.yml --list-tags

特殊标签taggeduntaggedall 用于批量选择。

14 执行策略:Linear、Free 与 Serial

答案:

Ansible 执行策略控制任务在受管主机之间的并行和排序方式。

策略行为适用场景
linear(默认)所有主机完成当前任务后才进入下一任务依赖顺序的执行,需全组一致
free各主机独立执行所有任务,不等待其他主机无依赖的批量操作,追求最大化速度
serial按批次串行执行,每批内按 linear 策略滚动更新、金丝雀发布
# serial 策略配置
- name: Rolling update
  hosts: webservers
  serial:
    - 1      # 第一批 1 台
    - 2      # 第二批 2 台
    - 5      # 第三批 5 台
    - 100%   # 剩余全部
  tasks:
    - name: Update application
      ansible.builtin.service:
        name: myapp
        state: restarted

策略选择原则

  • 状态一致的操作使用 linear
  • 无关联的批量巡检使用 free
  • 滚动发布使用 serial 控制速率
15 Ansible Vault 加密与解密

答案:

Ansible Vault 提供文件级加密机制,保护敏感数据(密码、密钥、证书)在版本控制中的安全性。

# 加密文件
ansible-vault encrypt credentials.yml

# 解密文件
ansible-vault decrypt credentials.yml

# 查看加密内容
ansible-vault view credentials.yml

# 编辑加密文件
ansible-vault edit credentials.yml

# 修改密码
ansible-vault rekey credentials.yml

加密文件在 Playbook 中的引用

# playbook.yml
- hosts: all
  vars_files:
    - credentials.yml
  tasks:
    - name: Create database user
      community.mysql.mysql_user:
        password: "XQOPEN db_master_password XQCLOSE"

密码提供方式

# 交互式输入
ansible-playbook site.yml --ask-vault-pass

# 密码文件
ansible-playbook site.yml --vault-password-file /path/to/vault_pass

# 多 Vault ID 管理不同环境
ansible-vault encrypt --vault-id prod@prompt prod_secrets.yml
ansible-playbook site.yml --vault-id prod@/path/to/prod_pass

文件加密限制:Vault 不能加密变量名,仅加密变量值;大文件建议拆分加密。

16 回调插件与事件通知

答案:

Callback Plugin 拦截 Ansible 执行事件并输出或转发到外部系统,支持日志、监控、通知等场景。

常用内置回调插件

插件功能
actionable仅显示变更和失败的 Play 结果
json将事件输出为 JSON 格式
mail邮件通知 Playbook 执行结果
slack发送执行状态到 Slack 频道
timer统计各个 Play 的执行耗时
profile_tasks输出每个任务的执行时间分布

自定义回调插件开发

# callback_plugins/custom_notifier.py
from ansible.plugins.callback import CallbackBase

class CallbackModule(CallbackBase):
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'notification'
    CALLBACK_NAME = 'custom_notifier'

    def v2_playbook_on_task_start(self, task, is_conditional):
        self._display.display(f"Starting task: {task.name}")

    def v2_runner_on_ok(self, result):
        self._display.display(f"Task succeeded: {result.task_name}")

    def v2_runner_on_failed(self, result, ignore_errors=False):
        self._display.display(f"Task failed: {result.task_name}")
        # 发送告警到外部系统

启用插件ansible.cfgstdout_callbackcallback_whitelist 配置。

17 动态 Inventory 插件(AWS、GCP、OpenStack)

答案:

Dynamic Inventory Plugin 从云服务商 API 实时获取主机清单,替代静态手工维护。

AWS EC2 动态 Inventory

# aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - ap-northeast-1
  - us-west-2
filters:
  instance-state-name: running
hostnames:
  - dns-name
  - private-dns-name
compose:
  ansible_host: private_ip_address
keyed_groups:
  - key: tags.Role
    prefix: role
  - key: placement.region
    prefix: region

GCP Compute Engine 动态 Inventory

# gcp_compute.yml
plugin: google.cloud.gcp_compute
projects:
  - my-project-id
auth_kind: serviceaccount
service_account_file: /path/to/sa-key.json
hostnames:
  - name
groups:
  - "XQOPEN gcp_labels | selectattr('key', 'equalto', 'env') | map(attribute='value') | first XQCLOSE"

OpenStack 动态 Inventory

# openstack.yml
plugin: openstack.cloud.openstack
available_now: true
expand_hostvars: true
fail_on_errors: true

缓存配置:避免每次执行都调用云 API,提升大规模集群执行效率。

18 Ansible Tower 与 AWX 功能对比

答案:

AWX 是 Ansible Tower 的开源上游项目,提供 Web UI、REST API、RBAC、作业调度等企业级功能。

特性AWX(开源)Ansible Tower(商业)
许可证Apache 2.0Red Hat 订阅
Web UI基础管理界面完整企业界面
RBAC支持团队/用户/角色支持 LDAP/SAML/SSO
作业模板支持支持,含 Survey 表单
动态 Inventory支持支持,含云提供商集成
通知Webhook/Email/Slack完整通知集成
调度Cron 表达式图形化调度
审计日志基础完整审计与合规追踪
支持社区Red Hat 官方支持

核心功能

  • 作业模板:将 Playbook、Inventory、凭据打包为可重复执行的作业
  • 工作流:将多个作业模板编排为 DAG 工作流,支持条件分支
  • 凭据管理:加密存储 SSH 密钥、密码、云 API 密钥
  • 实时输出:WebSocket 实时推送作业日志
19 Ansible Lint 与代码质量检查

答案:

ansible-lint 是 Playbook 和 Role 的静态分析工具,检测语法错误、最佳实践违规和安全风险。

# 安装
pip install ansible-lint

# 执行检查
ansible-lint playbook.yml

# 检查整个 Role
ansible-lint roles/my_role/

规则类别

规则 ID类别说明
name[casing]命名规范Task name 首字母大写
command-instead-of-module模块使用优先使用专用模块而非 command
no-changed-when幂等性非命令模块需声明 changed_when
risky-file-permissions安全文件权限需显式设置 mode
yaml[line-length]格式YAML 行长度不超过 160
jinja[spacing]模板Jinja2 表达式 {{ }} 需有空格
role-nameRole 命名Role 名称需符合标准命名规则

配置文件 .ansible-lint

exclude_paths:
  - .cache/
  - .github/
skip_list:
  - yaml[line-length]
warn_list:
  - command-instead-of-module
mock_modules:
  - custom_module

集成 CI/CD:在 Pipeline 中配置 ansible-lint 作为代码门禁,不合规阻断构建。

20 自定义 Module 开发

答案:

Ansible Module 是独立的可执行程序,遵循标准接口规范,支持 Python、Bash、PowerShell 等语言。

Python Module 标准结构

#!/usr/bin/python
# -*- coding: utf-8 -*-

from ansible.module_utils.basic import AnsibleModule

DOCUMENTATION = r'''
module: my_deploy
short_description: Deploy application package
description:
  - Deploy specified version of application to remote host
options:
  version:
    description: Application version to deploy
    required: true
    type: str
  environment:
    description: Target environment
    choices: ['staging', 'production']
    default: staging
    type: str
'''

EXAMPLES = r'''
- name: Deploy app
  my_deploy:
    version: v2.1.0
    environment: production
'''

RETURN = r'''
deploy_path:
  description: Path where application is deployed
  returned: always
  type: str
'''

def run_module():
    module_args = dict(
        version=dict(type='str', required=True),
        environment=dict(type='str', default='staging',
                         choices=['staging', 'production']),
    )

    result = dict(
        changed=False,
        deploy_path='',
        message=''
    )

    module = AnsibleModule(
        argument_spec=module_args,
        supports_check_mode=True
    )

    version = module.params['version']
    env = module.params['environment']

    # 业务逻辑实现
    deploy_path = f"/opt/app/{env}/{version}"

    if module.check_mode:
        module.exit_json(changed=True)

    # 实际部署操作
    result['changed'] = True
    result['deploy_path'] = deploy_path
    result['message'] = f"Deployed version {version} to {env}"

    module.exit_json(**result)

def main():
    run_module()

if __name__ == '__main__':
    main()

Module 开发规范

  • 返回 JSON 格式,必须包含 changed 和 failed 字段
  • 支持 check_mode(干运行)和 diff_mode
  • 使用 module_utils 复用公共逻辑
  • 文档字符串遵循 RETURNS/DOCUMENTATION/EXAMPLES 格式

存放路径library/my_module.pyroles/role_name/library/my_module.py

21 网络自动化与 Ansible Network

答案:

Ansible Network 模块基于 SSH 或 API 管理网络设备(Cisco、Juniper、Arista、华为等),无需在设备上安装代理。

网络设备连接

# inventory 配置网络设备
[switches]
core-sw01 ansible_host=10.0.1.1
access-sw01 ansible_host=10.0.1.2

[switches:vars]
ansible_connection=ansible.netcommon.network_cli
ansible_network_os=cisco.ios.ios
ansible_user=admin
ansible_ssh_private_key_file=/path/to/ssh_key

网络配置操作

- name: Configure VLAN
  hosts: switches
  gather_facts: no

  tasks:
    - name: Ensure VLAN 100 exists
      cisco.ios.ios_vlan:
        vlan_id: 100
        name: web_vlan
        state: present

    - name: Configure interface
      cisco.ios.ios_interface:
        name: GigabitEthernet0/1
        description: Web Server Connection
        mode: access
        access_vlan: 100

    - name: Backup running config
      cisco.ios.ios_config:
        backup: yes
        backup_options:
          dirname: /backup/network
          filename: "XQOPEN inventory_hostname XQCLOSE_XQOPEN ansible_date_time.date XQCLOSE.cfg"

关键特性

  • ansible_connection=network_cli:SSH CLI 交互模式
  • ansible_connection=netconf:NETCONF API 协议
  • ansible_connection=httpapi:RESTCONF 或专有 HTTP API
  • gather_facts: no:网络设备默认不采集 facts(需使用对应采集模块)
  • config 模块族的原子化配置推送
22 Windows 管理与 WinRM 配置

答案:

Ansible 通过 WinRM 协议管理 Windows 主机,使用 PowerShell Module 执行任务。

Windows 主机准备

# 在 Windows 主机上执行
Enable-PSRemoting -Force
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*"
New-SelfSignedCertificate -DnsName "$env:computername" -CertStoreLocation Cert:\LocalMachine\My
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'

Inventory 配置

# 单台 Windows 主机
win-server1:
  ansible_host: 192.168.1.50
  ansible_connection: winrm
  ansible_winrm_transport: credssp
  ansible_winrm_server_cert_validation: ignore
  ansible_user: Administrator
  ansible_password: "XQOPEN vault_win_password XQCLOSE"

常用 Windows Module

- name: Install Windows Feature
  ansible.windows.win_feature:
    name: Web-Server
    state: present

- name: Create Windows User
  ansible.windows.win_user:
    name: svc_account
    password: "XQOPEN vault_svc_password XQCLOSE"
    groups:
      - Administrators

- name: Execute PowerShell Script
  ansible.windows.win_shell: |
    Get-Service | Where-Object {$_.Status -eq "Running"}    
  register: running_services

WinRM 认证方式

  • basic:明文密码,需启用 HTTPS
  • ntlm:挑战响应认证
  • kerberos:域环境推荐
  • credssp:支持凭据转发,解决双跳问题
23 容器管理与 Docker Module

答案:

Ansible Docker Module 通过 Docker SDK for Python 控制本地或远程 Docker 守护进程。

- name: Docker container management
  hosts: docker_hosts
  tasks:
    - name: Pull image
      community.docker.docker_image:
        name: nginx
        tag: latest
        source: pull

    - name: Ensure container is running
      community.docker.docker_container:
        name: web_server
        image: nginx:latest
        state: started
        restart_policy: always
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - /data/www:/usr/share/nginx/html:ro
        env:
          NGINX_HOST: example.com
        networks:
          - name: web_network

    - name: Build image from Dockerfile
      community.docker.docker_image:
        name: myapp:XQOPEN version XQCLOSE
        build:
          path: /opt/myapp
          dockerfile: Dockerfile.prod
        source: build
        state: present

Docker Compose 管理

- name: Deploy stack with compose
  community.docker.docker_compose_v2:
    project_name: myapp
    definition:
      version: '3'
      services:
        app:
          image: myapp:latest
          ports:
            - "3000:3000"
        db:
          image: postgres:15
          environment:
            POSTGRES_PASSWORD: "XQOPEN db_password XQCLOSE"
    state: present
24 Kubernetes Module 管理

答案:

Ansible Kubernetes Module 通过 Kubernetes Python Client 与集群 API 交互,支持 Pod、Deployment、Service 等资源管理。

- name: Kubernetes resource management
  hosts: localhost
  tasks:
    - name: Create Namespace
      kubernetes.core.k8s:
        name: myapp
        api_version: v1
        kind: Namespace
        state: present

    - name: Deploy application
      kubernetes.core.k8s:
        state: present
        definition:
          apiVersion: apps/v1
          kind: Deployment
          metadata:
            name: web
            namespace: myapp
          spec:
            replicas: 3
            selector:
              matchLabels:
                app: web
            template:
              metadata:
                labels:
                  app: web
              spec:
                containers:
                  - name: web
                    image: nginx:latest
                    ports:
                      - containerPort: 80

    - name: Create Service
      kubernetes.core.k8s:
        state: present
        definition:
          apiVersion: v1
          kind: Service
          metadata:
            name: web-svc
            namespace: myapp
          spec:
            selector:
              app: web
            ports:
              - port: 80
                targetPort: 80
            type: ClusterIP

K8s 认证配置

# kubeconfig 认证
- name: Use kubeconfig
  kubernetes.core.k8s:
    kubeconfig: /home/admin/.kube/config
    context: prod-cluster
    ...

# inline token 认证
- name: Use token
  kubernetes.core.k8s:
    host: https://k8s-api.example.com:6443
    api_key: "XQOPEN vault_k8s_token XQCLOSE"
    validate_certs: yes
    ...

Helm Chart 管理

- name: Deploy via Helm
  kubernetes.core.helm:
    name: my-release
    chart_ref: stable/nginx-ingress
    release_namespace: ingress
    values:
      controller:
        replicaCount: 3
25 性能优化策略

答案:

Ansible 性能优化涵盖连接复用、执行方式、Fact 采集和数据传输等多个维度。

关键优化措施

措施配置效果
SSH Pipeliningpipelining = True减少 SSH 连接次数,提升 2-3 倍
ControlPersistssh_args = -o ControlMaster=auto -o ControlPersist=60s复用 SSH 连接,降低握手开销
Fact 缓存fact_caching = jsonfile + gathering = smart避免重复采集系统信息
SSH 复用ssh_args = -o ControlPath=~/.ssh/ansible-%%r@%%h:%%p并行执行时共享连接
# ansible.cfg 优化配置
[ssh_connection]
pipelining = True
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o ControlPath=~/.ssh/ansible-%r@%h:%p
control_path = %(directory)s/%%C

[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 3600
forks = 20

Mitogen 加速策略(社区方案):

  • 替代默认 SSH 连接方式,通过进程分支减少 Python 解释器启动开销
  • 实测可提升 5-10 倍执行速度
  • 需注意 Mitogen 与特定 Ansible 版本的兼容性

其他优化手段

  • serial + forks 配合控制并发粒度
  • 使用 --diff 仅输出变更内容减少日志量
  • strategy = free 解除无依赖任务的等待
  • gather_facts: no 在不需要 Facts 的 Play 中禁用
26 错误处理与回滚策略

答案:

Ansible 提供多层级错误处理机制,确保任务失败时可控恢复。

错误处理层级

# 忽略错误
- name: Ignore non-critical failure
  ansible.builtin.command: /opt/app/health_check.sh
  ignore_errors: yes

# 强制失败
- name: Force fail if critical condition not met
  ansible.builtin.fail:
    msg: "Critical service not running"
  when: service_status.rc != 0

# 自定义变更判定
- name: Execute migration
  ansible.builtin.shell: /opt/app/migrate.sh
  register: migrate_result
  changed_when: "'migration applied' in migrate_result.stdout"
  failed_when:
    - migrate_result.rc != 0
    - "'already up to date' not in migrate_result.stderr"

回滚策略示例

- name: Application upgrade with rollback
  block:
    - name: Backup current version
      ansible.builtin.archive:
        path: /opt/app/current
        dest: /opt/backup/app_XQOPEN ansible_date_time.epoch XQCLOSE.tar.gz

    - name: Deploy new version
      ansible.builtin.copy:
        src: "app_vXQOPEN new_version XQCLOSE.tar.gz"
        dest: /opt/app/
      notify: restart app

    - name: Verify deployment
      ansible.builtin.uri:
        url: http://localhost:8080/health
        status_code: 200
      register: health

  rescue:
    - name: Rollback - restore previous version
      ansible.builtin.unarchive:
        src: /opt/backup/app_XQOPEN backup_timestamp XQCLOSE.tar.gz
        dest: /opt/app/
        remote_src: yes
    - name: Notify rollback
      ansible.builtin.shell: |
        /usr/local/bin/alert.sh "Rollback executed for XQOPEN inventory_hostname XQCLOSE"        

最大失败比例控制

- hosts: webservers
  max_fail_percentage: 25
  any_errors_fatal: true
27 Git 版本控制与 CI/CD 集成

答案:

Ansible Playbook 和 Role 以代码形式纳入 Git 仓库管理,通过 CI/CD Pipeline 实现自动化验证与发布。

仓库结构规范

ansible-infra/
  inventories/
    development/host_vars/  # 环境级变量分离
    production/host_vars/
    staging/group_vars/
  playbooks/
    site.yml
    deploy.yml
    backup.yml
  roles/         # 从 Galaxy 安装或自建
  library/       # 自定义 Module
  filter_plugins/
  ansible.cfg
  requirements.yml
  .ansible-lint

CI/CD Pipeline 集成

# GitLab CI 示例 .gitlab-ci.yml
stages:
  - lint
  - syntax-check
  - dry-run
  - deploy

ansible-lint:
  stage: lint
  script:
    - ansible-lint playbooks/*.yml

syntax-check:
  stage: syntax-check
  script:
    - ansible-playbook --syntax-check playbooks/deploy.yml -i inventories/staging/

dry-run:
  stage: dry-run
  script:
    - ansible-playbook playbooks/deploy.yml -i inventories/staging/ --check --diff
  environment: staging
  only:
    - merge_requests

deploy-production:
  stage: deploy
  script:
    - ansible-playbook playbooks/deploy.yml -i inventories/production/ --vault-password-file $VAULT_PASS_FILE
  environment: production
  when: manual
  only:
    - main

版本控制最佳实践

  • 敏感数据使用 ansible-vault 加密后提交
  • 环境变量通过 group_vars/ 目录隔离
  • requirements.yml 锁定 Role 版本(tag 或 commit SHA)
  • CI Pipeline 中执行 lint + syntax-check + dry-run 三重验证
  • 生产环境部署设置人工审批门禁
28 Ansible 与 Terraform 对比分析

答案:

Ansible 和 Terraform 同为基础设施自动化工具,定位和侧重点各有不同。

维度AnsibleTerraform
定位配置管理与应用编排基础设施即代码(IaC)
架构无代理,Push 模式Push 模式 + Provider 插件
状态管理无中心状态,幂等依赖模块实现中心化 State 文件管理资源状态
语言YAML PlaybookHCL(HashiCorp Configuration Language)
配置漂移可定期执行 Playbook 修复Terraform Plan 检测漂移
生命周期配置部署与持续管理基础设施创建、更新、销毁
网络设备原生支持,模块丰富有限支持,依赖 Provider
编排顺序Playbook 顺序执行隐式依赖图自动排序

协同使用模式

Terraform 创建基础设施(云资源/VPC/集群)
    |
    v
Ansible 配置操作系统与中间件(软件安装/配置/部署)
    |
    v
Terraform 更新基础设施时保留 Ansible 配置结果
29 配置漂移检测与修复

答案:

配置漂移是指受管主机实际状态偏离 Playbook 定义期望状态的现象。Ansible 通过幂等执行和定期巡检建立漂移检测与修复机制。

检测策略

- name: Drift detection report
  hosts: all
  tasks:
    - name: Capture current package state
      ansible.builtin.package_facts:
        manager: auto

    - name: Validate required packages
      ansible.builtin.assert:
        that:
          - "'nginx' in ansible_facts.packages"
          - "'openssl' in ansible_facts.packages"
        fail_msg: "Package drift detected on XQOPEN inventory_hostname XQCLOSE"
        success_msg: "Package state compliant"
      register: drift_check
      ignore_errors: yes

    - name: Log drift findings
      ansible.builtin.copy:
        content: |
          Host: XQOPEN inventory_hostname XQCLOSE
          Time: XQOPEN ansible_date_time.iso8601 XQCLOSE
          Drift: XQOPEN drift_check.failed XQCLOSE          
        dest: "/var/log/drift/XQOPEN inventory_hostname XQCLOSE.log"
      delegate_to: localhost

修复模式

  • 被动修复:CI/CD 中定期执行 Playbook,发现漂移自动纠正
  • 事件驱动修复:通过 Webhook 或监控告警触发 Ansible Runner 执行修复 Playbook
  • 金丝雀验证:对灰度主机执行,确认无误后全量修复

ansible-cmdb 集成:将采集的 Fact 数据生成 CMDB 报告,可视化对比各主机配置状态。

# 采集所有主机 Facts
ansible all -m setup --tree /tmp/facts/

# 生成 CMDB HTML 报告
ansible-cmdb /tmp/facts/ > cmdb.html
30 Privilege Escalation 提权机制

答案:

Ansible 通过 become 机制在 Managed Node 上切换用户执行任务,默认切换到 root。

提权方式与配置

参数默认值说明
becomefalse是否启用提权
become_methodsudo提权方式(sudo/su/pbrun/doas)
become_userroot提权目标用户
become_flags-H -S -n提权附加参数

Playbook 级别配置

- hosts: all
  become: yes
  become_user: root
  become_method: sudo
  become_flags: '-H -S'
  tasks:
    - name: Install package
      ansible.builtin.yum:
        name: httpd
        state: present

Task 级别覆盖

- name: Run as application user
  ansible.builtin.command: /opt/app/control.sh status
  become: yes
  become_user: appuser
  become_method: su

密码管理

# 使用 --ask-become-pass 交互式输入 sudo 密码
ansible-playbook site.yml --ask-become-pass

# 在 inventory 中配置(不推荐明文)
ansible_become_password: "XQOPEN vault_sudo_password XQCLOSE"

无密码 sudo 配置:生产环境推荐在 Managed Node 上配置 NOPASSWD sudo 规则以支持无人值守执行。

31 Lookup 插件与数据源集成

答案:

Lookup Plugin 从外部数据源(文件、环境变量、密钥管理服务等)读取数据,注入 Playbook 变量。

常用 Lookup 插件

插件来源使用场景
file本地文件系统读取文件内容
env环境变量读取当前环境变量
password随机密码生成生成并存储随机密码
pipe命令行输出执行本地命令读取结果
templateJinja2 模板渲染预渲染模板内容
csvfileCSV 文件按列读取 CSV 数据
aws_secretAWS Secrets Manager读取密钥
hashi_vaultHashiCorp Vault读取密钥
- name: Read sensitive data from Vault
  ansible.builtin.debug:
    msg: "XQOPEN lookup('hashi_vault', 'secret/data/myapp:token', url='https://vault.example.com') XQCLOSE"

- name: Use CSV data as variable source
  ansible.builtin.debug:
    msg: "XQOPEN lookup('csvfile', 'web1 file=hosts.csv delimiter=, col=1') XQCLOSE"

- name: Generate random password and store
  ansible.builtin.debug:
    msg: "XQOPEN lookup('password', '/tmp/passwords/{{ inventory_hostname XQCLOSE chars=ascii_letters,digits') }}"

Query 与 Lookup 区别query 始终返回列表,lookup 返回字符串(单元素时)或列表(多元素时)。

32 Ansible Runner 与自动化平台集成

答案:

Ansible Runner 是 Ansible 的无头接口库,将 Playbook 执行封装为可编程的标准化过程,适用于集成到外部系统。

核心功能

  • 通过 Python API 或 CLI 启动 Playbook 执行
  • 标准化输出格式(JSON 事件流)
  • 支持私有数据目录隔离(Inventory、凭证、环境)
  • 可嵌入 Web 应用、ChatOps 机器人等
# Python API 调用示例
import ansible_runner

r = ansible_runner.run(
    private_data_dir='/tmp/runner_project',
    playbook='deploy.yml',
    inventory='inventories/production',
    extravars={'version': 'v2.1.0'},
    verbosity=2
)

print(f"Status: {r.status}")
print(f"Return Code: {r.rc}")
for event in r.events:
    print(f"Event: {event['event']} - {event.get('stdout', '')}")

标准输出事件流

Status: successful
Return Code: 0
Event: playbook_on_start - 
Event: runner_on_ok - ok: [web1]
Event: runner_on_ok - ok: [web2]
Event: playbook_on_stats - 

集成场景

  • 运维工单系统中嵌入 Playbook 自服务执行
  • ChatOps 机器人通过 Ansible Runner 执行运维命令
  • 监控告警联动自动执行修复 Playbook
33 Delegation 与本地执行

答案:

Delegation 机制允许任务在指定主机上执行而非当前 Play 目标主机,广泛用于负载均衡摘流、DNS 更新、监控抑制等场景。

关键关键字

  • delegate_to:将任务委托给指定主机执行
  • local_action:等同于 delegate_to: localhost 的简写
  • run_once:仅在一台主机上执行一次
- name: Rolling update with load balancer management
  hosts: webservers
  serial: 1

  tasks:
    - name: Remove server from LB pool
      ansible.builtin.shell: |
        curl -X POST -d '{"server":"XQOPEN inventory_hostname XQCLOSE","action":"disable"}' \
          http://lb-api.example.com/pool        
      delegate_to: localhost
      when: lb_enabled

    - name: Drain existing connections
      ansible.builtin.command: /opt/app/drain.sh
      become: yes

    - name: Update application
      ansible.builtin.copy:
        src: "/packages/app_XQOPEN version XQCLOSE.tar.gz"
        dest: /opt/app/
      notify: restart app

    - name: Add server back to LB pool
      ansible.builtin.uri:
        url: "http://lb-api.example.com/pool"
        method: POST
        body_format: json
        body:
          server: "XQOPEN inventory_hostname XQCLOSE"
          action: enable
      delegate_to: localhost

跨主机数据查询

- name: Check all hosts for a process
  hosts: all
  tasks:
    - name: Store hostname where service runs
      ansible.builtin.shell: pgrep -x myservice && echo "XQOPEN inventory_hostname XQCLOSE"
      register: service_host

    - name: Show only the active host
      ansible.builtin.debug:
        msg: "Service is running on XQOPEN hostvars[item]['inventory_hostname'] XQCLOSE"
      loop: "XQOPEN groups['all'] XQCLOSE"
      when: hostvars[item].service_host.stdout == item
      run_once: true
34 加密与证书管理

答案:

Ansible 通过内置模块和插件支持 x509 证书、OpenSSL 资源和 ACME 协议的自动化管理。

证书与密钥操作

- name: Certificate management
  hosts: all
  tasks:
    - name: Generate self-signed certificate
      community.crypto.x509_certificate:
        path: /etc/ssl/certs/server.crt
        privatekey_path: /etc/ssl/private/server.key
        provider: selfsigned
        subject:
          CN: "XQOPEN inventory_hostname XQCLOSE"
          O: MyOrganization
        force: false

    - name: Generate CSR
      community.crypto.x509_certificate:
        path: /etc/ssl/certs/server.csr
        privatekey_path: /etc/ssl/private/server.key
        provider: ownca
        ownca_path: /etc/ssl/ca/ca.crt
        ownca_privatekey_path: /etc/ssl/ca/ca.key
        subject:
          CN: "XQOPEN inventory_hostname XQCLOSE"

    - name: ACME certificate request (Let's Encrypt)
      community.crypto.acme_certificate:
        account_key_src: /etc/ssl/acme/account.key
        src: /etc/ssl/certs/server.csr
        cert: /etc/ssl/certs/server.crt
        challenge: http-01
        acme_directory: https://acme-v02.api.letsencrypt.org/directory
        terms_agreed: yes
      delegate_to: localhost

ACME 自动续期 Playbook

- name: Auto-renew Let's Encrypt certificates
  hosts: all
  vars:
    cert_domains:
      - example.com
      - www.example.com
  tasks:
    - name: Check certificate expiry
      community.crypto.x509_certificate_info:
        path: /etc/ssl/certs/server.crt
      register: cert_info

    - name: Renew if expiring within 30 days
      community.crypto.acme_certificate_renewal:
        src: /etc/ssl/certs/server.crt
      when:
        - cert_info.not_after is defined
        - cert_info.not_after < (ansible_date_time.epoch | int + 2592000)

    - name: Reload web server on renewal
      ansible.builtin.systemd:
        name: nginx
        state: reloaded
      when: cert_info.not_after is defined
35 大规模集群管理策略

答案:

当受管主机数量达到数百或数千台时,Ansible 的执行模型需要针对性调优。

规模化架构建议

管理平面分层
  Control Node (Ansible Runner)
      |
  +----+----+
  |         |
  Relay    Relay
  (IDC-A)  (IDC-B)
  |         |
  hosts     hosts

规模化配置要点

# ansible.cfg 规模化调优
[defaults]
forks = 50                    # 并行进程数,根据 Control Node CPU 核心调整
host_key_checking = False     # 跳过 SSH 主机密钥检查
timeout = 30                  # SSH 连接超时
gathering = smart             # 智能 Fact 采集
fact_caching = redis          # Redis 缓存 Facts
fact_caching_connection = localhost:6379:0
internal_poll_interval = 0.1  # 轮询间隔

[ssh_connection]
pipelining = True
ssh_args = -o ControlMaster=auto -o ControlPersist=120s -o ControlPath=~/.ssh/ansible-%r@%h:%p

执行策略优化

  • 分批次执行:ansible-playbook site.yml --limit web-1001-web-1200 -f 50
  • Pattern 匹配:使用主机名范围匹配 web-[1:100]
  • Inventory 分层:按机房/集群拆分 Inventory 文件
  • Ansible Runner:异步编排任务队列,避免 Control Node 过载

注意事项

  • 单个 Playbook 的 hosts 数量建议不超过 500 台
  • 大规模执行时优先使用动态 Inventory + 缓存
  • Pipelining 开启后 SSH 连接数从 2N 降至 N
  • 监控 Control Node 的 CPU、内存和网络 IO
36 Ansible Pull 与 Push 模式对比

答案:

Ansible 默认采用 Push 模式(Control Node 主动连接 Managed Node),也支持 Pull 模式(Managed Node 定期拉取配置)。

维度Push 模式Pull 模式(ansible-pull)
触发方式Control Node 主动执行受管主机 cron 定时拉取
适用规模中小规模集群大规模或不可达网络
网络要求控制节点可访问所有受管节点受管节点可访问 Git 仓库
实时性即时执行依赖 cron 间隔
中心控制集中管控去中心化
复杂度简单直接需配置 cron 和 Git

ansible-pull 工作方式

# 受管节点定期执行
ansible-pull -U https://git.example.com/ansible-config.git \
  -i inventories/production \
  playbooks/site.yml \
  --accept-host-key

Pull 模式适用场景

  • 受管主机在 NAT 后无法被 Control Node 主动连接
  • 超大规模集群(万级别),避免 Control Node 成为瓶颈
  • 离线环境或间歇性联网设备
  • IoT 设备、边缘节点管理
37 Windows 与 Linux 混合管理

答案:

Ansible 在一个 Playbook 中同时管理 Windows 和 Linux 主机,通过连接方式和模块自动适配。

混合 Inventory 配置

all:
  children:
    linux_servers:
      hosts:
        web1: {}
        web2: {}
      vars:
        ansible_connection: ssh
        ansible_user: admin
        ansible_python_interpreter: /usr/bin/python3

    windows_servers:
      hosts:
        win1:
          ansible_host: 10.0.0.100
      vars:
        ansible_connection: winrm
        ansible_winrm_transport: credssp
        ansible_shell_type: powershell

混合管理 Playbook

- name: Patch all servers
  hosts: all
  strategy: free

  tasks:
    - name: Update packages (Linux)
      ansible.builtin.yum:
        name: '*'
        state: latest
      when: ansible_system == "Linux"

    - name: Install Windows updates
      ansible.windows.win_updates:
        category_names:
          - SecurityUpdates
          - CriticalUpdates
        state: installed
      when: ansible_system == "Win32NT"
      register: update_result

    - name: Reboot Windows if required
      ansible.windows.win_reboot:
      when:
        - ansible_system == "Win32NT"
        - update_result.reboot_required

关键差异

  • Linux 使用 SSH 连接和 shell/bash 模块
  • Windows 使用 WinRM 连接和 PowerShell 模块
  • 变量和 Facts 采集路径不同(win 前缀 vs ansible 前缀)
  • gather_facts 在不同平台采集不同数据集合
38 Playbook 中的 Include 与 Import 区别

答案:

Include 和 Import 是 Playbook 任务复用的两种方式,核心区别在于加载时机和作用域。

维度Include(动态)Import(静态)
加载时机运行时Playbook 解析时
循环支持支持 loop 动态加载不支持循环
条件支持when 条件作用于包含操作条件作用于被导入文件整体
变量覆盖支持动态变量不支持动态变量
Tag 继承不继承外部 Tag继承外部 Tag
执行顺序按需随时包含预解析一次性展开

Include 示例

# 动态包含 - 根据条件加载不同任务文件
- name: Include platform-specific tasks
  ansible.builtin.include_tasks: "XQOPEN ansible_os_family XQCLOSE.yml"
  when: ansible_os_family == "RedHat"

Import 示例

# 静态导入 - 解析时展开
- name: Import common setup tasks
  ansible.builtin.import_tasks: setup.yml
  tags:
    - setup

# Import Playbook
- name: Import another playbook
  ansible.builtin.import_playbook: webserver.yml

最佳实践

  • 文件路径使用静态导入(import_playbook/import_tasks),确保 Tag 和条件正确传播
  • 动态加载根据不同条件选择任务文件时使用 include_tasks
  • Role 使用 roles: 方式引用,自动处理依赖和变量优先级
39 Filter Plugin 数据转换

答案:

Filter Plugin 基于 Jinja2 过滤器扩展,提供数据类型转换、JSON 操作、IP 计算、加密等能力。

内置常用过滤器

- name: Filter plugin demonstrations
  hosts: localhost
  vars:
    ip_list:
      - "192.168.1.10"
      - "10.0.0.1"
      - "172.16.0.1"
    raw_data: '{"name": "test", "value": 42}'

  tasks:
    - name: JSON parse and combine
      ansible.builtin.debug:
        msg:
          parsed: "XQOPEN raw_data | from_json XQCLOSE"
          merged: "XQOPEN [{'extra':'info'}] | combine({'key':'value'}) XQCLOSE"

    - name: IP address calculations
      ansible.builtin.debug:
        msg:
          in_subnet: "XQOPEN '192.168.1.15' in ip_list XQCLOSE"
          network: "XQOPEN '192.168.1.0/24' | ansible.utils.network_in_use(ip_list) XQCLOSE"

    - name: Data manipulation
      ansible.builtin.debug:
        msg:
          unique: "XQOPEN [1, 2, 2, 3] | unique XQCLOSE"
          flattened: "XQOPEN [[1, 2], [3]] | flatten XQCLOSE"
          dict_to_list: "XQOPEN {'a':1, 'b':2} | dict2items XQCLOSE"

自定义 Filter Plugin

# filter_plugins/my_filters.py
class FilterModule(object):
    def filters(self):
        return {
            'to_upper_version': self.to_upper_version,
        }

    def to_upper_version(self, version):
        parts = version.split('-')
        if len(parts) > 1:
            return f"{parts[0]}-{parts[1].upper()}"
        return version.upper()

使用自定义 Filter{{ "v2.1-beta" | to_upper_version }} 返回 v2.1-BETA

40 Ansible 运维审计与日志

答案:

Ansible 执行过程记录可通过多种方式实现审计追踪,满足合规要求。

日志记录配置

# ansible.cfg
[defaults]
log_path = /var/log/ansible/ansible.log

审计维度与实现

审计维度实现方式
执行记录日志文件 + 回调插件持久化
变更追踪–diff 模式输出变更详情
用户追溯Tower/AWX 作业记录关联用户
时间戳日志中 date_time Fact 标注
配置基线定期 Playbook 执行 + Fact 快照

自定义审计回调插件

# callback_plugins/audit_log.py
import json
import datetime

class CallbackModule(CallbackBase):
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'aggregate'
    CALLBACK_NAME = 'audit_log'

    def __init__(self):
        super().__init__()
        self.audit_events = []

    def v2_runner_on_ok(self, result):
        event = {
            'timestamp': datetime.datetime.utcnow().isoformat(),
            'host': result._host.name,
            'task': result.task_name,
            'status': 'ok',
            'changed': result.is_changed(),
        }
        self.audit_events.append(event)

    def v2_playbook_on_stats(self, stats):
        with open(f"/var/log/ansible/audit_{int(time.time())}.json", 'w') as f:
            json.dump(self.audit_events, f, indent=2)

Tower/AWX 审计:记录每个作业的启动用户、执行参数、输出日志和资产变更历史,支持 API 查询和导出。