ansible-2:playbook

一、回顾ansible命令执行过程(重)

  1. 加载自己的配置文件 默认为/etc/ansible/ansible.cfg

  2. 加载自己对应的模块文件,如command

  3. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程

服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件

  1. 给文件+x执行

  2. 执行并返回结果

  3. 删除临时py文件,sleep 0退出

执行状态:

绿色:执行成功并且不需要做改变的操作

黄色:执行成功并且对目标主机做变更

红色:执行失败

二、ansible的playbook基本介绍

playbook是由一个或多个"play"组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中task定义好的角色。从根本上来讲,task就是调用ansible的一个Module。将多个play组织在一个playbook中,即可以让他们联动起来,按照事先编排的机制同唱一台大戏。

三、YAML介绍 (Yet Another Markup Language)

1.基本介绍

一种可读性高的表达资料序列的格式,参考和其他很多语言,例如XML C java Python Perl go 等。

和脚本语言交互性很好;使用实现语言的数据类型;有一个一致的信息模型;易于实现

可以基于流来处理;表达能力强,扩展性好。

2.YAML语法

在单一文件的第一行,用连续的三个---开始,还有选择行的连续三个...用于表示文件的结尾

次行开始写playbook的内容,一般建议写明该playbook的功能

使用#号注释代码

缩进必须统一,不能空格和TAB混用

缩进的级别必须一致,同样的缩进代表着同样的级别。

YAML文件内容是区别大小写,key/value的值需要大小写敏感

多个key/value可同行写也可以换行写,同行使用,分割

value可以是字符串,也可以是另一个列表

YAML文件扩展名为yml或者yaml

3.YAML的数据类型

标量 :单个不可再分的值

标量包括:字符串、布尔值、整数、浮点数、Null、时间、日期

标量的写法,例如

name: wang

age: 18

标量使用缩进的方式写,例如:

name:

wang

age:

18

对象:键值对的集合,又称映射 (mapping)/ 哈希 (hashes)/ 字典 (dictionary)

字典由多个key和value构成,key和value之间用: 分隔,注意:后有一个空格,所有k/v可以放在一行,或者每个k/v分别放在不同行,例如:Python:{xxx:xxx}

account: { name: wang, age: 34 }

或者:

account: //标量

name: wang

age: 18

数组 (List 列表 ) :一组按次序排列的值,又称序列 / 列表

列表由多个元素组成,每个元素放在不同的行,且元素前均使用-打头,并且-后面有一个空格,

或者将所有元素用[]括起来 放在同一行

格式如下:

course: [ linux , python , java ]

也可以写成以-开头的多行

course:

  • linux: haowan

  • python: xing

  • java: yekeyi

【注】:列表也可以套用字典

4.补充知识点:三种常见的数据格式

①:XML

<Servers>

<Server>

<name>Server1</name>

<owner>wang</owner>

<created>123456</created>

<status>active</status>

</Server>

</Servers>

②:JSON(前端,不需要考虑缩进)

{

"Servers": {

"Server": {

"name": "Server1",

"owner": "wang",

"created": "123456",

"status": "active"

}

}

}

③:YAML(后端,必须考虑缩进)

Servers:

Server:

  • name: Server1

owner: wang

created: '123456'

status: active

转换工具:在线JSON转yaml,yaml转JSON-BeJSON.com

【注】:YAML语法和其他高级编程语言类似,简要、清晰。结构通过空格展示和缩进。序列(Sequence)里的项目用 - 来表示,键值用 : 分隔,例如如下示例

ansible-playbook --syntax 1.yml

ansible-playbook -C 1.yml(测试)

四、playbook核心组件

1.Hosts :执行的远程主机列表

- hosts: Inventory remote_user: USER(可不写) gather_facts: no(可不写) ignore_errors:yes忽略错误继续执行

2.tasks :任务集

由多个task的元素组成的列表,实现每个task是一个字典,一个完整的代码块功能,最少元素需包括name和task,一个name只能包括一个task

格式 1 action: module arguments (不推荐) 格式 2 module: arguments

3.Handlers 触发器

用于当关注的资源发生变化时采取一定的操作,可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性执行指定操作,在notify中调用handler中定义的操作

