Ansible - 基础
Ansible
1、简介
ansible 是2013年推出的一款 IT 自动化和 DevOps 软件,2015年被RedHat收购。
是基于Python 研发,糅合很多老运维工具的优点,实现了批量操作系统配置,批量程序部署,批量运行命令等功能。
1.1、ansible 功能
- 自动化部署APP
- 自动化管理配置项
- 自动化持续交付
- 自动化(AWS)云服务管理
1.2、ansible 优点
- 只需要 SSH 和 Python 即可使用
- 无客户端
- ansible 功能强大,模块丰富
- 上手容易,门槛低
- 基于 Python 开发,做二次开发更容易
- 使用公司比较多,社区活跃
1.3、ansible 特性
- 模块化设计,调用特定的模块完成特定任务
- 基于 Python 语言实现
- paramiko
- PyYAML(半结构化语言)
- Jinja2
- 其模块支持 JSON 等标准输出格式,可以采用任何编程语言重写
- 部署简单
- 主从模式工作
- 支持自定义模块
- 支持 playbook
- 易于使用
- 支持多层部署
- 支持异构 IT 环境
2、工作流程
- 大体执行过程
可以理解为,ansible中有两个集合:主机集合HOST、命令集合CMD
- 主机集合HOST中的各选定主机,同时执行命令集合CMD中的选定命令
- 主机集合HOST中的主机可以同时运行部署
- 命令集合CMD中的命令还是按顺序执行,不是同时执行。


