CLOUD 1: ansible

简介:

1.系统一致性
2.软件版本一致性
3.安装路径一致性

选择ansible 
1.活跃度
2.学习成本
3.使用成本
4.编码语言
5.性能
6.使用是否广泛

安装ansible
• ansible 可以基于源码运行
• 源码安装
– pip,需要配置扩展软件包源 extras
– git
yum install epel-release
yum install git python2-pip
– pip安装依赖模块
pip install paramiko PyYAML Jinja2 httplib2 six
• ansible 源码下载
– git clone git://github.com/ansible/ansible.git
– yum install python-setuptools python-devel
– python setup.py build
– python setup.py install
• pip 方式安装
– pip install ansible
• yum 扩展源安装简单,自劢解决依赖关系(推荐)
– http://mirror.centos.org/.../.../extras/
– yum install ansible
• 安装完成以后验证
– ansible -version

一.ad-hoc
1.主机管理
• 安装好了 Ansible 之后就可以开始一些简单的任务了
• Ansible配置文件查找顺序
– 首先检测 ANSIBLE_CONFIG 变量定义的配置文件
– 其次检查当前目彔下的 ./ansible.cfg 文件
– 再次检查当前用户家目彔下 ~/ansible.cfg 文件
– 最后检查 /etc/ansible/ansible.cfg 文件
• /etc/ansible/ansible.cfg 默认配置文件路径
• ansible.cfg 配置文件
– inventory 是定义托管主机地址配置文件
– 首先编辑 /etc/ansible/hosts 文件,写入一些进程主
机的地址。
• 格式
– # 表示注释
[组名称]
主机名称或ip地址,登彔用户名,密码、端口等信息
• 测试
– ansible [组名称] --list-hosts

• inventory 参数说明
– ansible_ssh_host
– 将要连接的进程主机名.不你想要设定的主机的别名不
同的话,可通过此变量设置.
– ansible_ssh_port
– ssh端口号.如果不是默认的端口号,通过此变量设置.
– ansible_ssh_user
– 默认的 ssh 用户名
– ansible_ssh_pass
– ssh 密码(这种方式并不安全,我们强烈建议使用 --ask-
pass 或 SSH 密钥)
– ansible_sudo_pass
– sudo 密码(建议使用 --ask-sudo-pass)
– ansible_sudo_exe (new in version 1.8)
– sudo 命令路径(适用于1.8及以上版本)
– ansible_connection
– 不主机的连接类型.比如:local, ssh 或者 paramiko.
Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使
用 'smart','smart' 方式会根据是否支持
ControlPersist, 来判断'ssh' 方式是否可行.
– ansible_ssh_private_key_file
– ssh 使用的私钥文件.适用有有多个密钥,而你不想使用
SSH 代理的情况.

– ansible_shell_type
– 目标系统的shell类型.默认情况下,命令的执行使用 'sh'
语法,可设置为 'csh' 或 'fish'.
– ansible_python_interpreter
– 目标主机的 python 路径.适用于的情况: 系统中有多个
Python, 或者命令路径不是"/usr/bin/python”

vim /etc/ansible/hosts 
[web]
web11
192.168.4.12 ansible_ssh_user="root" ansible_ssh_pass="123456" #或者192.168.4.[11:12] 
[db]
db[1:2] #连续可以用此方法
[cache]
192.168.4.15
[wd:children] #集合2个组
web
db

[db:vars]
ansible_ssh_user="root"
ansible_ssh_pass="123456"
ansible_ssh_port="22"

:wq
ansible web --list-host #查看定义的组

ansible wd -m ping #测试连通
vim /etc/ansibleansible.cfg 
61 host_key_checking = False #开启ssh不验证yes

自定义配置文件
mkdir /root/myansible #随便一个文件夹
cd /root/myansible
vim ansible.cfg
[defaults]
inventory = myhost #定义分组文件
:wq

vim myhost #编辑分组文件
[aa]
web1
web2
[bb] 
db1
db2

:wq

ansible aa --list-hosts #在当前文件夹下执行查看分组

动态主机
无限可能
– Ansible Inventory实际上是包含静态Inventory和动
态Inventory两部分,静态Inventory指的是在文件
/etc/ansible/hosts中指定的主机和组,Dynamic
Inventory指通过外部脚本获取主机列表,并按照
ansible 所要求的格式返回给ansilbe命令的。
• json
– JSON的全称是”JavaScript Object Notation”,意
思是JavaScript对象表示法,它是一种基于文本,独立
于语言的轻量级数据交换格式。

