# how to filter with variables instead of literals in ec2\_instance\_facts?

**URL:** <https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464>\
**Category:** Ansible Project\
**Created:** [May 5, 2018, 3:45pm UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464 "2018-05-05T15:45:00Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Karl\_Auer](https://avatars.discourse-cdn.com/v4/letter/k/cc9497/32.png) [@Karl\_Auer](https://forum.ansible.com/u/Karl_Auer)\
**Post date:** [May 5, 2018, 3:45pm UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/1 "2018-05-05T15:45:00Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Karl\_Auer](https://avatars.discourse-cdn.com/v4/letter/k/cc9497/32.png) [@Karl\_Auer](https://forum.ansible.com/u/Karl_Auer)\
**Post date:** [May 5, 2018, 10:57pm UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/2 "2018-05-05T22:57:33Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![flowerysong1](https://avatars.discourse-cdn.com/v4/letter/f/ecae2f/32.png) [@flowerysong1](https://forum.ansible.com/u/flowerysong1)\
**Post date:** [May 5, 2018, 11:08pm UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/3 "2018-05-05T23:08:17Z")

</div>

`

- ec2\_instance\_facts:  
filters: “{{ { tag\_name: tag\_value } }}”

`

---

<div class="post-metadata">

**Author:** ![Karl\_Auer](https://avatars.discourse-cdn.com/v4/letter/k/cc9497/32.png) [@Karl\_Auer](https://forum.ansible.com/u/Karl_Auer)\
**Post date:** [May 5, 2018, 11:54pm UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/4 "2018-05-05T23:54:08Z")

</div>

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’”

---

<div class="post-metadata">

**Author:** ![flowerysong1](https://avatars.discourse-cdn.com/v4/letter/f/ecae2f/32.png) [@flowerysong1](https://forum.ansible.com/u/flowerysong1)\
**Post date:** [May 6, 2018, 12:10am UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/5 "2018-05-06T00:10:04Z")

</div>

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

`

---

<div class="post-metadata">

**Author:** ![Karl\_Auer](https://avatars.discourse-cdn.com/v4/letter/k/cc9497/32.png) [@Karl\_Auer](https://forum.ansible.com/u/Karl_Auer)\
**Post date:** [May 6, 2018, 10:23am UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/6 "2018-05-06T10:23:22Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [May 6, 2018, 1:54pm UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/7 "2018-05-06T13:54:13Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Karl\_Auer](https://avatars.discourse-cdn.com/v4/letter/k/cc9497/32.png) [@Karl\_Auer](https://forum.ansible.com/u/Karl_Auer)\
**Post date:** [May 6, 2018, 2:37pm UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/8 "2018-05-06T14:37:53Z")

</div>

How does “~” differ from “+”?

“{{ ‘hello’ ~ name ~ ‘there!’ }}”

vs  
“{{ ‘hello’ + name + ‘there!’ }}”

?

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [May 6, 2018, 3:31pm UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/9 "2018-05-06T15:31:11Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![flowerysong1](https://avatars.discourse-cdn.com/v4/letter/f/ecae2f/32.png) [@flowerysong1](https://forum.ansible.com/u/flowerysong1)\
**Post date:** [May 6, 2018, 7:16pm UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/10 "2018-05-06T19:16:39Z")

</div>

Since this is an incredibly common question, I’ve written up a short explanation with examples:  
[https://immensefail.tumblr.com/post/173645339395/jinja-faq-concatenation](https://immensefail.tumblr.com/post/173645339395/jinja-faq-concatenation)

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.

```auto

```

```auto
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'"}

```

---

<div class="post-metadata">

**Author:** ![vivek\_dalal](https://avatars.discourse-cdn.com/v4/letter/v/a5b964/32.png) [@vivek\_dalal](https://forum.ansible.com/u/vivek_dalal)\
**Post date:** [September 19, 2019, 10:36pm UTC](https://forum.ansible.com/t/how-to-filter-with-variables-instead-of-literals-in-ec2-instance-facts/27464/11 "2019-09-19T22:36:56Z")

</div>

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!!
