一篇不错的ansible入门文章.

1,105 阅读22分钟
原文链接: www.vtlab.io

在运维工作中,学会使用几个配置管理工具对效率的提高是很有帮助的,甚至更多场景中,没有这些工具,会寸步难行。
这里,先介绍一款轻量级的配置管理工具——Ansible,作为开胃菜。

Ansible的特点

  1. 自动化引擎,可以实现配置管理、应用部署、服务编排 及其他各种IT需求
  2. 依赖 Jinja2、paramiko、PyYAML python库
  3. 安装部署简单:只需在主控端部署Ansible环境
  4. 基于SSH进行配置管理,充分利用现成的机制
  5. 不需要守护进程,维护简单、系统更加安全可靠
  6. 简单易用
  7. 功能强大:通过模块实现各种功能
  8. 设计优秀,便于分享。
  9. 对云计算和大数据平台都有很好的支持。包含了大量与云服务、AWS、OpenStack、Docker等相关的模块。

以上这些特点,基本涵盖了自动化运维的方方面面,并且易上手,不仅适合作为自动化工具使用,也可以学习到不错的自动化理念,对自研类似功能的工具也大有裨益。

Ansible安装

接下来我们进行Ansible的安装。
ansible使用python语言开发,可以直接使用pip安装:

# pip install ansible

也可以使用yum(Redhat、CentOS)和apt-get(Ubuntu、Debian)包管理工具进行安装:

# yum -y install ansible

此命令会安装:
1. ansible:ansible主命令
2. ansible-doc:获取ansible各模块文档
3. ansible-playbook:执行playbook时的命令
4. ansible-vault:对敏感信息进行加密,创建加密文件等
5. ansible-console:交互工具,可以像使用Shell一样使用ansible的内置命令
6. ansible-galaxy:下载和共享role
7. ansible-pull:ansible的pull工作模式,默认是push模式。

Ansible用法

在Ansible中,用户通过Ansible编排引擎管理主机。其中,主机可以通过配置文件配置、调用云计算接口获取、或者访问CMDB中的数据库获取。今天我介绍最简单的获取方式,Inventory方式,即在配置文件中定义目标管理主机。
Ansible的编排引擎由Inventory、API、Modules(模块)、Plugins 组成。
Ansible的典型用法:工程师将需要在远程主机上执行的操作写在Ansible Playbook中,然后使用Ansible执行Playbook中的操作。 通过配置文件设置目标管理主机

# vim /etc/ansible/hosts
[vtlab]
10.0.0.31 ansible_user = wt ansible_port = 11111
vtlab02
# vim /etc/ansible/ansible.cfg 
[defaults]
remote_user = wt
remote_port = 22
ansible_ssh_pass=password
ansible_ssh_privare_key_file=/PATH
host_key_checking = False

上面的示例我们定义了两个目标管理主机,分别是10.0.0.31和vtlab02,并且指定了用户名和ssh端口,通过简单的示例,可以看出ansible对主机及参数的定义还是比较灵活的,既有全局定义,也可局部定义。局部定义变量参数的优先级大于全局。
执行下列命令验证ansible配置是否成功

# ansible vtlab -m ping 
vtlab02 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
10.0.0.31 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

对Ansible来说,返回原谅色的输出,说明操作成功。

更多配置及用法

Inventory管理:

在Ansible中,将可管理的服务器集合称为Inventory。因此,对Inventory管理便是对目标服务器管理。Inventory的hosts文件位置:
1. 默认读取 /etc/ansible/hosts文件;
2. 通过命令行参数-i指定hosts文件;
3. 通过ansible.cfg文件中的inventory选项指定hosts文件:

vim /etc/ansible/hosts
[web]
vtweb[01:05].vtlab.io
[db]
db1.vtlab.io
db2.vtlab.io
[common:children]
web
db

以上实例中,我们配置了web、db以及名为common:children的三个组。web和db比较直观。
Ansible通过在组名后面加上”children”的方式表明这个组下面包含的是其他组,而不是普通的服务器地址。
除了通过组名称来引用hosts文件中定义的主机以外,Ansible还支持通配符、正则表达式等更加灵活的方式来匹配服务器。

Ansible命令语法

