Ansible从列表中创建目录

时间:2015-05-04 17:24:27

标签: loops variables dictionary ansible

我想从我vars/main.yml中的列表中创建一些目录。

- app_root:
    network_prod:   "/var/www/prod/network/app"
    database_prod:  "/var/www/prod/db/app"

我的tasks/main.yml到目前为止有这个:

- name: Create application directory structure
  file: 
    path: "{{ item }}"
    state: directory
    mode: 755
  with_items:
    - app_root

但不起作用。我认为这可以使用with_dict来实现,我也尝试过:

- name: Create application directory structure
  file: 
    path: "{{ item.value }}"
    state: directory
    mode: 755
  with_dict:
    - app_root

但我得到了:fatal: [vagrant.dev] => with_dict expects a dict

我已经阅读了有关looping-over-hashes的所有内容,但这似乎无法奏效。

我使用这种表示法的原因是因为我在其他地方使用这些变量,我需要知道如何调用它们。

3 个答案:

答案 0 :(得分:1)

I personally find it a bit easier to convert yaml to json to make sure I'm understanding it properly. Take your example:

- app_root:
    network_prod:   "/var/www/prod/network/app"
    database_prod:  "/var/www/prod/db/app"

What you have here is not a list, but a nested dictionary. If you converted this to json it would look like this:

[
  {
    "app_root": {
      "network_prod": "/var/www/prod/network/app",
      "database_prod": "/var/www/prod/db/app"
    }
  }
]

In order to loop through this in Ansible you would need to dereference two levels of a dictionary, the first being app_root and the second being the path elements. Unfortunately I don't think Ansible supports looping through nested dictionaries, only through nested loops.

Your best bet is probably to redo the way you're defining your paths so that you're not creating as complex a data structure. If all you're doing in this case is iterating over a list of paths in order to ensure the directories exist then I'd suggest something like this in your vars/main.yml file:

network_prod:   "/var/www/prod/network/app"
database_prod:  "/var/www/prod/db/app"

app_root:
  - network_prod
  - database_prod

Then you can have a task like this:

file: path={{ item }}
      state=directory 
with_items: app_root

答案 1 :(得分:0)

vars/main.yml中,尝试删除app_root前面的短划线。

app_root:
  network_prod:   "/var/www/prod/network/app"
  database_prod:  "/var/www/prod/db/app"

答案 2 :(得分:0)

我认为with_dict的方法是正确的,我认为这里唯一的问题是-变量前面的短划线app_root。而不是:

- name: Create application directory structure
  file: 
    path: "{{ item.value }}"
    state: directory
    mode: 755
  with_dict:
    - app_root

应该是:

- name: Create application directory structure
  file: 
    path: "{{ item.value }}"
    state: directory
    mode: 755
  with_dict: app_root

查看变量app_root传递给with_dict的方式的差异。

YAML中的破折号启动一个列表,并且元素不被视为变量而是视为文字,将其视为传递不可变字符串' app_root'到with_dict(不完全正确,但它有助于我这样思考)所以when_dict无法解析它,因为它被赋予一个列表而不是预期的字典。但是,如果没有短划线,with_dict会填充变量app_root,而且会解析它而不会出现问题。