Ansible environment Keyword: Set Environment Variables Per Task or Play
By Luca Berton · Published 2024-01-01 · Category: troubleshooting
How to set environment variables per task or play in Ansible using the environment keyword. Configure proxy, PATH, and app-specific variables with examples.

How to set remote environment per Ansible task or play?
I'm going to show you a live Playbook with some simple Ansible code. I'm Luca Berton and welcome to today's episode of Ansible Pilot.See also: Download a file using an HTTPS proxy via environment variables - Ansible get_url and environment
Set remote environment per Ansible task or play
•environment statement
You could set the remote environment with the Ansible statement environment.
The environment statement could be applied at the task level or play level.
It's very useful to set for example proxy in a corporate environment.
Links
• Setting the remote environment## Playbook
Set environment per Ansible Playbook task or play level.
code
---
- name: remote environment Playbook
hosts: all
gather_facts: false
environment:
EXAMPLE: test1
tasks:
- name: diplay EXAMPLE
ansible.builtin.command: "echo $EXAMPLE"
- name: diplay EXAMPLE
ansible.builtin.command: "echo $EXAMPLE"
environment:
EXAMPLE: test2
execution
You need to run the playbook with the verbose option (-v) in order to see the standard output on the console.
ansible-pilot $ ansible-playbook -i virtualmachines/demo/inventory ansible\ statements/environment-remote.yml
PLAY [remote environment Playbook] ********************************************************************
TASK [diplay EXAMPLE] *****************************************************************************
changed: [demo.example.com]
TASK [diplay EXAMPLE] *****************************************************************************
changed: [demo.example.com]
PLAY RECAP ****************************************************************************************
demo.example.com : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible-pilot $ ansible-playbook -i virtualmachines/demo/inventory ansible\ statements/environment-remote.yml -v
No config file found; using defaults
PLAY [remote environment Playbook] ********************************************************************
TASK [diplay EXAMPLE] *****************************************************************************
changed: [demo.example.com] => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": ["echo", "$EXAMPLE"], "delta": "0:00:00.002864", "end": "2022-02-21 09:05:33.059864", "msg": "", "rc": 0, "start": "2022-02-21 09:05:33.057000", "stderr": "", "stderr_lines": [], "stdout": "test1", "stdout_lines": ["test1"]}
TASK [diplay EXAMPLE] *****************************************************************************
changed: [demo.example.com] => {"changed": true, "cmd": ["echo", "$EXAMPLE"], "delta": "0:00:00.002800", "end": "2022-02-21 09:05:33.416884", "msg": "", "rc": 0, "start": "2022-02-21 09:05:33.414084", "stderr": "", "stderr_lines": [], "stdout": "test2", "stdout_lines": ["test2"]}
PLAY RECAP ****************************************************************************************
demo.example.com : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible-pilot $
idempotency
ansible-pilot $ ansible-playbook -i virtualmachines/demo/inventory ansible\ statements/environment-remote.yml -v
No config file found; using defaults
PLAY [remote environment Playbook] ********************************************************************
TASK [diplay EXAMPLE] *****************************************************************************
changed: [demo.example.com] => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": ["echo", "$EXAMPLE"], "delta": "0:00:00.002864", "end": "2022-02-21 09:05:33.059864", "msg": "", "rc": 0, "start": "2022-02-21 09:05:33.057000", "stderr": "", "stderr_lines": [], "stdout": "test1", "stdout_lines": ["test1"]}
TASK [diplay EXAMPLE] *****************************************************************************
changed: [demo.example.com] => {"changed": true, "cmd": ["echo", "$EXAMPLE"], "delta": "0:00:00.002800", "end": "2022-02-21 09:05:33.416884", "msg": "", "rc": 0, "start": "2022-02-21 09:05:33.414084", "stderr": "", "stderr_lines": [], "stdout": "test2", "stdout_lines": ["test2"]}
PLAY RECAP ****************************************************************************************
demo.example.com : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible-pilot $
before execution
ansible-pilot $ ssh devops@demo.example.com
Last login: Fri Feb 18 16:07:48 2022 from 192.168.0.59
[devops@demo ~]$ echo $EXAMPLE
[devops@demo ~]$
after execution
ansible-pilot $ ssh devops@demo.example.com
Last login: Mon Feb 21 07:05:33 2022 from 192.168.251.111
[devops@demo ~]$ echo $EXAMPLE
See also: Ansible Set Environment Variables: lineinfile for /etc/environment & .bashrc
Conclusion
Now you know how to set remote environment per Ansible task or play.
Per-Task Environment
- name: Run with proxy
ansible.builtin.apt:
name: nginx
state: present
environment:
http_proxy: http://proxy.corp.com:3128
https_proxy: http://proxy.corp.com:3128
become: true
See also: Ansible Environment Variables: Set, Read & Manage env vars (Complete Guide)
Per-Play Environment
- hosts: webservers
environment:
http_proxy: "{{ corporate_proxy }}"
https_proxy: "{{ corporate_proxy }}"
no_proxy: "localhost,127.0.0.1,.internal.com"
tasks:
- apt:
name: nginx # Uses proxy
- pip:
name: flask # Uses proxy
Custom PATH
- name: Run with custom PATH
ansible.builtin.command: myapp --version
environment:
PATH: "/opt/myapp/bin:{{ ansible_env.PATH }}"
Application Configuration
- name: Start app with env config
ansible.builtin.command: ./start.sh
args:
chdir: /opt/myapp
environment:
APP_ENV: production
DATABASE_URL: "postgresql://{{ db_host }}:5432/{{ db_name }}"
REDIS_URL: "redis://{{ redis_host }}:6379"
SECRET_KEY: "{{ vault_secret_key }}"
no_log: true
Environment from Variables
# group_vars/all.yml
proxy_env:
http_proxy: http://proxy.corp.com:3128
https_proxy: http://proxy.corp.com:3128
no_proxy: "localhost,.internal.com"
app_env:
APP_ENV: production
LOG_LEVEL: info
- hosts: webservers
environment: "{{ proxy_env }}"
tasks:
- apt: name=nginx
- name: Start app
command: ./start.sh
environment: "{{ proxy_env | combine(app_env) }}"
Per-Block Environment
- block:
- apt: name=python3-pip
- pip: name=flask
- pip: name=gunicorn
environment:
http_proxy: "{{ proxy_url }}"
become: true
In Roles
# roles/myapp/defaults/main.yml
myapp_environment:
APP_HOME: /opt/myapp
APP_ENV: production
# roles/myapp/tasks/main.yml
- name: Start application
command: ./start.sh
args:
chdir: "{{ myapp_environment.APP_HOME }}"
environment: "{{ myapp_environment }}"
environment vs shell export
| Method | Scope | Persistence |
|--------|-------|-------------|
| environment: | Single task/play | None (task only) |
| lineinfile on .bashrc | User sessions | Permanent |
| /etc/environment | System-wide | Permanent |
| systemd Environment= | Service | Service restarts |
FAQ
Does environment affect become/sudo?
By default, sudo resets the environment. Preserve it with:
become_flags: '-E'
Or configure sudoers: Defaults env_keep += "http_proxy https_proxy"
Can I merge multiple environment dicts?
environment: "{{ base_env | combine(app_env) | combine(extra_env) }}"
Does it set env on the controller or remote?
Remote host — the environment applies where the task runs. Use delegate_to: localhost for controller-side env.
Related Articles
• Ansible inventory complete reference • Ansible env var patternsCategory: troubleshooting
Watch the video: Ansible environment Keyword: Set Environment Variables Per Task or Play — Video Tutorial