Ansible 面试题
40 道题- 分类
- DevOps
- 题目数
- 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) |
| Playbook | YAML 格式的任务编排文件,定义主机与任务映射关系 |
| Plugin | 扩展 Ansible 功能的组件(连接/回调/过滤器等) |
| Galaxy | Role 共享社区仓库,支持依赖管理与版本控制 |
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_ec2、gcp_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 Module | Ansible 核心仓库 | 内置维护,稳定可靠 | copy、file、yum、service、command |
| Community Module | Ansible 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 变量遵循严格的优先级规则,高优先级变量覆盖低优先级变量。
优先级从高到低(前五项):
- extra vars(
-e命令行参数) - 任务级变量(
vars:任务内联) - Block 级变量
- Role 级变量(
defaults/main.yml优先级最低的 role 变量除外) - Include/Import 参数变量
- Play 级变量(
vars:字段) - Host facts 和 inventory 变量
- Playbook
vars_files - Group vars(
group_vars/) - 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_ipv4、ansible_all_ipv4_addresses、ansible_interfaces - 系统:
ansible_os_family、ansible_distribution_version、ansible_kernel - 硬件:
ansible_processor_cores、ansible_memtotal_mb、ansible_architecture - 磁盘:
ansible_devices、ansible_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 defined、is undefined、is none、is failed、is succeeded。
11 任务控制:Loop 循环迭代
答案:
Ansible 支持多种循环模式遍历数组、哈希和范围数据。
循环语法演进:
- 旧语法:
with_items、with_dict、with_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_var、pause、label。
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
特殊标签:tagged、untagged、all 用于批量选择。
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 格式 |
| 邮件通知 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.cfg 中 stdout_callback 和 callback_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.0 | Red 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-name | Role 命名 | 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.py 或 roles/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 APIgather_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 Pipelining | pipelining = True | 减少 SSH 连接次数,提升 2-3 倍 |
| ControlPersist | ssh_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 同为基础设施自动化工具,定位和侧重点各有不同。
| 维度 | Ansible | Terraform |
|---|---|---|
| 定位 | 配置管理与应用编排 | 基础设施即代码(IaC) |
| 架构 | 无代理,Push 模式 | Push 模式 + Provider 插件 |
| 状态管理 | 无中心状态,幂等依赖模块实现 | 中心化 State 文件管理资源状态 |
| 语言 | YAML Playbook | HCL(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。
提权方式与配置:
| 参数 | 默认值 | 说明 |
|---|---|---|
| become | false | 是否启用提权 |
| become_method | sudo | 提权方式(sudo/su/pbrun/doas) |
| become_user | root | 提权目标用户 |
| 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 | 命令行输出 | 执行本地命令读取结果 |
| template | Jinja2 模板渲染 | 预渲染模板内容 |
| csvfile | CSV 文件 | 按列读取 CSV 数据 |
| aws_secret | AWS Secrets Manager | 读取密钥 |
| hashi_vault | HashiCorp 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 查询和导出。