3、安装部署
3.1、管理主机
- 要求:Python 2.6 或 Python 2.7
- 一般RedHat6 对应的是 2.6,RedHat7 对应的是 2.7
- 需要安装模块
- paramiko
- PyYAML
- Jinja2
- httplib2
- six
3.2、被管理主机
- 也称为:托管主机
- ansible 默认通过SSH 协议管理机器
- 托管主机要开启SSH 服务,允许 ansible 主机登录
- 在托管节点上也需要安装 Python 2.5 或以上版本
- 如果托管节点开启了SELinx,需要安装 libselinux-python
3.3、安装
]# yum -y install ansible
]# ansible --version # 查看版本及配置文件信息
ansible 2.4.2.0
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, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
3.4、部署公钥
- 由于 ansible 是通过 SSH 在远程执行命令的
- SSH 远程执行命令必须要通过认证才行
- 密码写入配置文件安全性很差,所以一般使用密钥对方式认证
- 使用Key 方式认证
]# vim /etc/hosts # 全部主机都需要声明
192.168.1.40 ansible
192.168.1.41 web1
192.168.1.42 web2
192.168.1.43 db1
192.168.1.44 db2
192.168.1.45 cache
--------------------------------------------------------------------------
]# cd /root/.ssh
]# ssh-keygen -t rsa -b 2048 -N '' -f key # 生成自定义证书
]# ls /root/.ssh/
authorized_keys key key.pub known_hosts
-f # 定义密钥对名称。这里用自定义的名称,是为了避免与已有密钥冲突。
]# shh-copy-id -i key.pub 主机名 # 传送公钥(证书)给各主机
]# ssh -i key web1 # 连接时需要指定私钥
4、托管主机的管理
4.1、主机的定义与分组
- 默认的配置文件为:/etc/ansible/ansible.cfg
- 默认的主机管理文件:/etc/ansible/hosts
- 默认的已有的主机组:all、localhost
]# vim /etc/ansible/ansible.cfg
[defaults]
inventory = /etc/ansible/hosts # 定义管理托管主机的配置文件
host_key_checking = False # SSH时,False:不用yes;Ture:要输yes
------------------------------------------------------------------------------
]# vim /etc/ansible/hosts # 管理托管主机的配置文件
... ...
[web] # 定义一个组
web1
web2
[db]
db[1:20] # 组成员有大量数值时,可参考。
[other]
cache ansible_ssh_port=222 # 单个成员引用变量。
[app:children] # 定义一个组集合,成员是组,不是单台主机
web
db
[all:vars] # vars:定义一个变量,指定适用的组。
ansible_ssh_private_key_file="/root/.ssh/key"
4.2、自定义配置文件及主机管理文件
- ansible 可以定义多个配置文件,各自定义主机集合的
- 配置文件的读取顺序:
- 首先检测ANSIBLE_CONFIG 变量定义的配置文件
- 其次检查当前目录下的 ./ansible.cfg 文件
- 再次检查当前用户家目录下 ~/ansible.cfg 文件
- 最后检查默认的:/etc/ansible/ansible.cfg
]# mkdir /var/myansible
]# vim /var/myansible/ansible.cfg # 创建自定义配置文件
[defaults]
inventory = myhost # 定义主机管理配置文件。未指定绝对路径,则就在当前路径
host_key_checking = False
]# vim ./myhost # 在自定义的主机管理文件中再定义托管主机
[app1]
web1
db1
[app2]
web2
db2
[app:children]
app1
app2
----------------------------------------------------------------------------------
'注意:以上自定义了配置文件。那么在ansible操作这里定义的主机集合时,就需要进入该目录下操作'
]# cd /var/myansible
]# ansible app1 --list-hosts
]# ansible all --list-hosts
4.3、inventory 扩展变量
ansible_ssh_port # SSH 端口号:如果不是默认的端口,通过此变量可指定
ansible_ssh_user # 默认的ssh用户名
ansible_ssh_pass # SSH密码。(此方式并不安全,建议使用 --ask-pass 或 SSH密钥)
ansible_ssh_private_key_file # SSH使用的私钥文件,适用于有多个密钥,而不想使用SSH代理时
vars # 变量定义。用于组名后面
children # 子组定义。用于引用其它组名称
4.5、动态主机
- 以上设置均为静态主机配置,除此之外,还可设置动态主机,这就让ansible 拥有无限可能
- 静态主机,是指在文件/etc/ansible/hosts 中指定的主机和组
- 动态主机,是指通过外部脚本获取主机列表,按照其要求格式返回给ansible 命令
- JSON(JavaScript Object Notation)JavaScript 对象表示法:一种基于文本独立于语言的轻易级数据交换格式
5、基础命令
- 格式
`]# ansible 主机集合 -m 模块名称 -a 模块参数
-i # inventory文件路径,或可执行脚本
-k # 使用交互式登录密码
-e # 定义变量
-v # 显示详细信息
- 基础命令
ansible all --list-hosts
ansible all -m ping -k # ping模块,用于测试SSH的连通性。ping模块没有参数。
- 模块手册
ansible-doc # 模块手册相当于shell的man帮助
]# ansible-doc -l # 列出所有模块
]# ansible-doc modulename # 查看帮助
6、常用模块
command(默认模块)
- 该模块由于是直接在SSHD进程下执行命令,并不具备bash的相关特性。所以,要注意以下问题
- 命令中如有以下字符无法执行:>、<、|、&
`远程执行命令`
'格式:参数就相当于是命令'
ansible 组名或主机名 -m 模块 -a '参数'
例:
]# ansible web -m command -a 'uptime' # 查看机器负载
]# ansible web,db1 -a 'date +%F_%T' # 查看日期和时间。默认模块可不写
]# ansible all -a 'ls /root'
shell
- shell 模块用法基本和 command 一样,区别是:shell 模块是在SSHD进程下再启用/bin/sh 进行执行命令的,可以执行任意非交互式命令。
- 交互式命令不能执行。如vim、top等
- 变量解析
- ansible 执行命令是二次解析
- 第一次在本机解析,第二次在托管主机解析
- 需要第二次解析的变量要使用转义(\)
- 使用cd 时
- ansible 是使用ssh 多次连接执行的
- 连接退出后之前的状态就全部失效了
- 解决方法:使用 chdir 代替 cd 命令。或直接使用绝对路径
'注意:在使用变量时,要注意解析过程。以下两条命令使用不同引号,得出的结果不一致'
]# ansible web -m shell -a "echo $HOSTNAME"
ansible.tedu.cn
ansible.tedu.cn
]# ansible web -m shell -a 'echo $HOSTNAME'
web1.tedu.cn
web2.tedu.cn
`原因:在于执行过程中的解析顺序不一致。以下为第一种解析详情:`
书写命令: ansible xxx "echo $HOSTNAME"
解析命令: 本机[bash] 会先对变量进行替换 -----> ansible xxx "echo ansible"
执行命令: 将命令echo ansible 传输给 托管主机
解析命令: 托管主机收到传输过来的命令 echo ansible 进行解析
执行命令: 托管主机执行命令 echo ansible
输出结果: ansible
------------------------------------------------------------------------------
]# ansible web -m shell -a 'cd /tmp'
]# ansible web -m shell -a 'touch testfile'
# 以上两条命令是无法实现在/tmp目录下创建文件testfile的。需要用以下方法:
]# ansible web -m shell -a 'chdir=/tmp touch testfile'
或
]# ansible web -m shell -a 'touch /tmp/testfile'
script
- 在本地编写好脚本,然后使用 script 模块批量执行
- 该脚本包括但不限于 shell 脚本,只要指定Sha-bang 解释器的脚本都可运行,Python、php、Java等都支持。
]# vim useradd.sh
#!/bin/bash
id nb
if [ $? -ne 0 ];then
useradd wk
echo 456 | passwd --stdin wk
fi
]# ansible web -m script -a '/root/useradd.sh'
yum
- yum 模块:yum包管理器,用于管理软件包
'参数:'
name # 要进行操作的软件包名字
state # 动作(installed,removed)
]# ansible db -m yum -a 'name="mariadb-server" state=installed'
]# ansible cache -m yum -a 'name="lrzsz" state=removed'
service
- service 模块:服务管理模块
'参数:'
name # 必选项,服务名称
enabled # 是否开机启动 yes 或 no
sleep # 执行restarted,会在stop和start之间沉睡几秒钟
state # 对当前服务执行:启动、停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
]# ansible db -m service -a 'name=mariadb enabled=yes state=started'
copy
- copy 模块:复制文件到远程主机
'参数:'
src # 本地文件。注意:若路径以"/"结尾,只复制目录里的内容。不以"/"结尾,复制整个目录
dest # 远程主机的绝对路径,如果源文件是目录,那此路径必须也是目录
backup # 覆盖前先备份原文件,备份文件会包含时间信息。有2个选项:yes/no
force # 有2个选项:yes/no。yes:文件存在强制覆盖;no:不存在才复制。默认是yes
`复制文件`
]# ansible all -m copy -a 'src=/etc/resolv.conf dest=/etc/resolv.conf'
`复制目录`
]# ansible all -m copy -a 'src=/etc/yum.repos.d dest=/etc/'
lineinfile
- lineinfile 模块:类似 sed 的一种行编辑替换模块。效果是:整行替换
'参数:'
path # 目标文件
regexp # 正则表达式,搜索要修改的行
line # 最终修改的结果
]# ansible db -m lineinfile -a \
-> 'path=/etc/my.cnf regexp="^binlog-format" line="binlog-format=mixed"
replace
- 也是类似 sed 的一种行编辑替换模块。但是效果是:精确替换
'参数:'
path # 目标文件
regexp # 正则表达式。搜索要修改的
replace # 替换后的结果
]# ansible db -m replace -a 'path=/etc/my.cnf regexp=mixed replace=row'
setup
- 主要用于获取主机信息,playbooks 里经常会用的另一个参数 gather_facts 与该模块相关
- setup 模块最常用的参数是 filter
filter # 过虑所需要的信息
--tree:将所有主机的输出信息保存到指定目录下,以/etc/ansible/hosts里的主机名为文件名
]# ansible web -m setup -a 'filter=ansible_default_ipv4' --tree /tmp/
Playbook
1、ansible 的七种武器
-
ansible 命令
- 用于执行临时性的工作,必须掌握
-
ansible-doc
- 模块的文档说明,必须掌握
-
ansible-playbook
- 日常应用中使用频率最高的命令,必须掌握
- 工作机制:通过读取先编写好的 playbook 文件实现批量管理
- 可以理解为:按一定条件组成的 ansible 任务集
-
ansible-galaxy
- 从 github 上下载管理 Roles 的一款工具,与 python 的pip类似。里面有大量的经典案例,可用于以后工作中,需要知道
-
ansible-console
- 是 ansible 为用户提供的交互式工具
- 用户可在 ansible-console 虚拟出来的终端上像shell 一样使用 ansible 内置的各种命令
-
ansible-vault
- 主要用于配置文件加密。没什么大用,了解即可
-
ansible-pull
- ansible 的一种工作模式。
- ansible 有2种模式:push、pull
- 默认是push,可以理解为由ansible主动的发起配置工作。
- 默认模式push,在大批量机器配置时,即使是使用高并发线程依旧需要花费很多时间
- pull 模式:可以理解为由ansible 主机提供配置命令,由托管主机主动发起配置。
- 此模式适用大批量机器配置场景(一般2000台以上)
- 灵活性稍有欠缺
- 但是,效率几乎可以无限提升
- 对运维人员的技术水平和前瞻性规划有较高要求
2、JSON
2.1、JSON
- JSON 是 JavaScript 对象表示法,是一种基于文本、独立于语言、轻量级数据交换的,格式
- JSON 中的分隔符限于:单引号、小括号、中括号、大括号、冒号、逗号
- 简而言之:JSON 不是语言,就是一个字符串,一种格式,这个字符串有特定的格式
2.2、JSON 特性
- JSON 是纯文本
- JSON 具有”自我描述性“(人类可读)
- JSON 具有层级结构(值中存在值)
- JSON 可通过 JavaScript 进行解析
2.3、JSON 语法规则
- 数据在:名称/值
- 数据由逗号分隔
- 大括号保存对象
- 中括号保存数组
2.4、JSON 书写格式
- JSON 数据的书写格式:名称/值对
'两种基本形式'
[x,y,z] # 数组
k:v # 键值对
k:{x:y} # 值为键值对
k:[x,y,z] # 值为数组
k:[{x:1},{y:2},{z:3}] # 值为数组 套 键值对
3、YAML
3.1、YAML
- YAML (YAML Aii't Markup Language)
- YAML 是一个可读性高,用来表达数据序列的格式
- YAML 参考了多种语言,如:C、Python、Perl 等,并从XML、电子邮件的数据格式中获得灵感
- CLARK EVANS 在2001年首次发表了这种语言,目前已有数种编程语言或脚本语言支持这种语言
3.2、YAML 基础语法
- YAML 的结构通过空格来展示
- 数组使用"- "(注意,这里是:减号加空格)来表示
- 键值对使用:": "(冒号加空格)来表示
- YAML 使用一个固定的缩进风格表示数据、用来表示数据层级结构关系
- 一般每个缩进级别由两个以上空格组成
- #表示注释
- 重点注意
- 不要使用 TAB,一定要用空格
- 同一层级缩进必须对齐
'键值的表示方法'
# 采用冒号分隔
# 冒号后面必须有一个空格
'基本的2种形式表示:'
k: v # 第1种:冒号后面加空格
k: # 第2种:通过层级表示,层级之间至少有2个空格
v
'复杂的键值2种表示方法:'
k: {x: y}
k:
x:
y
'数组的表示方法:'
# 使用一个短横杠加一个空格
k: [x,y]
k:
- x
- y
- z
k: [{x: 1},{y: 2},{z: 3}]
k:
- x: 1
- y: 2
- z: 3
k: [ {[ {x1: 1},{x2: 2},{x3: 3} ]},{[ {y1: 1},{y2: 2},{y3: 3} ]},{[ {},{},{} ]} ]
k:
-
x1: 1
x2: 2
x3: 3
-
y1: 1
y2: 2
y3: 3
-
z1: 1
z2: 2
z3: 3
4、Jinja2
4.1、Jinja2
- 这是基于 Python 的模板引擎,包含:变量、表达式。两者在求值时会被替换为值
- 模板中还有标签,控制模板的逻辑
- playbook 的模板就是用 Jinja2 模板来处理的
4.2、基本语法
- 模板的表达式都是包含在分隔符 "{{ }}" 内的
- 控制语句都是包含在分隔符 "{% %}" 内的
- 模板支持注释,都是包含在分隔符 "{# #}" 内,支持块注释
- 在Jinja2 中,字符串必须加引号
{# 调用变量 #}
{{varname}}
{# 计算 #}
{{2+3}}
{# 判断 #}
{{1 in [1,2,3]}}
{# 控制语句 #}
{% if name == '诗仙' %}
李白
{% elif name == '诗圣' %}
杜甫
{% elif name == '诗魔' %}
白居易
{% else %}
李贺
{% endif %}
{% if name == ... ... %}
... ...
{% elif name == '于谦' %}
{% for method in [抽烟,喝酒,烫头] %}
{{do method}}
{% endfor %}
... ...
{% endif %}
- Jinja2 过滤器
- 变量可以通过过虑器修改。
- 过滤器与变量用管道符号(|)分割
- 也可以用圆括号()传递可选参数
- 多个过滤器可以链式调用,前一个过虑器的输出作为后一个过虑器的输入
- 在线文档:http://docs.jinkan.org/docs/jinja2/templates.html # builtin-filters
{# 加密一个字符 #}
{{ 'abcd' | password_hash('sha512') }}
password_hash 这就是一个变量过虑器
5、playbook
5.1、简介
- playbook 是 ansible 用于配置,部署和管理托管主机的剧本(相当于脚本)
- 通过 playbook 的详细描述,执行其中的一系列 tasks ,可以让远端主机达到预期状态
- 为什么要使用 playbook
- 当设施或部署过于复杂时,执行 ad-hoc 命令就不再方便适用了
- playbook 可以反复使用编写的代码,可以像函数一样,最大化利用代码
- 在使用 ansible 过程中,处理的大部分操作都是在编写 playbook
5.2、语法格式
- playbook 是由YAML 语言编写的,遵循YAML标准
- 在同一行中,# 之后的内容表示注释
- 同一个列表中的元素应该保持相同的缩进
- playbook 由一个或多个 play 组成
- play 中 hosts,variables,roles,tasks 等对象的表示方法都是键值中间以": "冒号空格分隔
- YAML 的文件开始行都是以"---"3个小横杠开始的
5.3、构成、结果
- playbook 的构成
- hosts:定义将要执行的 playbook 的远程主机组
- 主机的集合,以逗号为分隔符
- remote_user 用户名:这是用来定义SSH连接主机时使用哪个用户连接。默认是root
- vars:定义 playbook 运行时需要使用的变量
- tasks:定义将要在远程主机上执行的任务列表
- 命令的集合
- 每个play 包含一个task 列表(任务列表)
- 一个task 在其所对应的所有主机上执行完毕后,下一个task 都会执行
- handlers:定义 task 执行完成以后需要调用的任务,即触发任务
- hosts:定义将要执行的 playbook 的远程主机组
- playbook 执行结果
- 使用 ansible-playbook 运行 playbook 文件,输出内容为 JSON 格式
- 绿色代表执行成功
- ***色代表系统状态发生改变
- 红色代表执行失败
5.4、基本格式
]# vim myping.yml # 创建playbook文件,后缀以.yml 结尾
---
- name: 这里是注释
hosts: 主机组
remote_user: root SSH连接时的用户,默认是root,可不写
tasks: 命令的集合
- 模块名:
参数组
]# vim myping.yml
---
- name: test ping
hosts: web,db
remote_user: root
tasks:
- ping:
]# cat -A myping.yml # 这个命令可以检查出格式中是否有tab。
]# ansible-playbook mypb.yml -f 5
-f # 定义并发进程数量,默认是5。如需要自定义,一般设置为CPU的2~8倍。
6、语法进阶
vars 变量
---
- hosts: web
remote_user: root
vars:
uname: lisi
tasks:
- name: create user "{{uname}}"
user:
name: "{{uname}}"
- shell:echo 123 | passwd --stdin "{{uname}}"
- 以上playbook并不完善,密码还是用的shell模块;user 模块本身是有密码参数password的
- 但是user 模块的密码参数不能直接使用,因为password参数会把字符串直接写入/etc/shadow 中,会出现密码是明文的问题。
- 所以,需要通过变量过虑器passwork_hash 来实现加密
---
- hosts: web
remote_user: root
vars:
uname: lisi
pwd: 123
tasks:
- name: create user
user:
name: "{{uname}}"
passoword: "{{ pwd | passwork_hash('sha512') }}"
# password_hash 过虑器;sha512 Linux的加密方式
- 变量的参数可以通过命令中进行传递,或者将参数以JSON 或 YAML 格式写成文本进行读取
]# vim args.yml
---
uname: zhangsan
pwd: 123
]# ansible-playbook user.yml -e @args.yml
或:
]# ansible-playbook user.yml -e [{uname: zhangsan},{pwd: 123}]
ignore_errors
- ansible-playbook 对错误命令的处理方式
- 默认情况判断 $?,如果值不为0就停止执行
- 但有些情况我们需要忽略错误继续执行
- ignore_errors:对错误的处理方式
- Ture:忽略错误继续执行下一条命令
- False:遇到错误即停止(默认)
---
- hosts: web1
remote_user: root
tasks:
- shell: mkdir /tmp/apache
ignore_errors: Ture
- name: restart service httpd
service:
name: httpd
state: restarted
tags
- tags:给指定的任务定义一个调用标识。即打标签。
'使用格式'
- name: NAME
- module: arguments
- tags: TAG_ID # TAG_ID 自定义标签名
'调用方式'
]# ansible-playbook xxx.yml -t TAG_ID
---
- hosts: web
remot_user: root
tasks:
- name: modify index
copy:
src: /root/index.html
dest: /var/www/html/index.html
owner: root
group: root
mode: 0644
tags: update_index
- name: modify conf
copy:
src: /root/httpd.conf
dest: /etc/httpd/conf/httpd.conf
owner: apache
group: apache
mode: 0644
tags: update_conf
- name: restart httpd
service:
name: httpd
state: restarted
]# ansible-playbook conf.yml -t update_conf
handlers
- 触发任务:当关注的资源发生变化时采取的操作
- notify 这个 action 可用于在每个 play 的最后被触发,这样可以避免有多次改变发生时,每次都执行指定的操作,从而变成:仅在所有的变化发生完成后一次性地执行指定操作
- notify 是调用;handlers 是定义可以被触发执行的命令。即:notify 调用 handlers
- 注意:handlers一定要有- name。因为 notify 调用时就是以 NAME 为标识
---
- hosts: web
remot_user: root
tasks:
- name: modify index
copy:
src: /root/index.html
dest: /var/www/html/index.html
owner: root
group: root
mode: 0644
tags: update_index
- name: modify conf
copy:
src: /root/httpd.conf
dest: /etc/httpd/conf/httpd.conf
owner: apache
group: apache
mode: 0644
tags: update_conf
notify:
- restart httpd # 调用时就是填写handlers中的NAME
handlers: # 注意:handlers中一定要有命名:- name
- name: restart httpd
service:
name: httpd
state: restarted
- 注意事项
- 多个 task 触发同一个 notify 的时候,同一个服务只会触发一次
- notify 可以触发多个条件,在生产环境中往往涉及到某一个配置文件发生改变,需要重启多个服务的场景,handlers 用到这里就非常适合
- 结合 vars 可以写出非常普适的服务管理脚本
when
- 满足特定的条件后再触发某一项操作,或,特定的条件终止某个行为。用when 做条件判断
- 可将远程系统中的变量 facts 作为 when 的条件,facts可通过setup模块查看
---
- name: Install vim
hosts: all
tasks:
- name: when yum
yum:
name: vim
state: installed
when: ansible_os_family == "RedHat"
- name: when apt
apt:
name: vim
state: installed
when: ansible_os_family == "Debian"
register
- 保存前一个命令的返回状态,在后面进行调用
- 适用于需要判断前一个命令的状态,再决定是否执行下一步的操作
---
- hosts: web
remote_user: root
tasks:
- shell: uptime | awk '{printf ("%.2f\n",$(NF-2))}'
register: result # 注意:这里是一定写result的。
- service:
name: httpd
state: stopped
when: result.stdout|float > 0.7
]# awk 'BEGIN{while(1){}}' & # 此命令为提高CPU负载。一个死循环
此案例为:当系统负载超过一定值时,将httpd服务停止。
]# uptime
19:23:09 up 8:48, 1 user, load average: 0.00, 0.01, 0.05
]# uptime | awk '{printf ("%.2f\n",$(NF-2))}' # 此命令为提取CPU数据中1分钟那段
0.00
result.stdout|float > 0.7 # stdout:标准输出;float:浮点数据型
with_items
- with_items 是playbook 标准循环,可以用于迭代一个列表或字典,通过 {{ item }} 获取每次迭代的值
---
- hosts: web
remote_user: root
tasks:
- name: add users
user:
group: {{ item.group }}
password: {{ item.passwd | password_hash('sha512') }}
with_items:
- uname: nb
group: bin
passwd: "123456"
- uname: wk
group: man
passwd: banana
- uname: dd
group: daemon
passwd: book
- name: jj
group: mysql
passwd: 123qqq...A
include and roles
- 在编写 playbook 的时候,随着项目越来越大,playbook 也越来越复杂,修改也很麻烦
- 此时,可以把一些play、task 或 handler 放到其它文件中,通过 include 指令包含进来,容易管理
- 注意:include 只能引入单个文件
---
- hosts:
tasks:
- include: tasks/setup.yml
- include: tasks/users.yml user=plj # users.yml中可通过 {{user}} 来使用这些变量
... ...
handlers:
- include: handlers/handlers.yml
- roles 是加强版的 include,它可以引入一个项目的文件和目录
- 一般所需的目录层级有
- vars:变量层
- tasks:任务层
- handlers:触发条件
- files:文件
- template:模板
- default:默认,优先级最低
- 注意:roles 引用时规定了,只能引用的文件名为:main.yml
- 假如:有一个play 包含了一个叫 "x" 的 role,则
- x/tasks/main.yml
- x/vars/main.yml
- x/handler/main.yml
- x/... ... /main.yml
- 以上这些都会添加进这个 play
- 假如:有一个play 包含了一个叫 "x" 的 role,则
7、debug 调试
- 几种简单的排错调试方法
- 显示受到影响的主机:--list-hosts
- 显示工作的task:--list-tasks
- 显示将要运行的tag:--list-tags
- debug 模块:可以在运行时输出更为详细的信息,帮助我们排错
---
- hosts: web
remote_user: root
tasks:
- shell: uptime | awk '{printf ("%.2f\n",$(NF-2))}'
register: result
- service:
name: httpd
state: stopped
when: result.stdout|float > 0.7
- name: show debug info
debug:
var: result # 定义要输出详情的变量。
岁月悠悠!亘古一顺!

浙公网安备 33010602011771号