Ansible Environment Variables: Set, Read & Manage env vars (Complete Guide)
By Luca Berton · Published 2024-01-01 · Category: installation
How to set and read environment variables in Ansible. Use environment keyword, lookup('env'), ansible.builtin.lineinfile for /etc/environment.
Ansible Environment Variables: Set, Read & Manage env vars (Complete Guide)
Managing environment variables with Ansible is essential for application deployment, service configuration, and system administration. This guide covers every approach — from setting per-task environment variables to configuring persistent system-wide settings.
See also: Download a file using an HTTPS proxy via environment variables - Ansible get_url and environment
Reading Environment Variables
Read from the Control Node
Use the lookup('env') plugin to read environment variables from the Ansible control node:
---
- name: Read environment variables from control node
hosts: all
tasks:
- name: Display HOME directory
ansible.builtin.debug:
msg: "Home: {{ lookup('env', 'HOME') }}"
- name: Use env var in a task
ansible.builtin.copy:
content: "Deployed by: {{ lookup('env', 'USER') }}"
dest: /opt/app/deploy-info.txt
Read from Remote Hosts
Use ansible.builtin.shell with register or access ansible_env facts:
---
- name: Read environment from remote hosts
hosts: all
gather_facts: true
tasks:
- name: Display remote PATH
ansible.builtin.debug:
msg: "Remote PATH: {{ ansible_env.PATH }}"
- name: Display remote HOME
ansible.builtin.debug:
msg: "Remote HOME: {{ ansible_env.HOME }}"
- name: Read specific env var with shell
ansible.builtin.shell: echo $JAVA_HOME
register: java_home_result
changed_when: false
- name: Show JAVA_HOME
ansible.builtin.debug:
msg: "JAVA_HOME: {{ java_home_result.stdout }}"
Setting Environment Variables Per Task
Use the environment keyword at the task level:
---
- name: Set environment for specific tasks
hosts: all
tasks:
- name: Run application with custom environment
ansible.builtin.command: /opt/app/bin/start.sh
environment:
APP_ENV: production
DB_HOST: db.example.com
DB_PORT: "5432"
LOG_LEVEL: info
PATH: "/opt/app/bin:{{ ansible_env.PATH }}"
See also: Ansible Set Environment Variables: lineinfile for /etc/environment & .bashrc
Setting Environment Variables Per Play
Apply environment to all tasks in a play:
---
- name: Deploy application
hosts: app_servers
environment:
ANSIBLE_MANAGED: "true"
APP_ENV: production
http_proxy: "http://proxy.example.com:8080"
https_proxy: "http://proxy.example.com:8080"
no_proxy: "localhost,127.0.0.1,.internal.example.com"
tasks:
- name: Download dependencies
ansible.builtin.command: /opt/app/install-deps.sh
- name: Start application
ansible.builtin.command: /opt/app/start.sh
Setting Environment Variables Per Role
# roles/myapp/defaults/main.yml
myapp_env:
APP_ENV: production
LOG_LEVEL: info
# roles/myapp/tasks/main.yml
- name: Run application
ansible.builtin.command: /opt/myapp/run.sh
environment: "{{ myapp_env }}"
See also: Ansible environment Keyword: Set Environment Variables Per Task or Play
Setting Persistent Environment Variables
System-Wide (/etc/environment)
---
- name: Set persistent environment variables
hosts: all
become: true
tasks:
- name: Set JAVA_HOME in /etc/environment
ansible.builtin.lineinfile:
path: /etc/environment
regexp: '^JAVA_HOME='
line: 'JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64'
create: true
- name: Set multiple environment variables
ansible.builtin.lineinfile:
path: /etc/environment
regexp: "^{{ item.key }}="
line: "{{ item.key }}={{ item.value }}"
loop:
- { key: 'LANG', value: 'en_US.UTF-8' }
- { key: 'EDITOR', value: '/usr/bin/vim' }
- { key: 'JAVA_HOME', value: '/usr/lib/jvm/java-17-openjdk-amd64' }
User-Specific (~/.bashrc or ~/.profile)
- name: Add environment variable to user profile
ansible.builtin.lineinfile:
path: "/home/{{ ansible_user }}/.bashrc"
regexp: '^export GOPATH='
line: 'export GOPATH=$HOME/go'
create: true
- name: Add to PATH in .bashrc
ansible.builtin.lineinfile:
path: "/home/{{ ansible_user }}/.bashrc"
regexp: '^export PATH=.*go/bin'
line: 'export PATH=$PATH:$HOME/go/bin:/usr/local/go/bin'
Using /etc/profile.d/ (Recommended for Applications)
- name: Create application environment profile
ansible.builtin.copy:
content: |
export APP_HOME=/opt/myapp
export APP_ENV=production
export PATH=$PATH:/opt/myapp/bin
dest: /etc/profile.d/myapp.sh
owner: root
group: root
mode: '0644'
Systemd Service Environment
- name: Set environment for systemd service
ansible.builtin.template:
src: myapp.service.j2
dest: /etc/systemd/system/myapp.service
notify: reload systemd
- name: Create environment file for service
ansible.builtin.copy:
content: |
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
SECRET_KEY={{ vault_secret_key }}
dest: /etc/myapp/env
owner: root
group: myapp
mode: '0640'
notify: restart myapp
Using Variables to Define Environment
Store environment settings in group_vars:
# group_vars/production.yml
app_environment:
APP_ENV: production
LOG_LEVEL: warn
DB_HOST: db.prod.example.com
# group_vars/staging.yml
app_environment:
APP_ENV: staging
LOG_LEVEL: debug
DB_HOST: db.staging.example.com
# playbook.yml
- name: Deploy app
hosts: app_servers
tasks:
- name: Run with environment-specific settings
ansible.builtin.command: /opt/app/start.sh
environment: "{{ app_environment }}"
Proxy Configuration
Common pattern for corporate environments:
---
- name: Configure proxy settings
hosts: all
environment:
http_proxy: "{{ proxy_url | default('') }}"
https_proxy: "{{ proxy_url | default('') }}"
no_proxy: "{{ no_proxy_list | default('localhost,127.0.0.1') }}"
vars:
proxy_url: "http://proxy.corp.example.com:3128"
no_proxy_list: "localhost,127.0.0.1,.internal.corp,.example.com"
tasks:
- name: Install packages through proxy
ansible.builtin.apt:
name: nginx
state: present
FAQ
How do I set environment variables in Ansible?
Use the environment keyword at the task, play, or role level. For persistent variables, use ansible.builtin.lineinfile to modify /etc/environment, ~/.bashrc, or create files in /etc/profile.d/.
How do I read environment variables from the control node in Ansible?
Use lookup('env', 'VARIABLE_NAME') to read environment variables from the machine running Ansible. This is evaluated on the control node, not the remote host.
How do I access remote host environment variables in Ansible?
Enable gather_facts: true and access ansible_env.VARIABLE_NAME. For example, ansible_env.PATH returns the remote host's PATH. Alternatively, use ansible.builtin.shell: echo $VAR with register.
What is the difference between environment and ansible_env?
The environment keyword sets environment variables for the current task or play. The ansible_env fact reads existing environment variables from the remote host. They serve opposite purposes.
How do I pass environment variables to a systemd service with Ansible?
Create an environment file (e.g., /etc/myapp/env) with KEY=VALUE pairs, then reference it in the systemd unit with EnvironmentFile=/etc/myapp/env. Use ansible.builtin.copy or ansible.builtin.template to manage the file.
Conclusion
Ansible provides multiple ways to manage environment variables — from per-task settings with the environment keyword to persistent configuration via /etc/environment and /etc/profile.d/. Choose the right approach based on whether you need temporary task-level variables or permanent system configuration.
Related Articles
• Ansible lookup('file'): Read Local File Contents into Variable • ansible.builtin.set_fact Module: Set Variables Dynamically • Ansible lineinfile Module: Add, Replace & Delete Lines in Files • Ansible Python Interpreter: Fix ansible_python_interpreter ErrorsCategory: installation