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