文章目录

  • 为什么选择 Ansible
  • Ansible 基本架构
  • Ansible 基本组成
  • Ansible 工作原理
  • Ansible 安装
  • 主机清单
    • 1. 简单的主机和组
    • 2. 端口与别名
    • 3. 指定主机范围
    • 4. 使用主机变量
    • 5. 组内变量
    • 6. 组的包含与组内变量
    • 7. Patterns(主机与组正则匹配部分)
  • ansible.cfg 配置说明
    • 1. 配置读取顺序
    • 2. 配置详解
  • Ad-hoc 与命令执行模块
    • 1. Ad-hoc
    • 2. 命令执行模块
  • Ansible 常用模块
    • 1. setup 模块
    • 2. ping 模块
    • 3. file 模块
    • 4. copy 模块
    • 5. cron 模块
    • 6. yum 模块
    • 7. user 模块与 group 模块
    • 8. synchronize 模块
    • 9. filesystem 模块
    • 10. mount模块
    • 11. get_url 模块
    • 12. unarchive 模块
  • playbooks
    • 1. 用户组
    • 2. Tasks 列表
    • 3. Handlers
    • 4. playbook 之 Role、Include
    • 5. Variables
    • 6. 条件选择 when
    • 7. 条件导入
    • 8. 基于变量选择文件或者模板
    • 9. 注册变量
    • 10. 循环
      • 10.1. 标准循环
      • 10.2. 嵌套循环
      • 10.3. 对哈希表使用循环
      • 10.4. 对文件列表使用循环
      • 10.5. 对并行数据采用循环
      • 10.7. 对子元素进行循环
      • 10.8. 对整数序列进行循环
      • 10.9. 随机选择
      • 10.10 Do-Until 循环
      • 10.11. 查找第一个匹配文件

为什么选择 Ansible

相对于 puppet 和 saltstack,ansible 无需客户端,更轻量级 ansible 甚至都不用启动服务,仅仅只是一个工具,可以很轻松的实现分布式扩展更强的远程命令执行操作不输于 puppet 和 saltstack 的其他功能。

Ansible 基本架构

Ansible 基本组成

  • 核心:ansible
  • 核心模块(Core Modules):这些都是ansible自带的模块
  • 扩展模块(Custom Modules):如果核心模块不足以完成某种功能,
  • 可以添加扩展模块 插件(Plugins):完成模块功能的补充
  • 剧本(Playbooks):ansible的任务配置文件,将多个任务定义在剧本中,由ansible自动执行
  • 连接插件(Connectior Plugins):ansible基于连接插件连接到各个主机上,虽然ansible是使用ssh连接到各个主机的,但是它还支持其他的连接方法,所以需要有连接插件
  • 主机群(Host Inventory):定义ansible管理的主机

Ansible 工作原理

Ansible 安装

Ansible 的安装方式有很多种,常用的安装方法是基于 yum 或者源码,如果是基于 yum 安装,需要配置 epel 源,然后直接执行yum -y install ansible即可。源码安装配置如下:

# 解决依赖关系:
$ yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto# 下载ansible:
# wget https://github.com/ansible/ansible/archive/release1.6.1.zip# 解压安装
$ unzip release1.6.1
$ cd ansible-release1.6.1
$ python setup.py build
$ python setup.py install
$ mkdir /etc/ansible
$ cp -r examples/* /etc/ansible  

主机清单

1. 简单的主机和组

  • 中括号中的名字代表组名,可以根据自己的需求将庞大的主机分成具有标识的组,如上面分了两个组 webservers 和 dbservers 组;
  • 主机(hosts)部分可以使用域名、主机名、IP地址表示;
  • 当然使用前两者时,也需要主机能反解析到相应的IP地址,一般此类配置中多使用IP地址;
[webservers]
web1.yanruogu.com
web2.yanruogu.com [dbservers]
db1.yanruogu.com
db2.yanruogu.com

2. 端口与别名

如果某些主机的SSH运行在自定义的端口上,ansible 使用 Paramiko 进行ssh连接时,不会使用你SSH配置文件中列出的端口,但是如果修改 ansible 使用 openssh 进行ssh连接时将会使用:

# 192.168.1.1:3091
# 假如你想要为某些静态IP设置一些别名,可以这样做:web1 ansible_ssh_port = 3333 ansible_ssh_host = 192.168.1.2
上面的 web1别名就指代了IP为192.168.1.2,ssh连接端口为3333的主机。

3. 指定主机范围

[webservers]
www[01:50].yanruogu.com[databases]
db-[a:f].yanruogu.com# 上面指定了从web1到web50,webservers组共计50台主机;databases组有db-a到db-f共6台主机。

4. 使用主机变量

以下是Hosts部分中经常用到的变量部分:

ansible_ssh_host         # 用于指定被管理的主机的真实IP
ansible_ssh_port        # 用于指定连接到被管理主机的ssh端口号,默认是22
ansible_ssh_user        # ssh连接时默认使用的用户名
ansible_ssh_pass        # ssh连接时的密码
ansible_sudo_pass       # 使用sudo连接用户时的密码
ansible_sudo_exec       # 如果sudo命令不在默认路径,需要指定sudo命令路径
ansible_shell_type      # 目标系统的shell的类型,默认sh# 秘钥文件路径,秘钥文件如果不想使用ssh-agent管理时可以使用此选项
ansible_ssh_private_key_file    # SSH 连接的类型: local , ssh , paramiko,在 ansible 1.2 之前默认是 paramiko ,后来智能选择,优先使用基于 ControlPersist 的 ssh (支持的前提)
ansible_connection      # 用来指定python解释器的路径,默认为/usr/bin/python 同样可以指定ruby 、perl 的路径
ansible_python_interpreter    # 其他解释器路径,用法与ansible_python_interpreter类似,这里"*"可以是ruby或才perl等其他语言
ansible_*_interpreter
  • 示例如下:
[test]
192.168.1.1 ansible_ssh_user=root  ansible_ssh_pass='P@ssw0rd'
192.168.1.2 ansible_ssh_user=breeze ansible_ssh_pass='123456'
192.168.1.3 ansible_ssh_user=bernie ansible_ssh_port=3055 ansible_ssh_pass='456789'

说明: 上面的示例中指定了三台主机,三台主机的用密码分别是P@ssw0rd、123456、45789,指定的ssh连接的用户名分别为root、breeze、bernie,ssh 端口分别为22、22、3055 ,这样在ansible命令执行的时候就不用再指令用户和密码等了。

5. 组内变量

变量也可以通过组名,应用到组内的所有成员:

[test]
host1
host2[test:vars]
ntp_server=192.168.1.10
proxy=192.168.1.20 

说明: 上面 test 组中包含两台主机,通过对 test 组指定 vars 变更,相应的 host1 和 host2 相当于相应的指定了 ntp_server 和 proxy 变量参数值 。

6. 组的包含与组内变量

下列的示例中,指定了武汉组有web1、web2;随州组有web3、web4主机;又指定了一个湖北组,同时包含武汉和随州;同时为该组内的所有主机指定了2个vars变量。设定了一个组中国组,包含湖北、湖南。

注: vars变量在 ansible ad-hoc 部分中基本用不到,主要用在 ansible-playbook 中。

[wuhan]
web1
web2[suizhou]
web4
web3[hubei:children]
wuhan
suizhou[hubei:vars]
ntp_server=192.168.1.10
zabbix_server=192.168.1.10[china:children]
hubei
hunan

7. Patterns(主机与组正则匹配部分)

把Patterns 直接理解为正则实际是不完全准确的,正常的理解为patterns意味着在ansible中管理哪些主机,也可以理解为,要与哪台主机进行通信。在探讨这个问题之前我们先看下ansible的用法:

$ ansible <pattern_goes_here> -m <module_name> -a <arguments># 直接上一个示例:
$ ansible webservers -m service -a "name=httpd state=restarted"
# 这里是对webservers 组或主机重启httpd服务 ,其中webservers 就是Pattern部分。而之所以上面说Pattern(模式)可以理解为正则,主要针对下面经常用到的用法而言的。
  • 1、表示所有的主机可以使用 all 或 *
  • 2、通配符与逻辑或
    利用通配符还可以指定一组具有规则特征的主机或主机名,冒号表示or---逻辑或
web1.yanruogu.com
web1.yanruogu.com:web2.yanruogu.com
192.168.1.1
192.168.1.*
  • 当然,这里的*通配符也可以用在前面,如:
*.yanruogu.com
*.com
webservers1[0]
webservers1[0:25]

说明:
webservers1[0]: 表示匹配 webservers1 组的第 1 个主机
webservers1[0:25]: 表示匹配 webservers1 组的第 1 个到第 25 个主机(官网文档是":“表示范围,测试发现应该使用”-",注意不要和匹配多个主机组混淆)

  • 上面的用法,在多个组之间同样适用 ,如:
webservers
webservers:dbservers  # 表示两个组中所有的主机
  • 3、逻辑非与逻辑and
# 非的表达式,如,目标主机必须在组 webservers 但不在 phoenix 组中
webserver:!phoenix# 交集的表达式,如,目标主机必须即在组webservers中又在组staging中
webservers:&staging# 一个更复杂的示例:
webserver:dbservers:&staging:!phoenix

说明: 上面这个复杂的表达式最后表示的目标主机必须满足:在webservers或者dbservers组中,必须还存在于staging组中,但是不在phoenix组中 。

  • 4、混合高级用法
*.yanruogu.com:*.org# 还可以在开头的地方使用”~”,用来表示这是一个正则表达式:
~(web|db).*\.yanruogu\.com## 给两个ansible-playbook中具体可能用的用法:# a、在ansible-palybook命令中,你也可以使用变量来组成这样的表达式,但是你必须使用“-e”的选项来指定这个表达式(通常我们不这样用):
ansible-palybook -e webservers:!`excluded`:&`required`# b、在ansible和ansible-playbook中,还可以通过一个参数”--limit”来明确指定排除某些主机或组:
ansible-playbook site.yml --limit datacenter2# c、从Ansible1.2开始,如果想排除一个文件中的主机可以使用"@":
ansible-playbook site.yml --limit @retry_hosts.txt

ansible.cfg 配置说明

Ansible默认安装好后有一个配置文件/etc/ansible/ansible.cfg,该配置文件中定义了ansible的主机的默认配置部分,如默认是否需要输入密码、是否开启sudo认证、action_plugins插件的位置、hosts主机组的位置、是否开启log功能、默认端口、key文件位置等等。

1. 配置读取顺序

  • 1.环境变量
  • 2.当前目录中的ansible.cfg
  • 3.家目录中的ansible.cfg
  • 4./etc/ansible/ansible.cfg

2. 配置详解

[defaults]
## some basic default values...
# 指定默认hosts配置的位置
hostfile        = /etc/ansible/hosts
library_path    = /usr/share/my_modules/
remote_tmp      = $HOME/.ansible/tmp
# 如果在其他远程主机上使用另一种方式执行sudo操作, sudo程序的路径可以用这个参数更换,使用命令行标签来拟合标准sudo
sudo_exe        = sudo
# roles 路径指的是’roles/’下的额外目录,多条的路径可以用冒号分隔
roles_path      = /opt/mysite/roles
# ansible使用/usr/bin/ansible-playbook链接的默认用户名. 注意如果不指定,/usr/bin/ansible默认使用当前用户名称
remote_user     = root
# 默认库文件位置,脚本,或者存放可通信主机的目录
inventory       = /etc/ansible/hosts
# 可以在sudo环境下产生一个shell交互接口. 用户只在/bin/bash的或者sudo限制的一些场景中需要修改.大部分情况下不需要修改
executable      = /bin/bash
# 到没有使用TTY终端的时候,这个选项当用来强制颜色模式
force_color     = 1
# 即便这个用户崩溃,这个选项仍可以继续运行这个用户
force_handlers  = True
# 这个是/usr/bin/ansible的默认模块名(-m). 默认是’command’模块
module_name     = command
# Ansible 默认搜寻模块的位置
library         = /usr/share/ansible
# \\默认ansible会为输出结果加上颜色,用来更好的区分状态信息和失败信息.如果你想关闭这一功能,可以把’nocolor’设置为‘1’
nocolor         = 0
# playbook要通信的默认主机组.默认值是对所有主机通信
pattern         = *
# SSH链接尝试超市时间
timeout         = 10
# 这个选项设置在与主机通信时的默认并行进程数
forks           = 5
# 当具体的poll interval 没有定义时,多少时间回查一下这些任务的状态, 默认值是一个折中选择15秒钟
poll_interval   = 15
# 远程sudo用户,默认为root
sudo_user       = root
# Ansible playbook 在执行sudo之前是否询问sudo密码.默认为no
ask_sudo_pass   = True
# Ansible 剧本playbook 是否会自动默认弹出弹出密码.默认为no
ask_pass        = True
# 关闭运行ansible时系统的提示信息,一般为提示升级
system_warnings = False
transport       = smart
# 设置是系统默认的远程SSH端口,如果不指定,默认为22号端口
remote_port     = 22
# 这是默认模块和系统之间通信的计算机语言,默认为’C’语言
module_lang     = C
# 这个设置控制默认facts收集(远程系统变量)
gathering       = implicit# 当shell和命令行模块被默认模块简化的时,Ansible 将默认发出警告. 可以通过在命令行末尾添加 warn=yes 或者 warn=no选项来控制是否开启警告提示
command_warnings        = False
# 允许在ansible-playbook输出结果中禁用“不建议使用”警告
deprecation_warnings    = True
# 跳过的任务状态是否显示,默认不显示
display_skipped_hosts   = True
# 如果所引用的变量名称错误的话, 将会导致ansible在执行步骤上失败
error_on_undefined_vars = True
# 设置密码文件,也可以通过命令行指定``–vault-password-file``
vault_password_file     = /path/to/vault_password_file
# 是否检测主机密钥
host_key_checking       = False
# 登陆日志,需要时可以自行添加。chown -R root:root ansible.log
log_path                = /var/log/ansible.log
# 允许开启Jinja2拓展模块
jinja2_extensions       = jinja2.ext.do,jinja2.ext.i18n
# 如果你是用pem密钥文件而不是SSH 客户端或密钥认证的话,你可以设置这里的默认值,来避免每一次提醒设置密钥文件位置``–ansible-private-keyfile``
private_key_file        = /path/to/file.pem ## set plugin path directories here, separate with colons
# 用来激活一些事件,例如执行一个模块,一个模版,等等
action_plugins     = /usr/share/ansible_plugins/action_plugins
callback_plugins   = /usr/share/ansible_plugins/callback_plugins
# 连接插件允许拓展ansible拓展通讯信道,用来传输命令或者文件.
connection_plugins = /usr/share/ansible_plugins/connection_plugins
# 允许模块插件在不同区域被加载
lookup_plugins     = /usr/share/ansible_plugins/lookup_plugins
vars_plugins       = /usr/share/ansible_plugins/vars_plugins
# 过滤器是一种特殊的函数,用来拓展模版系统
filter_plugins     = /usr/share/ansible_plugins/filter_plugins[accelerate]
# 急速模式下使用的端口
accelerate_port     = 5099
# 控制从客户机获取数据的超时时间.如果在这段时间内没有数据传输,套接字连接会被关闭
accelerate_timeout  = 30
# 设置空着套接字调用的超时时间.这个应该设置相对比较短.这个和`accelerate_port`连接在回滚到ssh或者paramiko连接方式之前会尝试三次开始远程加速daemon守护进程.默认设置为1.0秒
accelerate_connect_timeout  = 5.0
# 控制加速daemon守护进程的超时时间,用分钟来衡量.默认为30分钟:
accelerate_daemon_timeout   = 30    [paramiko]
# 默认设置会记录并验证通过在用户hostfile中新发现的的主机
record_host_keys = True  [ssh_connection]
# ssh参数
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
# 保存ControlPath套接字的位置
control_path = %(directory)s/ansible-ssh-%%h-%%p-%%r
# 如果这个设置为True,scp将代替用来为远程主机传输文件
scp_if_ssh  = False
# 默认这个选项为了保证与sudoers requiretty的设置的兼容性是禁用的. 但是为了提高性能强烈建议开启这个设置.
pipelining  = False
  • 如果在对之前未连接的主机进行连结时报错如下:
$ ansible test -a 'uptime'192.168.1.1| FAILED =>Using a SSH password instead of a key is not possible because HostKeychecking is enabled and sshpass does not support this.Please add this host's fingerprint to your known_hosts file to manage this host.192.168.1.2 | FAILED => 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.

说明: 是由于在本机的~/.ssh/known_hosts文件中并有fingerprint key串,ssh第一次连接的时候一般会提示输入yes 进行确认为将key字符串加入到 ~/.ssh/known_hosts 文件中。

  • 方法1:
    在进行ssh连接时,可以使用-o参数将StrictHostKeyChecking设置为no,使用ssh连接时避免首次连接时让输入yes/no部分的提示。通过查看ansible.cfg配置文件,发现如下行:
[ssh_connection]
# ssh arguments to use
# Leaving off ControlPersist will result in poor performance, so use
# paramiko on older platforms rather than removing it
# ssh_args = -o ControlMaster=auto -o ControlPersist=60s
# 可以启用ssh_args 部分,使用下面的配置,避免上面出现的错误:ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no
  • 方法2:
    在 ansible.cfg 配置文件中,也会找到如下配置:
# uncomment this to disable SSH key host checking
host_key_checking = False# 默认host_key_checking部分是注释的,通过找开该行的注释,同样也可以实现跳过ssh 首次连接提示验证部分。但在实际测试中,似乎并没有效果,建议使用方法1.# 其他部分
# 默认ansible 执行的时候,并不会输出日志到文件,不过在ansible.cfg 配置文件中有如下行:log_path = /var/log/ansible.log
# 默认log_path这行是注释的,打开该行的注释,所有的命令执行后,都会将日志输出到/var/log/ansible.log文件。

Ad-hoc 与命令执行模块

Ad-Hoc 是指 ansible下临时执行的一条命令,并且不需要保存的命令,对于复杂的命令会使用playbook。Ad-hoc的执行依赖于模块,ansible官方提供了大量的模块。 如:command、raw、shell、file、cron等,具体可以通过ansible-doc -l 进行查看 。可以使用ansible-doc -s module来查看某个模块的参数,也可以使用ansible-doc help module来查看该模块更详细的信息。

1. Ad-hoc

  • 命令说明
    一个ad-hoc命令的执行,需要按以下格式进行执行:
$ ansible 主机或组 -m 模块名 -a '模块参数'  ansible参数

说明:

  1. 主机和组,是在 /etc/ansible/hosts 里进行指定的部分,当然动态 Inventory 使用的是脚本从外部应用里获取的主机;
  2. 模块名,可以通过 ansible-doc -l 查看目前安装的模块,默认不指定时,使用的是command模块,具体可以查看 /etc/ansible/ansible.cfg 的 “#module_name = command ” 部分,默认模块可以在该配置文件中进行修改;
  3. 模块参数,可以通过 ansible-doc -s 模块名 查看具体的用法及后面的参数;
  4. ansible参数,可以通过ansible命令的帮助信息里查看到,这里有很多参数可以供选择,如是否需要输入密码、是否sudo等。
  • 后台执行
        当命令执行时间比较长时,也可以放到后台执行,使用-B、-P参数,如下:
# 后台执行命令3600s,-B 表示后台执行的时间
$ ansible all -B 3600 -a "/usr/bin/long_running_operation --do-stuff" # 检查任务的状态
$ ansible all -m async_status -a "jid=123456789" # 后台执行命令最大时间是1800s即30分钟,-P 每60s检查下状态,默认15s
$ ansible all -B 1800 -P 60 -a "/usr/bin/long_running_operation --do-stuff"

2. 命令执行模块

命令执行模块包含如下 四个模块:

  • command模块:该模块通过-a跟上要执行的命令可以直接执行,不过命令里如果有带有如下字符部分则执行不成功 “ “<”, “>”, “|”, “&” ;

  • shell 模块:用法基本和command一样,不过其是通过/bin/sh进行执行,所以shell 模块可以执行任何命令,就像在本机执行一样;

  • raw模块:用法和shell 模块一样 ,其也可以执行任意命令,就像在本机执行一样;

  • script模块:其是将管理端的shell 在被管理主机上执行,其原理是先将shell 复制到远程主机,再在远程主机上执行,原理类似于raw模块。

注: raw模块和 comand、shell 模块不同的是其没有 chdir、creates、removes参数,chdir参数的作用就是先切到chdir指定的目录后,再执行后面的命令,这在后面很多模块里都会有该参数 。

command 模块包含如下选项:

  • creates:一个文件名,当该文件存在,则该命令不执行
  • free_form:要执行的linux指令
  • chdir:在执行指令之前,先切换到该指定的目录
  • removes:一个文件名,当该文件不存在,则该选项不执行
  • executable:切换shell来执行指令,该执行路径必须是一个绝对路径
# 使用chdir的示例:$ ansible 127.0.0.1 -m command -a 'chdir=/tmp/test.txt touch test.file'
$ ansible 127.0.0.1 -m shell -a 'chdir=/tmp/test.txt touch test2.file'
$ ansible 127.0.0.1 -m raw -a 'chdir=/tmp/text.txt touch test3.file'

说明: 三个命令都会返回执行成功的状态。不过实际上只有前两个文件会被创建成功。使用raw模块的执行的结果文件事实上也被正常创建了,不过不是在chdir指定的目录,而是在当前执行用户的家目录。

creates 与 removes示例:


# 当/tmp/server.txt文件存在时,则不执行uptime指令
$ ansible 192.168.1.1 -a 'creates=/tmp/server.txt uptime'         # 当/tmp/server.txt文件不存在时,则不执行uptime指令
$ ansible 192.168.1.1 -a 'removes=/tmp/server.txt uptime'

script 模块示例:

# 要执行的脚本文件script.sh内容如下:
# /bin/bash
ls /# 执行ansible指令:
$ ansible 10.212.52.252 -m script -a 'script.sh' |egrep '>>|stdout'
127.0.0.1 | SUCCESS => {"changed": true,"rc": 0,"stderr": "","stderr_lines": [],"stdout": "bin\nboot\ndata\ndev\netc\nhome\ninitrd.img\nlib\nlib64\nlost+found\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nsnap\nsrv\nsys\ntmp\nusr\nvar\nvmlinuz\n","stdout_lines": ["bin","boot","data","dev","etc","home","initrd.img","lib","lib64","lost+found","media","mnt","opt","proc","root","run","sbin","snap","srv","sys","tmp","usr","var","vmlinuz"]
}

Ansible 常用模块

模块名 说明
file 用于配置文件属性
yum 用于安装软件包
cron 配置计划任务
copy 复制文件到远程主机
command 在远程主机上执行命令
raw 类似于command模块,支持管道
user 配置用户 group:配置用户组
service 用于管理服务
ping 用于检测远程主机是否存活
setup 查看远程主机的基本信息
mount 配置挂载点
  • 展示所有模块
# 查看某模块相关参数
$ ansible-doc -l # 调用某模块,某个参数
$ ansible-doc -s user# -m 调用某个模块, -a 调用该模块下某个参数
$ ansible all -m command -a 'ls /home'

1. setup 模块

  • setup模块: 主要用于获取主机信息,在 playbooks 里经常会用到的一个参数gather_facts就与该模块相关。setup 模块 下经常使用的一个参数是 filter 参数,具体使用示例如下:
# 查看主机内存信息
$ ansible 10.212.52.252 -m setup -a 'filter=ansible_*_mb' # 查看地接口为eth0-2的网卡信息
ansible 10.212.52.252 -m setup -a 'filter=ansible_eth[0-2]' # 将所有主机的信息输入到/tmp/facts目录下,每台主机的信息输入到主机名文件中(/etc/ansible/hosts里的主机名)
$ ansible all -m setup --tree /tmp/facts

2. ping 模块

  • ping 模块:测试主机是否是通的,用法很简单,不涉及参数:
$ ansible test -m ping

3. file 模块

  • file 模块 :主要用于远程主机上的文件操作,file模块包含如下选项:
选项 说明
force 需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
group 定义文件/目录的属组
mode 定义文件/目录的权限
owner 定义文件/目录的属主
path 必选项,定义文件/目录的路径
recurse 递归的设置文件的属性,只对目录有效
src 要被链接的源文件的路径,只应用于state=link的情况
dest 被链接到的路径,只应用于state=link的情况

state:属性

参数 说明
directory 如果目录不存在,创建目录
file 即使文件不存在,也不会被创建
link 创建软链接
hard 创建硬链接
touch 如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent 删除目录、文件或者取消链接文件

使用示例:

$ ansible test -m file -a "src=/etc/fstab dest=/tmp/fstab state=link"
$ ansible test -m file -a "path=/tmp/fstab state=absent"
$ ansible test -m file -a "path=/tmp/test state=touch"

4. copy 模块

  • copy 模块:复制文件到远程主机,copy模块包含如下选项:
参数 说明
backup 在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
content 用于替代"src",可以直接设定指定文件的值
dest 必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
directory_mode 递归的设定目录的权限,默认为系统默认权限
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.

$ ansible test -m copy -a "src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode=0644"$ ansible test -m copy -a "src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes"$ ansible test -m copy -a "src=/mine/sudoers dest=/etc/sudoers validate='visudo -cf %s'"

5. 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 确认该任务计划是创建还是删除
user 以哪个用户的身份执行

示例:

$ ansible test -m cron -a 'name="a job for reboot" special_time=reboot job="/some/job.sh"'$ ansible test -m cron -a 'name="yum autoupdate" weekday="2" minute=0 hour=12 user="root$ ansible test -m cron  -a 'backup="True" name="test" minute="0" hour="5,2" job="ls -alh > /dev/null"'$ ansilbe test -m cron -a 'cron_file=ansible_yum-autoupdate state=absent' 

6. yum 模块

使用yum包管理器来管理软件包,其选项有:

选项 说明
config_file yum 的配置文件
disable_gpg_check 关闭 gpg_check
disablerepo 不启用某个源
enablerepo 启用某个源
name 要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
state 状态(present【安装】,absent【卸载】,latest)
  • 示例如下:
$ ansible test -m yum -a 'name=httpd state=latest'
$ ansible test -m yum -a 'name="@Development tools" state=present'
$ 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'

7. user 模块与 group 模块

user模块是请求的是useradd, userdel, usermod三个指令,goup模块请求的是groupadd, groupdel, groupmod三个指令。

  • user模块:
参数 说明
home 指定用户的家目录,需要与 createhome 配合使用
groups 指定用户的属组
uid 指定用的 uid
password 指定用户的密码
name 指定用户名
createhome 是否创建家目录 yes | no
system 是否为系统用户
remove 当 state=absent 时,remove=yes 则表示连同家目录一起删除,等价于userdel -r
state 是创建还是删除
shell 指定用户的 shell 环境

使用示例:

$ ansible test -m user -a 'createhome=yes home=/home/user1 password=123123 name=user2 state=present shell=/bin/bash'# 参数示例如下:
# user: name=johnd comment="John Doe" uid=1040 group=admin
# user: name=james shell=/bin/bash groups=admins,developers append=yes
# user: name=johnd state=absent remove=yes
# user: name=james18 shell=/bin/zsh groups=developers expires=1422403387
# 生成密钥时,只会生成公钥文件和私钥文件,和直接使用ssh-keygen 指令效果相同,不会生成 authorized_keys 文件。
# user: name=test generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa      

注: 指定password参数时,不能使用明文密码,因为后面这一串密码会被直接传送到被管理主机的/etc/shadow文件中,所以需要先将密码字符串进行加密处理。然后将得到的字符串放到password中即可。

$ echo "123456" | openssl passwd -1 -salt $(< /dev/urandom tr -dc '[:alnum:]' | head -c 32) -stdin
$1$4P4PlFuE$ur9ObJiT5iHNrb9QnjaIB0# 使用上面的密码创建用户
$ ansible all -m user -a 'name=foo password="$1$4P4PlFuE$ur9ObJiT5iHNrb9QnjaIB0"'# 注: 不同的发行版默认使用的加密方式可能会有区别,具体可以查看 /etc/login.defs 文件确认,centos 6.5版本使用的是SHA512加密算法。
  • group 示例
$ ansible all -m group -a 'name=somegroup state=present'

8. synchronize 模块

使用rsync同步文件,其参数如下:

参数 描述
archive 归档,相当于同时开启recursive(递归)、links、perms、times、owner、group、-D选项都为yes ,默认该项为开启
checksum 跳过检测sum值,默认关闭
compress 是否开启压缩
copy_links 复制链接文件,默认为 no ,注意后面还有一个links参数
delete 删除不存在的文件,默认 no
dest 目录路径
dest_port 默认目录主机上的端口 ,默认是22,走的ssh协议
dirs 传速目录不进行递归,默认为no,即进行目录递归
rsync_opts rsync参数部分
set_remote_user 主要用于/etc/ansible/hosts中定义或默认使用的用户与rsync使用的用户不同的情况
mode push 或 pull 模块,push模的话,一般用于从本机向远程主机上传文件,pull 模式用于从远程主机上取文件

使用示例:

src=some/relative/path dest=/some/absolute/path rsync_path="sudo rsync"
src=some/relative/path dest=/some/absolute/path archive=no links=yes
src=some/relative/path dest=/some/absolute/path checksum=yes times=no
src=/tmp/helloworld dest=/var/www/helloword rsync_opts=--no-motd,--exclude=.git mode=pull

9. filesystem 模块

在块设备上创建文件系统

选项 描述
dev 目标块设备
force 在一个已有文件系统 的设备上强制创建
fstype 文件系统的类型
opts 传递给mkfs命令的选项

示例:

$ ansible test -m filesystem -a 'fstype=ext2 dev=/dev/sdb1 force=yes'
$ ansible test -m filesystem -a 'fstype=ext4 dev=/dev/sdb1 opts="-cc"'

10. mount模块

配置挂载点 dump

选项 说明
fstype 必选项,挂载文件的类型
name 必选项,挂载点
opts 传递给 mount 命令的参数
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'

11. get_url 模块

该模块主要用于从httpftphttps服务器上下载文件(类似于wget),主要有如下选项:

名称 说明
sha256sum 下载完成后进行sha256 check
timeout 下载超时时间,默认10s
url 下载的URL
url_password、url_username 主要用于需要用户名密码进行验证的情况
use_proxy 是事使用代理,代理需事先在环境变更中定义

示例:

get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf mode=0440
get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf sha256sum=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c

12. unarchive 模块

用于解压文件,模块包含如下选项:

选项 说明
copy 在解压文件之前,是否先将文件复制到远程主机,默认为yes。若为no,则要求目标主机上压缩包必须存在。
creates 指定一个文件名,当该文件存在时,则解压指令不执行
dest 远程主机上的一个路径,即文件解压的路径
grop 解压后的目录或文件的属组
list_files 如果为yes,则会列出压缩包里的文件,默认为no,2.0版本新增的选项
mode 解决后文件的权限
src 如果copy为yes,则需要指定压缩文件的源路径
owner 解压后文件或目录的属主

示例如下:

- unarchive: src=foo.tgz dest=/var/lib/foo
- unarchive: src=/tmp/foo.zip dest=/usr/local/bin copy=no
- unarchive: src=https://example.com/example.zip dest=/usr/local/bin copy=no

playbooks

  • playbooks 是一种简单的配置管理系统与多机器部署系统的基础.与现有的其他系统有不同之处,且非常适合于复杂应用的部署.
  • playbooks 的格式是YAML(详见: YAML 语法),语法做到最小化,意在避免 playbooks 成为一种编程语言或是脚本,但它也并不是一个配置模型或过程的模型.
  • playbook 由一个或多个 plays 组成.它的内容是一个以 ‘plays’ 为元素的列表.

说明: 在 play 之中,一组机器被映射为定义好的角色.在 ansible 中,play 的内容,被称为 tasks,即任务.在基本层次的应用中,一个任务是一个对 ansible 模块的调用.

1. 用户组

# 自定义远程用户
---
- hosts: webserversremote_user: roottasks:- name: test connetionping: remote_user: yh
# sudo执行
---
- hosts: webserversremote_user: rootsudo: yes
# 单个 tasks 用 sudo 执行
---
- hosts: webserverremote_user: roottasks:- service: name=nginx state=staredsudo: yessudo_user: yh

2. Tasks 列表

每一个play包含一个task列表,每一个task在其所对应的主机上执行完毕后,下一个task才会执行,

3. Handlers

Handlers 最佳的应用场景是用来重启服务,或者触发系统重启操作.除此以外很少用到了。

handlers:- name: restart memcachedservice: name=memcached state=restarted- name: restart apacheservice: name=apache state=restarted

4. playbook 之 Role、Include

假如你希望在多个 play或者多个 playbook中重用同一个task列表,你可以使用include files做到这一点。

tasks- include: tasks/foo.yml

Roles 基于一个已知的文件结构,去自动的加载某些 vars_files,tasks 以及 handlers。基于 roles 对内容进行分组,使得我们可以容易地与其他用户分享 roles 。

这个 playbook 为一个角色 ‘x’ 指定了如下的行为:

  • 如果 roles/x/tasks/main.yml 存在, 其中列出的 tasks 将被添加到 play 中
  • 如果 roles/x/handlers/main.yml 存在, 其中列出的 handlers 将被添加到 play 中
  • 如果 roles/x/vars/main.yml 存在, 其中列出的 variables 将被添加到 play 中
  • 如果 roles/x/meta/main.yml 存在, 其中列出的 “角色依赖” 将被添加到 roles 列表中 (1.3 and later)
  • 所有 copy tasks 可以引用 roles/x/files/ 中的文件,不需要指明文件的路径。
  • 所有 script tasks 可以引用 roles/x/files/ 中的脚本,不需要指明文件的路径。
  • 所有 template tasks 可以引用 roles/x/templates/ 中的文件,不需要指明文件的路径。
  • 所有 include tasks 可以引用 roles/x/tasks/ 中的文件,不需要指明文件的路径。
---- hosts: webserversroles:- { role: some_role, when: "ansible_os_family == 'RedHat'" }

5. Variables

YAML语法要求如果值以{{ foo }}开头的话我们需要将整行用双引号包起来.这是为了确认你不是想声明一个YAML字典.

- hosts: app_serversvars:app_path: "{{ base_path }}/22"

获取远程主机的IP地址或者操作系统是什么,以及硬盘类型、主机名等都可以从中获取。

$ ansibel  hostname   -m setup

有些提供的facts,比如网络信息等,是一个嵌套的数据结构.访问它们使用简单的 {{ foo }} 语法并不够用,当仍然很容易.如下所示:

{{ ansible_eth0["ipv4"]["address"] }}

或者这样写:

{{ ansible_eth0.ipv4.address }}

相似的,以下代码展示了我们如何访问数组的第一个元素:

{{ foo[0] }}

Ansible 会自动提供给你一些变量,即使你并没有定义过它们.这些变量中重要的有 hostvars, group_namesgroups.由于这些变量名是预留的,所以用户不应当覆盖它们. environmen 也是预留的. hostvars 可以让你访问其它主机的变量,包括哪些主机中获取到的 facts.

说明: group_names 是当前主机所在所有群组的列表(数组).所以可以使用Jinja2语法在模板中根据该主机所在群组关系(或角色)来产生变化:

{% if 'webserver' in group_names %}#some part of a configuration file that only applies to webservers
{% endif %}

groups 是inventory中所有群组(主机)的列表.可用于枚举群组中的所有主机.例如:

{% for host in groups['app_servers'] %}# something that applies to all app servers.
{% endfor %}
  • 变量文件分割

把playbook置于源代码管理之下是个很好的注意,当你可能会想把playbook源码公开之余还想保持某些重要的变量私有.有时你也想把某些信息放置在不同的文件中,远离主playbook文件

你可以使用外部的变量文件来实现:

---- hosts: allremote_user: rootvars:favcolor: bluevars_files:- /vars/external_vars.ymltasks:- name: this is just a placeholdercommand: /bin/echo foo

这可以保证你共享playbook源码时隔离敏感数据的风险.

每个变量文件的内容是一个简单的YAML文件,如下所示:

---
# in the above example, this would be vars/external_vars.yml
somevar: somevalue
password: magic
  • 命令行中传参
        除了vars_promptvars_files也可以通过Ansible命令行发送变量.如果你想编写一个通用的发布playbook时则特别有用,你可以传递应用的版本以便部署:
ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"

其它场景中也很有用,比如为playbook设置主机群组或用户.

# Example:---- hosts: '{{ hosts }}'remote_user: '{{ user }}'tasks:- ...
$ ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"

6. 条件选择 when

tasks:- name: "shutdown Debian flavored systems"command: /sbin/shutdown -t nowwhen: ansible_os_family == "Debian"
tasks:- shell: echo "only on Red Hat 6, derivatives, and later"when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6

如果一个变量不存在,你可以使用Jinja2的defined命令跳过或略过.例如:

tasks:- shell: echo "I've got '{{ foo }}' and am not afraid to use it!"when: foo is defined- fail: msg="Bailing out. this play requires 'bar'"when: bar is not defined

7. 条件导入

举个例子,名字叫做Apache的包,在CentOSDebian系统中也许不同, 但是这个问题可以一些简单的语法就可以被Ansible Playbook解决:

---
- hosts: allremote_user: rootvars_files:- "vars/common.yml"- [ "vars/{{ ansible_os_family }}.yml", "vars/os_defaults.yml" ]tasks:- name: make sure apache is runningservice: name={{ apache }} state=running

8. 基于变量选择文件或者模板

有时候,你想要复制一个配置文件,或者一个基于参数的模版. 下面的结构选载选第一个宿主给予的变量文件,这些可以比把很多if选择放在模版里要简单的多. 下面的例子展示怎样根据不同的系统,例如CentOS,Debian制作一个配置文件的模版:

- name: template a filetemplate: src={{ item }} dest=/etc/myapp/foo.confwith_first_found:- files:- {{ ansible_distribution }}.conf- default.confpaths:- search_location_one/somedir/- /opt/other_location/somedir/

9. 注册变量

register关键词决定了把结果存储在哪个变量中.结果参数可以用在模版中,动作条目,或者 when 语句. 像这样(这是一个浅显的例子):

- name: test playhosts: alltasks:- shell: cat /etc/motdregister: motd_contents- shell: echo "motd contains the word hi"when: motd_contents.stdout.find('hi') != -1

10. 循环

功能 关键字 说明
标准循环 with_items
嵌套循环 with_nested
哈希列表循环 with_dict 【编译一个集合中的key和value】
文件列表循环 with_fileglob 【遍历一个目录下所有文件】
并行数据使用循环 with_together 【将两个数组一对一遍历成集合】
对子元素进行循环 with_subelements 【用来加载一个yml文件中的各元素以及子元素】
对整数序列采用循环 with_sequence 【循环某段整数之间的数字】
生成随机数字 random_choice
Do_until循环 until 【通过设定循环次数和循环时间等待服务达到某种状态】
查找第一个匹配的文件 with_fist_found
使用索引循环列表 with_indexd_items 【循环列表的同时可以换取索引所在位置】
循环匹配文件 with_ini 【ini插件可以使用正则表达式来获取一组键值对】
扁平化列表 with_flattened 【循环迭代多层嵌套列表】
循环中使用注册器 with_items 【循环获取registry的results】

10.1. 标准循环

为了保持简洁,重复的任务可以用以下简写的方式:

- name: add several usersuser: name={{ item }} state=present groups=wheelwith_items:- testuser1- testuser2

如果你在变量文件中或者 vars 区域定义了一组YAML列表,你也可以这样做:

with_items: "{{somelist}}"

以上写法与下面是完全等同的:

- name: add user testuser1user: name=testuser1 state=present groups=wheel
- name: add user testuser2user: name=testuser2 state=present groups=wheel

使用 with_items 用于迭代的条目类型不仅仅支持简单的字符串列表.如果你有一个哈希列表,那么你可以用以下方式来引用子项:

- name: add several usersuser: name={{ item.name }} state=present groups={{ item.groups }}with_items:- { name: 'testuser1', groups: 'wheel' }

10.2. 嵌套循环

循环也可以嵌套:

- name: give users access to multiple databasesmysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foowith_nested:- [ 'alice', 'bob' ]- [ 'clientdb', 'employeedb', 'providerdb' ]

和以上介绍的’with_items’一样,你也可以使用预定义变量.:

- name: here, 'users' contains the above list of employeesmysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foowith_nested:- "{{users}}"- [ 'clientdb', 'employeedb', 'providerdb' ]

10.3. 对哈希表使用循环

假如你有以下变量:

---
users:alice:name: Alice Appleworthtelephone: 123-456-7890bob:name: Bob Bananaramatelephone: 987-654-3210

你想打印出每个用户的名称和电话号码.你可以使用 with_dict 来循环哈希表中的元素:

tasks:- name: Print phone recordsdebug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"with_dict: "{{users}}"

10.4. 对文件列表使用循环

with_fileglob 可以以非递归的方式来模式匹配单个目录中的文件

---
- hosts: alltasks:# first ensure our target directory exists- file: dest=/etc/fooapp state=directory# copy each file over that matches the given pattern- copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600with_fileglob:- /playbooks/files/fooapp/*

10.5. 对并行数据采用循环

假设你通过某种方式加载了以下变量数据:

---
alpha: [ 'a', 'b', 'c', 'd' ]
numbers:  [ 1, 2, 3, 4 ]

如果你想得到’(a, 1)’和’(b, 2)’之类的集合.可以使用’with_together’:

tasks:- debug: msg="{{ item.0 }} and {{ item.1 }}"with_together:- "{{alpha}}"- "{{numbers}}"

10.7. 对子元素进行循环

假设你想对一组用户做一些动作,比如创建这些用户,并且允许它们使用一组SSH key来登录.

如何实现那? 先假设你有按以下方式定义的数据,可以通过 vars_filesgroup_vars/all 文件加载:

---
users:- name: aliceauthorized:- /tmp/alice/onekey.pub- /tmp/alice/twokey.pubmysql:password: mysql-passwordhosts:- "%"- "127.0.0.1"- "::1"- "localhost"privs:- "*.*:SELECT"- "DB1.*:ALL"- name: bobauthorized:- /tmp/bob/id_rsa.pubmysql:password: other-mysql-passwordhosts:- "db1"privs:- "*.*:SELECT"- "DB2.*:ALL"

那么可以这样实现:

- user: name={{ item.name }} state=present generate_ssh_key=yeswith_items: "{{users}}"- authorized_key: "user={{ item.0.name }} key='{{ lookup('file', item.1) }}'"with_subelements:- users- authorized

根据 mysql hosts 以及预先给定的 privs subkey 列表,我们也可以在嵌套的 subkey 中迭代列表:

- name: Setup MySQL usersmysql_user: name={{ item.0.user }} password={{ item.0.mysql.password }} host={{ item.1 }} priv={{ item.0.mysql.privs | join('/') }}with_subelements:- users- mysql.hosts

10.8. 对整数序列进行循环

with_sequence 可以以升序数字顺序生成一组序列.你可以指定起始值、终止值,以及一个可选的步长值.

指定参数时也可以使用key=value这种键值对的方式.如果采用这种方式,’format’是一个可打印的字符串.

数字值可以被指定为10进制,16进制(0x3f8)或者八进制(0600).负数则不受支持.请看以下示例:

---
- hosts: alltasks:# create groups- group: name=evens state=present- group: name=odds state=present# create some test users- user: name={{ item }} state=present groups=evenswith_sequence: start=0 end=32 format=testuser%02x# create a series of directories with even numbers for some reason- file: dest=/var/stuff/{{ item }} state=directorywith_sequence: start=4 end=16 stride=2# a simpler way to use the sequence plugin# create 4 groups- group: name=group{{ item }} state=presentwith_sequence: count=4

10.9. 随机选择

random_choice功能可以用来随机获取一些值.它并不是负载均衡器(已经有相关的模块了).它有时可以用作一个简化版的负载均衡器,比如作为条件判断:

- debug: msg={{ item }}# 提供的字符串中的其中一个会被随机选中.with_random_choice:- "go through the door"- "drink from the goblet"- "press the red button"- "do nothing"

10.10 Do-Until 循环

有时你想重试一个任务直到达到某个条件.比如下面这个例子:

- action: shell /usr/bin/fooregister: resultuntil: result.stdout.find("all systems go") != -1retries: 5delay: 10

说明: 上面的例子递归运行shell模块,直到模块结果中的stdout输出中包含all systems go字符串,或者该任务按照10秒的延迟重试超过5次.retriesdelay的默认值分别是3和5.
该任务返回最后一个任务返回的结果.单次重试的结果可以使用-vv选项来查看. 被注册的变量会有一个新的属性attempts,值为该任务重试的次数.

10.11. 查找第一个匹配文件

这其实不是一个循环,但和循环很相似.如果你想引用一个文件,而该文件是从一组文件中根据给定条件匹配出来的.这组文件中部分文件名由变量拼接而成.针对该场景你可以这样做:

- name: INTERFACES | Create Ansible header for /etc/network/interfacestemplate: src={{ item }} dest=/etc/foo.confwith_first_found:- "{{ansible_virtualization_type}}_foo.conf"- "default_foo.conf"

该功能还有一个更完整的版本,可以配置搜索路径.

- name: some configuration templatetemplate: src={{ item }} dest=/etc/file.cfg mode=0444 owner=root group=rootwith_first_found:- files:- "{{inventory_hostname}}/etc/file.cfg"paths:- ../../../templates.overwrites- ../../../templates- files:- etc/file.cfgpaths:- templates

当对处于循环中的某个数据结构使用 register 来注册变量时,结果包含一个 results 属性,这是从模块中得到的所有响应的一个列表.

以下是在 with_items 中使用 register 的示例:

- shell: echo "{{ item }}"with_items:- one- tworegister: echo 

返回的数据结构如下,与非循环结构中使用 register 的返回结果是不同的:

{"changed": true,"msg": "All items completed","results": [{"changed": true,"cmd": "echo \"one\" ","delta": "0:00:00.003110","end": "2013-12-19 12:00:05.187153","invocation": {"module_args": "echo \"one\"","module_name": "shell"},"item": "one","rc": 0,"start": "2013-12-19 12:00:05.184043","stderr": "","stdout": "one"},{"changed": true,"cmd": "echo \"two\" ","delta": "0:00:00.002920","end": "2013-12-19 12:00:05.245502","invocation": {"module_args": "echo \"two\"","module_name": "shell"},"item": "two","rc": 0,"start": "2013-12-19 12:00:05.242582","stderr": "","stdout": "two"}]
}

随后的任务可以用以下方式来循环注册变量,用来检查结果值:

- name: Fail if return code is not 0fail:msg: "The command ({{ item.cmd }}) did not have a 0 return code"when: item.rc != 0with_items: "{{echo.results}}"

自动化运维: Ansible相关推荐

  1. 自动化运维—ansible

    2019独角兽企业重金招聘Python工程师标准>>> 自动化运维-ansible 一.Ansible介绍 Ansilbe是一个部署一群远程主机的工具.远程的主机可以是远程虚拟机或物 ...

  2. 自动化运维---ansible常用模块之文件操作(findreplace模块)

    自动化运维-ansible常用模块之文件操作(find&replace模块) 文章目录 自动化运维---ansible常用模块之文件操作(find&replace模块) 1.find模 ...

  3. linux自动化运维ansible

    linux自动化运维ansible 一.概述 二.安装 1.配置安装源 2.安装 3.查询版本信息 三.设置主机清单 1.添加ip及账号信息 2.修改主配置文件 3.测试是否成功 四.模块应用 1.模 ...

  4. 企业自动化运维ansible

    自动化运维工具ansible 运维自动化发展历程及技术应用 云计算工程师核心职能 Linux运维工程师职能划分 自动化动维应用场景 文件传输 命令执行 应用部署 配置管理 任务流编排 企业实际应用场景 ...

  5. 自动化运维-Ansible详解

    ansible 简介 ansible 是什么? ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.chef.func.fabric)的优点,实现了批量系统 ...

  6. 自动化运维-Ansible 运维自动化 ( 配置管理工具 )

    当下有许多的运维自动化工具( 配置管理 ),例如:Ansible.SaltStack.Puppet.Fabric 等. Ansible 一种集成 IT 系统的配置管理.应用部署.执行特定任务的开源平台 ...

  7. 自动化运维-Ansible(redhat 8)

    在控制节点安装Ansible redhat 8自带python 3:如果没有安装,需要自行安装 查看是否安装python3 [root@localhost ~]# yum list installed ...

  8. 自动化运维-Ansible (第三部:Playbook 介绍)

    前言 之前有两篇文章分别讲了 Ansible 的部署.Ansible 的 模块使用,对 Ansible 有了最初的了解,这篇文章最主要是要介绍 Playbook. 需要了解 Ansible 的部署请点 ...

  9. 自动化运维工具Ansible详细部署

    一.基础介绍 ================================================================================= 1.简介 ansibl ...

最新文章

  1. 暴涨!BTC忠实粉丝转向BCH为BCH网络添砖加瓦
  2. 世界公认最好的记忆方法_世界记忆大师:6种简单实用记忆方法,让孩子成为学霸中学霸...
  3. 22.网络提速(最短路)
  4. 21. Leetcode 203. 移除链表元素 (链表-基础操作类-删除链表的节点)
  5. K8s 原生 Serverless 实践:ASK 与 Knative
  6. UOJ - #117. 欧拉回路(模板)
  7. 《深入浅出数据分析》第十二章——R语言lattice数据包
  8. HTML期末作业-中国足球网页
  9. java程序崩溃查询,java – 有程序识别它上次崩溃了吗?
  10. 图示SaaS:走向平台化,会产生什么变化?
  11. m3u8 video ios h5_移动端H5页面踩坑记
  12. 复合类型(json)
  13. 【框架-MFC】MFC 显示和隐藏 星号密码 以及如何预防被查看
  14. 解决adobe reader XI 打开后闪退问题,亲测有效
  15. 五千来字小作文,是的,我们是有个HTTP。
  16. SDUT 2504 多项式求和
  17. Java-数据库编程技术(MySQL)
  18. BT种子和BitTorrent协议
  19. 你否有遇到Spring事务失效,花费太多时间找bug
  20. 1. 深度生成模型-扩散模型(非均衡热力学的深度无监督学习)

热门文章

  1. 【Unity3D 游戏】 打飞机(仿微信打飞机) 源码
  2. 计算机音乐数字 98k,98k音乐数字谱 | 手游网游页游攻略大全
  3. 三年开发经验,字节跳动抖音组离职后,一口气拿到15家公司Offer
  4. 一位技术人的聚合支付项目经历
  5. 雷尼绍激光干涉仪丨汽车零部件加工在线快速检测方案
  6. DSPIC30F BLDC三相无刷电机驱动资料(速度开环/闭环PID控制)
  7. 所有问题计算机解决,为什么重新启动计算机可以解决许多问题? | MOS86
  8. 力天创见客流施工方案
  9. SQL 课堂作业答案
  10. 标准差和均方根误差的区别总结