how to filter with variables instead of literals in ec2_instance_facts?

452 views
Skip to first unread message

Karl Auer

unread,
May 5, 2018, 11:45:00 AM5/5/18
to Ansible Project
Trying to use ec2_instance_facts.

How do I use variables instead of literals when filtering on tags?

This works fine:

    - ec2_instance_facts:
        filters:
           "tag:Name" : "Some_name"
      register: instance_facts


But if I have the tag name and tag value in variables, I cannot get it to compile. It complains about an invalid filter.

This doesn't work (with tag_name and tag_value assigned appropriately:

    - ec2_instance_facts:
        filters:
           "{{ tag_group }}" : "{{ tag_value }}"
      register: instance_facts


And nor does this:

    - ec2_instance_facts:
        filters:
           "{{ '\"tag:' + tag_name }}" : "{{ tag_value }}"
      register: instance_facts


Or a dozen other variations I've tried. They all just say "the filter is invalid"

How do I do this with variables?

Regards, K.

Karl Auer

unread,
May 5, 2018, 6:57:33 PM5/5/18
to Ansible Project
I've tried a LOT of things now, and have come to the conclusion that ec2_instance_facts requires a literal filter name, at least in the case of "tags:Name".

This makes that filter essentially useless :-(

Please, can someone tell me I'm wrong, and how me how to filter on a tag:value pair passed in as a variable?

Thanks, K.

flowerysong

unread,
May 5, 2018, 7:08:17 PM5/5/18
to Ansible Project
On Saturday, May 5, 2018 at 6:57:33 PM UTC-4, Karl Auer wrote:
I've tried a LOT of things now, and have come to the conclusion that ec2_instance_facts requires a literal filter name, at least in the case of "tags:Name".

This makes that filter essentially useless :-(

Please, can someone tell me I'm wrong, and how me how to filter on a tag:value pair passed in as a variable?

    - ec2_instance_facts:
        filters: "{{ { tag_name: tag_value } }}"


 

Karl Auer

unread,
May 5, 2018, 7:54:27 PM5/5/18
to ansible...@googlegroups.com
Thanks, flowerysong

Did you actually try that?

When I use that, I get the same error as before: An error occurred (InvalidParameterValue) when calling the DescribeInstances operation: The filter 'GroupName' is invalid

("GroupName" is the value in my variable tag_name)

If you actually TRIED it and it worked, do let me know.

Here are some things that do not work:

#           "{{ { tag_name: tag_value } }}"
#           "{{ '\"tag:' + tag_name + '\"' }}" : "{{tag_value }}"
#           "{{ 'tag:' + tag_name }}" : "{{tag_value }}"
#           tag: "{{ tag_name + ':' + tag_value }}"
#           tag:"{{ tag_name + ':' + tag_value }}"
#            "{{ tag_name }}" : "{{tag_value }}"

The second last one (no space after the first colon) gives a different message: "argument filters is of type <type 'str'> and we were unable to convert to dict: dictionary requested, could not parse JSON or key=value"}

These work - but they have a literal filter name

#           "tag:GroupName" : "DEMO"
#           "tag:GroupName" : "{{tag_value }}"

Thanks, K.

PS: There was a typo in my last message. I meant to write "... at least in the case of 'tag:Name'"

--
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+unsubscribe@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/38b14171-3086-4c2d-868f-de3882384090%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Karl Auer

Email  : ka...@2pisoftware.com
Website: 
http://2pisoftware.com

GPG/PGP : 958A 2647 6C44 D376 3D63 86A5 FFB2 20BC 0257 5816
Previous: F0AB 6C70 A49D 1927 6E05 81E7 AD95 268F 2AB6 40EA

flowerysong

unread,
May 5, 2018, 8:10:05 PM5/5/18
to Ansible Project
On Saturday, May 5, 2018 at 7:54:27 PM UTC-4, Karl Auer wrote:

Did you actually try that?

When I use that, I get the same error as before: An error occurred (InvalidParameterValue) when calling the DescribeInstances operation: The filter 'GroupName' is invalid

("GroupName" is the value in my variable tag_name)

Yes, it works. You have to construct a valid filter, and GroupName isn't a valid filter.
 
- hosts: localhost
  become: false
  tasks:
    - ec2_instance_facts:
        filters: "{{ { tag_name: tag_value } }}"
      vars:
        tag_name: "tag:Name"
        tag_value: "*"
    - ec2_instance_facts:
        filters: "{{ { 'tag:' ~ tag_name: tag_value } }}"
      vars:
        tag_name: Name
        tag_value: "*"


PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [ec2_instance_facts] ******************************************************
ok: [localhost]

TASK [ec2_instance_facts] ******************************************************
ok: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0

Karl Auer

unread,
May 6, 2018, 6:23:36 AM5/6/18
to ansible...@googlegroups.com
Thank you! Those work, indeed they do. What does that "~" syntax mean?

The reason I said your earlier solution did not work one is that you did not in your first answer include the secret sauce of prefixing "tag": to the tag name in the tag_name variable itself. When I do that, the first variant works. I should have tried that, it seems obvious in hindsight :-)

