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 ?
Best Answer
Very rough proof-of-concept. I was curious, if it would work and it does.
The major problem is that dynamically-created playbook is called from inside a task and its stdout doesn't go into main Ansible log (can be registered in the variable of the main playbook and displayed as such). Errors propagate to the parent-playbook.
Main playbook:
Dynamic playbook template in
templates/role_call.yml.j2
file:roles/role1/tasks/main.yml
:I guess the internal
ansible-playbook
command could be called with a separateansible.cfg
as an argument to save the log to a different file.Overall not worth the hassle in your case, I guess, but for a problem that cannot be solved otherwise like this it looks promising.