The fundamental problem is that Ansible doesn't allow nested loops -- even 
though Ansible looks like a procedural language (it's executing 
commands/modules in order and it can loop over things), it really isn't. 
The only "simulation" of a for/while loop is the with_foobar stuff, which 
calls a lookup plugin that must return a simple list to iterate over. You 
could write your own lookup plugin that does a combination of the 
subelements and nested plugins, but if you want to stay in the "Ansible 
realm", then here's a solution that I used to solve a similar problem:

Define a helper variable that does the work of with_subelements:

monitor_exchange_demand_partners: |
  {%- set result = [] -%}
  {%- for exchange in monitor_exchanges|default([]) -%}
    {%- do result.extend(exchange.demand_partners|default([]) -%}
  {%- endfor -%}
  {{ result|unique }}

That exploits the fact that Ansible variables are Jinja templates, and that 
if a template evaluates into a string representation of a list or dict it 
will be converted to that list/dict. You'll have to add this to your 
ansible.cfg (Ansible variables in combination with Jinja look like a 
functional language, but Jinja lacks all the important tools of functional 
programming, so we'll use an extension that turns Jinja into a procedural 
language instead):

[defaults]
jinja2_extensions = jinja2.ext.do

Then you can use a simple with_nested:

- datadog_monitor: ...
  with_nested:
    - monitor_exchange_demand_partners
    - monitors




On Thursday, June 18, 2015 at 4:04:51 PM UTC+2, Ashley Penney wrote:
>
> Hi,
>
> We've run into an issue (and a pattern really) using ansible that we've 
> been unable to solve and I'm hoping the list can teach us the "ansible way".
>
> The background is that we want to create a number of monitors 
> automatically, based on certain information.  The solution we have today is 
> a variable:
>
> monitor_exchanges:
> - name: exchange1
>   demand_partners:
>     - 'dp1'
>     - 'dp2'
>     
> And the consumer:
>
> - name: Create datadog monitors
>   datadog_monitor:
>     state: "present"
>     type: "query alert"
>     name: '{{item.0.name}}-{{item.1}} over delivery'
>     query: 
> "avg({{monitor_interval}}):100*(avg:requests.outbound.transmitted.count{sp_name:{{
> item.0.name}}, dp_name:{{item.1}}} - avg:demand_partner.rps{sp_name:{{
> item.0.name}}, dp_name:{{item.1}}})/avg:demand_partner.rps{sp_name:{{
> item.0.name}}, dp_name:{{item.1}}} > {{monitor_threshold}}"
>     message: "test"
>     api_key: "{{datadog_api_key}}"
>     app_key: "{{datadog_app_key}}"
>   with_subelements:
>     - monitor_exchanges
>     - demand_partners
>   when: monitor_exchanges is defined
>   
> This then creates, for each exchange a monitor per demand partner.  That 
> part is fairly easy and works fine but we wanted to externalize the 
> 'query'/'name'/'message' part of the above thing, so that we'd have 
> something more like:
>
> - name: Create monitors
> datadog_monitor:
>   state: "present"
>   type: "query alert"
>   query: {{item.something.query}}
>   name: {{item.something.query}}
>   message: {{item.something.query}}
>   
> We kept trying to do this with two datastructures, the one from above and 
> then
> something like "monitors" that would be a list of hashes containing each 
> monitor to create.  I couldn't come up with the right combination of 
> iteration to make it work however, because I really needed to iterate over 
> two separate things in different ways, I couldn't just list the two 
> structures, I needed to do something more like:
>
> with_nested:
>   - with_subelements:
>     - monitor_exchanges
>     - demand_partners
>   - monitors
>   
> Is there another way I can model this that makes sense?  I really just 
> want to iterate over a list of monitors and then for each monitor iterate 
> over the `monitor_exchanges` list to pull all the appropriate data.  
>

-- 
You received this message because you are subscribed to the Google Groups 
"Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ansible-project/dd83926d-8aa4-4fe0-98dd-a32d9da9b4ac%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to