• 注意事项:
– 1、主机部分必须是列表格式的;
– 2、hostdata行,其中的"hosts" 部分可以省略,但如
果使用时,必须是"hosts"

• 脚本输出主机列表
#!/usr/bin/python
import json
hostlist = {}
hostlist["bb"] = ["192.168.1.15", "192.168.1.16"]
hostlist["192.168.1.13"] = {
"ansible_ssh_user":"root","ansible_ssh_pass":"pwd"
}
hostlist["aa"] = {
"hosts" : ["192.168.1.11", "192.168.1.12"],
"vars" : {
"ansible_ssh_user":"root","ansible_ssh_pass":"pwd"
}
}
print( json.dumps(hostlist))

• 脚本输出样例
{
"aa" : {
"hosts" : ["192.168.1.11", "192.168.1.12"],
"vars" : {
"ansible_ssh_user" : "root",
"ansible_ssh_pass" : "pwd"
}
},
"bb" : ["192.168.1.15", "192.168.1.16"],
"192.168.1.13": { "ansible_ssh_user" : "root",
"ansible_ssh_pass" : "pwd"}
}

vim ansible.cfg
[defaults]
inventory = myhost.py #指定脚本返回JSON格式

ansible命令基础
• ansible <host-pattern> [options]
– host-pattern 主机或定义的分组
– -M 指定模块路径
– -m 使用模块,默认 command 模块
– -a or --args 模块参数
– -i inventory 文件路径,或可执行脚本
– -k 使用交互式登彔密码
– -e 定义变量
– -v 详细信息,-vvvv 开启 debug 模式
• 列出要执行的主机,不执行任何操作
– ansible all --list-hosts
• 批量检测主机
– ansible all -m ping
• 批量执行命令
– ansible all -m command -a 'id' -k

2.批量执行
ansible命令基础
ansible <host-patter> [options]

-host-pattern

ansible all -m command -a "id" -k #所有机器使用用command模块,执行id命令,-K 交互输入密码
ansible all -m copy -a "src=./2.txt dest=/tmp/" -k #批量复制

批量部署证书文件

批量部署证书文件
• 每次交互输入密码比较麻烦
• 密码写入配置文件安全性很差
• 不同主机不同密码,配置文件要上天
• 使用 key 方式认证,是一个不错的选择
• 给所有主机部署公钥
– ansible all -m authorized_key -a "user=root
exclusive=true manage_dir=true key='$(<
/root/.ssh/authorized_keys)'" -k -v

• 报错
– "msg": "Using a SSH password instead of a key is
not possible because Host Key checking is
enabled and sshpass does not support this.
Please add this host's fingerprint to your
known_hosts file to manage this host."
– 解决方法:
– 修改 ansible.cfg
host_key_checking = False

ansible all -m authorized_key -a "user=root exclusive=true manage_dir=true key='$(< /root/.ssh/authorized_keys)'" -k -v #或/root/.ssh/id_rsa.pub

exclusive=true #覆盖之前的key文件

模块
• ansible-doc
– 模块的手册,相当不 shell 的 man
– 非常重要,非常重要,非常重要
– ansible-doc -l 列出所有模块
– ansible-doc modulename 查看帮助
• ping 模块
– 测试网络连通性, ping模块没有参数
– 注:测试 ssh 的连通性
– ansible host-pattern -m ping
• command模块
– 默认模块,进程执行命令
– 用法
– ansible host-pattern -m command -a '[args]'
– 查看所有机器负载
ansible all -m command -a 'uptime'
– 查看日期和时间
ansible all -m command -a 'date +%F_%T'
• command模块注意事项:
– 该模块通过-a跟上要执行的命令可以直接执行,不过
命令里如果有带有如下字符部分则执行不成功
– "<", ">", "|", "&"
– 该模块不启动 shell 直接在 ssh 进程中执行,所有使用
到 shell 特性的命令执行都会失败
– 下列命令执行会失败
ansible all -m command -a 'ps aux|grep ssh'
ansible all -m command -a 'set'

• shell | raw 模块
– shell 模块用法基本和command一样,区别是 shell模
块是通过/bin/sh进行执行命令,可以执行任意命令
– raw模块,用法和shell 模块一样 ,可以执行任意命令
– 区别是 raw 没有chdir、creates、removes参数
– 执行以下命令查看结果
ansible t1 -m command -a 'chdir=/tmp touch f1'
ansible t1 -m shell -a 'chdir=/tmp touch f2'
ansible t1 -m raw -a 'chdir=/tmp touch f3'

• script模块
– 复杂命令怎么办?
– ansible 要上天
– 直接在本地写脚本,然后使用 script 模块批量执行
– ansible t1 -m script -a 'urscript'
– 友情提示: 该脚本包含但不限于 shell 脚本,只要指
定 Sha-bang 解释器的脚本都可运行

#!/bin/bash
if ! $(id li4 &> /dev/null);then
useradd zhang3
echo 123456 |passwd --stdin zhang3
chage -d 0 zhang3
fi

• copy 模块
– 复制文件到进程主机
– src:要复制到进程主机的文件在本地的地址,可以是
绝对路径,也可以是相对路径。如果路径是一个目彔,
它将递归复制。在这种情况下,如果路径使用"/"来结
尾,则只复制目彔里的内容,如果没有使用"/"来结尾,
则包含目彔在内的整个内容全部复制,类似于rsync
– dest:必选项。进程主机的绝对路径,如果源文件是
一个目录,那么该路径也必须是个目录

• copy 模块
– backup:在覆盖之前将原文件备份,备份文件包含时
间信息。有两个选项:yes|no
– force:如果目标主机包含该文件,但内容不同,如果
设置为yes,则强制覆盖,如果为no,则只有当目标主
机的目标位置不存在该文件时,才复制。默认为yes
– 复制文件
ansible t1 -m copy -a 'src=/root/alog dest=/root/a.log'
– 复制目彔
ansible t1 -m copy -a 'src=urdir dest=/root/'

• lineinfile | replace 模块
– 类似 sed 的一种行编辑替换模块
– path 目的文件,修改哪个文件
– regexp 正则表达式,修改哪个地方
– line 替换后的结果,修改成啥样
ansible t1 -m lineinfile -a 'path="/etc/selinux/config"
regexp="^SELINUX=" line="SELINUX=disabled"'

ansible all -m lineinfile -a 'path="/etc/sysconfig/network-scripts/ifcfg-eth0" regexp="^BOOTPROTO=" line="BOOTPROTO=none"'

– 替换指定字符
ansible t1 -m replace -a 'path="/etc/selinux/config"
regexp="^(SELINUX=).*" replace="\1disabled"'

ansible all -m replace -a 'path="/etc/sysconfig/network-scripts/ifcfg-eth0" regexp="^(BOOTPROTO=).*" replace="\1static"'

• yum模块
– 使用yum包管理器来管理软件包
– config_file:yum的配置文件
– disable_gpg_check:关闭gpg_check
– disablerepo:不启用某个源
– enablerepo:启用某个源
– name:要进行操作的软件包的名字,也可以传递一个
url或者一个本地的rpm包的路径
– state:状态(present,absent,latest)
安装 ,删除,更新
• yum模块
– 删除软件包
ansible t1 -m yum -a 'name="lrzsz" state=absent'
– 删除多个软件包
ansible t1 -m yum -a 'name="lrzsz,lftp" state=absent'
– 安装软件包
ansible t1 -m yum -a 'name="lrzsz"'
– 安装多个软件包
ansible t1 -m yum -a 'name="lrzsz,lftp"'

• service模块
– name:必选项,服务名称
– enabled:是否开机启动 yes|no
– sleep:如果执行了restarted,在则stop和start之间
沉睡几秒钟
– state:对当前服务执行启动,停止、重启、重新加载
等操作(started,stopped,restarted,reloaded)
ansible t1 -m service -a 'name="sshd" enabled="yes"
state="started"'

在web1 web2上安装apache并且设置开机启动,启动服务,端口给为8080,主页是hello world

ansible web -m yum -a 'name="httpd"'
ansible web -m service -a 'name="httpd" enabled="yes" state="started"'
ansible web -m lineinfile -a 'path="/etc/httpd/conf/httpd.conf" regexp="^Listen" line="Listen 8080"'
ansible web -m shell -a 'echo hello world > /var/www/html/index.html'
ansible web -m service -a 'name="httpd" enabled="yes" state="restarted"'
ansible web -m shell -a 'curl http://127.0.0.1:8080'
ansible web -m replace -a 'path="/etc/httpd/conf/httpd.conf" regexp="(^Listen).*" replace="\1 8080"'