【注】1:单独定义,然后基于notify再模块中触发

2:如果多个task通知了相同的handlers,此handlers仅会再所有tasks结束之后运行一次

3:handlers是再前面的tasks都成功执行后才会执行,如果前面任何一个task失败,会导致handler跳过执行,可以使用force_handlers: yes(针对全局)强行执行handler

【注】:ansible和shell一样顺序执行,不同之处是ansible顺序执行如果报错,将停止执行

4.tags

在playbook文件中,可以利用tags组件,为特定task指定标签,当执行playbook时,可以只执行特定tags的task,而非整个playbook文件,可以一个task对应多个tag,也可以多个task对应一个tag

运行方式:ansible-playbook --list-tags 查看所有标签

前两个不跑,只跑我更改的任务:

ansible-playbook -t change_conf 1.yml

5.变量

6.模板 templates 下面重点说

7.角色

五、playbook 中使用变量操作

**变量名:**仅能由字母、数字、下划线组成,且只能以字母开头

变量来源:

1.ansible setup facts 远程主机的所有变量都可直接调用

2. 在/etc/ansible/hosts中定义

普通变量:主机组中主机单独定义,优先级低于公共变量

公共(组)变量:针对主机组中所有主机定义统一变量

①主机清单变量:范围太大,优先级比较低

②事实属于变量,见setup内置变量

3 通过命令行指定变量,优先级最高

ansible-playbook --e varname=value

例:ansible-playbook -e pkg=dhcp-server var2.yml

4 在playbook中定义(剧本变量,优先级高于主机清单,低于yml变量)

vars:

  • var1: value1

  • var2: value2

例:

5 在独立的变量YAML文件中定义 vars_files

6 在role中定义

注册变量,可以把其键值对取出来

下面操作属于注册变量:

②不写meg的效果:

六、变量

**变量定义:**variable=value

variable: value

调用变量: {{ variable }} 有时需要加双引号 "{{ variable }}"

ansible-playbook -e 选项指定 -e的方式优先级高于playbook内部的vars变量

例如:ansible-playbook test.yml -e "hosts=

1.setup 内置变量

回顾setup模块,setup模块来收集主机的信息,这些facts信息可以直接以变量的形式使用,但是如果主机数较多,会影响速度。

ansible all -m setup -a "filter=ansible_nodename"

ansible all -m setup -a "filter=ansible_hostname"

ansible all -m setup -a "filter=ansible_admin"

ansible all -m setup -a "filter=ansible_memtotal_mb"

ansible all -m setup -a "filter=ansible_memfree_mb"

ansible all -m setup -a "filter=ansible_os_family"

ansible all -m setup -a "filter=ansible_distribution_major_version"

ansible all -m setup -a "filter=ansible_distribution_version"

ansible all -m setup -a "filter=ansible_processor_vcpus"

ansible all -m setup -a "filter=ansible_all_ipv4_addresses"

ansible all -m setup -a "filter=ansible_architecture"

ansible all -m setup -a "filter=ansible_uptime_seconds"

ansible all -m setup -a "filter=ansible_processor"

ansible all -m setup -a "filter=ansible_env"

【注】:若在play_book中编写setup的内置变量。gather_facts需要收集信息,否则变量不可用

2.ansible 外部定义临时公共变量

例如:ansible-playbook test.yml -e "username=www groupname=public2"

3.playbook 内部公共变量

4.主机变量(优先级低于公共变量)

可以在inventory中定义主机时为其添加主机变量以便于在playbook中使用

示例:

webservers

www.xxhf123.com http_port=80 maxRequestsPerChild=100

www.xxhf456.com http_port=8080 maxRequestsPerChild=50

5.在独立的变量 YAML 文件中定义

cat vars.yml

var1: httpd

var2: nginx

6.注册变量 register debug

【注】:shell模块不支持幂等,会一直黄

七、playbook 中使用模板 templates

templates功能:根据模块文件动态生成对应的配置文件

templates文件必须存放于templates目录下,且命名为 .j2 结尾

yaml/yml 文件需和templates目录平级,目录结构如下

./

├── tem.yml

└── templates

└── 1.txt.j2

组成结构和特点:

1:文本文件,嵌套有脚本(使用模板编程语言编写)

