Ansible — 编程 — 条件与循环
Posted 范桂飓
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ansible — 编程 — 条件与循环相关的知识,希望对你有一定的参考价值。
目录
文章目录
When 条件语句
条件执行 — 在 tasks 中使用 when 语句
- 基于布尔值来决定一个任务是否被执行:
vars:
epic: true
tasks:
- shell: echo "This certainly is epic!"
when: epic
# or
tasks:
- shell: echo "This certainly isn't epic!"
when: not epic
- 基于字符串比对来决定任务是否执行:
tasks:
- name: "shutdown Debian flavored systems"
command: /sbin/shutdown -t now
when: ansible_os_family == "Debian"
- 基于注册变量(返回结果)来决定任务是否执行:
tasks:
- command: /bin/false
register: result
ignore_errors: True
- command: /bin/something
when: result|failed
- command: /bin/something_else
when: result|success
- command: /bin/still/something_else
when: result|skipped
- 基于复合条件来决定任务是否执行:
tasks:
- shell: echo "only on Red Hat 6, derivatives, and later"
when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6
- 基于一个变量是否存在来决定任务是否执行:
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
条件执行 — 在 roles 中使用 when 语句
- hosts: webservers
roles:
- { role: debian_stock_config, when: ansible_os_family == 'Debian' }
条件导入 — 在 includes 中使用 when 语句
NOTE:仅在 task include 场景中有用。
- include: tasks/sometasks.yml
when: "'reticulating splines' in output"
循环
with_items 标准循环
- 根据 with_items 循环执行 user Module:
# List 场景
- name: add several users
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2
# Dict 场景
- name: add several users
user: name={{ item.name }} state=present groups={{ item.groups }}
with_items:
- { name: 'testuser1', groups: 'wheel' }
- { name: 'testuser2', groups: 'root' }
with_sequence 对整数序列使用循环
with_sequence 以升序数字顺序生成一组序列,可以指定起始值、终止值、以及一个可选的步长值。数字值可以被指定为 10 进制、16 进制、八进制,负数则不受支持。
---
- hosts: all
tasks:
# create groups
- group: name=evens state=present
- group: name=odds state=present
# create some test users
- user: name={{ item }} state=present groups=evens
with_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=directory
with_sequence: start=4 end=16 stride=2
# a simpler way to use the sequence plugin
# create 4 groups
- group: name=group{{ item }} state=present
with_sequence: count=4
with_nested 嵌套循环
- 使用 with_nested 定义一个 二重嵌套循环。
- 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' ]
with_dict 对哈希表使用循环
- 定义哈希表变量:
---
users:
alice:
name: Alice Appleworth
telephone: 123-456-7890
bob:
name: Bob Bananarama
telephone: 987-654-3210
- 通过 with_dict 对哈希表使用循环:
tasks:
- name: Print phone records
debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
with_dict: "{{users}}"
with_fileglob 对文件列表使用循环
- with_fileglob 以非递归的方式来循环指定目录下的文件。
---
- hosts: all
tasks:
# 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=600
with_fileglob:
- /playbooks/files/fooapp/*
NOTE:当在 Role 中对 with_fileglob 使用相对路径时,Ansible 会把路径映射到 roles/{rolename}/files 目录下。
with_subelements 对子元素使用循环
- 编写一个数据结构:
---
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"
- 通过 with_subelements 对子元素使用循环:
- 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.user }} password={{ item.0.mysql.password }} host={{ item.1 }} priv={{ item.0.mysql.privs | join('/') }}
with_subelements:
- users
- mysql.hosts
with_random_choice 随机选择循环
with_random_choice 可以用来随机获取一些值,例如:提供的字符串列表中的其中一个会被随机选中。
- debug: msg={{ item }}
with_random_choice:
- "go through the door"
- "drink from the goblet"
- "press the red button"
- "do nothing"
Do-Until 循环
有时你希望一直重试某个任务直到某个条件,这时可以使用 Do-Until 循环:
- action: shell /usr/bin/foo
register: result
until: result.stdout.find("all systems go") != -1
retries: 5
delay: 10
with_ini 循环 INI 配置文件
- ini 配置文件
[section1]
value1=section1/value1
value2=section1/value2
[section2]
value1=section2/value1
value2=section2/value2
- 通过 with_ini 循环 INI 配置文件
- debug: msg="{{item}}"
with_ini: value[1-2] section=section1 file=lookup.ini re=true
- 以下是返回的值:
{
"changed": false,
"msg": "All items completed",
"results": [
{
"invocation": {
"module_args": "msg=\\"section1/value1\\"",
"module_name": "debug"
},
"item": "section1/value1",
"msg": "section1/value1",
"verbose_always": true
},
{
"invocation": {
"module_args": "msg=\\"section1/value2\\"",
"module_name": "debug"
},
"item": "section1/value2",
"msg": "section1/value2",
"verbose_always": true
}
]
}
在循环中使用注册器
当对处于循环中的某个数据结构使用 register 来注册变量时,会得到一个 results 变量,它是所有响应的一个列表。
- 在 with_items 中使用 register:
- shell: echo "{{ item }}"
with_items:
- one
- two
register: echo
- 返回的数据结构如下:
{
"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 0
fail:
msg: "The command ({{ item.cmd }}) did not have a 0 return code"
when: item.rc != 0
with_items: "{{echo.results}}"
以上是关于Ansible — 编程 — 条件与循环的主要内容,如果未能解决你的问题,请参考以下文章
ansible自动化运维详解ansible中的任务执行控制及实例演示:循环条件判断触发器处理失败任务
ansible自动化运维详解ansible中的任务执行控制及实例演示:循环条件判断触发器处理失败任务
Ansible 学习总结—— Ansible 循环条件判断触发器处理失败等任务控制使用总结