Ansible自动化运维介绍

一、Ansible介绍

Ansible 简单的说是一个配置管理系统(configuration management system)。你只需要可以使用 ssh 访问你的服务器或设备就行。它也不同于其他工具,因为它使用推送的方式,而不是像 puppet 等 那样使用拉取安装agent的方式。你可以将代码部署到任意数量的服务器上!

1.1、Ansible能做什么

ansible可以帮助我们完成一些批量任务,或者完成一些需要经常重复的工作。

  • 比如:同时在100台服务器上安装nginx服务,并在安装后启动它们。
  • 比如:将某个文件一次性拷贝到100台服务器上。
  • 比如:每当有新服务器加入工作环境时,你都要为新服务器部署某个服务,也就是说你需要经常重复的完成相同的工作。

这些场景中我们都可以使用到ansible。

1.2、Ansible特性

  • 模块化:调用特定的模块,完成特定任务
  • 有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块
  • 支持自定义模块
  • 基于Python语言实现
  • 部署简单,基于python和SSH(默认已安装),agentless
  • 安全,基于OpenSSH
  • 支持playbook编排任务
  • 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
  • 无需代理不依赖PKI(无需ssl)
  • 可使用任何编程语言写模块
  • YAML格式,编排任务,支持丰富的数据结构
  • 较强大的多层解决方案

1.3、Ansible架构

clip_image0026

Ansible核心组件说明:

AnsibleAnsible的核心程序
Host Lnventory记录了每一个由Ansible管理的主机信息,信息包括ssh端口,root帐号密码,ip地址等等。可以通过file来加载,可以通过CMDB加载
PlaybooksYAML格式文件,多个任务定义在一个文件中,使用时可以统一调用,“剧本”用来定义那些主机需要调用那些模块来完成的功能.
Core ModulesAnsible执行任何管理任务都不是由Ansible自己完成,而是由核心模块完成;Ansible管理主机之前,先调用core Modules中的模块,然后指明管理Host Lnventory中的主机,就可以完成管理主机。
Custom Modules自定义模块,完成Ansible核心模块无法完成的功能,此模块支持任何语言编写。
Connection Plugins连接插件,Ansible和Host通信使用

二、配置elep源

2.1、RHEL/Centos6

# yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm

2.2、RHEL/Centos7

# yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

三、安装ansible

# yum install ansible

补充、用户密码、密钥登录

补充1、用户密码登录

1.1、安装ssh_pass包

Ubuntu安装方式 apt-get install sshpass

Centos 安装方式 yum install sshpass

1.2、ansible配置文件修改

ansible.cfg配置文件修改

# vim /etc/ansible/ansible.cfg

##资产信息列表文件

inventory = /etc/ansible/hosts

##允许并发的数量为5个并发,也就是可以可以同时进行5个任务

forks = 5

##默认为root用户执行

sudo_user = root

##默认端口为22端口

remote_port = 22

##取消注释以禁用SSH密钥主机检查

host_key_checking = False

##超时时间

timeout = 10

##日志存放时间

log_path = /var/log/ansible.log

##私钥的目录

#private_key_file = /path/to/file

hosts资产信息列表文件修改

# cat /etc/ansible/hosts

[aliyun]

106.14.220.53 ansible_ssh_user=root ansible_ssh_pass='XUchangming1993285'

1.3、测试登录

# ansible aliyun -a 'ls /etc/ansible'

106.14.220.53 | SUCCESS | rc=0 >>

ansible.cfg

ansible.cfg.bak

hosts

hosts.bak

roles

[root@iZuf6e15robw9amyc9qt1lZ ansible]#

补充2、密钥登录

2.1、生成并配置ssh公钥、私钥

公钥文件为公钥id_rsa.pub,私钥文件为id_rsa

clip_image0046

使用ssh-copy-id IP命令把公钥发送到指定主机

clip_image0066

测试使用ssh登录远程主机看是否能登录

clip_image0086

2.2、配置ansible的hosts资产列表文件

hosts资产信息列表文件修改

# cat /etc/ansible/hosts

[aliyun]

