1.Ansible Task控制概述
在Ansible中,任务控制指的是通过一些选项来控制任务的行为。以下是一些常用的任务控制选项:
ignore_errors:当设置为yes时,即使任务失败,Ansible也会继续执行后续的任务。默认情况下,当任务失败时,Ansible会停止执行后续的任务。例如:
- name: 执行命令 command: some_command ignore_errors: yes
在这个示例中,即使some_command命令执行失败,Ansible也会继续执行后续的任务。
changed_when:用于指定任务在何种情况下被认为已经改变了系统状态。默认情况下,Ansible会根据模块的返回值来判断任务是否改变了系统状态。但有时模块的返回值并不能准确反映系统状态的改变,因此可以使用changed_when选项来自定义判断条件。例如:
- name: 创建目录 file: path: /path/to/directory state: directory changed_when: false
在这个示例中,无论目录是否已经存在,该任务都不会被标记为已改变系统状态。
failed_when:用于指定任务在何种情况下被认为失败。默认情况下,当任务的返回值为非零时,任务被标记为失败。但有时任务的返回值并不能准确反映任务是否成功,因此可以使用failed_when选项来自定义判断条件。例如:
- name: 检查文件是否存在 stat: path: /path/to/file register: file_info failed_when: file_info.stat.exists == False
在这个示例中,如果指定路径的文件不存在,任务将被标记为失败。
除了上述常用的任务控制选项外,还有一些其他选项可以进一步控制任务的行为,例如changed_callback选项可以指定一个回调插件来处理任务改变系统状态的通知。
任务控制选项可以根据需要进行组合和嵌套使用,以实现更复杂的任务控制逻辑。请参考Ansible官方文档以获取更详细的信息和示例
官网
2.Playbook条件语句
在Ansible Playbook中,可以使用条件语句来根据不同的条件执行不同的任务。以下是一些常用的条件语句:
when语句:when语句用于在任务级别上执行条件判断。只有当条件为真时,才会执行该任务。例如:
- name: 安装软件包 yum: name: mypackage state: present when: ansible_os_family == 'RedHat'
在这个示例中,只有当ansible_os_family变量的值为RedHat时,才会执行安装软件包的任务。
block语句:block语句用于在任务组级别上执行条件判断。可以将多个任务组合在一个block中,并根据条件判断是否执行该block。例如:
- name: 安装软件包 block: - name: 安装软件包(RedHat) yum: name: mypackage state: present when: ansible_os_family == 'RedHat' - name: 安装软件包(Debian) apt: name: mypackage state: present when: ansible_os_family == 'Debian'
在这个示例中,根据ansible_os_family变量的值,选择执行不同的安装软件包任务。
include语句:include语句用于在Playbook中包含其他的Playbook文件,并根据条件判断是否包含。例如:
- name: 执行任务 include: tasks.yml when: ansible_os_family == 'RedHat'
在这个示例中,只有当ansible_os_family变量的值为RedHat时,才会包含tasks.yml文件中的任务。
除了上述条件语句外,还可以使用vars语句来定义变量,并根据条件设置不同的变量值。还可以使用failed_when语句来根据条件将任务标记为失败。
条件语句可以根据需要进行组合和嵌套使用,以实现更复杂的条件逻辑。请参考Ansible官方文档以获取更详细的信息和示例
官网
when
ansible_facts:一个字典,包含 Ansible 事实(facts)
ansible_hostname:远程主机的主机名
ansible_distribution:远程主机的发行版
ansible_distribution_version:远程主机的发行版版本ansible_distribution_major_version:远程主机的发行版主要版本
ansible_architecture:远程主机的架构
ansible_os_family:远程主机的操作系统家族
ansible_system:远程主机的操作系统名称
ansible_virtualization_type:远程主机的虚拟化类型
ansible_check_mode:指定是否处于 Ansible 的检查模式
ansible_run_tags:一个列表,包含当前执行的任务的标签
ansible_skip_tags:一个列表,包含当前跳过的任务的标签
ansible_verbosity:指定 Ansible 的详细程度级别
inventory_hostname:远程主机在 Ansible 渲染期间的主机名inventory_hostname_short:远程主机在 Ansible 渲染期间的短主机名
groups:一个字典,包含主机组的信息
group_names:一个列表,包含当前主机所属的主机组
hostvars:一个字典,包含所有主机的变量
vars:一个字典,包含所有变量
vars_file:一个列表,包含从变量文件加载的变量
vars_files:一个列表,包含从变量文件加载的变量
ansible_env:一个字典,包含远程主机的环境变量
ansible_all_ipv4_addresses:一个列表,包含远程主机的所有 IPv4 地址ansible_all_ipv6_addresses:一个列表,包含远程主机的所有 IPv6 地址ansible_default_ipv4:一个字典,包含远程主机的默认 IPv4 地址ansible_default_ipv6:一个字典,包含远程主机的默认 IPv6 地址
根据不同操作系统,安装相同的软件包
添加
[centubt]
172.16.1.121(ubuntu)
172.16.1.145
剧本
[root@ansible /server/playbook]$ cat 10when.yml --- - hosts: centubt tasks: - name: CentOS install cowsay yum: name: - cowsay state: present when: ( ansible_distribution == "CentOS" ) - name: Ubuntu install cmatrix apt: name: - cmatrix state: present when: ( ansible_distribution == "Ubuntu" )
[root@ansible /server/playbook]$ ansible-playbook 10when.yml PLAY [centubt] **************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************** ok: [172.16.1.145] ok: [172.16.1.121] TASK [CentOS install cowsay] ************************************************************************************************** skipping: [172.16.1.121] changed: [172.16.1.145] TASK [Ubuntu install cmatrix] ************************************************************************************************* skipping: [172.16.1.145] changed: [172.16.1.121] PLAY RECAP ******************************************************************************************************************** 172.16.1.121 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 172.16.1.145 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
所有为web主机名的添加nginx仓库,其余的都跳过添加
剧本
[root@ansible /server/playbook]$ cat 11when-nginx.yml --- - hosts: all tasks: - name: Add yum Nginx yum_repository: name: nginx description: nginx repo baseurl: http://nginx.org/packages/centos/$releasever/$basearch/ enabled: yes gpgcheck: yes when: ( ansible_hostname is match("web") )
也可以使用and与or方式
when: (ansible_hostname is match(“web”)) or
(ansible_hostname is match(“lb”))
when: (ansible_hostname is match(“web”)) and
(ansible_hostname is match(“lb”))
根据前者命令执行的结果进行判断
通过register将命令执行结果保存至变量,然后通过when语句进行判断
剧本
[root@ansible /server/playbook]$ cat 12register-when.yml --- - hosts: web tasks: - name: Nginx Server command: systemctl is-active nginx ignore_errors: yes register: check_nginx - name: debug outprint debug: var: check_nginx - name: nginx restart service: name: nginx state: restarted when: check_nginx.rc == 0
when条件语句小结
当条件语句是 Ansible Playbook 中的一个重要组成部分,它允许您根据一些条件来控制任务的执行。以下是一些关键点的小结:
when 关键字用于定义条件语句,并根据条件的结果来决定是否执行任务
条件语句可以使用 Ansible 提供的事实(facts)和变量来构建
条件语句可以使用比较运算符(例如 ==、!=、>、<、>=、<=)来比较值
可以使用逻辑运算符(例如 and、or、not)来组合多个条件
可以使用正则表达式来匹配字符串
可以使用列表、字典和其他数据结构来检查值是否存在或满足特定条件
可以使用 Ansible 提供的事实(facts)和变量来获取有关远程主机的信息
可以使用 Ansible 的内置函数(例如 hostvars、groups、inventory_hostname)来访问有关主机和组的信息
可以使用 Ansible 的环境变量(例如 ansible_env)来获取有关远程主机的环境信息
可以使用 Ansible 的运行时变量(例如 ansible_check_mode、ansible_run_tags)来获取有关 Playbook 执行的信息
通过灵活使用条件语句,您可以根据不同的情况来动态地控制任务的执行,从而使 Ansible Playbook 更加灵活和可配置。有关更详细的信息和示例,请参阅 Ansible 官方文档中的条件语句部分
官网
3.Playbook循环语句
在 Ansible Playbook 中,循环语句可以使用多个模块来执行迭代操作。以下是一些常用的循环语句模块及其参数列表和详细说明
loop 模块
loop: 定义要迭代的列表或字典。
loop_control: 控制循环行为的选项。
loop_var: 指定循环变量的名称。
label: 指定循环的标签。
extended: 扩展循环变量的功能。
pause: 在迭代之间添加延迟。
delay: 设置延迟的秒数。timeout: 设置循环超时的秒数。
retries: 设置循环重试的次数。
retry_interval: 设置循环重试之间的间隔。
continue: 控制循环是否继续。
skip_errors: 控制是否跳过错误。
tag: 为循环添加标签。
示例:
- name: Loop example hosts: all tasks: - name: Print fruits debug: msg: "{{ item }}" loop: - apple - banana - orange
with_items 模块
with_items: 定义要迭代的列表或字典。
loop_control: 控制循环行为的选项。
示例
- name: Loop example hosts: all tasks: - name: Print fruits debug: msg: "{{ item }}" with_items: - apple - banana - orange
with_dict 模块
with_dict: 定义要迭代的字典。
loop_control: 控制循环行为的选项。
示例
- name: Loop example hosts: all tasks: - name: Print users debug: msg: "User {{ item.key }} has id {{ item.value }}" with_dict: user1: 1001 user2: 1002 user3: 1003
with_fileglob 模块
with_fileglob: 定义要迭代的文件路径模式。
loop_control: 控制循环行为的选项。
示例
- name: Loop example hosts: all tasks: - name: Print files debug: msg: "{{ item }}" with_fileglob: - /path/to/files/*.txt
with_sequence 模块
with_sequence: 定义要迭代的数字序列。
loop_control: 控制循环行为的选项。
示例
- name: Loop example hosts: all tasks: - name: Print numbers debug: msg: "{{ item }}" with_sequence: - start=1 end=5
循环语句模块允许您在循环中使用变量,并根据需要进行条件判断和控制循环行为。您可以使用模块提供的选项来定制循环的行为,例如设置循环索引、跳过迭代或中止循环等
官网
在 Ansible Playbook 中,您可以使用循环语句结合 vars 关键字来定义循环中的变量。vars 关键字后面可以跟一个字典,其中包含了循环变量的定义。下面是 vars 关键字的完整参数说明:
name(可选):用于标识变量定义块的名称
loop(可选):指定要循环迭代的列表或字典
with_items(可选):与 loop 相同,用于指定要循环迭代的列表或字典
with_dict(可选):与 loop 相同,用于指定要循环迭代的字典
when(可选):指定一个条件,只有当条件为真时才会执行变量定义块
loop_control(可选):用于控制循环的行为,可以包含以下参数:
loop_var:指定循环变量的名称,默认为 item
loop_index:指定循环索引的名称,默认为 ansible_loop.index
loop_first:指定一个变量名称,用于判断是否是第一次迭代,默为 ansible_loop.first
loop_last:指定一个变量名称,用于判断是否是最后一次迭代,默认为 ansible_loop.last
loop_length:指定一个变量名称,用于获取循环迭代的总长度,默认为 ansible_loop.length
下面是一个使用循环语句和 vars
关键字的示例,其中包含了上述参数的使用:
- name: Loop example hosts: all tasks: - name: Define variables vars: fruit_list: - apple - banana - orange loop: "{{ fruit_list }}" when: inventory_hostname == 'host1' loop_control: loop_var: my_fruit loop_index: my_index loop_first: is_first loop_last: is_last loop_length: total_count debug: msg: "Fruit: {{ my_fruit }}, Index: {{ my_index }}, First: {{ is_first }}, Last: {{ is_last }}, Total: {{ total_count }}"
在这个示例中,我们使用 vars 关键字定义了一个名为 fruit_list 的变量,然后使用 loop 参数指定了要循环迭代的列表。我们还使用了 when 参数来指定只有在 inventory_hostname 为 ‘host1’ 时才会执行变量定义块。使用 loop_control 参数来控制循环的行为,包括指定循环变量名称 my_fruit、循环索引名称 my_index、第一次迭代的变量名称 is_first、最后一次迭代的变量名称 is_last 和循环迭代的总长度的变量名称 total_count。最后,我们使用 debug 模块打印出循环变量和控制变量的值。
通过使用循环语句和 vars 关键字的完整参数,您可以更灵活地定义和控制循环中的变量,并根据需要进行条件判断和控制循环行为。有关更多详细信息和示例,请参阅 Ansible 官方文档中的循环语句和变量部分
官网
使用循环启动多个服务
剧本
[root@ansible /server/playbook]$ cat 13circulate.yml --- - hosts: web tasks: - name: restart all systemd: name: "{{ item }}" state: restarted with_items: - nginx - php-fpm - sshd - crond [root@ansible /server/playbook]$ ansible-playbook 13circulate.yml PLAY [web] ******************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************** ok: [172.16.1.45] ok: [172.16.1.145] TASK [restart all] ************************************************************************************************************ changed: [172.16.1.145] => (item=nginx) changed: [172.16.1.45] => (item=nginx) changed: [172.16.1.145] => (item=php-fpm) changed: [172.16.1.45] => (item=php-fpm) changed: [172.16.1.145] => (item=sshd) changed: [172.16.1.45] => (item=sshd) changed: [172.16.1.145] => (item=crond) changed: [172.16.1.45] => (item=crond) PLAY RECAP ******************************************************************************************************************** 172.16.1.145 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 172.16.1.45 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
定义变量方式循环
使用定义变量方式循环安装软件包(部分命令不支持)
剧本
[root@ansible /server/playbook]$ cat 14pack.yml --- - hosts: web tasks: - name: yum software yum: name: "{{ package }}" state: present vars: package: - nginx - tree
[root@ansible /server/playbook]$ ansible-playbook 14pack.yml PLAY [web] ******************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************** ok: [172.16.1.145] ok: [172.16.1.45] TASK [yum software] *********************************************************************************************************** ok: [172.16.1.145] ok: [172.16.1.45] PLAY RECAP ******************************************************************************************************************** 172.16.1.145 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 172.16.1.45 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
使用字典循环方式创建用户和批量拷贝文件
批量创建用户,使用key values字典的方式
剧本
[root@ansible /server/playbook]$ cat 15user.yml --- - hosts: web tasks: - name: useradd user: name: "{{ item.name }}" uid: "{{ item.uid }}" state: present with_items: - { name: 'Demon' , uid: 789 } - { name: 'devil' , uid: 891 } - { name: 'angel' , uid: 987 }
[root@ansible /server/playbook]$ ansible-playbook 15user.yml PLAY [web] ******************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************** ok: [172.16.1.145] ok: [172.16.1.45] TASK [useradd] **************************************************************************************************************** changed: [172.16.1.145] => (item={u'name': u'Demon', u'uid': 789}) changed: [172.16.1.45] => (item={u'name': u'Demon', u'uid': 789}) changed: [172.16.1.145] => (item={u'name': u'devil', u'uid': 891}) changed: [172.16.1.45] => (item={u'name': u'devil', u'uid': 891}) changed: [172.16.1.45] => (item={u'name': u'angel', u'uid': 987}) changed: [172.16.1.145] => (item={u'name': u'angel', u'uid': 987}) PLAY RECAP ******************************************************************************************************************** 172.16.1.145 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 172.16.1.45 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible /server/playbook]$ ansible web -a 'tail -3 /etc/passwd' 172.16.1.45 | CHANGED | rc=0 >> Demon:x:789:1003::/home/Demon:/bin/bash devil:x:891:1004::/home/devil:/bin/bash angel:x:987:1005::/home/angel:/bin/bash 172.16.1.145 | CHANGED | rc=0 >> Demon:x:789:1003::/home/Demon:/bin/bash devil:x:891:1004::/home/devil:/bin/bash angel:x:987:1005::/home/angel:/bin/bash