# Thoughts on Dynamic Variables

**URL:** <https://forum.ansible.com/t/thoughts-on-dynamic-variables/31178>\
**Category:** Ansible Project\
**Created:** [August 30, 2019, 2:50pm UTC](https://forum.ansible.com/t/thoughts-on-dynamic-variables/31178 "2019-08-30T14:50:00Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cade\_Lambert](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@Cade\_Lambert](https://forum.ansible.com/u/Cade_Lambert)\
**Post date:** [August 30, 2019, 2:50pm UTC](https://forum.ansible.com/t/thoughts-on-dynamic-variables/31178/1 "2019-08-30T14:50:00Z")

</div>

I wanted to see how you guys go about building dynamic variables. We have some playbooks/roles that require variables to be built based on various things, such as user input or other variables. I usually end up building a long line of ‘if-then-else’ statements, which can be difficult to read and troubleshoot. Is there a better way to go about this? How do you all tackle this?

---

<div class="post-metadata">

**Author:** ![dan\_linder](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/dan_linder/32/3833_2.png) [@dan\_linder](https://forum.ansible.com/u/dan_linder)\
**Post date:** [August 30, 2019, 8:08pm UTC](https://forum.ansible.com/t/thoughts-on-dynamic-variables/31178/2 "2019-08-30T20:08:04Z")

</div>

A lot of our builds have site or subnet specific differences so we use Ansible facts to include specific YML files for either additional variables or branching the execution.

For example, to choose the proper method to install VMware tools on our systems (RHEL 6 vs 7, and internet access or not) we use something like this:

- name: “Include the appropriate OS steps.”  
include: “{{ role\_path }}/tasks/OSsetup-{{ osver }}-{{ vmwaretools\_local|bool }}.yml”

| |
|
| |

Basically the "osver" variable is set earlier based on the OS name ("RedHat" vs "Debian" vs "Ubuntu"), then use the variable "vmwaretools\_local" to know if we need to get from a local repo (internally) or from the VMWare.com Internet site.

---

<div class="post-metadata">

**Author:** ![Cade\_Lambert](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@Cade\_Lambert](https://forum.ansible.com/u/Cade_Lambert)\
**Post date:** [September 3, 2019, 1:28pm UTC](https://forum.ansible.com/t/thoughts-on-dynamic-variables/31178/3 "2019-09-03T13:28:01Z")

</div>

The problem I come across is I’ll need logic to decide on the content of a variable and that logic will turn into a long string. For example, when determining which users to add to a system, we might have a variable like:

user\_list: "{{ ‘user1,user2,user3’ if server\_type=db\_server else ‘user4,user5,user6’ if server\_type=web\_server else ‘user7,user8,user1’ if server\_type=standard\_server }}’

These can get pretty long depending on what we’re trying to do, and fairly hard to read. I could do multi-line variables I guess, but was wondering if there’s a more clever way to handle stuff like this.

---

<div class="post-metadata">

**Author:** ![racke](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/racke/32/4767_2.png) [@racke](https://forum.ansible.com/u/racke)\
**Post date:** [September 3, 2019, 1:48pm UTC](https://forum.ansible.com/t/thoughts-on-dynamic-variables/31178/4 "2019-09-03T13:48:19Z")

</div>

> The problem I come across is I'll need logic to decide on the content of a variable and that logic will turn into a long  
> string. For example, when determining which users to add to a system, we might have a variable like:
> 
> user\_list: "{{ 'user1,user2,user3' if server\_type=db\_server else 'user4,user5,user6' if server\_type=web\_server else  
> 'user7,user8,user1' if server\_type=standard\_server }}'
> 
> These can get pretty long depending on what we're trying to do, and fairly hard to read. I could do multi-line variables  
> I guess, but was wondering if there's a more clever way to handle stuff like this.

That looks like the users should be named in group variables, e.g.:

db\_server:  
&nbsp;&nbsp;&nbsp;users:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- user1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- user2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- user3

That's better and more flexible than your conditional approach.

Regards  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Racke

---

<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:** [September 3, 2019, 2:02pm UTC](https://forum.ansible.com/t/thoughts-on-dynamic-variables/31178/5 "2019-09-03T14:02:42Z")

</div>

You could use set\_fact: stanzas instead, with when: clauses.

- set\_fact:  
user\_list: ‘user1, user2, user3’  
when: server\_type = ‘db\_server’

Even better, use lists rather than strings. You can always turn one into the other, and lists are more flexible:

- set\_fact:  
user\_list: [‘user1’, ‘user2’, ‘user3’]  
when: server\_type = ‘db\_server’

Or something like this:

vars:  
db\_users: [‘user1’, ‘user2’, ‘user3’]  
web\_users: [‘user4’, ‘user5’, ‘user6’]  
standard\_users: ‘user7’, ‘user8’, ‘user9’]

- set\_fact:  
user\_list: “{{ db\_users }}”  
when: server\_type = ‘db\_server’

Or this:

vars:  
user\_groups:  
{

‘db\_server’: [‘user1’, ‘user2’, ‘user3’],  
‘web\_server’: [‘user4’, ‘user5’, ‘user6’],  
‘standard\_server’: [‘user7’, ‘user8’, ‘user9’]  
}

- set\_fact:  
user\_list: “{{ user\_groups[server\_type] }}”

The syntax is off the top of my head so probably full of errors, but it should give you some ideas.

Regards, K.

---

<div class="post-metadata">

**Author:** ![dan\_linder](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/dan_linder/32/3833_2.png) [@dan\_linder](https://forum.ansible.com/u/dan_linder)\
**Post date:** [September 3, 2019, 3:58pm UTC](https://forum.ansible.com/t/thoughts-on-dynamic-variables/31178/6 "2019-09-03T15:58:41Z")

</div>

Dang! @Karl Auer beat me to this example. 🙂

Depending on your needs and comfort level, here are two examples with sample output.

The first “userlistA” is closer to your original example and has each list with a name that is not consistent with the server\_type variable. That leads to the first three “when” clauses to set the userlist variable based on the server\_type provided.

The second section using “userlistB” uses the server\_type variable to select the correct user list from the dictionary - it’s a single task in the playbook as opposed to three or more for the first method.

Here is my example playbook named “dynvar.yml”:

---

<div class="post-metadata">

**Author:** ![Cade\_Lambert](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@Cade\_Lambert](https://forum.ansible.com/u/Cade_Lambert)\
**Post date:** [September 3, 2019, 4:14pm UTC](https://forum.ansible.com/t/thoughts-on-dynamic-variables/31178/7 "2019-09-03T16:14:01Z")

</div>

Awesome, thanks for the responses. This definitely looks like a more logical, thoughtful approach than cramming a bunch of if-else statements into a single line. I’ll take these back and try reworking my vars file. Thanks again.