106.14.220.53 ansible_ssh_user=root ansible_ssh_key_file=/root/.ssh/id_rsa

四、ansible命令

4.1查看ansible帮助文档

# ansible –h

4.2、格式选项

ansible <host-pattern> [options]

options选项:

选项

注释

实例

-u

登录远程主机用户名,默认为root (可省略)

-i

指定用户清单,对那些清单进行操作,默认为(/etc/ansible/hosts)文件中的主机 (可省略)

-m

指定模块的名称

-a

指定模块的参数,具体执行的指令

-k

提示输入远程主机的密码

-C

只是测试一下会改变什么内容,不会真正去执行;相反,试图预测一些可能发生的变化

--list-hosts

输出匹配主机的列表

ansible all --list-hosts

--version

显示程序版本号

-v

输出执行的详细信息,使用-vvv获得更多,-vvvv 启用连接调试

五、添加远程主机

添加远程主机的配置文件为/etc/ansible/hosts文件。

添加一个组名称为aliyun,添加阿里云服务器IP,如下:

# vim /etc/ansible/hosts

[aliyun]

106.14.220.53

六、第一个列子

# ansible -i /etc/ansible/hosts aliyun -u root -m command -a 'ls /home' -k

SSH password:

106.14.220.53 | SUCCESS | rc=0 >>

backup.sh

www

xuchangming.txt

七、ansible常用模块

7.1、使用ansible-doc –l查看本身自带的模块

7.2、setup模块

Setup模块主要用卡查看远程主机的一些基本信息

# ansible -k aliyun -m setup

clip_image0106

7.3、ping模块

主要用于ping主机是否能ping通网络,如果主机在线则返回pong

# ansible -k aliyun -m ping

clip_image0126

7.4、file文件模块

file模块主要用于远程主机上的文件操作,file模块包含如下选项:
– force:需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no

– group:定义文件/目录的属组
– mode:定义文件/目录的权限
– owner:定义文件/目录的属主
– path:必选项,定义文件/目录的路径
– recurse:递归的设置文件的属性,只对目录有效
– src:要被链接的源文件的路径,只应用于state=link的情况
– dest:被链接到的路径,只应用于state=link的情况
– state:
   directory:如果目录不存在,创建目录
   file:即使文件不存在,也不会被创建
   link:创建软链接
   hard:创建硬链接
   touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
   absent:删除目录、文件或者取消链接文件

7.4.1、创建软连接

# ansible -k aliyun -m file -a "src=/var/DZWeb dest=/mnt/DZWeb state=link"

clip_image0146

7.4.2、删除文件

# ansible -k aliyun -m file -a "path=/mnt/DZWeb state=absent"

clip_image0166

7.4.3、创建文件

# ansible -k aliyun -m file -a "path=/mnt/zhangfile state=touch"

clip_image0186

7.4.4、创建目录
7.4.4.1、创建默认权限,默认属组属主的目录

# ansible -k aliyun -m file -a 'path=/mnt/zhangfile state=directory'

clip_image0206

7.4.4.2、创建权限为777,属组属主为root的目录

# ansible -k aliyun -m file -a 'path=/mnt/namedir state=directory group=root owner=root mode=777'

clip_image0226

7.5、copy复制模块

复制文件到远程主机,copy模块包含如下选项:

· backup:在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no

· content:用于替代"src",可以直接设定指定文件的值

· dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录

· directory_mode:递归的设定目录的权限,默认为系统默认权限

· -group:定义文件/目录的属组
– mode:定义文件/目录的权限
– owner:定义文件/目录的属主

· force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes

· others:所有的file模块里的选项都可以在这里使用

· src:要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用"/"来结尾,则只复制目录里的内容,如果没有使用"/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync。

· validate :The validation command to run before copying into place. The path to the file to validate is passed in via '%s' which must be present as in the visudo example below.

· clip_image0246

7.5.1、复制文件

# ansible aliyun -k -m copy -a 'src=/root/buffer.sh dest=/mnt/buffer.sh'

clip_image0266

7.5.2、复制文件并修改属组属主和权限

