Ansible Environment Variables — Set and Use env vars in Playbooks
Introduction
Ansible's environment keyword sets environment variables for task execution on remote hosts. This is essential for commands that need PATH modifications, proxy settings, API tokens, database connection strings, or any application that reads configuration from the environment.
Setting Environment Variables
Per Task
---
- name: Environment variable examples
hosts: all
tasks:
- name: Run with custom environment
ansible.builtin.command:
cmd: /opt/app/bin/migrate
environment:
DATABASE_URL: "postgresql://db.example.com:5432/myapp"
RAILS_ENV: production
SECRET_KEY_BASE: "{{ vault_secret_key }}"
Per Play
- name: Deploy application
hosts: webservers
environment:
HTTP_PROXY: "http://proxy.example.com:3128"
HTTPS_PROXY: "http://proxy.example.com:3128"
NO_PROXY: "localhost,127.0.0.1,.example.com"
tasks:
- name: Install packages (uses proxy)
ansible.builtin.apt:
name: nginx
state: present
- name: Download file (uses proxy)
ansible.builtin.get_url:
url: https://releases.example.com/app-2.0.tar.gz
dest: /tmp/app-2.0.tar.gz
Per Role
- name: Deploy with role
hosts: all
roles:
- role: deploy_app
environment:
APP_ENV: production
LOG_LEVEL: warn
From Variables
vars:
proxy_env:
HTTP_PROXY: "http://proxy.example.com:3128"
HTTPS_PROXY: "http://proxy.example.com:3128"
NO_PROXY: "localhost,127.0.0.1"
app_env:
DATABASE_URL: "{{ vault_db_url }}"
REDIS_URL: "redis://cache.example.com:6379"
tasks:
- name: Install with proxy
ansible.builtin.apt:
name: curl
state: present
environment: "{{ proxy_env }}"
- name: Run application command
ansible.builtin.command:
cmd: /opt/app/bin/setup
environment: "{{ proxy_env | combine(app_env) }}"
Reading Environment Variables
From the Controller
# Read env vars from the machine running ansible-playbook
- name: Use controller environment variable
ansible.builtin.debug:
msg: "Home dir: {{ lookup('env', 'HOME') }}"
- name: Deploy with controller's AWS credentials
amazon.aws.ec2_instance:
name: webserver
instance_type: t3.micro
environment:
AWS_ACCESS_KEY_ID: "{{ lookup('env', 'AWS_ACCESS_KEY_ID') }}"
AWS_SECRET_ACCESS_KEY: "{{ lookup('env', 'AWS_SECRET_ACCESS_KEY') }}"
From the Remote Host
# Read env vars from the remote host via facts
- name: Show remote PATH
ansible.builtin.debug:
msg: "Remote PATH: {{ ansible_env.PATH }}"
- name: Check if variable is set on remote
ansible.builtin.debug:
msg: "JAVA_HOME is {{ ansible_env.JAVA_HOME | default('not set') }}"
Playbook workflow
Generate a complete playbook from this tutorial
Use Ansible Environment Variables Guide as the starting context and generate an editable Ansible playbook in the playground.
One anonymous generation is available. Do not paste passwords, private keys, tokens, or customer secrets.
Common Use Cases
PATH Modification
- name: Run command with custom PATH
ansible.builtin.command:
cmd: my-custom-tool --version
environment:
PATH: "/opt/custom/bin:{{ ansible_env.PATH }}"
Python Virtual Environments
- name: Install Python packages in virtualenv
ansible.builtin.pip:
name: django
virtualenv: /opt/app/venv
environment:
VIRTUAL_ENV: /opt/app/venv
PATH: "/opt/app/venv/bin:{{ ansible_env.PATH }}"
Java Applications
- name: Run Java application
ansible.builtin.command:
cmd: java -jar /opt/app/app.jar
environment:
JAVA_HOME: /usr/lib/jvm/java-17
JAVA_OPTS: "-Xms512m -Xmx2048m -Djava.io.tmpdir=/opt/tmp"
SPRING_PROFILES_ACTIVE: production
Persistent Environment Variables
# Set env vars permanently on remote host
- name: Set system-wide environment variable
ansible.builtin.lineinfile:
path: /etc/environment
regexp: '^APP_ENV='
line: 'APP_ENV=production'
- name: Set user environment variable
ansible.builtin.lineinfile:
path: "/home/{{ app_user }}/.bashrc"
regexp: '^export DATABASE_URL='
line: 'export DATABASE_URL="{{ vault_db_url }}"'
- name: Create environment file for systemd service
ansible.builtin.template:
src: app.env.j2
dest: /etc/myapp/environment
mode: '0600'
notify: Restart myapp
Systemd Environment Files
# Template: app.env.j2
# DATABASE_URL={{ db_url }}
# REDIS_URL={{ redis_url }}
# SECRET_KEY={{ vault_secret_key }}
- name: Configure systemd service with env file
ansible.builtin.template:
src: myapp.service.j2
dest: /etc/systemd/system/myapp.service
notify: Reload systemd
# myapp.service.j2
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=myapp
EnvironmentFile=/etc/myapp/environment
ExecStart=/opt/app/bin/start
Restart=always
[Install]
WantedBy=multi-user.target
Proxy Configuration
# group_vars/all.yml — apply proxy to all hosts behind corporate firewall
proxy_env:
HTTP_PROXY: "http://proxy.corp.example.com:8080"
HTTPS_PROXY: "http://proxy.corp.example.com:8080"
NO_PROXY: "localhost,127.0.0.1,10.0.0.0/8,.corp.example.com"
http_proxy: "{{ HTTP_PROXY }}" # Some tools use lowercase
https_proxy: "{{ HTTPS_PROXY }}"
no_proxy: "{{ NO_PROXY }}"
Troubleshooting
| Issue | Solution |
|---|---|
| Environment not applied | environment only affects that task, not the session |
lookup('env') returns empty | Variable not set on controller; check with echo $VAR |
ansible_env missing variable | Run gather_facts: true; variable must be in remote shell |
| Proxy not working | Set both uppercase AND lowercase variants |
| PATH not found | Prepend to existing: "/new/path:{{ ansible_env.PATH }}" |
Best Practices
- Use
environmentkeyword, notshell: export— cleaner and scoped - Store env vars in
group_vars— defineproxy_envonce, use everywhere - Secrets via Vault —
DATABASE_URL: "{{ vault_db_url }}" - Use
combine()to merge —environment: "{{ base_env | combine(app_env) }}" - Persistent vars via files — use
/etc/environment,.bashrc, or systemdEnvironmentFile - Don't leak secrets in logs — use
no_log: trueon tasks with sensitive env vars
Conclusion
The environment keyword gives you precise control over task execution context — proxy settings, API keys, PATH modifications, and application configuration. Define environment dictionaries in group_vars, combine them with | combine(), and keep secrets in Vault. For persistent environment changes, use lineinfile on shell profiles or systemd EnvironmentFile.