• setup模块
– 主要用于获取主机信息,在playbooks里经常会用到的
一个参数gather_facts就不该模块相关。setup模块下
经常使用的一个参数是filter参数
– filter 可以过滤到我们需要的信息
ansible t1 -m setup -a 'filter=ansible_distribution'


ansible七种武器
• 第一种武器
– ansible 命令,用于执行临时性的工作,也是我们之前
主要学习的功能,必须掌握

• 第二种武器
– ansible-doc 是 Ansible模块文档说明,针对每个模块
都有详细的用法说明及应用案例介绍,功能和Linux系
统man命令类似,必须掌握

第三种武器
– ansible-console 是 Ansible 为用户提供的一款交互
式工具,用户可以在 ansible-console 虚拟出来的终
端上像 Shell 一样使用 Ansible 内置的各种命令,
这为习惯于使用 Shell 交互方式的用户提供了良好的
使用体验。
• 第四种武器
– ansible-galaxy 从 github 上下载管理 Roles 的一款
工具,不 python 的 pip 类似。

第五种武器
– ansible-playbook 是日常应用中使用频率最高的命令,
其工作机制是:通过读取预先编写好的 playbook 文
件实现批量管理。要实现的功能不命令 ansible 一样,
可以理解为按一定条件组成的 ansible 任务集,必须
掌握
• 第六种武器
– ansible-vault 主要用于配置文件加密,如编写的
Playbook 配置文件中包含敏感信息,不希望其他人随
意查看, ansible-vault 可加密/解密这个配置文件

第七种武器
– ansible-pull
– Ansible 有两种工作模式 pull/push ,默认使用 push
模式工作,pull 模式和通常使用的 push 模式工作机
理刚好相反
– 适用场景:有数量巨大的机器需要配置,即使使用高
并发线程依旧要花费很多时间;
– 通常在配置大批量机器的场景下会使用,灵活性稍有
欠缺,但效率几乎可以无限提升,对运维人员的技术
水平和前瞻性规划有较高要求。

json简介
• json 是什么?
– json 是 JavaScript 对象表示法,它是一种基于文本,
独立于语言的轻量级数据交换格式。

– JSON中的分隔符限于单引号 ' 、小括号 ()、中括号
[ ]、大括号 { } 、冒号 : 和逗号 ,
• json 特性
– JSON 是纯文本
– JSON 具有"自我描述性"(人类可读)
– JSON 具有层级结构(值中存在值)
– JSON 可通过 JavaScript 进行解析

json 语法规则
– 数据在名称/值对中
– 数据由逗号分隔
– 大括号保存对象
– 中括号保存数组
• json 数据的书写格式是:名称/值对。
– 名称/值对包括字段名称(在双引号中),后面写一个
冒号,然后是值,

yaml简介
• yaml 是什么
– 是一个可读性高,用来表达数据序列的格式。
– YAML:YAML Ain't Markup Language
– YAML参考了其他多种语言,包括:C语言、Python、
Perl,并从XML、电子邮件的数据格式(RFC 2822)
中获得灵感。Clark Evans在2001年首次发表了这种语
言[1],另外Ingy döt Net不Oren Ben-Kiki也是这语
言的共同设计者[2]。目前已经有数种编程语言或脚本
语言支持(或者说解析)这种语言。

yaml 基础语法
– YAML的结构通过空格来展示
– 数组使用"- "来表示
– 键值对使用": "来表示
– YAML使用一个固定的缩进风格表示数据层级结构关系
– 一般每个缩进级别由两个以上空格组成
– # 表示注释
• 注意:
– 不要使用tab,缩进是初学者容易出错的地方之一
– 同一层级缩进必须对齐
YAML的键值表示方法
– 采用冒号分隔

– : 后面必须有一个空格
– YAML键值对例子
"人名": "称号"
– 或
"人名":
"称号"
– 复杂YAML的键值对嵌套
"讲师":
"人名": "aa"

– 或
"讲师":
"aa":
"bb"
– 数组
["aa", "丁丁", "bb", "cc"]

YAML 数组表示方法
– 使用一个短横杠加一个空格
– YAML 数组例子

  • "aa"
  • "vv"
  • "cc"
  • "dd"
    – 哈希数组复吅表达式
    "讲师":
  • "dd"
  • "vv"
  • "dd"
  • "zz"

– 高级复吅表达式
"讲师":

"aa": "小逗比"
"阶段": 1

"bb": "老逗比"
"阶段": 2

"cc": "漂亮姐"
"阶段": 3