# ansible aliyun -k -m copy -a 'src=/root/buffer.sh dest=/mnt/buffer group=zabbix owner=zabbix mode=777'

clip_image0286

7.5.3、复制相同文件时,覆盖时并备份

目标主机的源文件

# ansible aliyun -k -m command -a 'cat /mnt/buffer.sh'

clip_image0306

当前主机更改后的源文件

# ansible aliyun -k -m command -a 'cat /root/buffer.sh'

clip_image0326

通过Ansible复制文件到目标主机

# ansible aliyun -k -m copy -a 'src=/root/buffer.sh dest=/mnt/buffer.sh group=zabbix owner=zabbix mode=777 backup=yes'

clip_image0346

查看目标主机的文件目录和复制后的文件及备份后的文件内容

clip_image0366clip_image0386

7.6、command命令模块

功能:命令模块,默认模块,用于在远程主机执行命令,缺点:运行的命令中无法使用变量,管道。变量和操作符号 "<", ">", "|", ";" and "&" 不能正常工作。如果需要使用,请使用 shell 模块。省略不写模块信息名称则默认为command模块

action: command

chdir # 在执行命令之前,先切换到该目录

creates # 一个文件名,当这个文件存在,则该命令不执行

executable # 切换shell来执行命令,该执行路径必须是一个绝对路径

free_form= #要执行的Linux指令,一般使用Ansible的-a参数代替。

removes #一个文件名,这个文件不存在,则该命令不执行

7.6.1、creates使用,当文件存在则该命令不执行,不存在则执行

# ansible aliyun -k -m command -a 'creates=/mnt/aaa.jpg ls /mnt'

clip_image0406

7.6.2、chdir在执行命令之前,先切换到该目录

ansible aliyun -k -m command -a 'ls /mnt/zhang'

ansible -k aliyun -m command -a 'chdir=/mnt/zhang/ ls'

以上两条命令是等价的,第一条是通过绝对路径进行查询,第二条命令是先进入目录在进行查询相当于cd /mnt/zhang 和 ls两条命令的结合体

clip_image0426

7.7、shell模块

功能:在远程节点上执行命令。

与command模快使用一致,但是,变量 和操作符号 "<", ">", "|", ";" and "&" 能正常工作。示例:

ansible test -m shell -a "somescript.sh >> somelog.txt"

我这里使用通配符,使用command模块是不行的。

# ansible cluster1 -m command -a 'ls -d /usr/local/tomcat0[1-3]'

10.0.0.4 | FAILED | rc=2 >>

ls: cannot access /usr/local/tomcat0[1-3]: No such file or directorynon-zero return code

10.0.0.9 | FAILED | rc=2 >>

ls: cannot access /usr/local/tomcat0[1-3]: No such file or directorynon-zero return code

改成shell模块就可以。

# ansible cluster1 -m shell -a 'ls -d /usr/local/tomcat0[1-3]'

10.0.0.4 | SUCCESS | rc=0 >>

/usr/local/tomcat01

/usr/local/tomcat02

/usr/local/tomcat03

10.0.0.9 | SUCCESS | rc=0 >>

/usr/local/tomcat01

/usr/local/tomcat02

/usr/local/tomcat03

7.8、service管理服务模块

用于管理服务
该模块包含如下选项:

· arguments:给命令行提供一些选项

· name:必选项,服务名称

· state:对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)

· sleep:如果执行了restarted,在则stop和start之间沉睡几秒钟

· enabled:是否开机启动 yes|no

· pattern:定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行

· runlevel:运行级别

7.8.1、启动vsftpd

# ansible -k aliyun -m service -a 'name=vsftpd state=started'

clip_image0446

7.8.2、停止vsftpd

# ansible -k aliyun -m service -a 'name=vsftpd state=stopped'

clip_image0466

7.9、cron计划任务模块

用于管理计划任务

