Reading multiple values from an env file with ansible and storing them as facts

时间秒杀一切 提交于 2021-02-19 05:30:07

问题


I have the following code which reads values from an environment (.env) file and stores them as facts:

- 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

It's quite bulky and unwieldy. I would like to write it something like this, but I can't figure out how :

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

Instead, I get this output:

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}

Even more ideal of course would be if there is an ansible module I have overlooked that allows me to load values from an environment file.


回答1:


Generally I would either put my variables into the inventory files themselves, or convert them to yml format and use the include_vars module (you might be able to run a sed script to convert your environment file to yml on the fly). Before using the below code make sure you are really required to use those environment files, and you cannot easily use some other mechanism like:

  • a YAML file with the include_vars module
  • putting the config inside the inventory (no modules required)
  • putting the config into an ansible vault file (no modules required, you need to store the decryption key somewhere though)
  • use some other secure storage mechanism, like Hashicorp's vault (with a plugin like https://github.com/jhaals/ansible-vault)

Back to your code, it is actually almost correct, you were missing a dollar from the read task, and some curly braces from the condition:

test.env

DB_NAME=abcd
DB_PASSWORD=defg
DB_USER=fghi

Note: make sure that this file adheres to sh standards meaning you don't put spaces around the = sign. Having something like DB_NAME = abcd will fail

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}}"

Running with ansible-playbook -i 127.0.0.1, play.yml:

TASK [Debug] *******************************************************************
ok: [127.0.0.1] => {
    "msg": "NAME: abcd PASS: defg USER: fghi"
}


来源:https://stackoverflow.com/questions/42253519/reading-multiple-values-from-an-env-file-with-ansible-and-storing-them-as-facts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!