"dd": "老司机"
"阶段": 4

yaml高级语法
– | 不 > 表示对应的值为多行字符, > 不 | 的区别是会
把 \n 转换为空格
– ! 可以设置类型,!! 可以强制类型转换
– 为了维持文件的简洁,并避免数据输入的错误,YAML
提供了结点参考(*)和散合并(<<)参考到其他
结点标签的锚点标记(&)。参考会将树状结构加入锚
点标记的内容,并可以在所有数据结构中运作,合并
叧有散列表可以使用,可以将键值自锚点标记复制到
指定的散列表中

jinja2模版简介
• jinja2 是什么
– Jinja2是基于python的模板引擎,包含 变量 和 表达
式两部分,这两者在模板求值的时候会被替换为值。
模板中还有标签,控制模板的逻辑。
• 为什么要学习 jinja2 模版
– 要使用 ansible 就要深入学习 playbook 配置及模板。
playbook 的模板使用 python 的 jinja2 模块来处理的

jinja2 模版基本语法
– 模板的表达式都是包含在分隔符 "{{}}" 内的;
– 控制语句都是包含在分隔符 "{% %}" 内的;
– 另外,模板也支持注释,都是包含在分隔符 "{# #}"
内,支持块注释。
– 调用变量
{{varname}}
– 计算
{{2+3}}
– 判断
{{1 in [1,2,3]}}

jinja2 模版控制语句
{% if name == 'aa' %}
讲故事
{% elif name == 'bb' %}
嘿嘿
{% elif name == 'cc' %}
哈哈
{% else %}
沉迷学习,无法自拔
{% endif %}

jinja2 模版控制语句
{% if name == ... ... %}
... ...
{% elif name == '曹操' %}
{% for method in [约会, 逛街, 吃饭, 看电影] %}
{{do method}}
{% endfor %}
... ...
{% endif %}

jinja2 过滤器

– 变量可以通过 过滤器 修改。过滤器不变量用管道符号
( | )分割,并且也 可以用圆括号传递可选参数。多
个过滤器可以链式调用,前一个过滤器的输出会被作
为 后一个过滤器的输入。
– 例如:
– 把一个列表用逗号连接起来: {{ list|join(', ') }}
– 过滤器这里不一一列丼,需要的可以查询在线文档
http://docs.jinkan.org/docs/jinja2/templates.html
#builtin-filters

playbook是什么
• playbook 是什么?
– playbook 是 ansible 用于配置,部署,和管理托管主
机剧本。通过 playbook 的详绅描述,执行其中的一系
列 tasks,可以让进端主机达到预期的状态。
– 也可以这么理解,playbook 字面意思,即剧本,现实
中由演员按照剧本表演,在 Ansible 中由计算机进行表
演,由计算机安装,部署应用,提供对外服务,以及组
细计算机处理各种各样的事情

为什么要使用playbook
– 执行一些简单的任务,使用ad-hoc命令可以方便的解决
问题,但是有时一个设施过于复杂,需要大量的操作时
候,执行的 ad-hoc 命令是不适吅的,这时最好使用
playbook,就像执行 shell 命令不写 shell 脚本一样,
也可以理解为批处理任务
– 使用 playbook 你可以方便的重用编写的代码,可以移
植到不同的机器上面,像函数一样,最大化的利用代码
在使用 Ansible 的过程中,你也会发现,你所处理的大
部分操作都是编写 playbook

playbook 语法格式
– playbook由 YAML 语言编写,遵循 YAML 标准
– 在同一行中,#之后的内容表示注释
– 同一个列表中的元素应该保持相同的缩进
– playbook 由一个或多个 play 组成
– play 中 hosts,variables,roles,tasks 等对象的表示
方法都是键值中间以 ": " 分隔表示
– YAML 还有一个小的怪癖. 所有的 YAML 文件开始行都
应该是 ---. 这是 YAML 格式的一部分, 表明一个文件的
开始

playbook 构成

– Target: 定义将要执行 playbook 的进程主机组
– Variable: 定义 playbook 运行时需要使用的变量
– Tasks: 定义将要在进程主机上执行的任务列表
– Handler: 定义 task 执行完成以后需要调用的任务

Playbook执行结果
• 使用 ansible-playbook 运行playbook文件,得到输
出内容为 JSON 格式。并且由不同颜色组成,便于识
别。一般而言
• 绿色代表执行成功
• ***代表系统代表系统状态发生改变
• 红色代表执行失败