The second variant is nicer IMHO because it keeps the specifics of the filter syntax in the filter clause itself, and the actual tag name can be passed in.

Thank you so much for your assistance. The solution using ec2_instance_facts is way simpler than the solution I had working with ec2.py.

Regards, K.


--
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+unsubscribe@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Kai Stian Olstad

unread,
May 6, 2018, 9:54:29 AM5/6/18
to ansible...@googlegroups.com
On 06.05.2018 12:23, Karl Auer wrote:
> What does that "~" syntax mean?

http://jinja.pocoo.org/docs/2.10/templates/#other-operators
Converts all operands into strings and concatenates them.


--
Kai Stian Olstad

Karl Auer

unread,
May 6, 2018, 10:38:14 AM5/6/18
to ansible...@googlegroups.com
How does "~" differ from "+"?


"{{ 'hello' ~ name ~ 'there!' }}"
vs
"{{ 'hello' + name + 'there!' }}"

?




--
Kai Stian Olstad

--
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+unsubscribe@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Kai Stian Olstad

unread,
May 6, 2018, 11:31:21 AM5/6/18
to ansible...@googlegroups.com
On 06.05.2018 16:37, Karl Auer wrote:
> How does "~" differ from "+"?
>
> "{{ 'hello' ~ name ~ 'there!' }}"
> vs
> "{{ 'hello' + name + 'there!' }}"

Have you read the documentation about + ?
http://jinja.pocoo.org/docs/2.10/templates/#math

--
Kai Stian Olstad

flowerysong

unread,
May 6, 2018, 3:16:39 PM5/6/18
to Ansible Project
On Sunday, May 6, 2018 at 10:38:14 AM UTC-4, Karl Auer wrote:
How does "~" differ from "+"?


"{{ 'hello' ~ name ~ 'there!' }}"
vs
"{{ 'hello' + name + 'there!' }}"

?

Since this is an incredibly common question, I've written up a short explanation with examples:

While they’re often interchangeable, developing a habit of using the concatenation operator means that you don’t have to worry about or code around the situations where they’re not.


TASK [Addition isn't concatenation] ********************************************
ok: [localhost] => {
    "13 + 37": "50"
}

TASK [Concatenation is concatenation] ******************************************
ok: [localhost] => {
    "13 ~ 37": "1337"
}

TASK [Concatenation handles mixed types] ***************************************
ok: [localhost] => {
    "13 ~ '37'": "1337"
}

TASK [It's possible to do the coercion manually, but who wants to do that?] ****
ok: [localhost] => {
    "13 | string + '37'": "1337"
}

TASK [Addition doesn't like mixed types] ***************************************
fatal: [localhost]: FAILED! => {"msg": "Unexpected templating type error occurred on ({{13 + '37'}}): unsupported operand type(s) for +: 'int' and 'str'"}


vivek dalal

unread,
Sep 19, 2019, 6:36:56 PM9/19/19
to Ansible Project
Thank you so much! The below syntax worked for me as well.

filters: "{{ { 'tag:' ~ tag_name: tag_value } }}"

I had a follow up question related to this. How can I add multiple filters with one filter being "{{ { 'tag:' ~ tag_name: tag_value } }}"?

I am trying to add it like we do in all other cases(shown below) but it gives an error.

        filters:
          instance-state-name: ["running"]
"{{ { 'tag:' ~ tag_name: tag_value } }}"

However, I get a syntax error.

Can you please suggest what am I doing wrong?

Thanks in advance!!
Reply all
Reply to author
Forward
0 new messages