ansible <pattern_goes_here> -m <module_name> -a <arguments>

Ansible匹配规则:

Ansible匹配服务器时,可以是组名匹配,也可以是模式匹配:

# ansible web -m service -a 'name=httpd state=restarted'
# ansible vtweb.vtlab.io -m service -a "name=httpd state=restarted"
  1. 当同时对多个组中的成员进行操作时,可以用”:”对组名进行分割,例如:
# ansible web:db --list-hosts
  1. 多台主机之间,也可用”:”分割,例如:
# ansible 10.0.0.21:vtlab01 -m ping
  1. all 或 * 匹配所以服务器,例如:
# ansible all -m ping | ansible * -m ping | ansible 192.168. -m ping
  1. 使用索引或切片的方式访问组中的服务器:
# ansible web[0:1] -m ping
  1. 匹配web组中且不在db组中的服务器:
# ansible web!db --list-hosts
  1. 以vtlab开头的主机:
# ansible ~vtlab* --list-hosts

Inventory行为参数

可以在/etc/ansible/ansible.cfg中配置

名称 默认值 描述
ansible_host 主机名称 SSH的目的主机名或IP
ansible_user 当前用户 SSH连接的用户名
ansible_port 22 SSH连接的端口号
ansible_ssh_private_key_file none SSH连接使用的私钥
ansible_connection smart Ansible使用的连接模式,smart、ssh 或 paramiko
ansible_become none 类似Linux下的sudo
ansible_become_user none 切换到哪个用户执行命令
ansible_shell_type sh 执行命令所使用的shell
ansible_python_interpreter /usr/bin/python 使用哪个Python解释器
ansible_*_interpreter none 指定其他语言的解释器

定义服务器变量

hosts文件中,除了行为参数,还可以定义普通的变量。
变量要求:参数名必须为字母、数字和下划线的组合,并且首字符必须为字母。示例:

127.0.0.1
mysql_port=3306
[db]
192.168.1.1 mysql_port=3307
# ansible db -a “echo {{mysql_port}}”
127.0.0.1 mysql_port=3306
[db]
192.168.1.1
192.168.1.2
[db:vars]
mysql_port=3307

需要定义多个变量时:
1. 为每个服务器和群组创建独立的变量文件
2. 将组的变量文件存放在名为group_vars目录下,目录下的文件名与组的名称相同,文件的扩展名.yml/.yaml或没有扩展名
3. 服务器的变量文件存放在名为host_vars目录下,文件名与服务器名称相同。
4. Ansible将依次在Playbook所在的目录、hosts文件所在的目录和/etc/ansible/目录下寻找group_vars/host_vars目录。

YAML语法规则

  1. 第一行”—“,表示这是一个YAML文件,通常在一个yaml文件中定义多个yaml块时使用。
  2. 大小写敏感
  3. 与Python一样,用缩进表示层级关系
  4. YAML的缩进不允许用Tab键,只运行使用空格,且空格的数目不重要,只要相同层级的元素左侧对齐即可
  5. #表示注释,从这个字符一直到行尾都会被解析器忽略

YAML支持三种格式的数据

  1. 对象:键值对的集合,又称为映射,类似于Python中的字典
  2. 数组:一组按次序排列的值,又称为序列(sequence),类似Python中的列表
  3. 纯量:scalars,单个的、不可再分的值,如字符串、布尔值与数字

常用模块介绍

工作原理:
1. 将模块拷贝到远程服务器
2. 执行模块定义的操作,完成对服务器的修改
3. 在远程服务器中删除模块

查看模块及查看指定模块

# ansible-doc -l
# ansible-doc -l file
# ansible-doc file
  1. ping模块,测试现有SSH参数是否能够顺利连通远程服务器。
# ansible vtlab -m ping 
  1. 远程命令模块。command、raw、script、shell模块都可以实现在远程主机上执行Linux命令。
    command 是默认模块
    raw模块相当于使用SSH直接执行Linux命令,不会进入到Ansible的模块子系统中
    shell模块还可以执行远程服务器上的shell脚本文件
# ansible vtlab -m shell -a '/root/sc/a.sh'

script模块可以在远程服务器上执行主控节点中的脚本文件,其功能相当于scp+shell的组合,执行完后会删除远程服务器上的脚本文件

