使用 ansible 从 env 文件中读取多个值并将它们存储为事实
Reading multiple values from an env file with ansible and storing them as facts
我有以下代码,它从环境 (.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 模块允许我从环境文件加载值,那就更理想了。
通常我会把我的变量本身放入清单文件中,或者将它们转换为 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"
}
我有以下代码,它从环境 (.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 模块允许我从环境文件加载值,那就更理想了。
通常我会把我的变量本身放入清单文件中,或者将它们转换为 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"
}