包含如下选项:

    backup:对远程主机上的原任务计划内容修改之前做备份

    cron_file:如果指定该选项,则用该文件替换远程主机上的cron.d目录下的用户的任务计划

    day:日(1-31,*,*/2,……)

    hour:小时(0-23,*,*/2,……)

    minute:分钟(0-59,*,*/2,……)

    month:月(1-12,*,*/2,……)

    weekday:周(0-7,*,……)

    job:要执行的任务,依赖于state=present

    name:该任务的描述

    special_time:指定什么时候执行,参数:reboot,yearly,annually,monthly,weekly,daily,hourly

    state:确认该任务计划是创建还是删除。默认为创建,删除为state=absent

    user:以哪个用户的身份执行

7.9.1、添加计划任务

添加计划任务每天的2点执行ls命令,注释为ls /mnt

# ansible -k aliyun -m cron -a 'name="ls /mnt" hour=2 user=root job="sbin/ls" '

clip_image0486

查看计划任务

[root@iZuf6e15robw9amyc9qt1lZ zhang]# ansible -k aliyun -m command -a 'crontab -l'

clip_image0506

7.9.2、删除计划任务

# ansible -k aliyun -m cron -a 'name="ls /mnt" hour=2 user=root job="sbin/ls" state=absent '

clip_image0526

查看是否被删掉了

# ansible -k aliyun -m command -a 'crontab -l'

clip_image0546

8.0、filesystem模块

在块设备上创建文件系统

选项:

    dev:目标块设备

   force:在一个已有文件系统的设备上强制创建

    fstype:文件系统的类型

   opts:传递给mkfs命令的选项

8.1、yum模块

使用yum包管理器来管理软件包

选项:

    config_file:yum的配置文件

    disable_gpg_check:关闭gpg_check

    disablerepo:不启用某个源

    enablerepo:启用某个源

    list

    name:要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径

    state:状态(absent, installed, latest, present, removed)

8.1.1、yum安装软件

# ansible -k aliyun -m yum -a 'name=ftp state=installed'

clip_image0566

8.1.2、使用yum安装软件包组

#  ansible test -m yum -a 'name="@Development tools" state=present'

8.1.3、安装网络rpm包

# ansible test -m yum -a 'name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present'

8.2、user用户管理模块

管理用户

createhome: 是否创建家目录

home: 家目录

groups: 组

uid: uid

password: 登录密码

name: 用户名称

      system:

remove: 配合state=absent使用,删除用户的家目录->remove=yes

state: present创建,absent删除

shell: 用户的shell设定

需要特别说明的是,password后面指定的密码不能是明文,后面这一串密码会被直接传送到被管理主机的/etc/shadow文件中,而登陆的时候输入的密码会被hash加密以后再去与/etc/shadow中存放的密码去做对比,会出现不一致的现象。所以需要先将密码字符串进行加密处理:openssl passwd -salt -1 "123456",然后将得到的字符串放到password中即可。

8.2.1、创建用户

# ansible -k aliyun -m user -a 'createhome=yes home=/home/zhang password=zhang name=zhang state=present shell=/bin/bash'

clip_image0586

clip_image0606

8.2.2、删除用户

# ansible -k aliyun -m user -a 'remove=yes state=absent name=zhang' clip_image0626

8.3、synchronize同步文件模块

使用sync同步文件

src: 源,同步的数据源

dest=: 目标地址

dest_port: 目标接受的端口,ansible配置文件中的ansible_ssh_port变量优先级高于该dest_port变量

group: 文件属组

owner: 文件属主

mode:(push, pull): 模式,rsync同步的方式PUSH / PULL,默认都是推送push,如果你在使用拉取pull功能的时候,可以参考如下来实现mode=pull更改推送模式为拉取模式

dirs: 以非递归的方式传输目录,默认为no,即进行目录递归

archive: 是否采用归档模式同步,即以源文件相同属性同步到目标地址

checksum: 是否校验

compress: 开启压缩,默认为开启

copy_links: 同步的时候是否复制连接

delete: 删除源中没有而目标存在的文件(即以推送方为主)

existing_only: skip createing new files on receiver

links

recursive: 是否递归yes / no

rsync_path: 服务的路径,指定rsync命令在远程服务器上运行。这个参考rsync命令的—sync-path参数,--rsync-path=PATH指定远程服务器上rsync命令所在的路径信息

times: 保持时间属性

8.3.1、同步文件

# ansible -k aliyun -m synchronize -a 'src=/opt/zhang dest=/root'

clip_image0646

8.3.2、同步目录

# ansible -k aliyun -m synchronize -a 'src=/opt/j dest=/root/ mode=push rsync_path=/usr/bin/rsync'

clip_image0666

8.4、mount分区挂载模块

配置挂载点

选项:

    dump

    fstype:必选项,挂载文件的类型

    name:必选项,挂载点

    opts:传递给mount命令的参数

    passno

    src:必选项,要挂载的文件

    state:必选项

            present:只处理fstab中的配置

            absent:删除挂载点

            mounted:自动创建挂载点并挂载之

            umounted:卸载

示例:

    name=/mnt/dvd src=/dev/sr0 fstype=iso9660 opts=ro state=present

    name=/srv/disk src='LABEL=SOME_LABEL' state=present

    name=/home src='UUID=b3e48f45-f933-4c8e-a700-22a159ec9077' opts=noatime state=present

    ansible test -a 'dd if=/dev/zero of=/disk.img bs=4k count=1024'

    ansible test -a 'losetup /dev/loop0 /disk.img'

    ansible test -m filesystem 'fstype=ext4 force=yes opts=-F dev=/dev/loop0'

    ansible test -m mount 'name=/mnt src=/dev/loop0 fstype=ext4 state=mounted opts=rw'

8.5、get_url下载模块

get_url模块主要用于下载,类似于 shell 命令 curl 或者 wget

参数

必填

默认值

注解

url

yes

url地址

dest

no

下载存放的路径

8.5.1、下载网络rpm包并保存在/opt目录下

# ansible -k aliyun -m get_url -a 'url=http://mirror.centos.org/centos/7/os/x86_64/Packages/apr-1.4.8-3.el7_4.1.x86_64.rpm dest=/opt'

clip_image0686

八、Playbook

8.1、Playbooks 简介

Playbooks 与 adhoc 相比,是一种完全不同的运用 ansible 的方式,是非常之强大的.

简单来说,playbooks 是一种简单的配置管理系统与多机器部署系统的基础.与现有的其他系统有不同之处,且非常适合于复杂应用的部署.

Playbooks 可用于声明配置,更强大的地方在于,在 playbooks 中可以编排有序的执行过程,甚至于做到在多组机器间,来回有序的执行特别指定的步骤.并且可以同步或异步的发起任务.

我们使用 adhoc 时,主要是使用 /usr/bin/ansible 程序执行任务.而使用 playbooks 时,更多是将之放入源码控制之中,用之推送你的配置或是用于确认你的远程系统的配置是否符合配置规范.

clip_image0706

8.2、playbook的组成

Paly:定义的是主机的角色

Task:定义的是具体执行的任务

Playboot:由一个或多个play组成,一个play可以包含多个task

clip_image0726

8.3、playbook的优势

1、功能比abhoc更全

2、控制依赖关系比较好

3、展现更直观

4、持久使用

8.4、playbook的配置语法

8.4.1、基本使用
1、playbook基础使用

Playbook的语法格式:ansible-playbook [options] playbook.yml [playbook2 ...]

Options参数:

l -u REMOTE_USER, --user=REMOTE_USER # ssh 连接的用户名

l -k, --ask-pass #ssh登录认证密码

l -s, --sudo #sudo 到root用户,相当于Linux系统下的sudo命令

l -U SUDO_USER, --sudo-user=SUDO_USER #sudo 到对应的用户

l -K, --ask-sudo-pass #用户的密码(—sudo时使用)

l -T TIMEOUT, --timeout=TIMEOUT # ssh 连接超时,默认 10 秒

l -C, --check # 指定该参数后,执行 playbook 文件不会真正去执行,而是模拟执行一遍,然后输出本次执行会对远程主机造成的修改

l -e EXTRA_VARS, --extra-vars=EXTRA_VARS # 设置额外的变量如:key=value 形式 或者 YAML or JSON,以空格分隔变量,或用多个-e

l -f FORKS, --forks=FORKS # 进程并发处理,默认 5

