在ansible中创建动态角色

Creating a dynamic role in ansible

在查阅了几个文档后我得出结论,我不能将 with_items 用于 roles

因此,我创建了一个 filter_plugin 来生成角色词典列表。

这是我的 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",
      }

我想动态生成上述角色,为此我创建了一个 filter_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}

我的计划是生成如下角色:

roles: "{{ EC2_REGIONS | vpcroles }}"

其中 EC2_REGIONS['ap-southeast-2', 'us-east-1']

但是角色不是那样工作的。

我收到以下错误:

ERROR! A malformed role declaration was encountered.

有 thoughts/ideas 吗?

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

主要问题是动态创建的剧本是从任务内部调用的,它的标准输出不会进入主 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.cfg 作为参数调用内部 ansible-playbook 命令以将日志保存到不同的文件。

总的来说,你的情况不值得麻烦,我想,但对于一个无法通过其他方式解决的问题 它看起来很有希望。

您可以使用虚拟主机作为解决方法:

---
- 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

我的同事向我展示了实现动态 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

中添加了我的任务