Ansible:当有些文件不存在时,我可以使用vars_files吗?

这是部分:

vars_files: - vars/vars.default.yml - vars/vars.yml 

如果一个文件vars/vars.yml不存在 – 这是一个错误。

 ERROR: file could not read: /.../vars/vars.yml 

如何才能从这个文件加载额外的variables,只要它存在? (没有错误)

这真的很简单。 您可以将不同的vars_files项目压缩到一个元组中,Ansible将自动遍历每个元素,直到find存在并加载它的文件。 例如:

 vars_files: - [ "vars/foo.yml", "vars/bar.yml", "vars/default.yml" ] 

根据Ansible的开发者 ,解决这个问题的正确方法是使用如下的东西:

 vars_files_var: ['../path/to/file1', '../path/to/file2', ...] - include_vars: {{item}} with_first_found: vars_files_var 

而且, 他们说 :

以上将正确加载find的第一个文件,并且比通过vars_files语言关键字尝试执行此操作更为灵活。

我在设置中遇到了这个问题,我需要创build多个部署环境(live,demo,sandbox)到同一个物理服务器(这里不允许使用虚拟机),然后使用一个脚本来部署任意的svn repos

这需要一个(可选的)variable.yml文件的目录树,它将合并在一起,不会抛出exception,如果任何地方丢失

首先启用合理的variables合并 – 请注意,这是浅层哈希合并(1层深),而不是完全recursion深层合并

ansible.cfg

 [defaults] hash_behaviour=merge ;; merge rather than replace dictionaries http://docs.ansible.com/ansible/intro_configuration.html###hash-behaviour 

Ansible目录布局

 /group_vars └── all.yml /playbooks ├── boostrap.yml ├── demo.yml ├── live.yml └── sandbox.yml /roles/deploy/ ├── files ├── tasks │  ├── includes.yml │  ├── main.yml └── vars ├── main.yml ├── project_1.yml ├── project_2.yml ├── demo │  ├── project_1.yml │  ├── project_2.yml │  └── main.yml ├── live │  ├── project_1.yml │  ├── project_2.yml │  └── main.yml └── sandbox ├── project_1.yml ├── project_2.yml └── main.yml 

angular色/部署/任务/ includes.yml

这是可选variables文件目录树的主要逻辑。

 ;; imports in this order: ;; - /roles/deploy/vars/main.yml ;; - /roles/deploy/vars/{{ project_name }}.yml ;; - /roles/deploy/vars/{{ project_name }}/main.yml ;; - /roles/deploy/vars/{{ project_name }}/{{ project_env }}.yml - include_vars: dir: 'vars' files_matching: "{{ item }}" depth: 1 with_items: - "main.yml" - "{{ project_name }}.yml" - include_vars: dir: 'vars/{{ env_name }}' files_matching: "{{ item }}" depth: 1 with_items: - "main.yml" - "{{ project_name }}.yml" 

group_vars / all.yml

为项目和各种用户和环境configuration默认variables

 project_users: bootstrap: env: bootstrap user: ansible group: ansible mode: 755 root: /cs/ansible/ home: /cs/ansible/home/ansible/ directories: - /cs/ansible/ - /cs/ansible/home/ live: env: live user: ansible-live group: ansible mode: 755 root: /cs/ansible/live/ home: /cs/ansible/home/ansible-live/ demo: env: demo user: ansible-demo group: ansible mode: 755 root: /cs/ansible/demo/ home: /cs/ansible/home/ansible-demo/ sandbox: env: sandbox user: ansible-sandbox group: ansible mode: 755 root: /cs/ansible/sandbox/ home: /cs/ansible/home/ansible-sandbox/ project_env: bootstrap project_user: "{{ ansible_users[project_env] }}" ;; this will be retroactively updated if project_env is redefined later 

angular色/configuration/瓦尔/ main.yml

项目默认值

 ansible_project: node_env: development node_port: 4200 nginx_port: 4400 

angular色/configuration/瓦尔/ project_1.yml

默认为project_1

 ansible_project: node_port: 4201 nginx_port: 4401 

angular色/configuration/瓦尔/现场/ main.yml

实时环境默认值,覆盖项目默认值

 ansible_project: node_env: production 

angular色/configuration/瓦尔/现场/ project_1.yml

最终覆盖project_1在现场环境

 ansible_project: nginx_port: 80 

剧本/ demo.yml

为每个环境configuration单独的手册

 - hosts: shared_server remote_user: ansible-demo vars: project_env: demo pre_tasks: - debug: "msg='{{ facter_gid }}@{{ facter_fqdn }} ({{ server_pseudonym }})'" - debug: var=project_ssh_user roles: - { role: deploy, project_name: project_1 } 

警告:因为所有的环境都存在于一台主机上,所有的剧本都必须单独运行,否则Ansible会突然尝试运行所有的脚本作为第一个sshlogin用户,并且只为第一个用户使用variables。 如果您需要按顺序运行所有脚本,则使用xargs将它们分别作为单独的命令运行。

 find ./playbooks/*.yml | xargs -L1 time ansible-playbook 

或者以更多的方式:

 - hosts: webservers vars: paths_to_vars_files: - vars/{{ ansible_hostname }}.yml - vars/default.yml tasks: - include_vars: "{{ item }}" with_first_found: "{{ paths_to_vars_files }}" 

也就是说,而不是用方括号写一行数组,如:

 ['path/to/file1', 'path/to/file2', ...] 

使用yaml方法在多行写数组值,如:

 - path/to/file1 - path/to/file2 

如前所述,这会查找名为{{ ansible_hostname }}.yml的variables文件,如果不存在,则使用default.yml