l -i INVENTORY, --inventory-file=INVENTORY # 指定 hosts 文件路径,默认 default=/etc/ansible/hosts

l -l SUBSET, --limit=SUBSET #指定一个 pattern,对- hosts:匹配到的主机再过滤一次

l --list-hosts #只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook

l --list-tasks #列出该 playbook 中会被执行的 task

l --private-key=PRIVATE_KEY_FILE # 私钥路径

l --step # 同一时间只执行一个 task,每个 task 执行前都会提示确认一遍

l --syntax-check # 只检测 playbook 文件语法是否有问题,不会执行该 playbook

l -t TAGS, --tags=TAGS #当 play 和 task 的 tag 为该参数指定的值时才执行,多个 tag 以逗号分隔

l --skip-tags=SKIP_TAGS #当 play 和 task 的 tag 不匹配该参数指定的值时,才执行

l -v, --verbose #输出更详细的执行过程信息,-vvv可得到所有执行过程信息。

2、使用场景

Ø Playbook的配置

演示列子:

[root@iZuf6e15robw9amyc9qt1lZ ansible]# cat ce.yml

---

- hosts: 106.14.220.53

remote_user: root

vars:

touch_file: zhang.file

tasks:

- name: touch file

# shell: echo hello world `date` by `hostname` >/tmp/hello.log

shell: "touch /opt/{{touch_file}}"clip_image0746

功能为:在192.168.1.101主机上在tmp目录下创建一个imoocc.file文件

Ø Playbook命令的执行

# ansible-playbook -i /etc/ansible/hosts --list-hosts ./f1.yml

# ansible-playbook ./f1.yml

Ø 执行结果返回

clip_image0765

#ansible-playbook -i /etc/ansible/hosts --list-hosts ./f1.yml结果为:

clip_image0785

# ansible-playbook ./f1.yml结果为:

clip_image0805

8.4.2、yaml语法和变量
8.4.2.1、yaml语法
1、yaml语法注意项

l 大小写敏感

l 使用缩进表示层级关系(只能使用空格不能使用tab)

l yaml文件以“- - -”作为文档的开始

2、支持的数据结构

数据结构可以为字典,列表,纯量三种

字典 列表 纯量:数字、布尔、字符串

{name:jeson} -Aple

-Orange

-strawberry

-Mango

3、yaml变量的应用

myname:jeson

name:“{{myname}}”

8.4.2.2、playbook变量

变量的定义

l playbook的yaml文件中定义变量赋值

列子:

使用# ansible-playbook ./ce.yml命令执行即可

clip_image0815

l --extra-vars执行参数付给变量

使用--extra-vars参数进行赋值变量

列子:

clip_image0835

clip_image0855

l 在文件中定义变量

文件中定义变量是指在hosts资产列表文件中添加变量

clip_image0875

l 注册变量

register关键字可以存储指定命令的输出结果到一个自定义的变量中

-name:get time

command:date

register:date_output

clip_image0895

8.4.3、基本语句

实例请查看本文后面的《playbook基本语句实例

1、条件语句

when语句

列子:

clip_image0915

2、循环语句

循环类型

关键字

标准循环

with_items

嵌套循环

with_nested

遍历字典

with_dict

并行遍历列表

with_together

遍历列表和索引

with_indexed_items

遍历文件列表的内容

with_file

遍历目录文件

with_fileglob

重试循环

until

查找第一个匹配文件

with_first_found

随机选择

with_random_choice

在序列中循环

with_sequence

3、条件循环语句复用

8.4.4、异常处理和相关操作
1、异常处理

Ø 忽略错误

默认会检查命令和模块的返回状态,遇到错误就中断playbook的执行

加入参数:ignore_errors:yes 进行忽略错误

例子:

说明:/bin/false返回状态为1,即错误信息,touch文件命令正常工作

clip_image0935

执行命令之后报错

clip_image0955

添加忽略错误信息并执行clip_image0975

clip_image0995

Ø 自定义错误

Ø 自定义change状态

例子:

不添加changed标签的状态

clip_image1015

clip_image1035

添加运行changed标签的结果

clip_image1055 clip_image1075