第一个playbook

  • hosts: all
    remote_user: root
    tasks:
  • ping:

    第一行,表示开始

    ansible-playbook myping.yml -f 5
    – -f 并发进程数量,默认是 5
    – hosts 行的内容是一个或多个组或主机的 patterns,以
    逗号为分隔符
    – remote_user 就是账户名

第一个playbook

  • hosts: all
    remote_user: root
    tasks:
  • ping:

    第一行,表示开始

    ansible-playbook myping.yml -f 5
    – -f 并发进程数量,默认是 5
    – hosts 行的内容是一个或多个组或主机的 patterns,以
    逗号为分隔符
    – remote_user 就是账户名

续... ...
– tasks
– 每一个 play 包含了一个 task 列表(任务列表).
– 一个 task 在其所对应的所有主机上(通过 host
pattern 匹配的所有主机)执行完毕之后,下一个 task
才会执行.
– 有一点需要明白的是(很重要),在一个 play 之中,
所有 hosts 会获取相同的任务指令,这是 play 的一个
目的所在,也就是将一组选出的 hosts 映射到 task,执
行相同的操作

playbook 执行命令
– 给所有主机添加用户 plj,设置默认密码 123456
– 要求第一次登录修改密码

  • hosts: all
    remote_user: root
    tasks:
  • name: create user plj
    user: group=wheel uid=1000 name=plj
  • shell: echo 123456 | passwd --stdin plj
  • shell: chage -d 0 plj
    变量
    • 添加用户
    – 给所有主机添加用户 plj,设置默认密码 123456

– 要求第一次登录修改密码(使用变量)

  • hosts: 192.168.1.16
    remote_user: root
    vars:
    username: plj
    tasks:
  • name: create user "{{username}}"
    user: group=wheel uid=1000 name={{username}}
  • shell: echo 123456 | passwd --stdin plj
  • shell: chage -d 0 {{username}}

续... ...
– 解决密码明文问题
– user 模块的 password 为什么不能设置密码呢?
– 经过测试发现,password 是把字符串直接写入
shadow,并没有改变,而 Linux 的 shadow 密码是
经过加密的,所以不能使用
– 解决方案:
– 变量过滤器 password_hash
– {{ 'urpassword' | password_hash('sha512')}}

变量过滤器
– 给所有主机添加用户 plj,设置默认密码 123456

– 要求第一次登录修改密码(使用变量)

  • hosts: 192.168.1.16
    remote_user: root
    vars:
    username: plj
    tasks:
  • name: create user "{{username}}"
    user: group=wheel uid=1000 password={{'123456' | password_hash('sha512')}} name={{username}} #分为多行写时,值要用“”引起 如 group: "whell"
  • shell: chage -d 0 {{username}}

error
• ansible-playbook 对错误的处理
– 默认情况判断 $?,如果 值 不为 0 就停止执行
– 但某些情况我们需要忽略错误继续执行

  • hosts: 192.168.1.16
    remote_user: root
    vars:
    username: plj
    tasks:
  • name: create user "{{username}}"
    user: group=wheel uid=1000
    password={{'123456'|password_hash('sha512')}}
    name={{username}}
  • shell: setenforce 0
  • shell: chage -d 0 {{username}}

error
• 续... ...
– 我们要关闭 selinux,如果 selinux 已经是关闭的,返
回 1 ,但我们的目的就是关闭,已经关闭算错误,
这个情况我们就需要忽略错误继续运行,忽略错误有
两种方法
– 第一种方式:
shell: /usr/bin/somecommand || /bin/true
– 第二种方式:

  • name: run some command
    shell: /usr/bin/somecommand
    ignore_errors: True

完整 playbook

  • hosts: 192.168.1.16
    remote_user: root
    vars:
    username: plj
    tasks:
  • name: create user "{{username}}"
    user: group=wheel uid=1000
    password={{'123456'|password_hash('sha512')}}
    name={{username}}
  • shell: setenforce 0
    ignore_errors: true
  • shell: chage -d 0 {{username}}

handlers
• 用于当关注的资源发生变化时采取一定的操作。
• "notify" 这个action可用于在每个play的最后被触发
这样可以避免多次有改变发生时每次都执行指定的操
作取而代之仅在所有的变化发生完成后一次性地执行
指定操作。
• 在 notify 中列出的操作称为 handler 也即 notify 中
调用 handler 中定义的操作
前面我们安装了 apache,很多情况是要修改 httpd
的配置文件的,修改配置文件以后要重新载入配置文
件让服务生效
• 这时候,我们可以使用 handlers 来实现
handlers:

  • name: restart apache
    service: name=apache state=restarted

