Dictionary keys and global variable namespace clash?

59 views
Skip to first unread message

Jameel Al-Aziz

unread,
Apr 2, 2015, 3:20:56 PM4/2/15
to ansible...@googlegroups.com
I'm not sure if this is a bug or intended behavior.

If I have the following playbook (the database_url variable actually lives in a separate var file):

---
- hosts: all
  vars
:
   
- environment: development
   
- database_url:
        development
: mysql://development
        production
: mysq://production
   
- env_vars:
        environment
: "{{ environment }}"
        database_url
: "{{ database_url[environment] }}"
  pre_tasks
:
   
- debug: var=environment
   
- debug: var=env_vars

and run it with "ansible-playbook -c local -i localhost, test.yml", I get:

PLAY [all] ********************************************************************


GATHERING FACTS
***************************************************************
ok
: [localhost]


TASK
: [debug var=environment] *************************************************
ok
: [localhost] => {
   
"var": {
       
"environment": {}
   
}
}


TASK
: [debug var=env_vars] ****************************************************
ok
: [localhost] => {
   
"var": {
       
"env_vars": {
           
"database_url": "{{ database_url[environment] }}",
           
"environment": {}
       
}
   
}
}


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

As you can see, the environment variable and database_url aren't resolved. It seems that the environment key under the env_vars dictionary clobbers the global environment key. I could simply set the value of the environment variable on the environment dictionary key itself (I don't need it to be global), but then the database_url still won't resolve. 

---
- hosts: all
  vars
:
   
- environment: development
   
- database_url:
        development
: mysql://development
        production
: mysq://production
   
- env_vars:
        environment
: development
        database_url
: "{{ database_url[environment] }}"
  pre_tasks
:
   
- debug: var=environment
   
- debug: var=env_vars

PLAY [all] ********************************************************************


GATHERING FACTS
***************************************************************
ok
: [localhost]


TASK
: [debug var=environment] *************************************************
ok
: [localhost] => {
   
"var": {
       
"environment": {}
   
}
}


TASK
: [debug var=env_vars] ****************************************************
ok
: [localhost] => {
   
"var": {
       
"env_vars": {
           
"database_url": "{{ database_url[environment] }}",
           
"environment": "development"
       
}
   
}
}


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


However, if I rename the global "environment" variable to "env", it works fine. At a high-level this seems like inconsistent behavior; a dictionary key clobbers a global variable, but then cannot be used as global variable.

I know I could just load a separate var file for each environment, but the issue would still exist where re-using a variable name as a dictionary key would clobber the variable.

Brian Coca

unread,
Apr 2, 2015, 3:25:09 PM4/2/15
to ansible...@googlegroups.com
environment is a reserved keyword, you should not be using it as a
variable name.



--
Brian Coca

Jameel Al-Aziz

unread,
Apr 2, 2015, 3:30:47 PM4/2/15
to ansible...@googlegroups.com
Wow. My bad.

Changing it to env makes everything work. Thanks for pointing that out!
Reply all
Reply to author
Forward
0 new messages