Repository: ansible/ansible

Issue:
Align vars in playbook and inventory
Currently playbooks define vars like:

```

---
- hosts: all
  vars:
    template: "../templates"
    netconfig_dir: "/etc/sysconfig/network-scripts"
  tasks:
  - name: do this
    action: ...
  - name: do that
    action: ...
```

For the inventory I didn't pay enough attention to this and designed the format as:

```

---
- group: greek
  hosts:
  - zeus
  - hera
  - poseidon
  vars:
  - ansible_ssh_port: 3000
  - ntp_server: olympus.example.com
```

Note the dash. Every other list item in a playbook has a dash (vars_files, notify). I get where it originates (hash vs list) and in that light it makes sense, but I believe it doesn't make sense to the casual observer.

Options:
- Change vars in inventory to match the style in playbooks
- Support 'listed vars' in playbooks too
- Support both syntaxes everywhere.

I can fix it any way you like. I prefer 3 as it gives the most flexibility...



Discussion:
Thanks for catching this...

I think 3 is the least error prone as well.   Sounds good.

If we can make playbooks also work like that... maybe it might eliminate a common class of YAML errors?   It's easy to typo.


Resolving patch:
diff --git a/lib/ansible/inventory.py b/lib/ansible/inventory.py
--- a/lib/ansible/inventory.py
+++ b/lib/ansible/inventory.py
@@ -216,11 +216,16 @@ def _parse_yaml(self):
 
     def _parse_yaml_host(self, item, variables=[]):
         def set_variables(host, variables):
-            for variable in variables:
-                if len(variable) != 1:
-                    raise errors.AnsibleError("Only one item expected in %s"%(variable))
-                k, v = variable.items()[0]
-                self._set_variable(host, k, v)
+            if type(variables) == list:
+                for variable in variables:
+                    if len(variable) != 1:
+                        raise errors.AnsibleError("Only one item expected in %s"%(variable))
+                    k, v = variable.items()[0]
+                    self._set_variable(host, k, v)
+            elif type(variables) == dict:
+                for k, v in variables.iteritems():
+                    self._set_variable(host, k, v)
+
 
         if type(item) in [str, unicode]:
             set_variables(item, variables)
diff --git a/lib/ansible/playbook.py b/lib/ansible/playbook.py
--- a/lib/ansible/playbook.py
+++ b/lib/ansible/playbook.py
@@ -118,8 +118,18 @@ def _get_vars(self, play, dirname):
         if play.get('vars') is None:
             play['vars'] = {}
         vars = play['vars']
-        if type(vars) != dict:
+        if type(vars) not in [dict, list]:
             raise errors.AnsibleError("'vars' section must contain only key/value pairs")
+
+        # translate a list of vars into a dict
+        if type(vars) == list:
+            varlist = vars
+            vars =  {}
+            for item in varlist:
+                k, v = item.items()[0]
+                vars[k] = v
+            play['vars'] = vars
+
         vars_prompt = play.get('vars_prompt', {})
         if type(vars_prompt) != dict:
             raise errors.AnsibleError("'vars_prompt' section must contain only key/value pairs")


Test patch:
diff --git a/test/TestInventory.py b/test/TestInventory.py
--- a/test/TestInventory.py
+++ b/test/TestInventory.py
@@ -220,13 +220,13 @@ def test_yaml_host_vars(self):
         inventory = self.yaml_inventory()
         vars = inventory.get_variables('saturn')
 
-        assert vars == {"moon":"titan"}
+        assert vars == {"moon":"titan", "moon2":"enceladus"}
 
     def test_yaml_port(self):
         inventory = self.yaml_inventory()
         vars = inventory.get_variables('hera')
 
-        assert vars == {'ansible_ssh_port': 3000}
+        assert vars == {'ansible_ssh_port': 3000, 'ntp_server': 'olympus.example.com'}
 
     ### Test Runner class method
 
diff --git a/test/yaml_hosts b/test/yaml_hosts
--- a/test/yaml_hosts
+++ b/test/yaml_hosts
@@ -3,7 +3,8 @@
 - jupiter
 - host: saturn
   vars:
-  - moon: titan
+    moon: titan
+    moon2: enceladus
 
 - zeus
 
@@ -14,6 +15,7 @@
   - poseidon
   vars:
   - ansible_ssh_port: 3000
+  - ntp_server: olympus.example.com
 
 - group: norse
   hosts: