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

相关推荐
Aimyon_364 天前
⾃动化运维利器 Ansible-Jinja2
运维·ansible
柒月VII5 天前
【Ansible常用命令+模块+Playbook+Roles】
linux·服务器·ansible
Linux运维技术栈5 天前
生产环境centos8 & Red Hat8部署ansible and 一键部署mysql两主两从ansible脚本预告
运维·数据库·mysql·自动化·ansible
Aimyon_365 天前
⾃动化运维利器 Ansible-最佳实战
linux·运维·ansible
饭桶也得吃饭5 天前
运维工具Ansible部署、配置
运维·服务器·ansible
陪小七许个愿5 天前
Ansible一键部署Kubernetes集群
容器·kubernetes·ansible
Aimyon_365 天前
⾃动化运维利器 Ansible-变量
运维·ansible
Aimyon_365 天前
⾃动化运维利器Ansible-基础
运维·windows·ansible
大风吹PP凉8 天前
38配置管理工具(如Ansible、Puppet、Chef)
linux·运维·服务器·ansible·puppet
IT-民工211109 天前
Ansible剧本检测Windows防火墙状态
linux·运维·windows·自动化·ansible