# ansible vtlab -m script -a 'test.sh'
  1. file模块,主要用于对远程服务器上的文件进行操作(包括链接和目录),修改文件的权限、属主、创建删除文件:
    path:执行文件、目录的路径
    recurse:递归设置文件属性,只对目录有效
    group:定义文件、目录的属组
    mode:定义文件、目录的权限
    owner:定义文件、目录的所有者
    src:要被链接的源文件路径,只应用与state为link的情况
    dest:被链接到的路径,只应用于state为link的情况
    force:在两种情况下会强制创建软链接,一种是源文件不存在但之后会建立的情况;一种是目标软链接已经存在,需要先取消之前的软链接,然后创建新的软链接,默认值 no。
# ansible vtlab -m file -a 'path=/data/release state=directory mode=0755'  # 创建目录
# ansible vtlab -m file -a 'path=/data/release state=touch mode="u=rw,g=r,o=r"'  # 修改权限
# ansible vtlab -m file -a 'src=/etc/passwd dest=/tmp/passwd state=link owner=wt group=wt'  # 创建一个软链接
# ansible vtlab -m file -a 'path=/tmp/passwd owner=root group=root mode=0644' -become  # 修改文件的所有者
  1. copy模块,用于将主控节点上的文件或目录拷贝到远程服务器上,类似scp:
    src:指定要复制到远程主机的文件或目录。如果路径以 / 结尾,则只复制目录里的内容,如果没有以 / 结尾,则复制包含目录在内的整个内容
    dest:文件复制的目的地,必须是一个绝对路径,如果源文件是一个目录,那么dest指向的也必须是一个目录
    force:默认取值为yes,表示目标主机包含此文件,但内容不同时,覆盖。
    backup:默认取值为no,如果为yes,在覆盖前将原文件进行备份
    directory_mode:递归设定目录权限,默认为系统默认权限
    others:所有file模块里的选项都可以在这里使用
# ansible vtlab -m copy -a 'src=index.html dest=/data/release/html/index.html'  # 拷贝文件到服务器
# ansible vtlab -m copy -a 'src=index.html dest=/data/release/html/index.html backup=yes force=yes'  # 拷贝文件到服务器,如果目标文件已存在,备份后覆盖
# ansible vtlab -m copy -a 'src=index.html dest=/data/release/html/index.html owner=root group=root mode=644 force=yes' # 拷贝文件到服务器,并设置属主及权限,如果目标文件存在则覆盖
  1. user/group模块,useradd/userdel/usermod groupadd/groupdel/groupmod
    name:需要操作的用户名或组名
    comment:用户的详细描述
    createhome:创建用户时,是否创建用户的家目录,默认为yes
    home:指定用户的家目录,需要和createhome配合使用
    groups:指定用户的属组
    uid:设置用户的uid
    gid:设置群组的gid
    password:设置用户的密码
    state:创建用户or删除用户,对应present和absent
    expires:用户的过期时间
    shell:指定用户的shell环境
# ansible vtlab -m user -a 'name=wt comment="wt user" uid=1001 group=root' -become  # 创建一个用户 
# ansible vtlab -m user -a 'name=wt state=absent' -become  # 删除一个用户 
# ansible vtlab -m user -a 'name=wt comment="wt user" generate_ssh_key=yes ssh_key_bits=2048' -become  # 创建一个用户并生成一对密钥 
# ansible vtlab -m group -a 'name=wt state=present gid=1001' -become  # 创建组及指定组ID 
# ansible vtlab -m group -a 'name=wt state=absent' -become  # 删除组 

6.apt模块,debian ubuntu系统中安装软件/删除软件
name:包名
state:软件包的状态,latest、absent、present、build-sep, 默认为present
autoremove:默认取值为no,如果取值为yes,将会移除不需要的软件包
force:强制安装或删除软件包
update_cache:作用与 apt-get update相同
deb:deb文件的路径

