【问题标题】:Iterating in a with_items loop ansible在 with_items 循环中迭代 ansible
【发布时间】:2019-05-23 09:25:50
【问题描述】:

您好,我正在 atm 尝试使用 aws 掌握 ansible 的窍门,到目前为止我真的很喜欢它的灵活性。

可悲的是,现在我的实验开始碰壁了。我正在尝试使用标签 environment: test 标记特定实例的卷 environment: testbackup: true 。如果我在 with_items 循环中指定数组的每个索引,则剧本按预期工作。到目前为止,这是我的剧本:

---
- name: Tag the EBS Volumes
  hosts: tag_environment_test
  gather_facts: False
  tags: tag
  vars_files:
    - /etc/ansible/vars/aws.yml

  tasks:
  - name: Gather instance instance_ids
    local_action:
        module: ec2_remote_facts
        region: '{{ aws_region }}'
        filters:
            instance-state-name: running
            "tag:environment": test
    register: test_id

  - name: Gather volume information for instance
    local_action:
        module: ec2_vol
        region: '{{ aws_region }}'
        instance: "{{ item.id }}"
        state: list
    with_items:
     - "{{ test_id.instances }}"
    register:  ec2_volumes
  - debug:
      var: ec2_volumes

  - name: Do some actual tagging
    local_action:
       module: ec2_tag
       region: '{{ aws_region }}'
       resource: "{{ item.id }}"
       args:
         tags:
          environment: test
          backup: true
    with_items:
      - "{{ ec2_volumes.results[0].volumes }}"
#      - "{{ ec2_volumes.results[1].volumes }}"

我现在的问题是可以遍历 ec2_volumes.results 中的整个数组,而无需指定数组中的每个值。例如 _ec2_volumes.results[X].volumes X=X+1_ 所以每次他通过循环时,他都会迭代 +1 直到数组的末尾。

剧本其余部分的每个输入都会非常受欢迎(就像我说的那样,仍在尝试掌握 ansible 的窍门。:)

问候 德雷斯

【问题讨论】:

  • ec2_volumes.results的内容是什么样的?请使用debug: var=ec2_volums.results 的输出更新您的问题。
  • ec2_volumes.results 实际上提供了有关具有上述标签的 ec2_instances 的所有数据。 ec2_volumes.results[0].volumes 返回第一个实例的音量。我可以使用 ec2_volumes.results[1].volumes 等来处理其他实例。发布输出需要付出很多努力,因为它包含很多我需要编辑的敏感数据。

标签: amazon-web-services amazon-ec2 ansible


【解决方案1】:

您可以遍历您的结果列表:

- name: Do some actual tagging
  delegate_to: localhost
  ec2_tag:
    region: '{{ aws_region }}'
    resource: "{{ item.volume.id }}"
    tags:
      environment: test
      backup: true
  with_items: "{{ ec2_volumes.results }}"

非常感谢剧本其余部分的每个输入

考虑使用delegate_to: localhost 而不是local_action。考虑这个任务:

- name: an example
  command: do something

使用delegate_to,我只需要添加一行:

- name: an example
  delegate_to: localhost
  command: do something

而使用local_action 我需要重写任务:

- name: an example
  local_action:
    module: command do something

当然,delegate_to 更灵活:您可以使用它来委托给 localhost 以外的主机。

更新

如果没有看到您的实际剧本,就很难确定错误的根源。这是一个成功运行的完整剧本(使用合成数据并将您的 ec2_tag 任务包装在 debug 任务中):

---
- hosts: localhost
  gather_facts: false
  vars:
    aws_region: example
    ec2_volumes:
      results:
        - volume:
            id: 1
        - volume:
            id: 2
  tasks:
    - name: Do some actual tagging
      debug:
        msg:
          ec2_tag:
            region: '{{ aws_region }}'
            resource: '{{ item.volume.id }}'
            tags:
              environment: test
              backup: true
      with_items: "{{ ec2_volumes.results }}"

【讨论】:

  • 感谢您的意见,从现在开始我将使用delegate_to,这似乎更舒服。可悲的是,当我尝试您的更改时,现在出现错误:The task includes an option with an undefined variable. The error was: 'item' is undefined\n\nThe error appears to have been in '/etc/ansible/playbooks/add_volume_tag.yml'
  • 我在清理你的任务时弄错了东西。我已经修复了答案中的缩进,并包含了完整的测试手册。
  • 实际剧本是什么意思?你的意思是调试信息?抱歉,如果我的问题看起来很愚蠢,就像我刚从 ansible 开始说的那样。我包括了我实际工作的剧本。我将尝试包含调试消息的输出。只是需要一段时间。
  • 什么?我没有说任何关于“实际剧本”的内容。我说我在回答中包含了一个完整的测试手册,以便您可以运行它并验证它是否符合您的要求。
  • 如果没有看到实际的剧本,就很难确定错误的来源。对不起,如果我误解了这句话。他们的剧本几乎可以满足我的要求,但仍然有固定的数量。我想要做的是标记 X 个实例的卷,每个实例都附加一个卷。
猜你喜欢
  • 1970-01-01
  • 2019-04-06
  • 2019-12-27
  • 1970-01-01
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多