2

我有以下代码从环境(.env)文件中读取值并将它们存储为事实:

- name: Read values from environment
  shell: "source {{ env_path }}; echo $DB_PASSWORD"
  register: output
  args:
    executable: /bin/bash
  changed_when: false

- name: Store read password
  set_fact:
    db_password: "{{ output.stdout }}"
  when:
    - db_password is undefined
  changed_when: false

- name: Read values from environment
  shell: "source {{ env_path }}; echo $DB_USER"
  register: output
  args:
    executable: /bin/bash
  changed_when: false

- name: Store read user
  set_fact:
    db_user: "{{ output.stdout }}"
  when:
    - db_user is undefined
  changed_when: false

- name: Read values from environment
  shell: "source {{ env_path }}; echo $DB_NAME"
  register: output
  args:
    executable: /bin/bash
  changed_when: false

- name: Store read db_name
  set_fact:
    db_name: "{{ output.stdout }}"
  when:
    - db_name is undefined
  changed_when: false

- name: Container environment loaded; the following facts are now available for use by ansible
  debug: "var={{ item }}"
  with_items:
    - db_name
    - db_user
    - db_password

它非常笨重且笨拙。我想写这样的东西,但我不知道如何:

vars:
    values:
       - db_name
       - db_password
       - db_user
tasks:
- name: Read values from environment
  shell: "source {{ env_path }}; echo {{ item|upper }}"
  register: output
  with_items: values
  args:
    executable: /bin/bash
  changed_when: false

- name: Store read value
  set_fact:
    "{{ item.0 }}": "{{ item.1.stdout }}"
  when:
    - item.0 is undefined
  with_together:
    - values
    - output.results
  changed_when: false

相反,我得到了这个输出:

ok: [default] => (item=values) => {"changed": false, "cmd": "source /var/www/mydomain.org/.env; echo VALUES", "delta": "0:00:00.002240", "end": "2017-02-15 15:25:15.338673", "item": "values", "rc": 0, "start": "2017-02-15 15:25:15.336433", "stderr": "", "stdout": "VALUES", "stdout_lines": ["VALUES"], "warnings": []}

TASK [sql-base : Store read password] ******************************************
skipping: [default] => (item=[u'values', u'output.results'])  => {"changed": false, "item": ["values", "output.results"], "skip_reason": "Conditional check failed", "skipped": true}

当然,更理想的情况是,如果有一个我忽略的 ansible 模块允许我从环境文件中加载值。

4

1 回答 1

2

通常,我要么将我的变量放入清单文件本身,要么将它们转换为yml格式并使用include_vars模块(您可能能够运行sed脚本将您的环境文件即时转换为 yml)。在使用以下代码之前,请确保您确实需要使用这些环境文件,并且您不能轻易使用其他一些机制,例如:

  • 带有include_vars模块的 YAML 文件
  • 将配置放入库存中(不需要模块)
  • 将配置放入 ansible vault 文件(不需要模块,但您需要将解密密钥存储在某处)
  • 使用其他一些安全存储机制,例如 Hashicorp 的保险库(使用https://github.com/jhaals/ansible-vault之类的插件)

回到您的代码,它实际上几乎是正确的,您在读取任务中缺少一美元,以及条件中的一些花括号:

test.env

DB_NAME=abcd
DB_PASSWORD=defg
DB_USER=fghi

注意:确保此文件符合sh标准,这意味着您不要在=标志周围放置空格。拥有类似的东西DB_NAME = abcd会失败

play.yml

- hosts: all
  connection: local
  vars:
      env_path: 'test.env'
      values:
         - db_name
         - db_password
         - db_user
  tasks:
  - name: Read values from environment
    shell: "source {{ env_path }}; echo ${{ item|upper }}"
    register: output
    with_items: "{{ values }}"
    args:
      executable: /bin/bash
    changed_when: false

  - name: Store read value
    set_fact:
      "{{ item.0 }}": "{{ item.1.stdout }}"
    when: '{{ item.0 }} is undefined'
    with_together:
      - "{{ values }}"
      - "{{ output.results }}"
    changed_when: false

  - name: Debug
    debug:
      msg: "NAME: {{db_name}} PASS: {{db_password}} USER: {{db_user}}"

运行ansible-playbook -i 127.0.0.1, play.yml

TASK [Debug] *******************************************************************
ok: [127.0.0.1] => {
    "msg": "NAME: abcd PASS: defg USER: fghi"
}
于 2017-02-15T16:57:14.410 回答