# ansible vtlab -m apt -a 'name=git state=present' -become  # 安装git包 
# ansible vtlab -m apt -a 'name=git state=absent' -become  # 卸载git包 
# ansible vtlab -m apt -a 'update_cache=yes' -become  # 更新包缓存 
  1. get_url模块,从互联网下载数据到本地,作用类似于Linux下的curl。
    url:必传选项,文件的下载地址
    dest:必传选项,文件保存的绝对路径
    mode:文件的权限
    others:所有file模块里的选项都可以在这里使用
    checksum:文件的校验码
    headers:传递给下载服务器的HTTP Headers
    backup:如果本地已经存在同名文件,备份文件
    timeout:下载的超时时间
# ansible vtlab -m get_url -a 'url=https://www.vtlab.io/abc.txt dest=/opt/ mode=0744 checksum=324988594fsj239432u' 
  1. unarchive模块,解压
    remote_src:表示被解压的文件在控制节点还是目标节点。默认为no,表示source指定的路径在控制节点;yes则告诉ansible,source指定的文件路径是目标主机上的路径。
    src:指定压缩文件的路径,该选项的取值取决与remote_src的取值,如果remote_src取值为yes,则src指定的路径是远程服务器中压缩包的地址,如果remote_src取值为no,则src指向的是控制节点中的路径
    dest:该选项指定的是远程服务器上的绝对路径,表示压缩文件解压的路径;
    list_files:默认情况下该选项取值为no,如果该选项取值为yes,解压文件时会在ansible的返回值中列出压缩包里的文件
    exclude:解压文件时排除exclude选项指定的文件或目录列表 keep_newer 默认取值为False,如果该选项取值为True,那么当目标地址中存在同名的文件,并且文件比压缩包中的文件更新时,不进行覆盖
# ansible vtlab -m unarchive -a 'src=data.tar.gz dest=/tmp/data list_files=yes'  # 将管理主机上data.tar.gz文件解压后并拷贝到被管理主机的/tmp/data目录下(目标管理主机的目标目录必须存在),并显示tar包中文件列表。 
# ansible vtlab -m unarchive -a 'src=data.tar.bz2 dest=/tmp/'  # 将管理主机上data.tar.bz2文件解压后并拷贝到被管理主机的/tmp/目录下,可以看出unarchive模块不论什么格式的压缩包都可以解压。 
# ansible vtlab -m unarchive -a 'src=/tmp/data.tar.bz2 dest=/tmp remote_src=yes'  # 解压目标主机上/tmp/data.tar.bz2文件到目标主机的/tmp目录下。 
  1. git模块,在远程服务器执行 git 相关操作
    repo:git仓库的地址,可以是git协议、ssh、http协议的git库地址
    dest:必选选项,git库 clone 到本地服务器以后保存到绝对路径
    version:克隆远程git库的版本,取值可为HEAD、分支多名称、tag名称,也可以是一个commit 的hash值
    force:默认取值为no,当该选项取值为yes时,如果本地的git库有修改,将会抛弃本地的修改
    accept_hostkey:当该选项取值为yes时,如果git库的服务器不在know_hosts中,则添加到know_hosts中 key_file 指定科隆远程git库地址时使用的私钥
# ansible vtlab -m git -a 'repo=https://github.com/kennethreitz/requests.git dest=/tmp/requests version=HEAD'  # 将requests克隆到/tmp/requests目录下 
# ansible vtlab -a 'python setup.py install chdir=/tmp/requests' -become  # 从源码安装requests 
# ansible vtlab -a 'python -c "import requests"'  # 为python导入 requests 模块 
  1. stat模块,获取远程服务器上的文件信息,类似Linux 下的stat命令,stat命令可以获取time、ctime、mtime、checksum 、 size 、 uid、gid等 path 指定文件或目录的路径
# ansible vtlab -m stat -a 'path=/etc/passwd' 
  1. cron模块,批量设置定时任务时,非常方便
    backup:默认 no,当为yes时,表示修改之前先做备份
    state:取值为present或absent,用来确认该任务是创建还是删除
    name:任务的描述/名字
    job:添加或删除任务,主要取决于state 的取值
    user:操作哪一个用户的crontab
    cron_file:如果指定该选项,则用该文件替换远程主机上的cron.d 目录下的用户任务计划
    month:月
    weekday:周 .
    day:日
    minute:分,minute 取值范围0~59,表示每分钟运行,*/5表示每5分钟运行
    hour:时
