Thanks much Todd, the above code works as expected. 

On Sunday, September 3, 2023 at 12:38:21 AM UTC+5:30 Todd Lewis wrote:

> You are close, and your intuition is correct that there's a way to loop 
> through with one item per (region × account). This is exactly the situation 
> that the subelements filter is designed for.  Try this:
>
>     - name: Populate acc_statements
>       ansible.builtin.set_fact:
>         acc_statements: "{{ acc_statements | default([]) | 
> combine({acc_id*[0]*.region: acc_statements[acc_id*[0]*.region] | default([]) 
> + [loop_statement]}) }}"
>       vars:
>         loop_statement:
>           byte_match_statement:
>             search_string: "{{ acc_id*[1]* }}"
>             positional_constraint: EXACTLY
>             field_to_match:
>               single_header:
>                 name: "accountmoid"
>             text_transformations:
>               - type: NONE
>                 priority: 0
>       loop: "{{ blocked_accounts.results *| 
> subelements('ansible_facts.blocked_account_list')* }}"
>       loop_control:
>         loop_var: acc_id
>
> The subelements filter takes a list (blocked_accounts.results in this 
> case) and duplicates each item once per each subelement of the item as 
> referenced by the given string. Each element of the list it returns (
> acc_id) will itself contain two elements: the first (acc_id[0]) is a copy 
> of an item from the original list (blocked_accounts.results); the second (
> acc_id[1]) is the subelement from acc_id[0] that this pair corresponds to.
>
> It's easy to get lost in all the words, but the simple demo is this:
>
>   orig:    - alpha: a
>       numbers:
>         - 1
>         - 2    - alpha: b
>       numbers:
>         - 3
>         - 4
>   result: "{{ orig | subelements('numbers') }}"
> # result looks like this:    - - alpha: a
>         numbers:
>           - *1*
>           - 2
>       - *1*
>     - - alpha: a
>         numbers:
>           - 1
>           - *2*
>       - *2*    - - alpha: b
>         numbers:
>           - *3*
>           - 4
>       - *3*
>     - - alpha: b
>         numbers:
>           - 3
>           - *4*
>       - *4*
>
>
>  
> On 9/2/23 12:18 PM, Shivani Arora wrote:
>
> The code I have written is:
>
>   - name: Populate acc_statements
>     set_fact:
>       acc_statements: "{{ acc_statements | combine({acc_id.region: 
> acc_statements[acc_id.region] | default([]) + [loop_statement]}) }}"
>     vars:
>       loop_statement:
>         byte_match_statement:
>           search_string: "{{ acc_id.ansible_facts.blocked_account_list }}"
>           positional_constraint: EXACTLY
>           field_to_match:
>             single_header:
>               name: "accountmoid"
>           text_transformations:
>             - type: NONE
>               priority: 0
>     loop: "{{ blocked_accounts.results }}"
>     loop_control:
>       loop_var: acc_id
>
>
>   - debug:
>       var: acc_statements
>
> * The output I'm getting:*
>
>
>     "acc_statements": {
>         "eu-central-1": [
>             {
>                 "byte_match_statement": {
>                     "field_to_match": {
>                         "single_header": {
>                             "name": "accountmoid"
>                         }
>                     },
>                     "positional_constraint": "EXACTLY",
>                     "search_string": [
>                         "5afabfb36d6c356772d84362",
>                         "5c46e33273766a3634f91a8d"
>                     ],
>                     "text_transformations": [
>                         {
>                             "priority": 0,
>                             "type": "NONE"
>                         }
>                     ]
>                 }
>             }
>         ],
>         "us-east-1": [
>             {
>                 "byte_match_statement": {
>                     "field_to_match": {
>                         "single_header": {
>                             "name": "accountmoid"
>                         }
>                     },
>                     "positional_constraint": "EXACTLY",
>                     "search_string": [
>                         "5afabfb36d6c356772d8ae02",
>                         "5c46e33273766a3634f91a7c"
>                     ],
>                     "text_transformations": [
>                         {
>                             "priority": 0,
>                             "type": "NONE"
>                         }
>                     ]
>                 }
>             }
>         ]
>     }
> }
>
> *And the output I want is, search_string should be a string instead of a 
> list:*
>
>     "acc_statements": {
>         "eu-central-1": [
>             {
>                 "byte_match_statement": {
>                     "field_to_match": {
>                         "single_header": {
>                             "name": "accountmoid"
>                         }
>                     },
>                     "positional_constraint": "EXACTLY",
>                     "search_string": "5afabfb36d6c356772d84362",
>                     "text_transformations": [
>                         {
>                             "priority": 0,
>                             "type": "NONE"
>                         }
>                     ]
>                 }
>             },
>             {
>                 "byte_match_statement": {
>                     "field_to_match": {
>                         "single_header": {
>                             "name": "accountmoid"
>                         }
>                     },
>                     "positional_constraint": "EXACTLY",
>                     "search_string": "5c46e33273766a3634f91a8d",
>                     "text_transformations": [
>                         {
>                             "priority": 0,
>                             "type": "NONE"
>                         }
>                     ]
>                 }
>             }
>         ],
>         "us-east-1": [
>             {
>                 "byte_match_statement": {
>                     "field_to_match": {
>                         "single_header": {
>                             "name": "accountmoid"
>                         }
>                     },
>                     "positional_constraint": "EXACTLY",
>                     "search_string":  "5afabfb36d6c356772d8ae02"
>                     "text_transformations": [
>                         {
>                             "priority": 0,
>                             "type": "NONE"
>                         }
>                     ]
>                 }
>             }
>         ]
>     }
> }
>
> On Saturday, September 2, 2023 at 9:36:47 PM UTC+5:30 Shivani Arora wrote:
>
>> Thanks, Todd.  I'm majorly facing issues with looping. I want to create 
>> regional_account_rules 
>> for us-east-1 and eu-central-1 and want to make sure correct 
>> "acc_statements" 
>> get created for each region with respective blocked accounts. Could you 
>> provide some suggestions how to achieve this?
>>
>> On Saturday, September 2, 2023 at 2:38:48 AM UTC+5:30 Todd Lewis wrote:
>>
>>> Your first task is replacing blocked_account_list each time through the 
>>> loop, so you end up with only those blocked accounts listed for the last 
>>> region.
>>>
>>> However, you are also registering the results, so you can create a loop 
>>> that retains all the blocked accounts along with their associated region.
>>>
>>>     - name: Tie region to the blocked accounts
>>>       ansible.builtin.debug:
>>>         msg: "{{ item }}"
>>>       vars:
>>>         ba_query: '[].{region: region, blocked_accounts: 
>>> ansible_facts.blocked_account_list}'
>>>       loop:
>>>         - "{{ blocked_accounts.results | json_query(ba_query) }}"
>>>
>>> This result in the following output. (Note, I'm running with
>>> ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook …
>>> and I've inserted the region into the account numbers so I can tell 
>>> which accounts came from which region.):
>>>
>>> TASK [Tie region to the blocked accounts] 
>>> ************************************************************************************************************************************
>>> ok: [localhost] => (item=[{'region': 'us-east-1', 'blocked_accounts': 
>>> ['20ea8d-us-east-1-bfbafa5', 'c7a19f-us-east-1-33e64c5']}, {'region': 
>>> 'eu-central-1', 'blocked_accounts': ['5afabf-eu-central-1-ae02', 
>>> '5c46e3-eu-central-1-1a7c']}]) => 
>>>   msg:
>>>   - blocked_accounts:
>>>     - 20ea8d-us-east-1-bfbafa5
>>>     - c7a19f-us-east-1-33e64c5
>>>     region: us-east-1
>>>   - blocked_accounts:
>>>     - 5afabf-eu-central-1-ae02
>>>     - 5c46e3-eu-central-1-1a7c
>>>     region: eu-central-1
>>>
>>> After that, it isn't particularly clear to me how the region is supposed 
>>> to play into the following tasks. But perhaps this will help get past the 
>>> first problem.
>>> --
>>> Todd
>>>
>>>
>>> On 9/1/23 2:54 PM, Shivani Arora wrote:
>>>
>>> Hi Team,
>>>
>>> I'm having issues with looping in Ansible. The background of what I'm 
>>> trying to do is - 
>>> I have 2 regions in aws_cloud_regions and their respective 
>>> waf_blocked_accounts list, which looks like the one below. 
>>>
>>> I want to create regional_account_rules in waf for both the regions (as 
>>> in us-east-1 blocked_account_list gets attached to 
>>> regional_account_rules for US East and the same for another region) but 
>>> facing issues while looping over regions and blocked_account_list 
>>> together. 
>>>
>>>
>>> Also note, that search_string in "Create statements" accepts a string 
>>> list, so we have to create one outer loop and one inner loop, an outer 
>>> loop for regions, and an inner for adding blocked account lists one by one.
>>>
>>>  
>>>
>>> -bash-4.2$ cat environment/QAtest/us-east-1/waf_blocked_accounts.yml
>>>
>>> blocked_account_list:
>>>
>>>   - 5afabfb36d6c356772d8ae02
>>>
>>>   - 5c46e33273766a3634f91a7c
>>>
>>>     
>>>
>>> "aws_cloud_regions": [
>>>         "us-east-1",
>>>         "eu-central-1"
>>>     ]
>>>
>>>
>>> The playbook which needs modification, it is not region-specific as of 
>>> now:
>>>
>>>   - name: Loop over AWS regions
>>>
>>>     include_vars:
>>>
>>>         file: "environment/QAtest/{{ region }}/waf_blocked_accounts.yml"
>>>
>>>     loop: "{{ aws_cloud_regions }}"
>>>
>>>     loop_control:
>>>
>>>         loop_var: region
>>>
>>>     register: blocked_accounts
>>>
>>>
>>>   - name: Create statements
>>>
>>>     set_fact:
>>>
>>>       acc_statements: "{{ acc_statements + [loop_statement] }}"
>>>
>>>     vars:
>>>
>>>       loop_statement:
>>>
>>>         byte_match_statement:
>>>
>>>           search_string: "{{ acc_id }}"
>>>
>>>           positional_constraint: EXACTLY
>>>
>>>           field_to_match:
>>>
>>>             single_header:
>>>
>>>               name: "accountmoid"
>>>
>>>           text_transformations:
>>>
>>>           - type: NONE
>>>
>>>             priority: 0
>>>
>>>     loop: "{{ blocked_account_list }}"
>>>
>>>     loop_control:
>>>
>>>       loop_var: acc_id
>>>
>>>  
>>>
>>>   - set_fact:
>>>
>>>       regional_account_rules:
>>>
>>>       - name: "BlockedAccounts"
>>>
>>>         priority: 3
>>>
>>>         action:
>>>
>>>           block: {}
>>>
>>>         visibility_config:
>>>
>>>           sampled_requests_enabled: yes
>>>
>>>           cloud_watch_metrics_enabled: yes
>>>
>>>           metric_name: "BlockedAccounts"
>>>
>>>         statement:
>>>
>>>           or_statement:
>>>
>>>             statements: "{{ acc_statements }}"
>>>
>>>   - set_fact:
>>>
>>>       regional_account_rules: "{{ regional_account_rules | default([]) 
>>> }}"
>>>
>>>
>>>
>>> Any help is appreciated. Thanks in advance.
>>>
>>> -- 
>>> 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 view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/ansible-project/cd18c106-b3c0-4f3b-8e6c-60c52ee3e5e6n%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/ansible-project/cd18c106-b3c0-4f3b-8e6c-60c52ee3e5e6n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>>
>>> -- 
>>> Todd
>>>
>>> -- 
> 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 view this discussion on the web visit 
> https://groups.google.com/d/msgid/ansible-project/aa3774cf-77f9-4337-96a6-7c5b19d116c6n%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/ansible-project/aa3774cf-77f9-4337-96a6-7c5b19d116c6n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
>
> -- 
> Todd
>
>

-- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/ansible-project/ef1dd347-4413-4276-b17a-c1df413f7504n%40googlegroups.com.

Reply via email to