文章目录
- Ansible
-
- [第一章:Ansible 基本概念简介](#第一章:Ansible 基本概念简介)
-
- [1.1 什么是 Ansible?](#1.1 什么是 Ansible?)
- [1.2 Ansible 的主要用途](#1.2 Ansible 的主要用途)
- [1.3 Ansible 的核心概念](#1.3 Ansible 的核心概念)
-
- [1.3.1 主机清单(Inventory)](#1.3.1 主机清单(Inventory))
- [示例:INI 格式的主机清单](#示例:INI 格式的主机清单)
- [示例:YAML 格式的主机清单](#示例:YAML 格式的主机清单)
- [1.3.2 剧本(Playbook)](#1.3.2 剧本(Playbook))
- [示例:一个简单的 Playbook](#示例:一个简单的 Playbook)
- [1.3.3 模块(Module)](#1.3.3 模块(Module))
- 常见模块示例:
- [1.3.4 任务(Task)](#1.3.4 任务(Task))
- 示例任务结构:
- [1.3.5 Play](#1.3.5 Play)
- [示例 Play 结构:](#示例 Play 结构:)
- [1.3.6 其他关键概念](#1.3.6 其他关键概念)
- [第二章:Ansible Playbook 的编写和运行](#第二章:Ansible Playbook 的编写和运行)
-
- [2.1 Playbook 概述](#2.1 Playbook 概述)
- [2.2 Playbook 的基本结构](#2.2 Playbook 的基本结构)
-
- [2.2.1 剧本的开头标记](#2.2.1 剧本的开头标记)
- [2.2.2 Play 的定义](#2.2.2 Play 的定义)
- [2.2.3 任务(Task)与模块(Module)](#2.2.3 任务(Task)与模块(Module))
- [2.2.4 示例:创建用户 Playbook](#2.2.4 示例:创建用户 Playbook)
- [2.3 Playbook 的编写规范与格式](#2.3 Playbook 的编写规范与格式)
-
- [2.3.1 编写规则](#2.3.1 编写规则)
- [2.3.2 YAML 注释](#2.3.2 YAML 注释)
- [2.3.3 YAML 字符串](#2.3.3 YAML 字符串)
- [2.3.4 YAML 多行字符串](#2.3.4 YAML 多行字符串)
- [2.3.5 YAML 字典](#2.3.5 YAML 字典)
- [2.3.6 YAML 列表](#2.3.6 YAML 列表)
- [2.4 Playbook 编写格式示例](#2.4 Playbook 编写格式示例)
- [2.5 Playbook 运行方式](#2.5 Playbook 运行方式)
-
- [2.5.1 运行 Playbook](#2.5.1 运行 Playbook)
- [2.5.2 语法检查](#2.5.2 语法检查)
- [2.5.3 模拟运行(空运行)](#2.5.3 模拟运行(空运行))
- [2.5.4 提高输出详细程度](#2.5.4 提高输出详细程度)
- [2.6 Playbook 的提权控制](#2.6 Playbook 的提权控制)
- [2.7 Playbook 编辑器优化设置(Vim)](#2.7 Playbook 编辑器优化设置(Vim))
- [2.8 Playbook 文件结构总结](#2.8 Playbook 文件结构总结)
- [第三章:Ansible 变量与 Facts 管理](#第三章:Ansible 变量与 Facts 管理)
-
- [3.1 变量(Variables)简介](#3.1 变量(Variables)简介)
- [3.2 变量命名规则](#3.2 变量命名规则)
- [3.3 变量的作用域和优先级](#3.3 变量的作用域和优先级)
- [3.4 变量的引用方式](#3.4 变量的引用方式)
- [3.5 变量文件的使用(`vars_files`)](#3.5 变量文件的使用(
vars_files)) - [3.6 Ansible Vault 管理敏感变量](#3.6 Ansible Vault 管理敏感变量)
- [3.7 命令行与 Playbook 的变量传递(`-e` 命令)](#3.7 命令行与 Playbook 的变量传递(
-e命令)) - [3.8 与 Ansible Vault 搭配使用的配置建议](#3.8 与 Ansible Vault 搭配使用的配置建议)
- [3.9 Ansible Facts(主机信息变量)](#3.9 Ansible Facts(主机信息变量))
- [3.10 事实变量的使用方式](#3.10 事实变量的使用方式)
- [3.11 `setup` 模块和 `gather_facts` 的使用](#3.11
setup模块和gather_facts的使用) - [3.12 关闭 Facts 收集](#3.12 关闭 Facts 收集)
- [3.13 变量优先级验证示例](#3.13 变量优先级验证示例)
- [3.14 常见变量和 Facts 的对照关系](#3.14 常见变量和 Facts 的对照关系)
Ansible
第一章:Ansible 基本概念简介
1.1 什么是 Ansible?
Ansible 是一款开源自动化运维工具 ,用于配置管理、应用部署、任务自动化等。它以简单、可读性高和无需代理的方式实现跨平台的自动化操作,支持 Linux、Windows、macOS 等多种操作系统,并且广泛应用于 DevOps 流程中。
Ansible 的核心是通过YAML 格式的剧本(Playbook)来描述任务,利用SSH 协议 与被管理的节点(Managed Nodes)进行通信,并通过模块化的方式执行各种操作。
1.2 Ansible 的主要用途
- 配置管理:通过模块化任务,将服务器配置标准化,确保所有节点保持一致的状态。
- 应用部署:自动化应用程序的安装、配置和部署流程。
- 任务自动化:实现日常运维任务(如日志轮转、服务重启、备份等)的自动化。
- 多云与混合云管理:统一管理本地数据中心和多个云平台(如 AWS、Azure、Google Cloud 等)的服务器。
- 批量操作:一次任务可以同时操作多个节点,提高运维效率。
1.3 Ansible 的核心概念
1.3.1 主机清单(Inventory)
主机清单 是 Ansible 中用来声明哪些主机可以被管理 以及如何分组的文件。它可以是静态的(inventory.ini),也可以通过动态脚本生成。
-
作用:
- 定义被管理的节点(主机)。
- 设置节点的分组,便于批量操作。
- 指定节点的连接信息(如 IP 地址、端口、用户名、密码或密钥)。
-
常见格式:
- INI 格式(推荐用于简单场景)
- YAML 格式(结构更清晰,适合复杂分组)
- 也可以通过程序或 API 动态生成。
示例:INI 格式的主机清单
ini
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com
db2.example.com
示例:YAML 格式的主机清单
yaml
all:
hosts:
web1.example.com:
web2.example.com:
children:
webservers:
hosts:
web1.example.com:
web2.example.com:
dbservers:
hosts:
db1.example.com:
db2.example.com:
1.3.2 剧本(Playbook)
剧本是 Ansible 中最核心的文件,它由一个或多个"剧(Play)"组成,用于描述自动化任务的执行流程。
-
作用:
- 定义任务的执行目标(即哪些主机)。
- 定义执行的具体步骤(任务列表)。
- 可以包含角色(Roles)和变量,实现更灵活的任务管理。
-
语法结构:
- 使用 YAML 语法编写。
- 每个 Play 包含
name(任务名称)、hosts(目标主机)、tasks(执行的操作)等字段。
示例:一个简单的 Playbook
yaml
---
- name: 配置 Web 服务器
hosts: webservers
become: yes
tasks:
- name: 安装 Nginx
apt:
name: nginx
state: present
tags: web
- name: 启动 Nginx 服务
service:
name: nginx
state: started
enabled: yes
tags: web
1.3.3 模块(Module)
Ansible 的任务通常由模块驱动,每个模块代表一项操作。模块是 Ansible 的"原子操作",执行特定功能,例如安装软件、管理服务、复制文件等。
常见模块示例:
yum: 管理基于 Red Hat 的系统软件包。apt: 管理基于 Debian 的系统软件包。copy: 复制文件到目标主机。service: 管理服务(启动、停止、重启等)。template: 使用模板文件生成配置文件。shell: 执行任意 Shell 命令。
1.3.4 任务(Task)
任务是 Playbook 中的基本执行单元,每一个任务调用一个模块并传递参数。任务通过 tasks 列表组织,在 Playbook 中按顺序执行。
示例任务结构:
yaml
- name: 安装 Apache 服务
yum:
name: httpd
state: present
1.3.5 Play
一个 Play 是一组相关 Task 的集合,它描述了如何对一组主机进行操作。Play 中可以指定:
hosts:要适用于哪些主机。become: 是否以特权用户身份(如 root)执行任务。vars: 全局变量。handlers: 仅在特定任务完成后触发(如重启服务)。tags: 用于选择性执行任务。
示例 Play 结构:
yaml
- name: 配置防火墙规则
hosts: dbservers
become: yes
tasks:
- name: 开放 3306 端口
ufw:
rule: allow
port: 3306
proto: tcp
1.3.6 其他关键概念
- Inventory:被管理主机列表,可读可编程。
- Connection:Ansible 通过 SSH 连接到目标节点,支持密码、密钥认证。
- Tower / AWX:企业级 Ansible Web 管理界面,支持任务调度和监控。
- Roles :用于组织 Playbook,将任务分成逻辑单元(如
web,database,network等)。 - Facts:Ansible 自动收集的主机信息,如系统版本、IP 地址等。
- Inventory Plugins:用于动态获取主机信息的插件,如通过云平台 API 获取云主机列表。
第二章:Ansible Playbook 的编写和运行
2.1 Playbook 概述
Ansible Playbook 是 Ansible 实现自动化任务部署与配置管理 的核心工具。它是一组由多个 Play 组成的YAML 格式文件 ,每个 Play 指定了在哪些主机 上运行,以及执行哪些任务。
Playbook 使得复杂的运维操作变得可读、可重复、可维护,是 Ansible 中最强大的自动化方式。它适用于:
- 批量配置管理
- 应用部署
- IT 运维流程的自动化
- 基础设施即代码(IaC)的实现
Playbook 的优点包括:
- 使用 YAML 编写,结构清晰且可读性强
- 任务可复用性高
- 利于团队协作
- 支持条件判断、变量、循环等高级特性
2.2 Playbook 的基本结构
一个简单但完整的 Playbook 通常包括以下几个部分:
2.2.1 剧本的开头标记
每个 Playbook 应以 --- 开始,表示 YAML 文档的开始。
yaml
---
2.2.2 Play 的定义
Playbook 中的 Play 是任务执行的单元。每个 Play 包含以下关键字段:
name: 任务的名称,用于描述该 Play 的作用hosts: 指定该 Play 应在哪些主机上执行tasks: 一个任务列表,包含具体执行的各个操作模块become: 是否以特权用户(如 root)执行任务remote_user: 连接目标主机使用的用户become_method: 提权方式,如sudo、su等
2.2.3 任务(Task)与模块(Module)
每个任务调用一个 Ansible 模块,模块封装了具体的运维操作(如安装软件、配置服务、复制文件等)。
2.2.4 示例:创建用户 Playbook
下面是一个创建用户 newbie 并设置 UID 为 4000 的 Playbook 示例:
yaml
---
- name: Create user 'newbie' with UID 4000
hosts: node1
become: yes
tasks:
- name: Ensure user exists
user:
name: newbie
uid: 4000
state: present
这个 Playbook 定义了一个 Play,目标主机是 node1,任务是使用 user 模块来创建用户。
2.3 Playbook 的编写规范与格式
2.3.1 编写规则
| 项目 | 说明 |
|---|---|
| 缩进 | 使用空格缩进,同一个层级使用相同的缩进,子层级使用更多空格 |
| 空格数量 | 虽然不限制空格数量,但通常使用 2 个空格作为一级缩进,4 或 8 个空格适合嵌套 |
| 注释 | 以 # 开始,适用于解释任务或配置信息 |
| 结束标记 | 每个 Playbook 应以 ... 结束,但也可省略(推荐使用 --- 开头) |
2.3.2 YAML 注释
YAML 中注释使用 #,设置在行首或行尾都可以。
yaml
# 这是一个注释
- name: Create user
user:
name: laogao
# 配置其他属性
2.3.3 YAML 字符串
YAML 的字符串通常不需要引号,即使是带有空格的情况:
yaml
msg: "Welcome to example.com"
也可以使用双引号或单引号包裹,但需注意:
- 双引号:会保留字符串中的空格(除非是特殊字符)
- 单引号:会删除字符串中的空格(适用于需要折叠文本的情况)
yaml
msg: "This is a string"
msg: 'This is another string'
2.3.4 YAML 多行字符串
使用 | 还是 > 来处理多行字符串:
|保留换行,适合需要保留原有格式的内容>替换换行符为空格,适合需要直观展示的文本
yaml
msg: |
Example Company
123 Main Street
Atlanta, GA 30303
msg: >
This is an example
of a long string,
that will become
a single sentence once folded.
通常用于生成配置文件、脚本内容等的场景中,可提高 Playbook 的可读性。
2.3.5 YAML 字典
YAML 支持使用键-值对表示配置信息,键是模块的参数,值是参数的具体内容。
yaml
user:
name: laogao
uid: 1088
state: absent
适用于更复杂的配置,支持结构化数据。
2.3.6 YAML 列表
YAML 列表用于让任务操作多个对象或执行多个指令,通常用 - 表示列表项。
yaml
- name: Install packages
yum:
name:
- httpd
- firewalld
state: latest
在 Playbook 中,经常用于处理多个软件包、多个主机等。
2.4 Playbook 编写格式示例
以下是一个更完整的 Playbook 示例,包含注释、多行字符串、字典以及多个任务:
yaml
---
# Playbook: Enable intranet services on node1
- name: Enable intranet services
hosts: node1
become: yes
become_method: sudo
become_user: root
remote_user: laogao
tasks:
- name: Ensure httpd and firewalld are installed
yum:
name:
- httpd
- firewalld
state: latest
- name: Create the index.html file with a welcome message
copy:
content: "Welcome to example.com\n"
dest: /var/www/html/index.html
- name: Ensure firewalld is enabled and running
service:
name: firewalld
enabled: true
state: started
- name: Allow http service through firewalld
firewalld:
service: http
permanent: true
state: enabled
immediate: yes
- name: Ensure httpd is enabled and running
service:
name: httpd
enabled: true
state: started
2.5 Playbook 运行方式
2.5.1 运行 Playbook
使用 ansible-playbook 命令来执行 Playbook:
bash
ansible-playbook playbook.yaml
注意:运行前确保
playbook.yaml文件路径正确。
2.5.2 语法检查
使用 --syntax-check 选项来检查 Playbook 是否语法正确:
bash
ansible-playbook playbook.yaml --syntax-check
此命令不会执行任何任务,只检查格式是否正确。
2.5.3 模拟运行(空运行)
使用 -C(或 --check)选项来模拟执行任务,不实际修改任何内容。
bash
ansible-playbook playbook.yaml -C
适用于测试和确认任务执行逻辑,避免误操作。
2.5.4 提高输出详细程度
你可以通过设置 -v、-vv、-vvv 等选项来增强 Playbook 执行时的信息输出:
bash
ansible-playbook playbook.yaml -v
ansible-playbook playbook.yaml -vv
ansible-playbook playbook.yaml -vvv
-vvv会显示连接、模块调用等详细信息。
2.6 Playbook 的提权控制
You can specify privilege escalation (如 sudo 提权) using become 、become_method 、become_user 等参数。
例如:
yaml
---
- name: Enable intranet services
hosts: node1
become: yes
become_method: sudo
become_user: root
tasks:
- name: Install httpd
yum:
name: httpd
state: latest
become: yes表示任务需要用提权执行become_method: sudo表示使用sudo方式提权become_user: root表示任务将以root身份运行
你在
ansible.cfg中也可以配置这些参数,如果 Playbook 中未指定,则使用全局配置。
2.7 Playbook 编辑器优化设置(Vim)
如果你使用 Vim 编辑 Playbook,可以通过以下设置提升可读性:
在 ~/.vimrc 文件中添加如下内容:
vim
set ai
set ts=2
autocmd FileType yaml set ai ts=2
ai:即autoindex,自动缩进ts=2:tabstop设置为 2,表示 Tab 键=2 个空格autocmd FileType yaml set ai ts=2:当文件类型为yaml时应用这些设置
这些配置会让 YAML 文件在 Vim 中更易读、更易编写。
2.8 Playbook 文件结构总结
| 模块 | 说明 |
|---|---|
name |
描述该 Play 或 Task 的作用 |
hosts |
指定执行目标主机 |
tasks |
定义任务列表,每个任务调用模块 |
become |
是否启用提权(True/False) |
become_method |
提权方式(sudo、su 等) |
become_user |
用哪一个用户完成提权 |
第三章:Ansible 变量与 Facts 管理
3.1 变量(Variables)简介
在 Ansible 中,变量 用于存储和引用重复使用的数据,极大地提高 Ansible 项目的可读性、可维护性和重用性。Ansible 支持多种方式定义和使用变量,包括:
- 全局变量(通过 Ansible 配置或命令行)
- Play 级变量(在 Playbook 级别定义)
- Host 级变量 (在清单文件或
group_vars、host_vars目录中定义)
这些变量可以在 Playbook 中任意位置被引用,用于控制任务行为、决定配置逻辑、增加灵活性等。
3.2 变量命名规则
- 变量名只能包含字母、数字和下划线 (
_)。 - 变量名不能以数字开头。
- 变量名不可以包含空格、点、符号(如
$等),否则将被视为非法变量名。 - 例如:
user1是合法变量,而user name、user.name、user$1都是非法变量名。
3.3 变量的作用域和优先级
Ansible 的变量分为三个作用域层级,优先级从高到低如下:
| 作用域 | 描述 |
|---|---|
Global |
由 ansible.cfg、ansible-playbook 命令或 Ansible Playbook 开始时定义 |
Play |
在 Play 级别通过 vars 或 vars_files 定义 |
Host |
在 host_vars、group_vars 或清单文件中定义 |
示例说明
yaml
# 全局变量定义(通过 ansible.cfg 或命令行)
---
- name: test vars statement in play
hosts: node1
vars:
user: user3
tasks:
- name: debug output
debug:
msg: hello {{ user }}
同时,在 Play 中有 vars、vars_files、include_vars 等多种方式引入变量。
3.4 变量的引用方式
在 Ansible 中,变量通过 {``{ variable_name }} 进行引用,但 在值的开头时必须使用引号包裹:
✅ 正确引用格式
yaml
- name: add user
user:
name: "{{ user }}"
❌ 错误引用格式
yaml
- name: add user
user:
name: { user }
注:如果变量值从任务结果中获取,有时需要使用
{``{ }}来进行引用。
3.5 变量文件的使用(vars_files)
作用:
- 若变量很多,维护起来比较麻烦,可以将不同组或角色的变量单独放在变量文件中。
- 变量文件可以包含 YAML、YAML 带密码保护(使用 Ansible Vault)。
示例结构
project_dir/
├── ansible.cfg
├── inventory
├── group_vars
│ ├── all.yaml
│ └── servers.yaml
├── host_vars
│ ├── node1.yaml
│ └── node2.yaml
└── playbook.yaml
示例:使用 vars_files 引入变量
yaml
---
- name: Create user job
hosts: node1
vars_files:
- vault/mysql.yml
tasks:
- name: install packages
yum:
name:
- mariadb-server
- python2-PyMySQL
state: present
- name: enable and start mariadb
service:
name: mariadb
enabled: yes
state: started
3.6 Ansible Vault 管理敏感变量
Ansible Vault 用于加密敏感数据如密码、密钥等,防止流量中泄露或被轻易访问。
用法简介
-
创建加密文件:
bashansible-vault create vault/mysql.yml -
查看加密文件:
bashansible-vault view vault/mysql.yml -
编辑加密文件(会打开默认编辑器):
bashansible-vault edit vault/mysql.yml -
解密一个文件:
bashansible-vault decrypt vault/mysql.yml -
修改加密文件的密码:
bashansible-vault rekey vault/mysql.yml
3.7 命令行与 Playbook 的变量传递(-e 命令)
示例命令行使用变量
bash
ansible-playbook playbook.yaml -e "user=admin"
它将
user: admin传递给 Playbook,适用于临时调试和测试。
示例 Playbook 中使用 -e 传参
yaml
---
- name: test command line variables
hosts: node1
tasks:
- name: debug user
debug:
msg: "Welcome, {{ user }}"
3.8 与 Ansible Vault 搭配使用的配置建议
可将敏感信息(如密码、密钥)放在 vault/ 目录下的加密文件中,并在 Playbook 中通过 vars_files 加载。
示例:vault/mysql.yml 内容如下(加密后)
yaml
password: "{{ password }}"
user: "{{ user }}"
host: "{{ host }}"
priv: "{{ priv }}"
注意:变量本身也需要在 Vault 文件中使用
{``{ }}进行引用。
总结推荐做法:
- 敏感变量使用 Ansible Vault 加密(如密码、密钥等)
host_vars和group_vars用于管理可信变量- 若变量报错,优先检查缩进、命名、是否被正确使用
3.9 Ansible Facts(主机信息变量)
Ansible 的 Facts 是在连接受管主机后自动收集的主机状态信息。这些信息可用于动态配置或条件判断,比如:
yaml
- name: check if HTTPD is installed
hosts: node1
tasks:
- name: Install HTTPD if not present
shell: "rpm -q httpd"
register: installed_result
- name: Debug if installed
debug:
msg: "HTTPD is already installed: {{ installed_result.stdout }}"
3.10 事实变量的使用方式
Facts 的作用域是当前受管节点,和 Play 中的变量一样,可以被直接使用:
yaml
- name: show stored facts
hosts: node1
tasks:
- debug:
msg: "Facts of current host: {{ ansible_facts }}"
常用 Facts 变量
- 主机名 :
ansible_facts['hostname']或ansible_hostname - 系统信息 :如
ansible_distribution、ansible_distribution_version - 网络信息 :如
ansible_default_ipv4.address、ansible_networking.interfaces - 硬件信息 :
ansible_devices['vda']['partitions']['vda1']['size']
3.11 setup 模块和 gather_facts 的使用
使用 setup 收集 Facts
yaml
- name: Collect facts
hosts: node1
tasks:
- name: print facts
setup:
控制 Facts 收集的范围
可以通过 filter 和 gather_subset 来限制收集的内容:
filter:只收集指定的事实名称gather_subset:控制收集哪些事实(例如all、network、hardware等)
使用示例:
bash
ansible node1 -m setup -a "filter=ansible_default_ipv4"
3.12 关闭 Facts 收集
在某些场景下,可以直接关闭 Facts 收集:
在 Ansible 配置文件中关闭 Facts:
ini
[defaults]
gathering = explicit
设置为
explicit表示只在需要时主动运行setup模块收集 Facts。
在 Play 中关闭 Facts:
yaml
---
- name: test playbook with no facts
hosts: node1
gather_facts: no
tasks:
- name: debug output
debug:
msg: "Node info not available {{ ansible_facts }}"
保留
setup模块进行事实收集,可以通过执行setup模块实现。
3.13 变量优先级验证示例
以下是不同位置变量的定义优先级顺序(从高到低):
| 变量定义位置 | 变量值 |
|---|---|
命令行 -e "user=user1" |
user1 |
include_vars |
user2 |
vars 在 Play 中定义 |
user3 |
vars_files 引入的变量 |
user4 |
group_vars 中定义的变量 |
user8 |
host_vars 中定义的变量 |
user6 |
inventory 中定义的变量 |
user7 |
3.14 常见变量和 Facts 的对照关系
| 旧命名格式 | 新命名格式 |
|---|---|
ansible_distribution |
ansible_facts['distribution'] |
ansible_distribution_version |
ansible_facts['distribution_version'] |
ansible_default_ipv4 |
ansible_facts['default_ipv4'] |
ansible_kernel |
ansible_facts['kernel'] |