# ansible vtlab -m cron -a 'name="check url" minute=</em>/2 hour=* job="curl http://www.vtlab.io > /dev/null"'  # 每隔两分钟curl一下www.vtlab.io这个网站 
# ansible vtlab -m cron -a 'name="check url" minute=<em>/2 hour=</em> job="curl http://www.vtlab.io > /dev/null" state=absent' # 取消这条crontab 
  1. service模块,管理服务的模块,用来启动、停止、重启服务
    name:服务名称,该选项为必选项
    state:取值为 started、stopped、restarted、reloaded。 started和stopped为幂等的,也就是已经启动的服务,执行started不会有任何操作
    sleep:重启的过程中,先停止服务sleep几秒后再启动
    pattern:定义一个模式,Ansible首先通过status命令查看服务的状态,以此判断服务是否在运行,如果通过status查看服务状态时没有响应,Ansible会尝试匹配ps命令的输出,当匹配到相应模式时,认为服务已经启动,否则认为服务没有启动
    enabled:取值为yes 或 no,用来设置服务是否开机启动
# ansible vtlab -m apt|yum -a 'name=nginx state=present' -become  # 安装nginx服务,apt为Ubuntu或Debian系统使用的模块选项,yum是Redhat和CentOS使用的模块选项 
# ansible vtlab -m service -a 'name=nginx state=stopped'  # 停止nginx服务 
# ansible vtlab -m service -a 'name=nginx state=restarted'  # 重启nginx服务 
  1. sysctl模块,与linux 下 sysctl命令相似,控制Linux 内核参数
    name:要设置的参数
    value:需要设置的值
    sysctl_file:sysctl.conf 文件的绝对路径,默认路径为/etc/sysctl.conf
    reload:取值为yes 或 no,默认yes,表示设置完成后,执行sysctl -p 操作
# ansible vtlab -m sysctl -a 'name=vm.overcommit_memory value=1' -become
  1. mount模块,在远程服务器上挂载磁盘,在挂盘操作时,如果指定的挂载点不存在,则创建该路径
    name:挂载点的路径
    state:present、absent、mounted、unmounted。其中mounted与unmounted用来处理磁盘的挂载和卸载,并且会正确配置stab文件,present和absent只会设置stab文件,不会去操作磁盘
    fstype:指定文件系统类型,当state取值为present或mounted时,该选项为必填选项
    src:挂载点设备
# ansible vtlab -m mount -a 'name=/mnt/data src=/dev/vda fstype=xfs state=mounted' 
  1. synchronize模块,对rsync命令的封装,用于文件同步
    src:需要同步到远程服务器的文件或目录
    dest:远程服务器保存数据的路径
    archive:默认取值为yes,相当于同时开启recursive、links、perms、times、owner、group、-D选项
    compress:默认为yes,表示在文件同步过程中启用压缩
    delete:默认为no,当取为yes时,表示删除dest中存在而src中不存在的文件
# ansible vtlab -m synchronize -a 'src=/data/test dest=/tmp'
```  # 将控制节点/data/test目录拷贝至目标主机的/tmp目录下 

#### 模块的返回值
当我们执行ansible命令时,每次都有一堆输出,这些输出是什么意思呢?ansible又有哪些返回值呢?
1. changed 几乎所有的Ansible模块都会返回该变量,表示模块是否对远程主机执行了修改操作 
2. failed 模块未能执行完成,返回failed 为 true msg 模块执行失败的原因,常见的错误如ssh连接失败,没有权限执行模块等 rc 与命令行工具相关的模块会返回rc,表示执行Linux命令的返回码 stdout 与rc类似,返回的是标准输出的结果 stderr 与rc类似,返回的是错误输出的结果 
3. backup_file 所有存在backup选项的模块,用来返回备份文件的路径 results 应用在Playbook中存在循环的情况,返回多个结果Playbook,上面的这么多命令,都是在命令行终端执行,功能也相对简单,实现的功能不足以应付更负责的场景,比如我想copy文件后再执行一些其他命令,按照上面的命令,需要逐条去执行,很影响作业效率,为了应付这些问题,ansible推出了playbook,我们先通过一个简单的剧本来熟悉下playbook的语法,playbook是使用yaml语言定义的。 
示例:copy index.html文件到远端主机,并对远端主机安装telnet和git包
```yaml
# vim t1_palybook.yml
- hosts: vtlab
  become: yes
  become_method: sudo
  tasks:
  - name: copy file
    copy: src=/tmp/index.html dest=/html/index.html
  - name: change mode
    file: dest=/html/index.html mode=500 owner=nginx group=nginx
  - name: ensure packages installed
    yum: pkg={{ item }} state=present
    with_items:
      - telnet
      - git