2、tags标签处理

意义:通过tags和任务对象进行捆绑,控制部分或者指定的task执行

Ø 打标签

对一个对象打一个标签

对一个对象打多个标签

打标签的对象包括:单个task任务、include对象、roles对象等

例子:

clip_image1095

Ø 标签的使用

-t:执行指定的tag标签任务

--skip-tags:执行—skip-tags之外的标签任务

例子:

只执行cfile1标签,执行结果如下

clip_image1115

只执行除了cfile1之外的标签,结果如下

clip_image1135

8.4.5、roles角色和场景演练
1、使用roles
a) 、include的用法

include_tasks/include:动态的包含tasks任务列表执行clip_image1155

实例:

添加touchf1.yml文件

clip_image1175

添加touchf2.yml文件

clip_image1195

添加include文件

clip_image1215

执行结果即可

b) 、为什么需要使用到roles
c) 、官方建议的剧本结构
d) 、剧本涉及的思路
2、场景演练

错误解决

1、在第一次使用时,报下面错误

[root@localhost ~]# ansible -k aliyun -m command -a 'ls'

SSH password:

192.168.1.101 | FAILED | rc=-1 >>

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.

[root@localhost ~]#

解决方法:使用ssh 手动连接下就可以

playbook基本语句实例

种类一、标准循环
添加多个用户

- name: add several users

user: name={{ item }} state=present groups=wheel

with_items:

- testuser1

- testuser2

添加多个用户,并将用户加入不同的组内。

- name: add several users

user: name={{ item.name }} state=present groups={{ item.groups }}

with_items:

- { name: 'testuser1', groups: 'wheel' }

- { name: 'testuser2', groups: 'root' }

种类二、锚点嵌套循环
分别给用户授予3个数据库的所有权限

- name: give users access to multiple databases

mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo

with_nested:

- [ 'alice', 'bob' ]

- [ 'clientdb', 'employeedb', 'providerdb' ]

种类三、锚点遍历字典
输出用户的姓名和电话

tasks:

- name: Print phone records

debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"

with_dict: {'alice':{'name':'Alice Appleworth', 'telephone':'123-456-789'},'bob':{'name':'Bob Bananarama', 'telephone':'987-654-3210'} }

种类四、锚点并行遍历列表

tasks:

- debug: "msg={{ item.0 }} and {{ item.1 }}"

with_together:

- [ 'a', 'b', 'c', 'd','e' ]

- [ 1, 2, 3, 4 ]

如果列表数目不匹配,用None补全

种类五、锚点遍历列表和索引

- name: indexed loop demo

debug: "msg='at array position {{ item.0 }} there is a value {{ item.1 }}'"

with_indexed_items: [1,2,3,4]

item.0 为索引,item.1为值

种类六、锚点遍历文件列表的内容

---

- hosts: all

tasks:

- debug: "msg={{ item }}"

with_file:

- first_example_file

- second_example_file

种类七、锚点遍历目录文件
with_fileglob匹配单个目录中的所有文件,非递归匹配模式。

---

- hosts: all

tasks:

- file: dest=/etc/fooapp state=directory

- copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600

with_fileglob:

