5

After going through several documentation I concluded that, I can't use with_items for roles.

So, I created a filter_plugin to generate a list of dictionaries for roles.

Here is my Play:

---
- name: Boostrap vpc and subnets with route table
  hosts: localhost
  connection: local
  gather_facts: no
  pre_tasks:
    - include_vars: ec2_vars/common/regions.yml
    - include_vars: environment.yml
  roles:
    - {
        role: vpc,
        ec2_region: 'ap-southeast-2'
      }
    - {
        role: vpc,
        ec2_region: "ap-southeast-1",
      }
    - {
        role: vpc,
        ec2_region: "us-west-2",
      }

I want to generate above roles dynamically and for that I created a filter_plugin which generates a list of dictionaries and that is working right.

Here is my plugin:

# this is for generating vpc roles

def roles(ec2_regions):
    return [{'role': 'vpc', 'ec2_region': ec2_region} for ec2_region in ec2_regions]


class FilterModule(object):
    def filters(self):
        return {'vpcroles': roles}

My plan was to generate roles like following:

roles: "{{ EC2_REGIONS | vpcroles }}"

where EC2_REGIONS is ['ap-southeast-2', 'us-east-1']

But roles are not working in that way.

I am getting following error:

ERROR! A malformed role declaration was encountered.

Any thoughts/ideas ?

4

3 回答 3

2

我的同事向我展示了一种实现动态role. 就是这样。

目录结构:

- vpc.yml
|
- roles/vpc/tasks/main.yml
|
- roles/vpc/tasks/real.yml

播放 - vpc.yml

---
- name: Boostrap vpc and subnets with route table
  hosts: localhost
  connection: local
  gather_facts: no
  vars:
  pre_tasks:
    - include_vars: environment.yml
  roles:
    - { role: "vpc", ec2_regions: "{{ EC2_REGIONS }}"}

角色 - roles/vpc/tasks/main.yml:

- include: real.yml ec2_region="{{ _region }}"
  with_items: "{{ ec2_regions }}"
  loop_control:
    loop_var: _region

然后将我的任务添加到roles/vpc/tasks/real.yml

于 2016-08-22T23:12:23.013 回答
2

非常粗略的概念验证。我很好奇,它是否会起作用并且确实有效。

主要问题是动态创建的剧本是从任务内部调用的,它的标准输出不会进入主 Ansible 日志(可以在主剧本的变量中注册并显示为这样)。错误传播到父剧本。

主要剧本:

---
- hosts: localhost
  connection: local
  vars:
    params:
      - val1
      - val2
  tasks:
    - template:
        src: role_call.yml.j2
        dest: ./dynamic/role_call.yml
    - command: ansible-playbook ./dynamic/role_call.yml

文件中的动态剧本模板templates/role_call.yml.j2

- hosts: localhost
  connection: local
  roles:
  {% for param in params %}
    - { role: role1, par: {{param}} }
  {% endfor %}

roles/role1/tasks/main.yml

- debug: var=par

ansible-playbook我猜想可以使用单独的参数调用内部命令ansible.cfg,以将日志保存到不同的文件中。

我想,总体而言,您的情况不值得麻烦,但是对于像这样无法解决的问题,它看起来很有希望。

于 2016-08-22T08:34:25.643 回答
1

You may use dummy-hosts as a workaround:

---
- hosts: localhost
  vars:
    ec2_regions:
      - ap-southeast-2
      - ap-southeast-1
      - us-west-2
  tasks:
    - add_host: name=vpc_{{ item }} ansible_connection=local group=vpcs ec2_region={{ item }}
      with_items: "{{ ec2_regions }}"

- hosts: vpcs
  roles:
    - role: my_role
于 2016-08-22T09:07:36.330 回答