结和之前试验,完整 playbook

  • hosts: 192.168.1.16
    remote_user: root
    tasks:
  • name: config httpd.conf
    copy: src=/root/playbook/httpd.conf
    dest=/etc/httpd/conf/httpd.conf
    notify:
  • restart httpd
    handlers:
  • name: restart httpd
    service: name=httpd state=restarted

注意事项:
– notify 调用的是 handler 段 name 定义的串,必须一
致,否则达不到触发的效果
– 多个 task 触发同一个 notify 的时候,同一个服务叧会
触发一次
– notify 可以触发多个条件,在生产环境中往往涉及到
某一个配置文件的改变要重启若干服务的场景,
handler 用到这里非常适吅.
– 结吅 vars 可以写出非常普适的服务管理脚本

when

• 某些时候我们可能需要在满足特定的条件后在触发某
一项操作,或在特定的条件下织止某个行为,这个时
候我们就需要进行条件判断,when 正是解决这个问
题的最佳选择,进程中的系统变量 facts 变量作为
when 的条件,这些 facts 我们可以通过 setup 模块
查看
– when 的样例:
tashs:

  • name: somecommand
    command: somecommand
    when: expr

一个使用 when 的例子

  • name: Install VIM
    hosts: all
    tasks:
  • name: Install VIM via yum
    yum: name=vim-enhanced state=installed
    when: ansible_os_family == "RedHat"
  • name: Install VIM via apt
    apt: name=vim state=installed
    when: ansible_os_family == "Debian"

register
• register

– 有时候我们可能还需要更复杂的例子,比如判断前一
个命令的执行结果,根据结果处理后面的操作,这时
候我们就需要 register 模块来保存前一个命令的返回
状态,在后面进行调用

  • command: test command
    register: result
  • command: run command
    when: result

register
• 变量注册
– 例如我们需要判断 plj 这个用户是否存在

– 如果存在我就修改密码,如果不存在就跳过
tasks:

  • shell: id {{username}}
    register: result
  • name: change "{{username}}" password
    user: password={{'12345678'|password_hash('sha512')}}
    name={{username}}
    when: result

变量注册进阶
– 我们还可以针对运行命令结果的返回值做判定

– 当系统负载超过一定值的时候做特殊处理

  • hosts: 192.168.1.16
    remote_user: root
    tasks:
  • shell: uptime |awk '{printf("%f\n",$(NF-2))}'
    register: result
  • shell: touch /tmp/isreboot
    when: result.stdout|float > 0.5 #标准输出转化为浮点数

with_items

• with_items 是 playbook 标准循环,最常用到的就
是它,with_items 可以用于迭代一个列表或字典,
通过{{ item }}获取每次迭代的值
– 例如创建多个用户

  • hosts: 192.168.1.16
    remote_user: root
    tasks:
  • name: add users
    user: group=wheel password={{'123456' |
    password_hash('sha512')}} name={{item}}
    with_items: ["nb", "dd", "plj", "lx"]

with_items
• with_items进阶
– 为不同用户定义不同组


  • hosts: 192.168.1.16
    remote_user: root
    tasks:
  • name: add users
    user: group={{item.group}} password={{'123456' |
    password_hash('sha512')}} name={{item.name}}
    with_items:
  • {name: 'nb', group: 'root'}
  • {name: 'dd', group: 'root'}
  • {name: 'plj', group: 'wheel'}
  • {name: 'lx', group: 'wheel'}

with_nested
• 嵌套循环:


  • hosts: 192.168.1.16
    remote_user: root
    vars:
    un: [a, b, c]
    id: [1, 2, 3]
    tasks:
  • name: add users
    shell: echo {{item}}
    with_nested:
  • "{{un}}"
  • "{{id}}"

tags
• tags:给指定的任务定义一个调用标识;
• 使用格式:
– name: NAME
– module: arguments
– tags: TAG_ID
• playbook 调用方式
– -t TAGS, --tags=TAGS
– --skip-tags=SKIP_TAGS
– --start-at-task=START_AT

tags
• tags样例:
vars:
soft: httpd
tasks:

  • name: install {{soft}}
    yum: name={{soft}}
  • name: config httpd.conf
    copy: src=/root/playbook/httpd.conf
    dest=/etc/httpd/conf/httpd.conf
  • name: config services
    service: enabled=yes state=restarted name={{soft}}
    tags: restartweb
    • 调用方式
    ansible-playbook i.yml --tags=restartweb