语法解析:
1. Playbook文件首先包含了一些声明信息,如hosts关键字声明该Playbook应用的服务器列表,
2. -表示定义列表,
3. become和become_method表示在远程服务器通过sudo执行操作
4. Playbook最后包含了若干task,每一个task对应前面的一条ad-hoc命令。
5. 具体执行时,多个task按顺序执行
6. 测试执行,验证playbook是否有语法问题:

# ansible-playbook t1_palybook.yml -C 
  1. 执行:
# ansible-playbook t1_palybook.yml 

在Ansible Playbook中,每个play必须包含以下两项:
hosts:指定对哪些服务器组进行操作
tasks:对服务器组执行的命令
tasks定义形式:

-name: names
  module: action 

YAML中,使用 > 进行折叠,参数较多时,Playbook可以这么写:

- name: install apache
  apt: >
    name=apache2
    update_cache=yes
    state=present

也可以使用缩进字块的形式:

- name: install apache2
  apt:
    name: apache2
    update_cache: yes
    state: present

前者代表一个比较长的字符串,后者是一个字典。在task中,name是可选的。 Playbook中,也可以包含其他Playbook,例如:

# vim all.yaml 
---
- include: db.yaml
- include: web.yaml

ansible-playbook与ansible的命令对比

相同子命令:
-T –timeout: 建立SSH连接的超时时间
–key-file –private-key: 建立SSH连接时的私钥
-i –inventory-file: 指定Inventory 文件,默认为 /etc/ansible/hosts
-f –forks: 并发执行的进程数,默认5
–list-hosts: playbook 匹配的服务器列表

ansible-playbook特有的命令选项:
–list-tasks: 列出任务列表
–step: 每执行一个任务后停止,等待用户确认, N,y,c。 no yes continue
–syntax-check: 检查Playbook 的语法 -C –check: 检查当前Playbook是否会修改远程服务器,相当于测试Playbook的执行结果

权限:默认使用当前用户连接远程服务器及进行相关操作

---
- hosts: vtlab
  remote_user: root
  tasks:
    - name: test connection
      ping:
      remote_user: wt

使用sudo权限

---
- hosts: vtlab
  remote_user: wt
  tasks:
    - service: name=nginx state=started
      become: yes
      become_method: sudo

看了几个简单的playbook示例,对playbook的写法大家应该相对了解了,但这些还远远不能满足工作中的需求,比如现在,我需要安装web服务,并且希望对web服务的配置文件改动之后,ansible-playbook能自动触发web服务重启的机制。

--- 
- hosts: vtlab
  tasks:
  - name: ensure nginx
    yum: name={{ item }} state=present
    with_items:
    - telnet
    - git
  - name: write the nginx config file
    template: src=/software/nginx/conf/nginx.j2 dest=/data/nginx/conf/nginx.conf
    notify:
    - restart nginx
  - name: ensure nginx is running
    service: name=nginx state=started
  handlers:
  - name: restart nginx
    service: name=nginx state=restarted

这个playbook中,引用了一个新的指令handler,作用是在所有task执行完后执行,一个handler被触发多次,它也只会执行一次。 Ansible-playbook中的变量: 变量需要定义在playbook的vars选项中,在上面的示例中,我们在yum模块中已经使用到了变量,即传递安装包的名字。

- hosts: web
  vars:
    mysql_port: 3307

可以将变量保存在独立的文件,并通过 vars_files 选项应用

- hosts: vtlab
  vars: 
    favcolor: blue
  vars_files:
  - /vars/ex_vars.yml
  tasks:
  - name: this is just a placeholder
  command: /bin/echo foo

保存变量的文件是一个简单的YAML格式的字典: somevar: some value password: wt 将任务的执行结果存储为变量,注册变量,使用register获取:

---
- hosts: web
  tasks:
  - shell: /usr/bin/foo
   register: foo_result
   ignore_errors: True
  - shell: /usr/bin/bar
   when: foo_result.rc == 5

Facts 变量:Ansible 执行远程部署之前从远程服务器中获取的系统信息,包括服务器名称、IP、操作系统、分区信息、硬件信息等 通过setup模块查看 Facts 变量的列表 # ansible vtlab -m setup 可以在 playbook 中直接通过变量名字进行引用,也可以在jinja2模版中通过变量的名字引用变量。

---
- hosts: vtlab
  tasks:
    - shell: echo {{ansible_os_family}}
      register: myecho 
    - debug: var=myecho.stdout_lines
    - name: install git on Debian Linux
      apt: name=git state=installed
      when: ansible_os_family == ‘Debian’

setup 模块为了输出结果的可读性,对模块的输出进行了归类和整理。因此,当我们访问复杂的子属性时,需要使用嵌套结构 获取ipv4地址 ansible_eth0[“ipv4”][“address”] ansible_eth0.ipv4.address

---
- hosts: web
  gather_facts: yes
  tasks:
    - shell: echo {{ansible_eth0[“ipv4”][“address"]}}
      register: myecho 
     - debug: var=myecho.stdout_lines
     - shell: echo {{ansible_eth0.ipv4.address}}
      register: myecho 
     - debug: var=myecho.stdout_lines

gather_facts 选项控制是否收集远程服务器的信息,默认取值为yes,不需要可以设为no,提高ansible的部署效率 循环:

- name: install mysql
      yum: name={{ item }} state=installed
      with_items:
            - mysql-server
            - MySQL-python
            - libselinux-python

条件:在 Playbook 中可以通过when选项执行条件语句

tasks:
  - name: “shut down Debian flavored systems”
    command: /sbin/shutdown -t now
    when: ansible_os_family == “Debian”

when 选项支持多个条件语句,下面时一个YAML格式的多条件:

tasks:
  - name: “shut down Ceontos6 systems”
    command: /sbin/shutdonw -t now
    when:
        - ansible_distribution == “Centos”
        - ansible_distribution_major_version == “6”

and/or

tasks:
  - name: “shut down Centos 6 and Debian 7 systems”
    command: /sbin/shutdown -t now
    when: (ansible_distribution == “Centos” and ansible_distribution_major_version == “6”) or (ansible_distribution == “Debian” and ansible_distribution_major_version == “7”)

when 选项中可以使用Jinja2的过滤器tasks:
– command: /bin/false
register: result
ignore_errors: True
– command: /bin/someting
when: result|failed
– command: /bin/someting_else
when: result|succeeded
when读取变量的值: vars:

epic: True
tasks:
  - shell: echo "This certainly is epic"
   when: epic

when选项和循环一起使用:

tasks:
    - command: echo {{ item }}
      with_item: [0,2,4,6,8,10]
      when: item > 5

任务执行策略: Ansible中,Playbook 的执行是以task为单位进行的。Ansible 默认使用5个进程对远程服务器执行任务。在默认情况的任务执行策略(linear)中,Ansible首先执行task1,并且等所有服务器都执行完了task1再开始执行task2,以此类推。 Ansible2.0开始,支持名为free的任务执行策略,允许执行快的服务器提前完成Play的部署,不再等待其他服务器

---
- hosts: web
  strategy: free
  tasks:

最后示例:Playbook 部署 Nginx

---
- hosts: web
  become: yes
  become_method: sudo
  vars:
      worker_processes: 4
      worker_connections: 768
      max_open_files: 65506
  tasks:
      - name: install nginx
        apt: name=nginx update_cache=yes state=present
      - name: copy nginx config file
        template: src=/home/wt/ansible/nginx.conf.j2 dest=/etc/nginx/nginx.conf
        notify: restart nginx
      - name: copy index.html
        template:
            src: /home/wt/ansible/index.html.j2
            dest: /usr/share/nginx/www/index.html
            mode: 0644
        notify: restart nginx
  handlers:
      - name: restart nginx
        service: name=nginx state=restarted

这里介绍了部分ansible的功能,角色及更高级的用法,以后有时间再慢慢分享。