Persist environment variables for future ansible tasks
Question:
i´m triying to set in my localhost via a play env vars for future tasks/playbooks in the same localhost.
- name: Environment_vars
hosts: 127.0.0.1
connection: local
vars:
env_vars: /opt/env_vars.yml
env_path: ~/.bashrc
tasks:
- name: put into .bashrc
lineinfile:
path: "{{env_path}}"
state: present
regexp: "^{{ item.key }}="
line: "export {{item.key}}={{item.value}}"
with_dict: "{{ env_vars_dict }}"
become: yes
- name: test bash
shell: source ~/.bashrc
i have tried all of this methods that i found here, here and here. All of them worked but only inside the tasks. Including also, tasks to restart or source the shell, however didn´t work.
Is there any chance to set env vars in a play and use in the next play via ‘ansible.builtin.env lookup’? and also these new vars stay in the ‘env’??
Thanks!!!
Answers:
Q: "Set env vars in a play and use in the next play."
A: It is not possible. You can set environment in the scope of a play. There is no such thing as a ‘scope of a playbook’. For example, the second play knows nothing about the environment set in the first play only
- hosts: localhost
environment:
MY_VAR1: my variable 1
tasks:
- command: echo $MY_VAR1
register: out
- debug:
var: out.stdout
- hosts: localhost
tasks:
- command: echo $MY_VAR1
register: out
- debug:
var: out.stdout
gives (abridged)
out.stdout: my variable 1
out.stdout: $MY_VAR1
As a workaround, you can put the environment into the vars. For example, into the group_vars/all
shell> cat group_vars/all/my_env.yml
my_env:
MY_VAR1: my variable 1
MY_VAR2: my variable 2
Then, you can use it in each play
- hosts: localhost
environment: "{{ my_env }}"
tasks:
- command: echo $MY_VAR1
register: out
- debug:
var: out.stdout
- hosts: localhost
environment: "{{ my_env }}"
tasks:
- command: echo $MY_VAR1
register: out
- debug:
var: out.stdout
gives (abridged)
out.stdout: my variable 1
out.stdout: my variable 1
Q: "Set env vars in a play and use ansible.builtin.env"
A: The lookup plugin env never returns environment set via the keyword environment
- hosts: localhost
environment:
MY_VAR1: my variable 1
tasks:
- debug:
msg: "{{ lookup('ansible.builtin.env', 'SHELL') }}"
- debug:
msg: "{{ lookup('ansible.builtin.env', 'MY_VAR1') }}"
gives (abridged)
msg: /bin/bash
msg: ''
Any lookup plugin is always running on the localhost. The plugin env returns the environment inherited from the shell running the ansible-* utility.
Both command and shell modules do not run the commands in the inherited environment. For example,
shell> cat pb.yml
- hosts: localhost
environment:
MY_VAR1: my variable 1
tasks:
- debug:
msg: "{{ lookup('ansible.builtin.env', 'MY_VAR3') }}"
- command: echo $MY_VAR3 $MY_VAR1
register: out
- debug:
var: out.stdout
gives (abridged)
shell> MY_VAR3='my variable 3' ansible-playbook pb.yml
msg: my variable 3
out.stdout: $MY_VAR3 my variable 1
i´m triying to set in my localhost via a play env vars for future tasks/playbooks in the same localhost.
- name: Environment_vars
hosts: 127.0.0.1
connection: local
vars:
env_vars: /opt/env_vars.yml
env_path: ~/.bashrc
tasks:
- name: put into .bashrc
lineinfile:
path: "{{env_path}}"
state: present
regexp: "^{{ item.key }}="
line: "export {{item.key}}={{item.value}}"
with_dict: "{{ env_vars_dict }}"
become: yes
- name: test bash
shell: source ~/.bashrc
i have tried all of this methods that i found here, here and here. All of them worked but only inside the tasks. Including also, tasks to restart or source the shell, however didn´t work.
Is there any chance to set env vars in a play and use in the next play via ‘ansible.builtin.env lookup’? and also these new vars stay in the ‘env’??
Thanks!!!
Q: "Set env vars in a play and use in the next play."
A: It is not possible. You can set environment in the scope of a play. There is no such thing as a ‘scope of a playbook’. For example, the second play knows nothing about the environment set in the first play only
- hosts: localhost
environment:
MY_VAR1: my variable 1
tasks:
- command: echo $MY_VAR1
register: out
- debug:
var: out.stdout
- hosts: localhost
tasks:
- command: echo $MY_VAR1
register: out
- debug:
var: out.stdout
gives (abridged)
out.stdout: my variable 1
out.stdout: $MY_VAR1
As a workaround, you can put the environment into the vars. For example, into the group_vars/all
shell> cat group_vars/all/my_env.yml
my_env:
MY_VAR1: my variable 1
MY_VAR2: my variable 2
Then, you can use it in each play
- hosts: localhost
environment: "{{ my_env }}"
tasks:
- command: echo $MY_VAR1
register: out
- debug:
var: out.stdout
- hosts: localhost
environment: "{{ my_env }}"
tasks:
- command: echo $MY_VAR1
register: out
- debug:
var: out.stdout
gives (abridged)
out.stdout: my variable 1
out.stdout: my variable 1
Q: "Set env vars in a play and use ansible.builtin.env"
A: The lookup plugin env never returns environment set via the keyword environment
- hosts: localhost
environment:
MY_VAR1: my variable 1
tasks:
- debug:
msg: "{{ lookup('ansible.builtin.env', 'SHELL') }}"
- debug:
msg: "{{ lookup('ansible.builtin.env', 'MY_VAR1') }}"
gives (abridged)
msg: /bin/bash
msg: ''
Any lookup plugin is always running on the localhost. The plugin env returns the environment inherited from the shell running the ansible-* utility.
Both command and shell modules do not run the commands in the inherited environment. For example,
shell> cat pb.yml
- hosts: localhost
environment:
MY_VAR1: my variable 1
tasks:
- debug:
msg: "{{ lookup('ansible.builtin.env', 'MY_VAR3') }}"
- command: echo $MY_VAR3 $MY_VAR1
register: out
- debug:
var: out.stdout
gives (abridged)
shell> MY_VAR3='my variable 3' ansible-playbook pb.yml
msg: my variable 3
out.stdout: $MY_VAR3 my variable 1