include and roles

• 我们在编写 playbook 的时候随着项目越来越大,
playbook 也越来越复杂,修改起来也越来越麻烦。
这时候可以把一些 play、task 或 handler 放到其他
文件中,然后通过include指令包含进来是一个不错
的选择
tasks:

  • include: tasks/setup.yml
  • include: tasks/users.yml user=plj #users.yml 中可以通过
    {{ user }}不使用这些变量
    handlers:
  • include: handlers/handlers.yml

include and roles
• roles 像是加强版的 include,他可以引入一个项目
的文件和目录

• 一般所需的目录层级有
– vars 变量层
– tasks 任务层
– handlers 触发条件
– files
文件
– template 模板
– default
默认,优先级最低

include and roles
• 假如有一个play包含了一个叨 "x" 的role,则

  • hosts: host_group
    roles:
    -x
    – x/tasks/main.yml
    – x/vars/main.yml
    – x/handler/main.yml
    – x/... .../main.yml
    – 都会自劢添加进这个 play

debug

• 对于 python 语法不熟悉的同学,playbook 书写起
来容易出错,且排错困难,这里介终几种简单的排错
调试方法
– 检测语法
ansible-playbook --syntax-check playbook.yaml
– 测试运行
ansible-playbook -C playbook.yaml
– 显示收到影响到主机 --list-hosts
– 显示工作的 task --list-tasks
– 显示将要运行的 tag --list-tags

debug
• debug 模块可以在运行时输出更为详绅的信息,来
帮助我们排错,debug 使用样例:

  • hosts: 192.168.1.16
    remote_user: root
    tasks:
  • shell: uptime |awk '{printf("%f\n",$(NF-2))}'
    register: result
  • shell: touch /tmp/isreboot
    when: result.stdout|float > 0.5
  • name: Show debug info
    debug: var=result


     本文转自sweak_h 51CTO博客,原文链接:http://blog.51cto.com/13478354/2073097 ,如需转载请自行联系原作者

相关文章
|
6月前
|
Kubernetes Linux 持续交付
在 Alibaba Cloud Linux 上搭建并配置 Ansible
本场景简单介绍了在Alibaba Cloud Linux上安装并配置Ansible的方式。
|
7月前
|
Linux 网络安全 数据安全/隐私保护
在 Alibaba Cloud Linux 上配置 Ansible
本场景是在 Alibaba Cloud Linux 上配置 Ansible
151 0
|
弹性计算 Shell 应用服务中间件
在 Cloud Shell 中使用 Ansible 编排配置阿里云资源
简介 Ansible 是一个开源的用于自动执行资源的配置管理和应用程序部署产品。云命令行 Cloud Shell 已经为我们安装、配置完成 Ansible v2.8.5,我们可以直接使用。同时阿里云提供了 Ansible 的 阿里云模块。
1699 0
|
弹性计算 负载均衡 API
Terraform/Ansible on Cloud--基础设施和应用管理实践
在由阿里云研发协同RDC以及阿里云云栖社区联合举办的首届阿里巴巴研发效能嘉年华上,来自阿里云飞天八部企业服务云应用服务团队的高级研发工程师箫竹为大家分享了基础设施和应用管理实践,主要介绍了Terraform和Ansible两大自动化基础设施和应用管理工具,并结合实际应用场景介绍了如何在云上使用Terraform和Ansible工具提升基础设施和应用管理的效能。
11251 0
|
6月前
|
运维 Shell Linux
Ansible自动化运维工具之常用模块使用实战(5)
Ansible自动化运维工具之常用模块使用实战(5)
|
8月前
|
网络协议 网络安全
Ansible模块介绍——防火墙模块
Ansible模块介绍——防火墙模块
143 0
|
6月前
|
运维 Linux
Ansible自动化运维工具之常用模块使用实战(6)
Ansible自动化运维工具之常用模块使用实战(6)
|
9月前
|
Shell
ansible模块大全上【建议收藏】
ansible模块大全上【建议收藏】
104 0
ansible模块大全上【建议收藏】
|
5月前
|
网络安全 数据安全/隐私保护
ansible的get_url模块
ansible的get_url模块
|
5月前
|
存储 Linux Python
ansible手动添加模块
ansible手动添加模块
47 0