Jinja2语言,使用字面量,有下面形式

字符串:使用单引号或双引号

数字:整数,浮点数

列表:[item1, item2, ...]

元组:(item1, item2, ...)

字典:{key1:value1, key2:value2, ...}

布尔型:true/false

算术运算:+, -, *, /, //, %, **

比较操作:==, !=, >, >=, <, <=

逻辑运算:and, or, not

流表达式:For If When

Playbook template 算术运算:

算法运算:

示例:

vim nginx.conf.j2

worker_processes {{ ansible_processor_vcpus**2 }};

worker_processes {{ ansible_processor_vcpus+2 }};

在10.120主机查看:

template 中使用 for if

{% for o om EXPR %} ... {% endfor %}

示例:{% for i in range(1,10} %}

Server_name www{{ i }};

{% endfor %}

例:

首先编辑j2模版:

其次编辑变量:

在10.120主机验证:

迭代:当有需要重复性执行的任务时,可以使用迭代机制

对迭代项的引用,固定变量名为"item"

要在task中使用with_items / loop( 新版本 ) 给定要迭代的元素列表

列表格式:字符串

字典

例:

迭代嵌套子变量

until 循环:

with_line 逐行处理

条件测试之 when

条件测试:如果需要根据变量、facts或此前任务的执行结果来做为某task执行与

否的前提时要用到条件测试,通过when语句实现,在task中使用

when语句

在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法

示例:

tasks:

  • name: "shutdown RedHat flavored systems"

command: /sbin/shutdown -h now

when: ansible_os_family == "RedHat"

判断nginx是否启动,如果启动,就停止服务

关闭 changed 状态:

当确定某个task不会对被控制端做修改时,但是结果显示是黄色的changed状态,可以通过changed_when: false关闭changed状态

利用 changeed_when 检查 task 返回结果

八、roles

ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中

复杂场景:建议使用roles,代码复用度高

变更指定主机或主机组

如命名不规范维护和传承成本大

某些功能需多个Playbook,通过includes即可实现

角色 (roles) :角色集合

roles/

mysql/

httpd/

nginx/

memcached/

roles 目录结构:

每个角色,以特定的层级目录结构进行组织

roles 目录结构:

playbook.yml

roles/

project/

tasks/

files/

vars/

templates/

handlers/

default/ 不常用

meta/ 不常用

Roles 各目录作用

/roles/project/ : 项目名称 , 有以下子目录

files/ :存放由copy或script模块等调用的文件

templates/:template模块查找所需要模板文件的目录

tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;

其它的文件需要在此文件中通过include进行包含

handlers/:至少应该包含一个名为main.yml的文件;其它的文件需要在此

文件中通过include进行包含

vars/:定义变量,至少应该包含一个名为main.yml的文件;其它的文件需要

在此文件中通过include进行包含

meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为

main.yml的文件,其它文件需在此文件中通过include进行包含

default/:设定默认变量时使用此目录中的main.yml文件

案例结构:

httpd-role.yml

roles/

└── httpd

├── files

│ └── main.yml

├── tasks

│ ├── groupadd.yml

│ ├── install.yml

│ ├── main.yml

│ ├── restart.yml

│ └── useradd.yml

└── vars

└── main.yml

相关推荐
风清再凯1 天前
自动化工具ansible,以及playbook剧本
运维·自动化·ansible
IT乌鸦坐飞机1 天前
ansible部署数据库服务随机启动并创建用户和设置用户有完全权限
数据库·ansible·centos7
遇见火星15 天前
如何使用Ansible一键部署MinIO集群?
ansible
粥周粥15 天前
ANSIBLE
ansible
码农101号15 天前
Linux中ansible模块补充和playbook讲解
linux·运维·ansible
码农101号15 天前
Linux的Ansible软件基础使用讲解和ssh远程连接
ansible
烟雨书信16 天前
ANSIBLE运维自动化管理端部署
运维·自动化·ansible
碎碎-li16 天前
ANSIBLE(运维自动化)
运维·自动化·ansible
@donshu@19 天前
Linux运维-ansible-python开发-获取inventroy信息
linux·运维·ansible
Kendra91922 天前
Ansible
ansible