Update string variable if the value matches in Ansible Play

I pass a variable fRegion to my ansible playbook.

I wish to set fRegion to this string → ‘prd’ OR region LIKE ‘dr’

if the passed value is either “prd_and_dr” or “dr_and_prd”.

I call the playbook like this :

ansible-playbook site.yml -e "fRegion=dr_and_prd"

Here is my attempted playbook that does not help.

`

  • name: “Play 1-Find the details here”

hosts: localhost
any_errors_fatal: True
vars:

fRegion: “‘prd’ OR region LIKE ‘dr’”
when: fRegion == “prd_and_dr” or fRegion == “dr_and_prd”
ansible_ssh_extra_args: -o StrictHostKeyChecking=no

debug:
msg: “{{ fRegion }}”
`

Can you please suggest ?

I am truly confused about the logic.

You’re trying to set a variable based on itself, OR itself?

Could you maybe explain what you are trying to achieve?

Even within this information I would definitely restructure things…

Dick

@Dick hi,

We can definitely use a different variable here

fRegion: "'prd' OR region LIKE 'dr'"

I wanted to have less variables hence kept it the same.

The variable is used in a complex SQL query that is run by my playbook and as we know SQL queries need single quotes (')

Thus, the fRegion variable or any other should be assigned the string which will embed in the SQL query to get it to work.

If I understand correctly you have a variable called fRegion that contains a value.

You want to change that variable to contain the string “‘prd’ OR region LIKE ‘dr’” if the variable initially contains either the value “prd_or_dr” or the value “dr_or_prd”.

  • set_fact:
    fRegion: “‘prd’ OR region LIKE ‘dr’”
    when: fRegion == ‘prd_or_dr’ or fRegion == ‘dr_or_prod’

The problem with doing this is that you have lost the original value of fRegion now. And you are IMHO misusing the variable; a variable should in general either be a control variable (one that controls program flow) or data. Using the same variable to contain both control information and data at different times is confusing and leads to error. This would be nicer:

  • set_fact:
    sqlFragment: “‘some default value’”

  • set_fact:
    sqlFragment: “‘prd’ OR region LIKE ‘dr’”
    when: fRegion == ‘prd_or_dr’ or fRegion == ‘dr_or_prd’

Then it is completely clear that you are testing fRegion to find out what yor SQL fragment should be.

Regards, K.

@Karl you have correctly understood my requirement.

However, can you propose a solution with vars instead of using set_fact ?

In this case you could use a ternary filter:

vars:
f1: “‘prd’ OR region LIKE ‘dr’”
f2: “some_default”
sqlFragment: “{{(fRegion == ‘prd_or_dr’ or fRegion == ‘dr_or_prd’)|ternary(f1, f2)}}”

You could also use membership in a list of values as your condition:

vars:
f1: “‘prd’ OR region LIKE ‘dr’”
f2: “some_default”
vals: [‘dr_or_prd’, ‘prd_or_dr’]

sqlFragment: “{{(fRegion in vals) |ternary(f1, f2)}}”

BTW I used the f1 and f2 variables because it’s the easiest way (maybe the only way) to get single quotes into a variable.

IMHO this is not a good solution. The set_facts solution is much easier to understand (and you can combine it with the list of values idea to simplify it).

Regards, K.

@Karl your set_fact recoomendation has syntax issues …

Below is how it fails.

- name: "Play 1-Find the details here"

hosts: localhost
any_errors_fatal: True
vars:
ansible_ssh_extra_args: -o StrictHostKeyChecking=no
set_fact:
fRegion: "'prd' OR region LIKE 'dr'"
when: fRegion == 'prd_and_dr' or fRegion == 'dr_and_prd'

debug:
msg: "{{ fRegion }}"

Output:

That error is in code you added. I’m sure you’ll figure it out.

The fragments I supply here are tested unless I say otherwise.

Regards, K.

@Karl I tried set_fact as suggested but the assigned value is not getting substituted to the variable fRegion. Please look at the red bold text in the output below.

Below is the playbook:

cat finalattempt.yml

`

I’m sorry, I just don’t know what’s wrong with that. Please provide the exact SQL statement you WANT to see, so we can compare it with the SQL statement you are actually getting.

I can’t help feeling it would be simpler to provide just two booleans “dr” and “prod” and pass in one or both, rather than comparing strings.

Regards, K.

@Karl, the user passes fRegion=prd_and_dr as evident from my previous post.

`
ansible-playbook -vv finalattempt.yml -e “My_Number=54321 Layer=APP Environment=UAT fRegion=prd_and_dr”

`

In my playbook the below condition should be met (true)

when: fRegion == 'prd_and_dr' or fRegion == 'dr_and_prd'

Thus, the fRegion variable should now get the value below instead of the one passed to the playbook.

fRegion: "'prd_only' OR region LIKE 'dr_only'"

However, in the output you can see ‘{{ fRegion }}’ the persists dr_and_prd value marked in BOLD RED in my previous post instead of printing (substituting) the new value i.e. ‘prd_only’ OR region LIKE ‘dr_only’

Can you let me know how fRegion variable can be overwritten once the when condition is met ?

My script uses inline variables, your script is passing in variables on the command line.

It isn’t obvious, but the fRegion you are setting is actually a different variable to the one you are using later! To see this in action, try this script using the command line “ansible-playbook -v scriptname -e envvar=fred”:

Works !! and thank you for the explanation :slight_smile: Anyways, i can thank you ??

Below is the final working script.

`