Ansible 如何循环执行一系列任务?
How can Ansible loop over a sequence of tasks?
Ansible playbook loop 如何完成一系列任务?我希望实现一个执行任务序列直到任务成功的轮询循环。当它失败时,异常处理程序将尝试修复条件,然后循环将重复任务序列。
考虑以下假想的例子:
- action:
- block:
- debug: msg='i execute normally'
- command: /bin/foo
rescue:
- debug: msg='I caught an error'
- command: /bin/fixfoo
always:
- debug: msg="this always executes"
register: result
until: result
retries: 5
delay: 10
在 Ansible 中 1.x 这根本无法完成。只是不是那样设计的。
Ansible 2.0 支持循环包含文件,因此您可以将所有任务放在一个文件中,然后执行如下操作:
- include: test.yml
with_items:
- 1
- 2
- 3
但是我不相信您提到的任何其他构造(register
、until
、retries
、delay
等)都适用于此。虽然其中一些理论上可以应用于包含文件中的所有任务,但其他像 register
和 until
明确绑定到单个任务。让多个任务尝试注册相同的输出变量是没有意义的。
根据 URL 的 JSON 回复,我需要类似的东西。这是我的尝试:
https://gist.github.com/ParagDoke/5ddfc3d5647ce9b0110d1b9790090092
想法是递归地包含另一个任务列表 yaml 文件。如果包含文件名是 foobar.yml
:
- task1
- task2
- task3
- include_tasks: foobar.yml
until: "some condition"
从 Ansible 2.5 开始,建议使用 loop
而不是 with_items
。此外,由于您不想假设您的子任务没有任何循环,因此您可以使用比 "item" 更具描述性的名称。这是一个在循环中使用循环的示例,稍微被截断但如果您定义适当的配置仍然有效:
# terminate-instances-main.yml:
---
- hosts: local
connection: local
vars:
regions:
- ap-southeast-1
- us-west-1
tasks:
- include_tasks: "terminate-instance-tasks.yml"
loop: "{{ regions }}"
loop_control:
loop_var: region
# terminate-instance-tasks.yml:
---
- name: Gather EC2 facts
ec2_instance_facts:
region: "{{ region }}"
filters:
"tag:temporary": "true"
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
register: ec2
- name: Terminate Temp EC2 Instance(s)
ec2:
instance_ids: '{{ item.instance_id }}'
state: absent
region: "{{ region }}"
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
loop: "{{ ec2.instances }}"
Ansible playbook loop 如何完成一系列任务?我希望实现一个执行任务序列直到任务成功的轮询循环。当它失败时,异常处理程序将尝试修复条件,然后循环将重复任务序列。
考虑以下假想的例子:
- action:
- block:
- debug: msg='i execute normally'
- command: /bin/foo
rescue:
- debug: msg='I caught an error'
- command: /bin/fixfoo
always:
- debug: msg="this always executes"
register: result
until: result
retries: 5
delay: 10
在 Ansible 中 1.x 这根本无法完成。只是不是那样设计的。
Ansible 2.0 支持循环包含文件,因此您可以将所有任务放在一个文件中,然后执行如下操作:
- include: test.yml
with_items:
- 1
- 2
- 3
但是我不相信您提到的任何其他构造(register
、until
、retries
、delay
等)都适用于此。虽然其中一些理论上可以应用于包含文件中的所有任务,但其他像 register
和 until
明确绑定到单个任务。让多个任务尝试注册相同的输出变量是没有意义的。
根据 URL 的 JSON 回复,我需要类似的东西。这是我的尝试: https://gist.github.com/ParagDoke/5ddfc3d5647ce9b0110d1b9790090092
想法是递归地包含另一个任务列表 yaml 文件。如果包含文件名是 foobar.yml
:
- task1
- task2
- task3
- include_tasks: foobar.yml
until: "some condition"
从 Ansible 2.5 开始,建议使用 loop
而不是 with_items
。此外,由于您不想假设您的子任务没有任何循环,因此您可以使用比 "item" 更具描述性的名称。这是一个在循环中使用循环的示例,稍微被截断但如果您定义适当的配置仍然有效:
# terminate-instances-main.yml:
---
- hosts: local
connection: local
vars:
regions:
- ap-southeast-1
- us-west-1
tasks:
- include_tasks: "terminate-instance-tasks.yml"
loop: "{{ regions }}"
loop_control:
loop_var: region
# terminate-instance-tasks.yml:
---
- name: Gather EC2 facts
ec2_instance_facts:
region: "{{ region }}"
filters:
"tag:temporary": "true"
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
register: ec2
- name: Terminate Temp EC2 Instance(s)
ec2:
instance_ids: '{{ item.instance_id }}'
state: absent
region: "{{ region }}"
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
loop: "{{ ec2.instances }}"