- /playbooks/files/fooapp/*

当在role中使用with_fileglob的相对路径时,Ansible解析相对于roles/<rolename>/files目录的路径。

种类八、锚点遍历ini文件
lookup.ini
[section1]
value1=section1/value1
value2=section1/value2

[section2]
value1=section2/value1
value2=section2/value2

- debug: msg="{{ item }}"

with_ini: value[1-2] section=section1 file=lookup.ini re=true

获取section1 里的value1和value2的值

种类九、锚点重试循环 until

- action: shell /usr/bin/foo

register: result

until: result.stdout.find("all systems go") != -1

retries: 5

delay: 10

"重试次数retries" 的默认值为3,"delay"为5。

锚点查找第一个匹配文件

tasks:

- debug: "msg={{ item }}"

with_first_found:

- "/tmp/a"

- "/tmp/b"

- "/tmp/default.conf"

依次寻找列表中的文件,找到就返回。如果列表中的文件都找不到,任务会报错。

种类十、锚点随机选择with_random_choice
随机选择列表中得一个值

- debug: msg={{ item }}

with_random_choice:

- "go through the door"

- "drink from the goblet"

- "press the red button"

- "do nothing"

循环程序的结果
tasks:

· debug: "msg={{ item }}"
with_lines: ps aux
种类十一、锚点循环子元素
定义好变量

#varfile

---

users:

- name: alice

authorized:

- /tmp/alice/onekey.pub

- /tmp/alice/twokey.pub

mysql:

password: mysql-password

hosts:

- "%"

- "127.0.0.1"

- "::1"

- "localhost"

privs:

- "*.*:SELECT"

- "DB1.*:ALL"

- name: bob

authorized:

- /tmp/bob/id_rsa.pub

mysql:

password: other-mysql-password

hosts:

- "db1"

privs:

- "*.*:SELECT"

- "DB2.*:ALL"

---

- hosts: web

vars_files: varfile

tasks:

- user: name={{ item.name }} state=present generate_ssh_key=yes

with_items: "{{ users }}"

- authorized_key: "user={{ item.0.name }} key='{{ lookup('file', item.1) }}'"

with_subelements:

- "{{ users }}"

- authorized

- name: Setup MySQL users

mysql_user: name={{ item.0.name }} password={{ item.0.mysql.password }} host={{ item.1 }} priv={{ item.0.mysql.privs | join('/') }}

with_subelements:

- "{{ users }}"

- mysql.hosts

{{ lookup('file', item.1) }} 是查看item.1文件的内容

with_subelements 遍历哈希列表,然后遍历列表中的给定(嵌套)的键。

种类十二、锚点在序列中循环with_sequence
with_sequence以递增的数字顺序生成项序列。 您可以指定开始,结束和可选步骤值。 参数应在key = value对中指定。 'format'是一个printf风格字符串。

数字值可以以十进制,十六进制(0x3f8)或八进制(0600)指定。 不支持负数。

---

- hosts: all

tasks:

# 创建组

- group: name=evens state=present

- group: name=odds state=present

# 创建格式为testuser%02x 的0-32 序列的用户

- user: name={{ item }} state=present groups=evens

with_sequence: start=0 end=32 format=testuser%02x

# 创建4-16之间得偶数命名的文件

- file: dest=/var/stuff/{{ item }} state=directory

with_sequence: start=4 end=16 stride=2

# 简单实用序列的方法:创建4 个用户组分表是组group1 group2 group3 group4

- group: name=group{{ item }} state=present

with_sequence: count=4

种类十三、锚点随机选择with_random_choice
随机选择列表中得一个值

- debug: msg={{ item }}

with_random_choice:

- "go through the door"

- "drink from the goblet"

- "press the red button"

- "do nothing"

合并列表

安装所有列表中的软件

- name: flattened loop demo

yum: name={{ item }} state=installed

with_flattened:

- [ 'foo-package', 'bar-package' ]

- [ ['one-package', 'two-package' ]]

- [ ['red-package'], ['blue-package']]

注册变量使用循环

- shell: echo "{{ item }}"

with_items:

- one

- two

register: echo

- name: Fail if return code is not 0

fail:

msg: "The command ({{ item.cmd }}) did not have a 0 return code"

when: item.rc != 0

with_items: "{{ echo.results }}"

循环主机清单

输出所有主机清单里的主机

- debug: msg={{ item }}

with_items: "{{ groups['all'] }}"

输出所有执行的主机

- debug: msg={{ item }}

with_items: play_hosts

输出所有主机清单里的主机

· debug: msg={{ item }}
with_inventory_hostnames: all

输出主机清单中不在www中的所有主机

· debug: msg={{ item }}
with_inventory_hostnames: all:!www
改变循环的变量项

# main.yml

- include: inner.yml

with_items:

- 1

- 2

- 3

loop_control:

loop_var: outer_item

# inner.yml

- debug: msg="outer item={{ outer_item }} inner item={{ item }}"

with_items:

- a

- b

- c

猜你喜欢

转载自blog.51cto.com/bosszhang/2284765