认识ansible(入门)
什么是ansible?
Ansible是一款自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
Ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是Ansible所运行的模块,Ansible只是提供一种框架。主要包括:
(1) 连接插件connection plugins:负责和被监控端实现通信;
(2) host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
(3) 各种模块核心模块、command模块、自定义模块;
(4) 借助于插件完成记录日志邮件等功能;
(5) playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。
Ansible 无需代理
Ansible 围绕无代理架构构建。通常而言,Ansible 通过 OpenSSH 或 WinRM 连接它所管理的主机并且运行任务,方法通常是将称为 Ansible 模块的小程序推送至这些主机。这些程序用于将系统置于需要的特定状态。在 Ansible 运行完其任务后,推送的所有模块都会被删除。
Ansible 不需要批准使用任何特殊代理,然后再部署到受管主机上。由于没有代理,也不需要额外的自定义安全基础架构,
Ansible 具有多个重要的优点:
跨平台支持:Ansible 提供Linux、Windows、UNIX和网络设备的无代理支持,适用于物理、虚拟、云和容器环境。
人类可读的自动化:Ansible Playbook采用YAML文本文件编写,易于阅读,有助于确保所有人都能理解它们的用途。
完美描述应用:可以通过 Ansible Playbook进行每种更改,并描述和记录应用环境的每一个方面。
轻松管理版本控制:Ansible Playbook和项目是纯文本。它们可以视作源代码,放在现有版本控制系统中。
支持动态清单:可以从外部来源动态更新 Ansible 管理的计算机列表,随时获取所有受管服务器的当前正确列表,不受基础架构或位置的影响。
编排可与其他系统轻松集成:能够利用环境中现有的 HP SA、Puppet、Jenkins、红帽卫星和其他系统,并且集成到 Ansible 工作流中。
一:Ansible 的清单(Inventory)
1 什么是 Inventory?
作用:列出 Ansible 需要管理的主机(IP/域名)和分组。
默认路径:
/etc/ansible/hosts
,但通常使用自定义路径并通过-i
指定。格式:支持 INI 或 YAML 格式(推荐 INI 简单易读)。
2. 基础用法
2.1 定义主机
# 直接定义单个主机(IP 或域名)
192.168.1.10
web.example.com# 指定 SSH 端口和用户
db-server ansible_host=192.168.1.11 ansible_port=2222 ansible_user=admin
ansible_host
:覆盖默认的主机名。ansible_port
:指定非标准 SSH 端口(默认 22)。ansible_user
:登录远程主机的用户。
2.2 定义主机组
# 定义组 [组名],组内包含主机
[web_servers]
192.168.1.10
192.168.1.11[db_servers]
db-server # 引用之前定义的主机别名# 嵌套组(:children)
[prod:children]
web_servers
db_servers
组可以嵌套(通过
:children
声明)。示例中
prod
组包含web_servers
和db_servers
的所有主机。
2.3 为主机或组分配变量
# 主机变量
[web_servers]
web1 ansible_host=192.168.1.10 http_port=80# 组变量(通过 :vars)
[db_servers:vars]
ansible_user=postgres
db_version=14
变量可以在 Playbook 或模板中通过
{{ http_port }}
引用。
3. 动态清单(Dynamic Inventory)
当主机列表频繁变化(如云环境),静态文件难以维护,此时可以用动态清单脚本(返回 JSON 格式的主机信息)。
3.1 动态清单示例(AWS EC2)
# 使用 aws_ec2 插件(需安装 boto3)
ansible-inventory -i aws_ec2.yaml --list
配置文件 aws_ec2.yaml
:
plugin: aws_ec2
regions:- us-east-1
filters:tag:Environment: prod
3.2 动态清单的优势
自动从云平台(AWS、Azure、GCP)或 CMDB 获取最新主机列表。
支持过滤(如按标签、区域等)。
4. 高级功能
4.1 模式匹配
在命令中灵活选择主机:
# 匹配 web_servers 组
ansible web_servers -m ping# 通配符匹配所有以 "web" 开头的主机
ansible "web*" -m ping# 排除 db_servers 组
ansible all:!db_servers -m ping
4.2 使用多个清单文件
通过目录合并多个清单:
/etc/ansible/inventories/
├── production
├── staging
└── cloud
运行命令时指定目录:
ansible -i /etc/ansible/inventories/production all -m ping
4. 高级功能
4.1 模式匹配
在命令中灵活选择主机:
# 匹配 web_servers 组
ansible web_servers -m ping# 通配符匹配所有以 "web" 开头的主机
ansible "web*" -m ping# 排除 db_servers 组
ansible all:!db_servers -m ping
4.2 使用多个清单文件
通过目录合并多个清单:
/etc/ansible/inventories/
├── production
├── staging
└── cloud
运行命令时指定目录:
ansible -i /etc/ansible/inventories/production all -m ping
二:ansible的运行临时命令
1. 临时命令的基本格式
ansible <主机或组名> -m <模块名> -a "<模块参数>" [其他选项]
<主机或组名>:
可以是 Inventory 文件中定义的主机名、组名,或通配符(如 all 表示所有主机)。
示例:web_servers、192.168.1.10。
-m <模块名>:指定要使用的模块(如 command、shell、copy 等)。
如果省略 -m,默认使用 command 模块。
-a "<模块参数>":传递给模块的参数(如命令、文件路径等)。
[其他选项]:如 -i 指定 Inventory 文件、-u 指定用户等。
2. 常用模块的临时命令示例
(1)执行 Shell 命令
# 在所有主机上执行 `ls /tmp`
ansible all -m command -a "ls /tmp"# 使用 shell 模块(支持管道)
ansible web_servers -m shell -a "cat /var/log/nginx/access.log | grep 404"
(2)文件管理
# 复制本地文件到远程主机
ansible db_servers -m copy -a "src=/etc/hosts dest=/tmp/hosts mode=0644"# 删除远程文件
ansible 192.168.1.10 -m file -a "path=/tmp/old.log state=absent"
(3)软件包管理
# 在 CentOS 上安装 nginx
ansible web -m yum -a "name=nginx state=present"# 在 Ubuntu 上更新所有软件包
ansible ubuntu_servers -m apt -a "upgrade=dist"
(4)服务管理
# 启动 nginx 并设置开机自启
ansible web -m service -a "name=nginx state=started enabled=yes"
(5)用户管理
# 创建用户
ansible all -m user -a "name=testuser groups=wheel"
(6)收集主机信息(使用 setup 模块)
# 获取所有主机的内存信息
ansible all -m setup -a "filter=ansible_memtotal_mb"
3. 常用选项
选项说明:
-i <路径> 指定自定义的 Inventory 文件(默认 /etc/ansible/hosts)。
-u <用户名> 指定远程主机的登录用户(如 -u root)。
--become 提权(默认用 sudo,等同于 -b)。
--become-user 提权到指定用户(如 --become-user=root)。
-k 提示输入 SSH 密码(如果未配置密钥认证)。
-K 提示输入提权密码(如 sudo 密码)。
-v / -vvv 输出详细日志(-v 为基本信息,-vvv 为调试信息)。
--limit <主机> 限制执行的主机(如 --limit 192.168.1.10)。
示例:
# 以 admin 用户登录,sudo 执行命令
ansible db -u admin --become -K -m shell -a "whoami"
4. 实际场景示例
(1)批量重启服务
ansible web_servers -m service -a "name=httpd state=restarted" --become
(2)检查磁盘空间
ansible all -m shell -a "df -h /"
(3)批量推送公钥
ansible all -m authorized_key -a "user=root key='{{ lookup('file', '/root/.ssh/id_rsa.pub') }}'"
5. 注意事项
幂等性:
大多数模块(如 yum、copy)是幂等的(多次执行结果一致),但 shell 和 command 模块可能不是。
安全性:
避免在 -a 中直接传递敏感信息(如密码),建议使用 Ansible Vault。
性能:
临时命令是同步执行的,若需并行控制,可使用 -f <并发数>(如 -f 10)。
6. 与 Playbook 的区别
临时命令 Playbook
单行命令,快速执行简单任务。 YAML 文件,适合复杂、多步骤的任务。
无需保存,适合临时操作。 可复用、版本控制、支持条件判断等逻辑。
示例:ansible all -m ping 示例:ansible-playbook deploy.yml
总结
临时命令是 Ansible 快速操作的利器,适合:
快速验证模块功能。
紧急修复或一次性任务。
简单的主机状态检查。
掌握后,可以结合 Playbook 实现更强大的自动化!
三:ansible常用模块
1. command 模块
用途:在远程主机上执行简单的命令。
特点:
不支持管道(|)、重定向(>)等 Shell 特性。
如果需要 Shell 功能,应使用 shell 模块。
常用参数:
cmd: 要执行的命令(可选,可以直接写命令字符串)。
chdir: 执行命令前切换到的目录。
示例:
- name: 查看当前目录内容command: ls -lregister: result # 将命令输出保存到变量 result- name: 打印命令输出debug:var: result.stdout
2. shell 模块
用途:在远程主机上通过 Shell 执行命令(支持管道、重定向等)。
特点:
比 command 更灵活,但可能有安全风险(如用户输入未过滤时)。
常用参数:
cmd: 要执行的命令。
executable: 指定 Shell 路径(如 /bin/bash)。
示例:
- name: 使用管道统计文件行数shell: cat /etc/passwd | wc -lregister: line_count- name: 打印行数debug:var: line_count.stdout
3. copy 模块
用途:将本地文件复制到远程主机。
常用参数:
src: 本地源文件路径。
dest: 远程目标路径(必须是完整路径)。
owner: 设置文件所有者。
group: 设置文件所属组。
mode: 设置文件权限(如 0644)。
示例:
- name: 复制本地文件到远程主机copy:src: ./app.confdest: /etc/app.confowner: rootgroup: rootmode: '0644'
4. file 模块
用途:管理文件和目录(创建、删除、修改权限等)。
常用参数:
path: 文件/目录路径。
state: 状态(file、directory、link、absent 等)。
recurse: 递归设置目录属性(如权限)。
示例:
- name: 创建目录file:path: /opt/myappstate: directorymode: '0755'- name: 删除文件file:path: /tmp/old.logstate: absent
5. yum (或 apt) 模块
用途:管理软件包(yum 用于 CentOS/RHEL,apt 用于 Debian/Ubuntu)。
常用参数:
name: 包名(支持列表)。
state: present(安装)、latest(更新)、absent(卸载)。
示例:
- name: 安装 Nginxyum: # 对于 Debian 替换为 aptname: nginxstate: present
6. service 模块
用途:管理服务(启动、停止、重启等)。
常用参数:
name: 服务名。
state: started、stopped、restarted。
enabled: 是否开机自启(yes/no)。
示例:
- name: 启动 Nginx 并设置开机自启service:name: nginxstate: startedenabled: yes
7. template 模块
用途:将 Jinja2 模板渲染后复制到远程主机(常用于配置文件动态生成)。
常用参数:
src: 本地模板文件(.j2 后缀)。
dest: 远程目标路径。
示例:
- name: 生成 Nginx 配置template:src: ./nginx.conf.j2dest: /etc/nginx/nginx.conf
8. user 模块
用途:管理用户账号。
常用参数:
name: 用户名。
state: present(创建)或 absent(删除)。
groups: 用户所属组。
password: 加密后的密码(需使用 openssl passwd 生成)。
示例:
- name: 创建用户user:name: devusergroups: wheelstate: present
9. debug 模块
用途:调试任务(打印变量或消息)。
常用参数:
msg: 打印自定义消息。
var: 打印变量值。
示例:
- name: 显示变量debug:var: my_variable- name: 打印消息debug:msg: "任务执行完成!"
10. fetch 模块
用途:从远程主机拉取文件到本地。
常用参数:
src: 远程文件路径。
dest: 本地存储目录(会自动创建以主机名命名的子目录)。
示例:
- name: 拉取远程日志文件fetch:src: /var/log/app.logdest: /tmp/backups/
四:Ansible Playbook 详细讲解
Playbook 是 Ansible 的核心组件,用于定义复杂的自动化任务流程。它以 YAML 格式编写,能够实现配置管理、应用部署、编排等高级功能。下面我将从基础到高级全面讲解 Playbook 的使用。
1. Playbook 基础结构
一个基本的 Playbook 包含以下元素:
---
- name: 我的第一个Playbook # Playbook描述hosts: web_servers # 目标主机或组become: yes # 是否提权执行vars: # 定义变量http_port: 80tasks: # 任务列表- name: 确保nginx已安装yum:name: nginxstate: present
1.1 核心组成部分
name: Playbook 或任务的描述性名称
hosts: 指定在哪些主机/组上运行
become: 是否使用特权升级(sudo等)
vars: 定义变量
tasks: 要执行的任务序列
2. Playbook 编写详解
2.1 多Play结构
一个Playbook可以包含多个Play:
---
- name: 配置Web服务器hosts: web_serverstasks:- name: 安装nginxyum: name=nginx state=latest- name: 配置数据库服务器hosts: db_serverstasks:- name: 安装PostgreSQLyum: name=postgresql-server state=latest
2.2 变量使用
变量可以在多个位置定义:
---
- hosts: allvars: # Play级别变量package_name: nginxvars_files: # 引入外部变量文件- vars/main.ymltasks:- name: 安装{{ package_name }}yum:name: "{{ package_name }}"state: present- name: 使用Facts变量debug:msg: "{{ ansible_hostname }} 的内存是 {{ ansible_memtotal_mb }}MB"
2.3 条件与循环
条件判断:
tasks:- name: 仅当是CentOS时安装yum: name=nginx state=presentwhen: ansible_os_family == "RedHat"
循环:
tasks:- name: 添加多个用户user:name: "{{ item.name }}"groups: "{{ item.groups }}"loop:- { name: 'user1', groups: 'wheel' }- { name: 'user2', groups: 'root' }
3. 常用模块在Playbook中的应用
3.1 文件管理
tasks:- name: 复制配置文件copy:src: files/nginx.confdest: /etc/nginx/nginx.confowner: rootgroup: rootmode: '0644'notify: 重启nginx # 触发handler- name: 创建目录file:path: /var/www/htmlstate: directorymode: '0755'
3.2 包管理
tasks:- name: 安装EPEL仓库yum:name: epel-releasestate: present- name: 安装必要软件包yum:name: "{{ packages }}"state: latestvars:packages:- nginx- php-fpm- mariadb-server
3.3 服务管理
tasks:- name: 确保nginx运行service:name: nginxstate: startedenabled: yes
4. 高级功能
4.1 Handlers(触发器)
tasks:- name: 更新nginx配置template:src: templates/nginx.conf.j2dest: /etc/nginx/nginx.confnotify: 重启nginx # 配置文件改变时触发handlers:- name: 重启nginxservice:name: nginxstate: restarted
4.2 模板(Jinja2)
templates/db.conf.j2
:
[database]
host = {{ db_host }}
port = {{ db_port | default(3306) }}
user = {{ db_user }}
password = {{ db_password }}
Playbook中使用:
tasks:- name: 配置数据库连接template:src: templates/db.conf.j2dest: /etc/app/db.confvars:db_host: "192.168.1.100"db_user: "appuser"db_password: "{{ vault_db_password }}" # 使用加密变量
4.3 角色(Roles)组织
推荐的项目结构:
site.yml
roles/common/tasks/handlers/files/templates/vars/defaults/meta/webserver/database/
使用角色:
---
- hosts: allroles:- common- webserver
5. 错误处理
5.1 忽略错误
tasks:- name: 尝试停止服务command: /bin/falseignore_errors: yes
5.2 重试机制
tasks:- name: 等待端口响应wait_for:port: 80host: "{{ inventory_hostname }}"delay: 10timeout: 300register: resultuntil: result is succeededretries: 5delay: 30
6. 实际案例:部署Web应用
---
- name: 部署WordPress站点hosts: web_serversbecome: yesvars:wp_version: "5.8"db_name: "wordpress"db_user: "wpuser"tasks:- name: 安装依赖yum:name: [nginx, php-fpm, php-mysql, mariadb]state: latest- name: 下载WordPressunarchive:src: "https://wordpress.org/wordpress-{{ wp_version }}.tar.gz"dest: /var/www/remote_src: yes- name: 配置nginxtemplate:src: templates/wordpress.conf.j2dest: /etc/nginx/conf.d/wordpress.confnotify: 重启nginx- name: 设置文件权限file:path: /var/www/wordpressowner: nginxgroup: nginxrecurse: yeshandlers:- name: 重启nginxservice:name: nginxstate: restarted
7. 最佳实践
保持幂等性:确保Playbook可以安全重复运行
使用标签:为任务添加标签便于选择性运行
tasks:- name: 安装软件yum: name=nginxtags: install
运行:
ansible-playbook site.yml --tags "install"
变量分层:
defaults/ (最低优先级)
group_vars/
host_vars/
Playbook vars
命令行-e传递变量 (最高优先级)
加密敏感数据:
ansible-vault create secrets.yml
使用:
vars_files:- secrets.yml
测试与验证:
--check
干跑模式--diff
显示变更--step
逐步执行
8. 调试技巧
使用debug模块:
- debug:var: hostvars[inventory_hostname]
增加详细输出:
ansible-playbook playbook.yml -vvv
注册变量检查:
- command: ls /tmpregister: result - debug:var: result
总结
Ansible Playbook 提供了强大的自动化能力,通过:
YAML结构化:清晰定义自动化流程
模块化设计:使用各种模块完成具体任务
变量系统:实现灵活配置
条件控制:处理复杂逻辑
错误处理:保证可靠性
角色组织:提高复用性
五:Ansible 变量管理
Ansible支持利用变量来存储值,并在Ansible项目的所有文件中重复使用这些值。这可以简化项目的创建和维护,并减少错误的数量。
通过变量,可以轻松地在Ansible项目中管理给定环境的动态值。例如,变量可能包含下面这些值:
要创建的用户
要安装的软件包
要重新启动的服务
要删除的文件
要从互联网检索的存档
一、变量基础概念
1.1 变量定义方式
Ansible 支持多种变量定义形式:
# 键值对形式
variable_name: "value"# 列表形式
packages:- nginx- mysql-server# 字典形式
user:name: aliceuid: 1001groups: wheel
1.2 变量引用语法
基本引用:
{{ variable_name }}
访问字典:
{{ user.name }}
访问列表:
{{ packages[0] }}
二、变量作用域与优先级
2.1 作用域类型
作用域 | 描述 | 示例 |
---|---|---|
全局 | 对所有Play有效 | group_vars/all.yml |
Play | 当前Play内有效 | Play中的vars: 段 |
Host | 特定主机有效 | host_vars/web1.yml |
Task | 仅当前任务有效 | 任务中的vars: |
2.2 完整优先级顺序(从低到高)
命令行
-e
传递的变量(最高优先级)
三、变量定义位置详解
3.1 Inventory 变量
# inventory.ini
[web]
web1 ansible_host=192.168.1.10 http_port=8080[web:vars]
nginx_version=1.18
3.2 独立变量文件
# group_vars/web.yml
service_name: nginx
config_path: /etc/nginx/nginx.conf# host_vars/web1.yml
max_connections: 2048
3.3 Playbook 中定义
- hosts: webvars:deploy_user: "www-data"vars_files:- vars/secrets.yml
3.4 角色变量
roles/webserver/defaults/main.yml # 默认变量(低优先级)vars/main.yml # 角色变量(高优先级)
四、特殊变量类型
4.1 Facts 变量
系统自动收集的主机信息:
- debug:msg: "{{ ansible_distribution }} {{ ansible_distribution_version }}"
4.2 注册变量(Registered Variables)
捕获任务输出:
- name: 检查服务状态command: systemctl is-active nginxregister: nginx_statusignore_errors: yes- name: 根据状态处理service:name: nginxstate: "{{ 'restarted' if nginx_status.rc != 0 else 'started' }}"
4.3 魔法变量(Magic Variables)
Ansible 内置特殊变量:
inventory_hostname
:当前操作的主机名groups
:所有分组信息ansible_play_hosts
:当前Play的目标主机列表
五、高级变量技术
5.1 变量合并(hash_behaviour)
配置ansible.cfg
:
[defaults]
hash_behaviour = merge # 合并字典而不是覆盖
5.2 变量过滤器
Jinja2过滤器应用:
- debug:msg: "{{ user_input | lower | replace(' ', '_') }}"
5.3 动态变量
从命令获取变量值:
- name: 获取最新版本号command: curl -s https://api.github.com/repos/foo/bar/releases/latestregister: releasechanged_when: false- set_fact:latest_version: "{{ release.stdout | from_json | json_query('tag_name') }}"
六、安全变量管理
6.1 Ansible Vault 加密
# 创建加密文件
ansible-vault create vars/secrets.yml# 编辑加密文件
ansible-vault edit vars/secrets.yml# 运行Playbook时解密
ansible-playbook site.yml --ask-vault-pass
6.2 加密变量示例
# vars/secrets.yml
db_password: !vault |$ANSIBLE_VAULT;1.1;AES256663864396532363364626265666530633361646239663038633737346...
七、变量调试技巧
7.1 查看所有变量
# vars/secrets.yml
db_password: !vault |$ANSIBLE_VAULT;1.1;AES256663864396532363364626265666530633361646239663038633737346...
7.2 特定变量检查
- debug:var: hostvars[inventory_hostname]
7.3 变量类型检查
- debug:msg: "{{ some_var | type_debug }}"
八、最佳实践
命名规范:
使用小写和下划线:
app_port
而非appPort
避免特殊字符和空格
结构设计:
inventory/production/group_vars/all.ymlweb.ymlhost_vars/web1.ymlvars/common.ymlsecrets.yml
文档注释:
# 数据库连接配置 db:host: "db.example.com" # 主数据库服务器port: 5432 # 默认PostgreSQL端口
版本控制:
将变量文件纳入版本控制
敏感数据使用Vault加密后提交
九、实战案例
9.1 多环境配置管理
# inventory/
# production/
# group_vars/all.yml
env: production
db_host: db-prod.example.com# staging/
# group_vars/all.yml
env: staging
db_host: db-stage.example.com
9.2 条件变量应用
- name: 配置防火墙firewalld:port: "{{ item.port }}/tcp"state: enabledpermanent: yesloop: "{{ firewall_rules | default([]) }}"when: firewall_enabled | default(true)
9.3 变量继承示例
# roles/common/defaults/main.yml
package_version: "1.0.0"# playbook.yml
- hosts: allroles:- role: commonvars:package_version: "2.0.0" # 覆盖默认值
六:Ansible 机密管理
Ansible可能需要访问密码或API密钥等敏感数据,以便能配置受管主机。通常,此信息可能以纯文本形式存储在清单变量或其他Ansible文件中。但若如此,任何有权访问Ansible文件的用户或存储这些Ansible文件的版本控制系统都能够访问此敏感数据。这显示存在安全风险。
Ansible提供的Ansible Vault可以加密和解密任何由Ansible使用的结构化数据文件。若要使用Ansible Vault,可通过一个名为ansible-vault的命令行工具创建、编辑、加密、解密和查看文件。Ansible Vault可以加密任何由Ansible使用的结构化数据文件。这可能包括清单变量、playbook中含有的变量文件、在执行playbook时作为参数传递的变量文件,或者Ansible角色中定义的变量。
1.1 Ansible Vault 基础
加密原理
Ansible Vault 使用 AES-256 对称加密算法保护敏感数据,通过密码或密钥文件进行加解密。
基本操作命令
# 创建加密文件
ansible-vault create secrets.yml# 编辑加密文件
ansible-vault edit secrets.yml# 查看加密文件
ansible-vault view secrets.yml# 加密现有文件
ansible-vault encrypt existing.yml# 解密文件
ansible-vault decrypt secrets.yml --output=plaintext.yml
1.2 高级加密技术
变量文件加密
# 创建加密文件
ansible-vault create secrets.yml# 编辑加密文件
ansible-vault edit secrets.yml# 查看加密文件
ansible-vault view secrets.yml# 加密现有文件
ansible-vault encrypt existing.yml# 解密文件
ansible-vault decrypt secrets.yml --output=plaintext.yml
Playbook 中引用加密变量
- hosts: db_serversvars_files:- group_vars/prod/vault.ymltasks:- name: 配置数据库密码mysql_user:name: app_userpassword: "{{ db_password }}"
1.3 多密码管理
密码文件使用
# 创建密码文件
echo "myvaultpassword" > ~/.vault_pass.txt
chmod 600 ~/.vault_pass.txt# 使用密码文件
ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt
不同环境不同密码
# ansible.cfg 配置
[vault]
vault_password_file = dev@~/.vault_pass_dev.txt
vault_password_file = prod@~/.vault_pass_prod.txt
1.4 最佳安全实践
密码轮换:定期更改Vault密码
ansible-vault rekey secrets.yml
最小权限原则:按角色分配访问权限
# 在playbook中条件加载 vars_files:- "vars/{{ env }}/vault.yml"
七:Ansible Facts
Ansible事实是Ansible在受管主机上自动检测到的变量。事实中包含有与主机相关的信息,可以像play中的常规变量、条件、循环或依赖于从受管主机收集的值的任何其他语句那样使用。
为受管主机收集的一些事实可能包括:
主机名称
内核版本
网络接口
IP地址
操作系统版本
各种环境变量
CPU数量
提供的或可用的内存
可用磁盘空间
借助事实,可以方便地检索受管主机的状态,并根据该状态确定要执行的操作。例如:
可以根据含有受管主机当前内核版本的事实运行条件任务,以此来重启服务器
可以根据通过事实报告的可用内存来自定义MySQL配置文件
可以根据事实的值设置配置文件中使用的IPv4地址
通常,每个play在执行第一个任务之前会先自动运行setup模块来收集事实。
查看为受管主机收集的事实的一种方式是,运行一个收集事实并使用debug模块显示ansible_facts变量值的简短playbook
1 Facts 系统架构
收集流程
通过
setup
模块连接目标主机执行Python脚本收集系统信息
返回结构化JSON数据
核心组件
Gatherers:特定类型数据的收集器
Cache:事实缓存系统(JSON文件、Redis等)
Custom Facts:用户自定义的
.fact
文件
2 Facts 分类与应用
系统基础信息
- debug:msg: |主机名: {{ ansible_hostname }}操作系统: {{ ansible_distribution }} {{ ansible_distribution_version }}内核版本: {{ ansible_kernel }}处理器架构: {{ ansible_architecture }}
网络配置
- name: 显示所有IP地址debug:var: ansible_all_ipv4_addresses- name: 主网络接口debug:msg: "主接口: {{ ansible_default_ipv4.interface }}"
存储信息
- name: 显示磁盘空间debug:msg: "根分区可用空间: {{ ansible_mounts | json_query('[?mount==`/`].size_available') }} bytes"- name: 列出所有块设备debug:var: ansible_devices
3 高级 Facts 技术
条件收集
- hosts: webserversgather_facts: true # 默认开启tasks:- name: 仅收集网络factssetup:gather_subset:- network- !hardware # 排除硬件信息
自定义 Facts
在目标主机创建:
# /etc/ansible/facts.d/appinfo.fact
[deployment]
version=2.3.1
environment=production
在Playbook中使用:
- debug:var: ansible_local.appinfo.deployment
Facts 缓存配置
# ansible.cfg
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 86400 # 24小时
4 Facts 性能优化
增量收集:
- setup:filter: "ansible_distribution*"
并行收集:
ansible-playbook -f 10 site.yml # 10个并行进程
缓存策略:
# ansible.cfg [defaults] fact_caching = redis fact_caching_timeout = 3600