# Input validation on user-supplied variable (example, setting environment to production/development/staging)

**URL:** <https://forum.ansible.com/t/input-validation-on-user-supplied-variable-example-setting-environment-to-production-development-staging/32794>\
**Category:** Ansible Project\
**Created:** [April 27, 2020, 9:14pm UTC](https://forum.ansible.com/t/input-validation-on-user-supplied-variable-example-setting-environment-to-production-development-staging/32794 "2020-04-27T21:14:56Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael\_Moody](https://avatars.discourse-cdn.com/v4/letter/m/9fc29f/32.png) [@Michael\_Moody](https://forum.ansible.com/u/Michael_Moody)\
**Post date:** [April 27, 2020, 9:14pm UTC](https://forum.ansible.com/t/input-validation-on-user-supplied-variable-example-setting-environment-to-production-development-staging/32794/1 "2020-04-27T21:14:56Z")

</div>

Good afternoon,

I opened an issue on GitHub, and was directed here, which is the obvious place. (I initially thought that the behavior was indeed a bug, but there was some clarity added).

What would be the preferred method to perform input validation on a user supplied variable provided via extra vars? Is the recommended approach to simply handle an error (and end the host, play or task) if the variable doesn’t match an expected input, as it is not possible to overwrite it due to precedence?

As it was, we were trying to use “-e” for the extra variables, and then using set\_fact to overwrite it if it didn’t meet the expected requirements.

This is what I was trying:

`

```auto
###This works as expected
- name: "Setting Deploy Environment Variable for Deployment Tasks"
  set_fact:
    deploy_environment: "Development"

  when: deploy_environment is undefined
  
  tags:
    - variable-test-task

###This does not work
- name: "Setting Deploy Environment Variable for Deployment Tasks"
  set_fact:
    deploy_environment: "Development"

  when: deploy_environment != "Development"
  
  tags:
    - variable-test-task

###This does not work
- name: "Setting Deploy Environment Variable for Deployment Tasks"
  set_fact:
    deploy_environment: "Development"

  when: deploy_environment == "Production"
  
  tags:
    - variable-test-task

###This does not work, playing with syntax, might be expected
- name: "Setting Deploy Environment Variable for Deployment Tasks"
  set_fact:
    deploy_environment: "Development"

  when: not (deploy_environment is defined) or not ((deploy_environment == 'Development') or (deploy_environment == 'Production'))
  
  tags:
    - variable-test-task

###This does not work, playing with syntax, might be expected
- name: "Setting Deploy Environment Variable for Deployment Tasks"
  set_fact:
    deploy_environment: "Development"

  when: (deploy_environment is undefined) or ((deploy_environment != 'Development') or (deploy_environment != 'Production'))
  
  tags:
    - variable-test-task

###This does not work, playing with syntax, might be expected
- name: "Setting Deploy Environment Variable for Deployment Tasks"
  set_fact:
    deploy_environment: "Development"

  when: (deploy_environment != 'Development') or (deploy_environment != 'Production')
  
  tags:
    - variable-test-task

```

`

And that was patiently explained to have been by design. I’m open to suggestions on the best overall way to accomplish this.

(Slightly related, I’d like to submit documentation changes that may make this more clear for users, and is that best done via a merge request?)

Thanks,  
Michael

---

<div class="post-metadata">

**Author:** ![Dick\_Visser](https://avatars.discourse-cdn.com/v4/letter/d/d9b06d/32.png) [@Dick\_Visser](https://forum.ansible.com/u/Dick_Visser)\
**Post date:** [April 28, 2020, 9:45am UTC](https://forum.ansible.com/t/input-validation-on-user-supplied-variable-example-setting-environment-to-production-development-staging/32794/2 "2020-04-28T09:45:47Z")

</div>

Hi

> Good afternoon,
> 
> I opened an issue on GitHub, and was directed here, which is the obvious place. (I initially thought that the behavior was indeed a bug, but there was some clarity added).
> 
> What would be the preferred method to perform input validation on a user supplied variable provided via extra vars? Is the recommended approach to simply handle an error (and end the host, play or task) if the variable doesn't match an expected input, as it is not possible to overwrite it due to precedence?
> 
> As it was, we were trying to use "-e" for the extra variables, and then using set\_fact to overwrite it if it didn't meet the expected requirements.
> 
> This is what I was trying:
> 
> ###This works as expected  
> - name: "Setting Deploy Environment Variable for Deployment Tasks"  
> &nbsp;&nbsp;set\_fact:  
> &nbsp;&nbsp;&nbsp;&nbsp;deploy\_environment: "Development"
> 
> &nbsp;&nbsp;when: deploy\_environment is undefined
> 
> &nbsp;&nbsp;tags:  
> &nbsp;&nbsp;&nbsp;&nbsp;- variable-test-task
> 
> ###This does not work  
> - name: "Setting Deploy Environment Variable for Deployment Tasks"  
> &nbsp;&nbsp;set\_fact:  
> &nbsp;&nbsp;&nbsp;&nbsp;deploy\_environment: "Development"
> 
> &nbsp;&nbsp;when: deploy\_environment != "Development"
> 
> &nbsp;&nbsp;tags:  
> &nbsp;&nbsp;&nbsp;&nbsp;- variable-test-task
> 
> ###This does not work  
> - name: "Setting Deploy Environment Variable for Deployment Tasks"  
> &nbsp;&nbsp;set\_fact:  
> &nbsp;&nbsp;&nbsp;&nbsp;deploy\_environment: "Development"
> 
> &nbsp;&nbsp;when: deploy\_environment == "Production"
> 
> &nbsp;&nbsp;tags:  
> &nbsp;&nbsp;&nbsp;&nbsp;- variable-test-task
> 
> ###This does not work, playing with syntax, might be expected  
> - name: "Setting Deploy Environment Variable for Deployment Tasks"  
> &nbsp;&nbsp;set\_fact:  
> &nbsp;&nbsp;&nbsp;&nbsp;deploy\_environment: "Development"
> 
> &nbsp;&nbsp;when: not (deploy\_environment is defined) or not ((deploy\_environment == 'Development') or (deploy\_environment == 'Production'))
> 
> &nbsp;&nbsp;tags:  
> &nbsp;&nbsp;&nbsp;&nbsp;- variable-test-task
> 
> ###This does not work, playing with syntax, might be expected  
> - name: "Setting Deploy Environment Variable for Deployment Tasks"  
> &nbsp;&nbsp;set\_fact:  
> &nbsp;&nbsp;&nbsp;&nbsp;deploy\_environment: "Development"
> 
> &nbsp;&nbsp;when: (deploy\_environment is undefined) or ((deploy\_environment != 'Development') or (deploy\_environment != 'Production'))
> 
> &nbsp;&nbsp;tags:  
> &nbsp;&nbsp;&nbsp;&nbsp;- variable-test-task
> 
> ###This does not work, playing with syntax, might be expected  
> - name: "Setting Deploy Environment Variable for Deployment Tasks"  
> &nbsp;&nbsp;set\_fact:  
> &nbsp;&nbsp;&nbsp;&nbsp;deploy\_environment: "Development"
> 
> &nbsp;&nbsp;when: (deploy\_environment != 'Development') or (deploy\_environment != 'Production')
> 
> &nbsp;&nbsp;tags:  
> &nbsp;&nbsp;&nbsp;&nbsp;- variable-test-task
> 
> And that was patiently explained to have been by design. I'm open to suggestions on the best overall way to accomplish this.

You're right about the precedence getting in the way of altering  
variables set with '-e', that's indeed not possible.  
However this is usually not a problem, as long as you use it to  
override something that is set already.  
But set\_fact can't win from '-e', so that won't work.  
There are a few alternatives.  
I usually avoid having to change variables directly, and instead use  
two variables. One meant for 'internal' use inside the role, which as  
a convention, I prefix with an underscore.  
For instance '\_env'. And then have an 'external' var meant for command  
line usage, say 'deploy\_environment'. Then any logic with set\_fact etc  
will work.

But, looking at your code again - all you seem to want is to provide a  
default for the 'deploy\_environment' variable.  
In that case, '-e' will just work fine, for instance:

- hosts: localhost  
&nbsp;&nbsp;connection: local  
&nbsp;&nbsp;gather\_facts: no

&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;deploy\_environment: Development

&nbsp;&nbsp;tasks:  
&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: |  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;We are deploying the {{ deploy\_environment }} environment now

If you run this without any '-e' switched, it will use Development.  
And you can just override it with '-e deploy\_environment=Production'.

For failing gracefully, look at the 'assert' module. The following  
example ensure only valid environments are being used:
