文前说明
作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。
本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。
1. 概述
- Ansible 是一个部署一群远程主机的工具。
- 远程主机( Remote Host )是指任何可以通过 SSH 登录的主机,所以它既可以是远程虚拟机或物理机,也可以是本地主机。
- 通过 SSH 协议 实现管理节点与远程节点之间的通信。
- 解决了如何大批量、自动化地实现系统配置、应用部署、命令和服务操作的问题。
- 可以同时管理 Red Hat 系的 Linux、 Debian 系的 Linux 以及 Windows 主机。
1.1 安装
- Redhat/CentOS Linux 上,直接通过 yum 安装。
[root@localhost ~]# sudo yum install ansible -y
[root@localhost ~]# ansible --version
ansible 2.7.5
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, May 3 2017, 07:55:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-14)]
- 配置 Ansible 管理节点和主机的连接,其实也就是配置从管理节点到远程主机之间基于密钥(无密码的方式)的 SSH 连接。
[root@localhost ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:eksWOOjo38EfPHIOvinM2D5hNKql1XT3WTnoGrwkz+o root@localhost.localdomain
The key's randomart image is:
+---[RSA 2048]----+
| |
| |
| . . |
| +.... . + |
| =.oooSo o . |
| +o+..++.+ |
| =.*..*=O+ |
|o.. *o %=+ |
| .oo+Eo+ |
+----[SHA256]-----+
[root@localhost ~]# ssh-copy-id root@192.168.xxx.xxx
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.xxx.xxx (192.168.xxx.xxx)' can't be established.
ECDSA key fingerprint is SHA256:rjsAhpndANGanOU7KBry0ZNHizyv7Nh9/z1FcPoeKKw.
ECDSA key fingerprint is MD5:57:ec:0b:95:a8:ee:24:75:4a:31:a6:c3:d4:86:b8:85.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.xxx.xxx's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.xxx.xxx'"
and check to make sure that only the key(s) you wanted were added.
- 验证 SSH 配置可以在管理节点执行下面的 SSH 命令,既不需要输入密码,也不会提醒存储密钥为成功。
[root@localhost ~]# ssh 192.168.xxx.xxx
Last login: Mon Apr 1 17:20:32 2019 from manager.example.com
node status: OK
See `nodectl check` for more information
Admin Console: https://192.168.xxx.xxx:9090/
2. 配置
- 通过 /etc/ansible/ansible.cfg 文件的内容和注释可以了解到所有可以配置的选项,也可以 在线查看 ansible.cfg 文件。
[defaults]
# some basic default values...
#inventory = /etc/ansible/hosts
#library = /usr/share/my_modules/
#module_utils = /usr/share/my_module_utils/
#remote_tmp = ~/.ansible/tmp
#local_tmp = ~/.ansible/tmp
......
常用配置选项 | 说明 |
---|---|
inventory | 主机清单文件。 |
library | extra 模块放置路径。 |
remote_temp | 远程主机的临时文件位置。 |
local_temp | 管理节点上临时文件的位置。 |
accelerate_port | 连接端口。 |
accelerate_timeout | 连接时间。 |
forks | 默认情况下 ansible 最多能有多少个进程同时工作,默认设置最多 5 个进程并行处理。 |
sudo_user | 设置默认执行命令的用户,也可以在 Playbook 中重新设置这个参数。 |
remote_port | 指定连接被管节点的管理端口,默认是 22。 |
host_key_checking | 设置是否检查 SSH 主机的密钥。 |
timeout | 设置 SSH 连接的超时间隔,单位是秒。 |
log_path | 默认不记录日志。执行 ansible 的用户需要有写入日志的权限,模块将会调用被管节点的 syslog 来记录,口令是不会出现的日志中。 |
private_key_file | SSH 公钥私钥登录系统时候,使用的密钥路径。 |
- 更详细的配置选项解释可以 查看官方。
配置文件优先级
- Ansible 会按照以下的顺序查找配置文件,并使用第一个发现的配置文件。
- ANSIBLE_CONFIG (环境变量设置)
- ansible.cfg (当前目录中)
- ~/.ansible.cfg (主目录中)
- /etc/ansible/ansible.cfg(默认配置文件)
3. 主机清单(Inventory 配置文件)
- 设置 Ansible 需要管理的主机范围,以及这些主机的分类和分组信息的文件。
- 在实际使用中,可根据远程主机所在的地域、功能分类。
- 默认文件为 /etc/ansible/hosts。
- 可在 ansible.cfg 文件中通过 inventory 配置选项设置,也可以在 ansible-playbook 命令中通过参数 -i 或 --inventory-file 设置。
3.1 分组
- 使用 [ ] 进行简单的分组。
[dbservers]
one.example.com
two.example.com
three . example. com
[webservers]
www[01:50] .example.com
[databases]
db-[a:f] .example.com
- 分组可以嵌套,如下 b 组包含 a 组。
[a]
one.example.com
two.example.com
three . example. com
[b:a]
www[01:50] .example.com
[c]
db-[a:f] .example.com
3.2 设置连接参数
- 可以在 inventory 文件中指定主机的连接参数, 包括连接方法、用户等,用空格分隔多个参数。
[targets]
localhost ansible_connection=local ansible_user=root
otherl.example.com ansible_connection=ssh ansible_user=test
other2.example.com ansible_connection=ssh ansible_user=test
参数 | 说明 |
---|---|
ansible_connection | SSH 的连接方式。可指定为 smart、ssh、local 或者 paramiko 等。 |
ansible_user | SSH 的连接用户。 |
ansible_host | 连接主机地址,如果 Ansible 中给主机起了别名,需要用到。 |
ansible_port | SSH 端口号,默认 22。 |
ansible_ssh_pass | SSH 连接使用密码。尽量使用 values 对密码进行加密存储。 |
ansible_ssh_private_key_file | 基于 key 的 SSH 连接,使用 private_key 文件。 |
ansible_ssh_common_args | 通过本参数指定 SFTP、SCP 和 SSH 默认的额外参数。 |
3.3 定义变量
3.3.1 在文件中定义变量
- 为单个远程主机指定参数。
[a]
hostl http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909
- 为一个组指定变量。
[a]
host1
host2
[a.vars]
http_port=80
maxRequestsPerChild=808
3.3.2 按目录结构存储变量
- 假设主机清单文件为 /etc/ansible/hosts ,那么相关的主机和组变量可以分别放在 /etc/ansible/host_ vars/ 和 /etc/ansible/group_vars/ 下的主机或组同名的文件。
- 文件也支持 " .yml "," .yaml " 和 " .json " 为后缀的 YMAL 和 JSON 文件。
[root@localhost group_vars]# pwd
/etc/ansible/group_vars
[root@localhost group_vars]# ll
total 4
-rw-r--r--. 1 root root 41 Jan 10 16:52 a
[root@localhost group_vars]# cat a
---
http_port=80
maxRequestsPerChild=808
- 如果对应的名字为目录名,则 Ansible 会读取这个目录下面所有文件的内容。
[root@localhost a]# pwd
/etc/ansible/group_vars/a
[root@localhost a]# ll
total 4
-rw-r--r--. 1 root root 41 Jan 10 16:52 http_port
- /group_ vars 和 /host_vars 目录可放在 inventory 文件同级目录下,或是 Playbook 文件同级目录下。 如果两个目录下都存在变量文件,那么 Playbook 目录下的值会覆盖 inventory 目录下变量的值。
4. Ansible 的命令
- 针对一组主机定义并运行单个任务。
命令格式
- ansible <host-pattern> [options]。
操作选项 | 说明 |
---|---|
--become-method 'BECOME_METHOD' | 使用权限提升方法(BECOME_METHOD 默认是 sudo),有效值有 sudo、su、pbrun、pfexec、doas、dzdo、ksu、runas、pmrun、enable、machinectl。 |
--become-user 'BECOME_USER' | 用此用户身份操作,默认 root。 |
--list-hosts | 输出匹配主机的列表,不执行任何其他操作。 |
--private-key,--key-file | 使用此文件对连接进行身份验证。 |
--scp-extra-args 'SCP_EXTRA_ARGS' | 指定只传递给 SCP 的额外参数。例如 -l |
--sftp-extra-args 'SFTP_EXTRA_ARGS' | 指定只传递给 SFTP 的额外参数。例如 -f,-l。 |
--ssh-common-args 'SSH_COMMON_ARGS' | 指定只传递给 SCP/SFTP/SSH 的公共参数。例如 ProxyCommand。 |
--ssh-extra-args 'SSH_EXTRA_ARGS' | 指定只传递给 SSH 的额外参数。例如 -R。 |
--syntax-check | 对剧本(Playbook)进行语法检查,但不执行它。 |
--vault-id | 使用的保管库标识。 |
--vault-password-file | 指定保管库密码文件。 |
--version | 显示版本信息。 |
-B 'SECONDS',--background 'SECONDS' | 异步运行,X 秒后失败。(默认 N/A 不限制) |
-C,--check | 尝试预测一些可能发生的变化,但不做任何改变。 |
-D,--diff | 更改(小)文件和模板时,显示这些文件中的差异,适用于 --check。 |
-K,--ask-become-pass | 请求权限提升的密码。 |
-M,--module-path | 为模块库准备冒号分隔的路径。(默认为 [u'/home/jenkins/.ansible/plugins/modules',u'/usr/share/ansible/plugins/modules') |
-P 'POLL_INTERVAL',--poll 'POLL_INTERVAL' | 如果使用 -B,则设置轮询间隔。 |
-T 'TIMEOUT',--timeout 'TIMEOUT' | 以秒为单位覆盖连接超时。(默认值为 10) |
-a 'MODULE_ARGS',--args 'MODULE_ARGS' | 模块参数。 |
-b,--become | 运行操作。 |
-c 'CONNECTION',--connection 'CONNECTION' | 要使用的连接类型。(默认值 smart) |
-e,--extra-vars | 如果文件名以 @ 开头,将附加变量设置为 key = value 或 yaml/json。 |
-f 'FORKS',--forks 'FORKS' | 指定要使用的并行进程数。(默认值为 5) |
-h,--help | 显示帮助信息。 |
-i,--inventory,--inventory-file | 设置主机清单。 |
-k,--ask-pass | 请求连接的密码。 |
-l 'SUBSET',--limit 'SUBSET' | 将所选主机进一步限制为其他模式。 |
-m 'MODULE_NAME',--module-name 'MODULE_NAME' | 要执行的模块名称(默认值为 command)。 |
-o,--one-line | 简要输出。 |
-t 'TREE',--tree 'TREE' | 日志输出到此目录。 |
-u 'REMOTE_USER',--user 'REMOTE_USER' | 使用此用户连接。(默认无) |
-v,--verbose | 使用显示模式。(-vvv 表示更多,-vvvv 表示启用连接调试) |
- 其他命令
- ansible-config 配置命令行类。
- ansible-console 一个 REPL,允许针对选定的清单运行特殊任务。(基于 dominis 的 ansible shell)
- ansible-doc 显示有关安装在可转换库中的模块的信息。它显示插件及其简短描述的简要列表,提供文档字符串的打印输出,并且可以创建一个可以粘贴到剧本中的简短 " 片段 "。
- ansible-galaxy 用于管理共享存储库中可应答角色的命令,默认值为 Ansible Galaxy
- ansible-inventory 用于显示或转储已配置的清单。
- ansible-playbook 运行 Ansible Playbook 的工具,这是一个配置和多节点部署系统。可看 项目主页。
-
ansible-pull 用于在每个受管节点上建立 Ansible 的远程副本,每个集通过 cron 运行,并通过源存储库更新 Playbook 源。这将反转 Ansible 的默认 push 架构,成为一个拉式架构。
- 可以调整设置剧本(Playbook),将 cron 频率、日志记录位置和参数更改为 Ansible Pull。这对于极端的扩展和定期的修复都很有用。
- 使用 " fetch " 模块从 Ansible Pull 运行中检索日志,将是从 Ansible Pull 收集和分析远程日志的一种很好的方法。
-
ansible-vault 可以加密 Ansible 使用的任何结构化数据文件。
- 这可以包括组变量/或主机变量/库存变量、由包含变量或变量文件加载的变量或传递的变量文件。
- 带 -e @file.yml 或 -e @file.json 的 ansible-playbook 命令行。
- 还包括角色变量和默认值。
- 因为可应答的任务、处理程序和其他对象都是数据,所以也可以使用保管库对它们进行加密。
- 如果不想公开正在使用的变量,可以保留单个任务文件完全加密。
- 对于要同时使用的所有文件,当前与保管库一起使用的密码必须相同。
4.1 模块
- bash 无论是在命令行上执行,还是在 bash 脚本中,都需要调用 cd、 ls、 copy、 yum 等命令。 模块就是 Ansible 的 " 命令 "。
- 模块是 Ansible 命令行和脚本中都需要调用的。
- Ansible 默认提供了很多模块可供使用。
- 通过 ansible-doc -l 命令查看到当前 Ansible 支持的模块列表。
- 通过 ansible-doc -s [模块名] 可以查看该模块有哪些参数可以使用。
- 官网上可以 查看模块用法
- Ansible 命令行中。
- -m 后面接调用模块的名字。
- -a 后面接调用模块的参数。
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"
ansible a_group -m yum -a "narne=httpd state=present"
- 像 Linux 中的命令一样, Ansible 的模块既可以在命令行中调用,也可以在 Ansible 的脚本 Playbook 中调用。
- 每个模块的参数和状态的判断,都取决于该模块的具体实现,所以在使用它们之前需要查阅该模块对应的文挡。
- 通过命令 ansible-doc 也可以查看模块的用法。
- Ansible 提供一些常用功能的模块,同时 Ansible 也提供 API, 让用户可以自定义模块,使用的编程语言是 Python。
常用模块 | 说明 |
---|---|
ping | ping 一下远程主机, 如果可以通过 Ansible 连接成功,那么返回 pong。 |
debug | 用于调试的模块,只是简单打印一些消息, 有点像 Linux 的 echo 命令。 |
copy | 从本地复制文件到远程节点。 |
template | 从本地复制文件到远程节点,并进行变量的替换。 |
file | 设置文件属性。 |
user | 管理用户账户。 |
yum | RedHat 系 Linux 上的包管理。 |
service | 管理服务。 |
firewalld | 管理防火墙中的服务和端口。 |
shell | 在节点上执行 shell 命令,支持 $HOME、" < "、" > "、" | "、" ; "、" & "。 |
command | 在远程节点上面执行命令,不支持 $HOME、" < "、" > "、" | "、" ; "、" & "。 |
cron | 计划任务管理。 |
synchronize | 使用 rsync 同步文件。 |
group | 系统用户组管理。 |
setup
- 用来查看远程主机的一些基本信息。
ansible node -m setup
ping
- 用来测试远程主机的运行状态
ansible node -m ping
- 使用样例。
[root@localhost ~]# ansible node -m ping
192.168.xxx.xxx | SUCCESS => {
"changed": false,
"ping": "pong"
}
file
- 设置文件的属性。
ansible node -m file -a "src=/etc/resolv.conf dest=/tmp/resolv.conf state=link"
- 使用样例。
[root@localhost ~]# ansible node -m file -a "src=/etc/resolv.conf dest=/tmp/resolv.conf state=link"
192.168.xxx.xxx | CHANGED => {
"changed": true,
"dest": "/tmp/resolv.conf",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 16,
"src": "/etc/resolv.conf",
"state": "link",
"uid": 0
}
属性 | 说明 |
---|---|
force | 需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes\no。 |
group | 定义文件/目录的属组。 |
mode | 定义文件/目录的权限。 |
owner | 定义文件/目录的属主。 |
path | 必选项,定义文件/目录的路径。 |
recurse | 递归设置文件的属性,只对目录有效。 |
src | 被链接的源文件路径,只应用于 state = link 的情况。 |
dest | 被链接到的路径,只应用于 state = link 的情况。 |
state | 说明 |
---|---|
directory | 如果目录不存在,就创建目录。 |
file | 即使文件不存在,也不会被创建。 |
link | 创建软链接。 |
hard | 创建硬链接。 |
touch | 如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间。 |
absent | 删除目录、文件或者取消链接文件。 |
copy
- 复制文件到远程主机。
ansible node -m copy -a "src=/etc/ansible/ansible.cfg dest=/tmp/ansible.cfg owner=root group=root mode=0644"
- 使用样例。
[root@localhost ~]# ansible node -m copy -a "src=/etc/ansible/ansible.cfg dest=/tmp/ansible.cfg owner=root group=root mode=0644"
192.168.xxx.xxx | CHANGED => {
"changed": true,
"checksum": "21b4003ea442380222fbeb0300e9be93f8c23ff7",
"dest": "/tmp/ansible.cfg",
"gid": 0,
"group": "root",
"md5sum": "05536ea3aca89e90d626ba85e50efd1f",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 20301,
"src": "/root/.ansible/tmp/ansible-tmp-1547234966.54-104160260765671/source",
"state": "file",
"uid": 0
}
属性 | 说明 |
---|---|
backup | 在覆盖之前,将源文件备份,备份文件包含时间信息。有两个选项:yes\no。 |
content | 用于替代 " src ",可以直接设定指定文件的值。 |
dest | 必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录。 |
directory_mode | 递归设定目录的权限,默认为系统默认权限。 |
force | 如果目标主机包含该文件,但内容不同,如果设置为 yes,则强制覆盖,如果为 no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为 yes。 |
others | 所有的 file 模块里的选项都可以在这里使用。 |
src | 被复制到远程主机的本地文件,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用 " / " 来结尾,则只复制目录里的内容,如果没有使用 " / " 来结尾,则包含目录在内的整个内容全部复制,类似于 rsync。 |
command
- 在远程主机上执行命令。
ansible node -m command -a "uptime"
- 使用样例。
[root@localhost ~]# ansible node -m command -a "uptime"
192.168.xxx.xxx | CHANGED | rc=0 >>
07:53:20 up 231 days, 21:21, 3 users, load average: 14.17, 13.85, 13.35
属性 | 说明 |
---|---|
creates | 一个文件名,当该文件存在,则该命令不执行。 |
free_form | 要执行的 linux 指令。 |
chdir | 在执行指令之前,先切换到该目录。 |
removes | 一个文件名,当该文件不存在,则该选项不执行。 |
executable | 切换 shell 来执行指令,该执行路径必须是一个绝对路径。 |
shell
- 切换到某个 shell 执行指定的指令,参数与 command 相同。
- 与 command 不同的是,此模块可以 支持命令管道,同时还有另一个模块也具备此功能:raw。
ansible node -m shell -a "ls -al | grep a"
- 使用样例。
[root@localhost ~]# ansible node -m shell -a "ls -al | grep a"
192.168.96.177 | CHANGED | rc=0 >>
total 120336
dr-xr-x---. 12 root root 4096 Apr 3 07:43 .
dr-xr-xr-x. 24 root root 4096 Sep 17 2018 ..
-rw-r--r--. 1 root root 196640 Nov 28 16:55 aaaa
-rw-------. 1 root root 2490 May 8 2018 anaconda-ks.cfg
drwx------. 4 root root 4096 May 21 2018 .ansible
drwxr-xr-x. 2 root root 16384 Apr 2 14:06 .ansible_async
-rw-r--r--. 1 root root 40 Mar 18 17:53 a.sh
......
4.1.1 模块的分类
- 在 Ansible 模块文档上查看单个模块的时候, 每一个模块文档的底部都会标识, 这是 Core
Module,还是 Extra Module。- Core 模块(核心模块)
- 不需要额外下载和配置,安装 Ansible 后就可以直接使用的。
- 比较常用的模块。
- 经过严格测试的模块。
- Extra 模块(额外模块)
- 需进行下载和额外的配置才能使用。
- 次常用的模块。
- 还有可能存在 bug 的模块。
- Core 模块(核心模块)
5. Ansible 的脚本 Playbook
- Playbook(剧本)是 Ansible 的脚本语言,使用的是 YAML 格式。
- Ansible 提供了一个单独的命令 ansible-playbook 执行剧本。
命令格式
- ansible-playbook [options] playbook.yml [playbook2 ...]
参数 | 说明 |
---|---|
--ask-vault-pass | 请求保管库的密码。 |
--become-method 'BECOME_METHOD' | 使用权限提升方法(BECOME_METHOD 默认是 sudo),有效值有 sudo、su、pbrun、pfexec、doas、dzdo、ksu、runas、pmrun、enable、machinectl。 |
--become-user 'BECOME_USER' | 用此用户身份操作,默认 root。 |
--flush-cache | 清除清单中每个主机的缓存。 |
--force-handlers | 即使任务失败也运行处理程序。 |
--list-hosts | 输出匹配主机的列表,不执行任何其他操作。 |
--list-tags | 列出所有可用标签,不执行任何其他操作。 |
--list-tasks | 列出所有要执行的任务,不执行任何其他操作。 |
--private-key,--key-file | 使用此文件对连接进行身份验证。 |
--scp-extra-args 'SCP_EXTRA_ARGS' | 指定只传递给 SCP 的额外参数。例如 -l |
--sftp-extra-args 'SFTP_EXTRA_ARGS' | 指定只传递给 SFTP 的额外参数。例如 -f,-l。 |
--ssh-common-args 'SSH_COMMON_ARGS' | 指定只传递给 SCP/SFTP/SSH 的公共参数。例如 ProxyCommand。 |
--ssh-extra-args 'SSH_EXTRA_ARGS' | 指定只传递给 SSH 的额外参数。例如 -R。 |
--skip-tags | 仅运行标记与这些值不匹配的任务。 |
--start-at-task 'START_AT_TASK' | 在与此名称匹配的任务处启动剧本。 |
--step | 一步一步:运行前确认每个任务。 |
--syntax-check | 对剧本(Playbook)进行语法检查,但不执行它。 |
--vault-id | 使用的保管库标识。 |
--vault-password-file | 指定保管库密码文件。 |
--version | 显示版本信息。 |
-C,--check | 尝试预测一些可能发生的变化,但不做任何改变。 |
-D,--diff | 更改(小)文件和模板时,显示这些文件中的差异,适用于 --check。 |
-K,--ask-become-pass | 请求权限提升的密码。 |
-M,--module-path | 为模块库准备冒号分隔的路径。(默认为 [u'/home/jenkins/.ansible/plugins/modules',u'/usr/share/ansible/plugins/modules') |
-T 'TIMEOUT',--timeout 'TIMEOUT' | 以秒为单位覆盖连接超时。(默认值为 10) |
-b,--become | 运行操作。 |
-c 'CONNECTION',--connection 'CONNECTION' | 要使用的连接类型。(默认值 smart) |
-e,--extra-vars | 如果文件名以 @ 开头,将附加变量设置为 key = value 或 yaml/json。 |
-f 'FORKS',--forks 'FORKS' | 指定要使用的并行进程数。(默认值为 5) |
-h,--help | 显示帮助信息。 |
-i,--inventory,--inventory-file | 设置主机清单。 |
-k,--ask-pass | 请求连接的密码。 |
-l 'SUBSET',--limit 'SUBSET' | 将所选主机进一步限制为其他模式。 |
-t,--tags | 仅运行使用这些值标记的任务。 |
-u 'REMOTE_USER',--user 'REMOTE_USER' | 使用此用户连接。(默认无) |
-v,--verbose | 使用显示模式。(-vvv 表示更多,-vvvv 表示启用连接调试) |
- 使用样例。
- hosts: node
serial: 10
user: root
gather_facts: no
vars:
package_name: pssh-2.3.1
src_path: /root/pssh-2.3.1.tar.gz
tasks:
- copy:
src: "{{ src_path }}"
dest: /data/
- name: untar
shell: 'tar -xvf /data/{{ package_name }}.tar.gz -C /data/&& rm -rf /data/{{ package_name }}.tar.gz'
async: 10
poll: 2
- name: upgrade
shell: 'ls /data/{{ package_name }}'
register: result
async: 10
poll: 2
handlers:
- name: clean
shell: 'rm -rf /data/{{ package_name }}'
async: 10
poll: 2
- 最基本的 Playbook 脚本分为三个部分。
- 执行的对象 hosts、user。
- 执行的任务 tasks。
- 善后工作 handlers。
5.1 主机(hosts)和用户(user)
key | 说明 |
---|---|
hosts | 为主机 IP、主机组名或者关键字 all。 |
user | 在远程主机上使用设置身份运行。 |
become | 切换成其他用户执行,值为 yes 或 no。 |
become_method | 与 become 一起使用,可以为 sudo、su、pbrun、pfexec 等。 |
become_user | 与 become_method 一起使用,可以为 root 或者其他用户名。 |
- 脚本里用 become 时,执行的 Playbook 必须加参数 --ask-become-pass,提示用户输入 sudo 的密码。
5.2 任务列表(tasks)
- 任务( task )是从上至下顺序执行的 , 如果中间发生错误, 那么整个 Playbook 会中止。 但可以改修文件后,再重新执行。
- 每一个任务都是对模块的一次调用,只是使用不同的参数和变量而已。
- 每一个任务最好有 name 属性,这是供人读的, 没有实际的操作。然后会在命令行里面输出,提示用户执行情况。
- 写了 name 的任务在 Playbook 执行时,会显示对应的名字,信息更友好、丰富。
参数的不同写法
- 了最基本的传入模块的参数的方法 key = value。
- 当需要传入参数列表过长时, 可以分隔到多行。
- 用 YML 的字典格式传入参数。
任务的执行状态
- 任务中每个 Action 会调用一个模块,然后在模块中检查当前系统状态是否需要重新执行。
- 如果 本次执行了 , 那么 Action 会得到返回值 changed。
- 如果 不需要执行,那么 Action 会得到返回值 ok。
- 模块的执行状态的具体判断规则由各个模块自己决定和实现。例如, copy 模块的判断方法 是比较文件的 checksum。
5.3 晌应事件(handlers)
- handler 是 Playbook 的 Event。
- handlers 里面的每一个 handler 都是对模块的一次调用。
- handler 与任务不同,任务会默认地接定义顺序执行每一个任务, handler 则不会,它需要在任务中被调用,才有可能被执行。
- 任务表中的任务都是有状态的 changed 或者 ok。在 Ansible 中, 只有在任务的执行状态为 changed 时,才会执行该任务调用的 handler。这也是 handler 与普通的 Event 机制不 同的地方。
- 一个 handler 最多只执行 次,并且在所有的任务都执行完之后再执行。如果有多个任务调用( notify )同一个 handler, 那么只执行一次。
- 只有 changed 状态的任务才会触发 handler 的执行。
- 当任务的执行状态为 changed 时,才会触发 notify handler 的执行。
- handler 是按照定义的顺序执行的,而不是按照安装在任务中调用的顺序执行的。
5.4 变量(vars)
- 在 Playbook 中,常用的几种变量包括以下几种情况。
- 在 Playbook 中用户自定义的变量。
- 用户无须自定义, Ansible 会在执行 Playbook 之前去全程主机上搜集关于远程节点系统 信息的变量。
- 在文件模板中,可以直接使用上述两种变量。
- 把任务的运行结果作为一个变量来使用,这个变量叫作注册变量。
- 为了使 Playbook 更灵活、通用性更强,允许用户在执行 Playbook 时传入变量的值,这 个时候就需要用到 " 额外变量 "。
用户自定义变量
- 用户可以在 Playbook 中,通过 vars 关键字自定义变量,使用时用 {{}} 引用起来即可。如上述用例中的 src_path。
- 当变量较多的时候, 或者变量需要在多个 Playbook 中重用的时候,可以把变量放到一个单 独的文件中,通过关键字 var_files 把文件中定义的变量引用到 Playbook 中。使用变量的方 法和在本文件中定义变量的使用方法相同。
- 变量还可以定义成格式为 YAML 的字典格式。
- 访问该变量的属性,可以使用中括号或者点号,例如 foo ['field'] 或者 foo.field。
- 某些时候 YAML 和 Ansible Playbook 的变量语法不能在一起好好工作。这里仅发生在当冒号后面的值不以 { 开头的时候, 如果有必要以 { 开头,则必须加上引号。
- 在 YAML 值的定义中,只要提示 YMAL 语法错误, 就可以尝试加入引号来解决。
vars:
package_name: pssh-2.3.1
src_path: /root/pssh-2.3.1.tar.gz
远程主机的系统变量( Facts)
- Ansible 会通过模块 setup 来搜集主机的系统信息,这些搜集到的系统信息叫作 Facts。
- 每个 Playbook 在执行前都会默认执行 setup 模块,所以这些 Facts 信息可以直接以变量的形式使用。
- 复杂的变量,可以使用中括号或者点号访问。
- 搜集 Facts 信息会消耗额外时间,如果不需要 Facts 信息,则可以在 Playbook 中,通过关键字 gather_facts 来控制是否搜集远程系统的信息。
文件模板中使用的变量
- 在 Playbook 中定义的变量 ,可以直接在 template 中使用,同时 Facts 变量也可以直接在 template 中使用,当然也包含在 Inventory 里面定义的 Host 和 Group 变量。
- 所有在 Playbook 中 可以访问的变量,都可以在 template 文件中使用。
把运行结果当作变量使用(注册变量)
- 把任务的执行结果当作一个变量的值也是可以的。这个时候就需要用到 " 注册变量 ", 即把 执行结果注册到一个变量中 , 待后面的任务使用。
- 把执行结果注册到变量中的关键字是 register。
- 注册变量经常和 debug 模块一起使用,这样可以得到更多的关于执行错误的信息,以帮助 用户调试。
- name: upgrade
shell: 'ls /data/{{ package_name }}'
register: result
用命令仔传递参数
- 为了使 Playbook 更灵活、通用性更强,允许用户在执行的时候传入变量的值,这时候就需 要用到 " 额外变量 "。
- 可以将 hosts 和 user 都定义为变量,可以从命令行传递变量值。
- hosts: '{{ hosts }}'
serial: 10
user: '{{ user }}'
gather_facts: no
[root@localhost ansible]# ansible-playbook node_upgrade.yml --extra-vars "hosts=node user=root"
- 还可以用 JSON 格式传递参数。
[root@localhost ansible]# ansible-playbook node_upgrade.yml --extra-vars "{'hosts':'node','user':'root'}"
- 还可以将参数放在文件里面。
[root@localhost ansible]# cat vars.json
{'hosts':'node','user':'root'}
[root@localhost ansible]# ansible-playbook node_upgrade.yml --extra-vars "@vars.json"
5.4.1 变量的作用域
- Global,作用域为全局。
- Ansible 配置文件中定义的变量。
- 环境变量。
- ansible/ansible-playbook 命令行中传进来的变量。
- Play,作用域为 Play (一个 Playbook 由多个 Play 构成)。
- Play 中 vars 关键字下定义的变量。
- 通过模块 include_vars 定义的变量。
- role 在文件 default/main.yml 和 vars/main.yml 中定义的变量。
- Host,作用域为某个主机。
- 定义在主机清单中的变量。
- 主机的系统变量。
- 注册变量。
- 除了 role defaults 变量外,其他变量的作用域越小越精确 ,变量的优先级越高。
- inventory 中的全局变量可以被 Play 中的变量覆盖,Playbook 中的变量可以被 host 变量覆盖,host 变量又可以被 task 变量覆盖。
- 变量优先级最高的是 extra 变量,又叫命令行变量,只在某一次执行时生效的变量优先级最高。
- 变量的优先级只有在变量重名的时候才需要区分, 所以建议除了 role defaults 变量外,尽量不要有相同名字的变量。
5.5 逻辑控制语句
- when:条件判断语句 , 类似于编程语言中的 if。
- loop:循环语旬,类似于编程语言的中的 while。
- block:把几个任务组成一个代码块,以便于针对一组操作的异常进行处理等操作。
条件判断语句(when)
tasks:
- command: /bin/false
register: result
ignore_error: True
- command: /bin/something
when: result|failed
- command: /bin/something_else
when: result|success
- command: /bin/skill/something_else
when: result|skipped
循环语句(loop)
-
with_items 用于迭代的 list 类型变量。
- 不仅支持简单的字符串列表,还支持 hash 列表。
vars:
somelist: ["testuserl","testuser2"]
tasks:
-name: add several user
user: name={{ item }} state=present groups=wheel
with_items: "{ {some list } }"
- name : add several users
user : name={{ item. name }} state=present groups={ { item. groups }}
with_items:
- { name:'testuserl', groups:'wheel' }
- { name:'testuser2', groups :'root' }
-
with_nested 可以处理嵌套循环的情况。
- 可以用 [ ] 访问内层和外层的循环。
- 也可以用 (.) 访问内层和外层的变量。
- name : give users access to multiple databases
mysql_user : name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
#mysql_user : name={{ item.0 }} priv={{ item.1 }}.*:ALL append_privs=yes password=foo
with_nested:
- [ 'alice','bob' ]
- [ 'clientdb','employeedb','providerd' ]
- with_fileglob 可以以非递归的方式来模拟匹配单个目录中的文件。
with_fileglob:
- /playbooks/files/fooapp/*
代码块(block)
- 多个 action 组装成块后,可以根据不同条件执行一段语旬。
tasks:
- block:
- yum: name={{ item}} state=installed
with_items:
- httpd
- memcached
- template: src=templates/src.j2 dest=/etc/foo.conf
- service: name=bar state=started enabled=True
when: ansible_distribution =='CentOS'
become: true
become_user: root
- 组装成块后,处理异常会更加方便。
tasks :
- block:
- debug: msg='i execute normally'
- command: /bin/false
- debug: msg='i never execute, cause ERROR !'
5.6 Playbook 的重用
- Playbook 支持两种重用机制,一种是重用静态单个 Playbook 脚本,另外一种是重用实现特 定功能的文件夹,类似于 Python 等编程语言中的包( Package )。
- include 语句 重用单个 Playbook 脚本,使用起来简单、 直接。
-
role 语句 重用实现特定功能的 Playbook 文件夹,使用方法稍复杂、功能强大。
- Ansible 还为 role 创建了一个共享平台 Ansible Galaxy,role 是 Ansible 最为推荐的重用和分享 Playbook 的方式。
include 语句
tasks:
- include: tasks/firewall_httpd_default.yml
- 在被 include 的文件中定义参数,可以通过向执行的 Playbook 中传参数,可以加在行尾,使用空格分隔。
tasks:
- include : tasks/firewall.yml port=80
- 也可以使用 YAML 字典传参数。
tasks :
- include: wordpress.yml
vars:
wp_user: timmy
ssh_keys:
- keys/one.txt
- keys/two.txt
- 把一条任务简写成一个类 JSON 的形式传参数。
tasks:
- { include: wordpress.yml, wp_user: timmy, ssh_keys:[ 'keys/one.txt','keys/two.txt' ]}
- 如果在 Playbook 中已经定义了的参数,就不需要再显示传入值。
- hosts: node
vars:
port: 3206
remote_user: root
tasks:
- include: tasks/firewall.yml
- Ansible 1.9 及之前的版本不能调用 include 里面的 handler,Ansible 2.0+ 则可以调用。
handlers:
- include: handlers/handlers.yml
- name: restart apache
- debug: msg="This is the handler restart apache"
role 语句
- 在 Ansible 中,通过遵循特定的目录结构,就可以实现对 role 的定义。
- 如果文件 roles/x/tasks/main.yml 存在,则文件中列出的任务都将被添加到 Play 中。
- 如果文件 roles/x/handlers/main.yml 存在,则文件中列出 handler 都将被添加到 Play 中。
- 如果文件 roles/x/vars/main.yml 存在,则文件中列出的变量都将被添加到 Play 中。
- 如果文件 roles/x/defaults/main.yml 存在,则文件中列出的变量都会被添加到 Play 中。
- 如果文件 roles/x/meta/main.yml 存在,则文件中列出的所有依赖的 role 都将被添加到 Play 中。
- 此外,下面的文件不需要绝对或者是相对路径,和放在同一个目录下的文件一样,直接使用即可。
- copy 或者 script 使用 roles/x/files/ 下的文件。
- template 使用 roles/x/templates/ 下的文件。
- include 使用 roles/x/tasks/ 下的文件。
- 在写 role 的时候,一般都要包含 role 入口文件 roles/x/tasks/main.yml ,其他的文件和目录, 可以根据需求选择是否加入。
- 使用带参数的 role
- hosts : webservers
roles:
- { role: myrole, param:'Call some_role for the 1st time' }
- { role: myrole, param:'Call some role for the 2nd time' }
- 或者写成 YAML 字典格式。
- hosts : webservers
roles:
- role: myrole
param: 'Call some_role for the 1st time'
- role: myrole
param: 'Call some_role for the 2nd time'
- role 指定默认的参数。
- 指定默认参数后,如果在调用时传参数了,那么就使用传入的参数值, 如果在调用的时候 没有传参数,那么就使用默认的参数值,通过配置 defaults 中的 main.xml 实现。
# roles/myrole/defaults/main.yrnl
param: "I am the default value"
role 和任务的执行顺序
- pre_tasks > role > tasks > post_tasks。
- hosts: node
pre_tasks:
- name: pre
shell: echo 'hello'
roles:
- { role: some role }
tasks:
- name: task
shell: echo 'still busy'
post_tasks:
- name: post
shell: echo 'goodbye'
5.7 标签
- 如果 Playbook 文件比较大,并且在执行的时候只是想执行部分功能,Playbook 提供了标签( tags )可以实现部分运行。
tasks:
- yum: name={ { item } } state=installed
with_items:
- httpd
tags:
- packages
- name: copy httpd.conf
template: src=templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
tags:
- configuration
- 如果不加任何 tag 参数,那么会执行所有标签对应的任务。
- 如果指定执行部分任务,则可以利用关键字 --tags 指定需要执行的标签名。
ansible-playbook example.yml --tags "packages"
- 如果指定不执行的任务,则可以利用关键字 --skip-tags。
ansible-playbook example.yml --skip-tags "configuration"
特殊的标签
- 只要在执行 Playbook 时,如果没有明确指定不执行 always 标签,那么 always 标签 所对应的任务就始终会被执行。
tasks:
- debug: msg="Always print this debug message"
tags:
- always
- 可以使用 --tags tagged 来执行所有标记了标签的任务, 无论标记的标签的名字是什么。
- 可以使用 --tags untagged 来执行所有没有标记了标签的任务,无论标记的标签的名字是什么。
- 可以使用 --tags all 来执行所有的任务。
- include 语句指定执行的标签的语法。
- include: foo.yml
tags: [web, foo]
- 调用 role 中的标签的语法。
roles:
- { role: webserver, port: 5000, tags: [ 'web','foo' ]}
5.8 lookup
读取文件
- file 类型的 lookup 可以读取文件。
{{ lookup('file','data/plain.txt') }}
生成随机密码
- 第一次执行时,如果密码文件 /tmp/password/kitty 不存在, lookup 会生成长度为 5 的随机密码,存储在文件中。如果密码文件存在,那么直接读取该文件中的内容作为密码。
password: "{{ lookup('password','/tmp/password/kitty length=5') }}"
读取环境变量
- env 类型的 lookup 可以读取 Linux 上的环境变量。
debug: msg="{{ lookup('env','HOME') }} is an environment variable"
读取 Linux 命令的执行结果
- pipe 类型的 lookup 可以将 Linux 上命令的执行结果读取到 Ansible 中。
debug: msg=" {{ lookup('pipe','date') }} is the raw result of running this command"
读取 template 变量替换后的文件
- template 类型的 lookup 可以将一个 template 文件经过变量替换后的内容读取到 Ansible 中。
- 如果在 template 文件中有未定义的变量 ,则会报错。
debug: msg="{{ lookup('template','data/some_template .j2') }} is a value from evaluation of this template"
读取配置文件
- lookup 支持读取两种类型的配置文件 ini 和 Java 的 properties。
- 使用语法。
- lookup ('ini','key [type=<properties I ini>] [ section=section] [ file=file.ini] [re=true] [default=<defaultvalue>]')
msg:"User in integration is {{ lookup('ini','user section= integration file=data/users.ini') }}"
debug: msg="user.name is {{ lookup('ini','user.name type=properties file=data/user.properties ') }}"
参数 | 默认值 | 说明 |
---|---|---|
type | ini | 文件类型。 |
file | ansible.ini | 加载文件名称。 |
section | global | 默认在设置 section 中查找 key。 |
re | False | key 的正则表达式。 |
default | 空字符串 | key 不存在时的返回值。 |
- 每个参数都有默认值,所以在使用 ini 类型的 lookup 时,每一个参数都是可选的,没有传入的参数会使用默认值。
读取 csv 文件的指定单元
- 使用语法。
- Lookup('csvfile','key argl=vall arg2=val2 ...')
debug: msg="The atomic mass of Lithium is {{ lookup('csvfile','Lifile=elements.csv delimiter=, col=2') }}"
参数 | 默认值 | 说明 |
---|---|---|
file | ansible.csv | 加载文件的名称。 |
col | 1 | 输出的列的索引,索引从 0 开始计数。 |
delimiter | TAB | csv 文件的分隔符:tab 可以用 TAB 或者 t 来表示。 |
default | 空字符串 | 如果元素不存在的返回值。 |
encoding | utf-8 | CSV 文件的编码格式。 |
读取 DNS 解析的值
- dig 类型的 lookup 可以向 DNS 服务器查询指定域名的 DNS 记录。
- 可以查询任何 DNS 记录,包括正向查询和反向查询。
debug: msg="The IPv4 address for baidu.com. is {{ lookup('dig', 'baidu.com.') }}"
- 更多的 lookup 功能可以 参考官方文档
5.9 过滤器
- 过滤器( filter )是 Python 模板语言 Jinja2 提供的模块,可以用来操作数据。
- 它在 Ansible 的管理节点上执行并操作数据,而不是在远程的目标主机上。
- 过滤器和 lookup 类似,都是在 {{ }} 中使用。
- 不同类型的过滤器的功能差距很大。
- 过滤器是 Ansible 使用的模板语言 Jinja2 的内置功能。
- 在 Ansible 中,不仅可以使用 Jinja2 自带的过滤器, 还可以使用 Ansible 提供的过滤器,以及用户根据自己的需要自定义的过滤器。
5.9.1 对普通变量的操作
为没有定义的变量提供默认值
- 用到了 default 过滤器。
- some_undefined_variable 变量没有定义时,输出 Default。
debug: msg="{{ some_undefined_variable | default("Default") }}"
忽略变量
- 用到了 omit 占位符。
- 与 default 一起使用时,如果某个变量没有定义,那么使用 omit 占位符, Ansible 就会把这个对应的参数按照没有传这个参数的值来处理。
file: dest={{item.path}} state=touch mode={{ item.mode | default(omit)) }}
强制变量定义
- 强制变量必须定义,否则抛错,用到了 mandatory。
- 在 Ansible 默认的配置中,如果变量没有定义 ,那么直接使用未定义的变量会抛错。
- 如果在 Ansible 配置文件中使用了下面的配置,那么遇到未定义的变量时, Ansible 就不会抛错。
error_on_undefined_vars = False
- 这种情况下如果想约束某一个变量必须定义, 就可以使用 mandatory。
debug: msg="{{ some undefined variable | mandatory }}"
判断变量是否为布尔类型
- bool 类型的过滤器用来判断变量是否为布尔类型。
when: some_book_value | bool
条件表达式
- ternary 类似于编程语言中的类型表达式(A?B:C)当条件为真时,返回前一个值,当条件为假时,返回另外一个值。
debug: msg="{{ (name == "John") | ternary('Mr','Ms') }}"
5.9.2 对文件路径的操作
- Linux 文件路径的操作的过滤器。
- basename:获取路径中的文件名。
- dirname:获取文件的目录。
- expanduser:扩展~为实际的目录。
- realpath:获得链接文件所指文件的真实路径。
- relpath:获得相对某一根目录的相对路径。
- splitext:把文件名用点号(.)分割成多个部分。
- Windows 文件路径的操作的过滤器。
- win_basename:获得 Windows 路径的文件名。
- win_dimame:获得 Windows 路径的文件目录。
- win_splitdrive:把 Windows 路径分割成多个部分。
5.9.3 对字符串变量的操作
字符串加引号
- 用到了 quote 过滤器。
- my_test_strinq 变量值输出时会加上单引号。
debug: msg="echo {{ my_test_strinq | quote }}"
得到字符串的 Base64 编码
- 用到了 b64encode、b64decode、to_uuid。
debug: msg="{{ my_comment | b64encode }}"
debug: msg="{{ my_comment | b64decode }}"
debug: msg="{{ my_comment | to_uuid }}"
获取字符串的哈希值
- 计算啥希值的算法有很多,如 shal、md5、checksum 等。
debug: msg="{{ my_password | hash('sha1') }}"
debug: msg="{{ my_password | hash('md5') }}"
debug: msg="{{ my_password | hash('blowfish') }}"
debug: msg="{{ my_password | checksum }}"
debug: msg="{{ my_password | password_hash('sha512') }}"
debug: msg="{{ my_password | password_hash('sha256','mysecretsalt') }}"
把字符串变成代码注释的一部分
- comment 有很多风格和格式。
debug: msg="{{ my_comment | comment }}"
debug: msg="{{ my_comment | comment('c') }}"
debug: msg="{{ my_comment | comment('cblock') }}"
debug: msg="{{ my_comment | comment('erlang') }}"
debug: msg="{{ my_comment | comment('xml') }}"
利用正则表达式对字符串进行替换
- 可以使用 regex_replace 实现。
debug: msg="{{ 'ansible' | regex_replace('^a.* i(.*)$','a\\1') }}"
判断字符串是否是合法的 IP 地址
- 可以使用 ipaddr、ipv4、ipv6 等实现。
debug: msg="{{ my_valid_ip | ipaddr }}"
debug: msg="{{ my_valid_ip | ipv4 }}"
debug: msg="{{ my_valid_ip | ipv6 }}"
debug: msg="{{ '192.0.2.1' | ipaddr('address') }}"
将字符串类型的时间转换成时间戳
- 可以使用 to_datetime 实现。
debug: msg="{{ ('2016-08-04 20:00:12' | to_datetime) }}"
过滤器对 JSON 的操作
- 将变量的值按照 JSON/YMAL 格式输出。
- 可以使用 to_json、to_ymal 等实现。
{{ some_variable | to_json }}
{{ some_variable | to_ymal }}
{{ some_variable | to_nice_json }}
{{ some_variable | to_nice_ymal }}
- 在一个 JSON 对象里,搜索符合条件的属性,返回符合条件的属性数组。
- 可以使用 json_query 实现。
with_items:"{{ domain_ definition | json_query('domain.cluster[*] .name') }}"
- 合并两个 JSON 对象的值。
- 可以使用 combine 实现。
debug: msg="{{ {'a':1,'b':2} | combine({'b':3}) }}"
5.9.4 对数据结构的操作
- 取随机数,可以使用 random。
debug: msg="{{ ['a','b','c'] | random }}"
debug: msg="{{ 59 | random }}"
debug: msg="{{ 100 | random(step=10) }}"
debug: msg="{{ 100 | random(2,10) }}"
debug: msg="{{ 100 | random(start=2,step=10) }}"
- 对 List 的操作。
- min:取最小值。
- max:取最大值。
- join:将 List 中的所有元素连接成一个新的字符串。
- shuffle:将 List 做顺序打乱成一个新的 List。
- map:实现对 List 的映射操作。
- 对 Set 的操作。
- unique:去除重复的元素。
- union:取交集。
- differentce:取差集。
- symmetric_difference:取对称差。
5.9.5 过滤器的链式/连续使用
- Ansible 的过滤器是支持链式使用的,即在一个 {{ }} 中使用多个过滤器。
debug: msg="{{ [0,2] | map('extract',['x','Y','z']) | join('|') }}"
5.9.6 测试字符串
- Ansible 除了支持 Jinja2 自带的所有测试 外,还提供了几个在 Ansible 中常用的测试功能。
-
match 和 search 是用于测试字符串是否符合某一个正则表达式的测试。
- 其中 match 是完全匹配,search 只需部分匹配。
when: url | match("http://example.com/users/.*/resources/.*")
when: url | search("/resources/")
5.9.7 比较版本
- 版本的比较是常用的功能, Ansible 提供了 version_compare 类型的测试来实现。
debug: msg="{{ ansible_distribution_version I version_compare('12.04','>=') }}"
debug: msg="{{ ansible_distribution_version I version_compare('12.04',operator='lt',strict=True) }}"
5.9.8 测试 List 的包含关系
- issubset 可以分别测试 List 是否被包含或包含另外一个 List。
when: a | issuperset(b)
5.9.9 测试文件路径
- 可以使用 is_dir、is_file、is_link、exists 等。
when: mypath | is_dir
when: mypath | is_file
when: mypath | is_link
when: mypath | exists
5.9.10 测试任务的执行结果
- Ansible 提供了一系列的测试,可以用来判断任务的执行结果。
when: result | failed
when: result | chanqed
when: result | success
when: result | skipped
5.10 插件
- Ansible 插件( plugin )并不像模块一样有统一出现的位置和相似的使用方法。
- 只是对 Ansible 功能的补充。
- Ansible 插件会因类型不同而使用不同的方法。
- 有不同类型的插件。
- Action 插件,和模块的使用方法类似,只不过执行目标不是远程主机, 而是在 Ansible 的控制节点(管理节点 )本机上。
- Cache 插件,为 Facts (主机变量 )提供缓存, 以避免多次执行 Playbook 时在搜集 Facts 上有过度的时间开销。
- Callback 插件,Ansible 执行 Playbook 后,提供额外的行为。例如,将执行结果发送到 E-mail 中,或者将执行结果写入 Log 中等等。
-
connection 插件,Ansible 为管理节点和远程主机之间提供了更多的连接方法。默认的连接协议是基于 paramiko 的 SSH 协议。
- paramiko 对于大多数基本需求已经够用 ,如果有高级的需求,则可以通过自定义的插件来提供 SNMP、 Message bug 等传输协议。
- filters 插件,为过滤器提供更多的功能。
- lookup 插件,为 lookup 提供更多的功能。
- strategy 插件,为执行 Playbook 提供更多的执行策略。
- shell 插件,通过 shell 插件可以提供远程主机上更多类型的 shell(csh、 ksh 和 tcsh)等的支持。
- test 插件,为 Ansbile Jinja2 test 提供更多的功能。
-
vars 插件,Ansible 可以将 inventory/playbook/ 命令行中的变量注入 Ansible 中。
- 通过 vars 插件, 可以实现更多方式的变量注入。
网友评论