AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible Set Environment Variables: lineinfile for /etc/environment & .bashrc

By Luca Berton · Published 2024-01-01 · Category: troubleshooting

How to permanently set system-wide and user-level environment variables on Linux with Ansible. Use lineinfile for /etc/environment, profile.d, and .bashrc.

Ansible Set Environment Variables: lineinfile for /etc/environment & .bashrc

How to permanently set system-wide environment variables on remote Linux with Ansible?

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

Permanently Set System-Wide Environment Variables on Remote Linux

• /etc/environment • /etc/profile.d directory

There are principally two ways to configure System-Wide Environment Variables on Linux: • /etc/environment is a system-wide configuration file, which means it is used by all users. It is owned by root so you need admin user privilege or sudo to modify it. Specifically, this file stores the system-wide locale and path settings. • /etc/profile and /etc/profile.d/.sh are the global initialization scripts. This file gets executed whenever a bash login shell is entered via console, terminal, ssh, or graphical user interface. The global scripts get executed before the user-specific scripts though, and the main /etc/profile executes all the .sh scripts in /etc/profile.d/ just before it exits. Each user could customize their ~/.profile, the user's personal shell initialization scripts. Every user has one and can edit their file without affecting others. This is the equivalent to /etc/profile for each user.

Links

ansible.builtin.lineinfile

## Playbook

How to permanently set System-Wide Environment variables on Remote Linux with Ansible Playbook.

code

---
- name: set environment Playbook
  hosts: all
  gather_facts: false
  become: true
  vars:
    os_environment:
      - key: EDITOR
        value: vi
      - key: MY_ENV_VARIABLE
        value: ansiblepilot
  tasks:
    - name: customize /etc/environment
      ansible.builtin.lineinfile:
        dest: "/etc/environment"
        state: present
        regexp: "^{{ item.key }}="
        line: "{{ item.key }}={{ item.value }}"
      with_items: "{{ os_environment }}"

execution

ansible-pilot $ ansible-playbook -i virtualmachines/demo/inventory ansible\ statements/set-environment.yml
PLAY [set environment Playbook] ***********************************************************************
TASK [customize /etc/environment] *****************************************************************
changed: [demo.example.com] => (item={'key': 'EDITOR', 'value': 'vi'})
changed: [demo.example.com] => (item={'key': 'MY_ENV_VARIABLE', 'value': 'ansiblepilot'})
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ansible-pilot $

idempotency

ansible-pilot $ ansible-playbook -i virtualmachines/demo/inventory ansible\ statements/set-environment.yml
PLAY [set environment Playbook] ***********************************************************************
TASK [customize /etc/environment] *****************************************************************
ok: [demo.example.com] => (item={'key': 'EDITOR', 'value': 'vi'})
ok: [demo.example.com] => (item={'key': 'MY_ENV_VARIABLE', 'value': 'ansiblepilot'})
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ansible-pilot $

before execution

ansible-pilot $ ssh devops@demo.example.com
Last login: Tue Feb 22 18:45:12 2022 from 192.168.131.111
[devops@demo ~]$ sudo su
[root@demo devops]# printenv | grep EDITOR
[root@demo devops]# printenv | grep MY_ENV_VARIABLE
[root@demo devops]# cat /etc/environment 
[root@demo devops]#

after execution

ansible-pilot $ ssh devops@demo.example.com
Last login: Tue Feb 22 18:48:46 2022 from 192.168.131.111
[devops@demo ~]$ sudo su
[root@demo devops]# printenv | grep EDITOR
EDITOR=vi
[root@demo devops]# printenv | grep MY_ENV_VARIABLE
MY_ENV_VARIABLE=ansiblepilot
[root@demo devops]# cat /etc/environment 
EDITOR=vi
MY_ENV_VARIABLE=ansiblepilot
[root@demo devops]#

code with ❤️ in GitHub

See also: Ansible environment Keyword: Set Environment Variables Per Task or Play

Conclusion

Now you know how to Permanently Set System-Wide Environment Variables on Remote Linux with Ansible.

System-Wide Environment Variables

/etc/environment (all users, all shells)

- name: Set system-wide env vars
  ansible.builtin.lineinfile:
    path: /etc/environment
    regexp: '^{{ item.key }}='
    line: '{{ item.key }}="{{ item.value }}"'
  loop:
    - { key: JAVA_HOME, value: /usr/lib/jvm/java-17 }
    - { key: EDITOR, value: vim }
    - { key: LANG, value: en_US.UTF-8 }
  become: true

/etc/profile.d/ (login shells)

- name: Create app environment script
  ansible.builtin.copy:
    content: |
      export APP_HOME=/opt/myapp
      export APP_ENV=production
      export PATH="$APP_HOME/bin:$PATH"
    dest: /etc/profile.d/myapp.sh
    mode: '0644'
  become: true

See also: Ansible Environment Variables: Set, Read & Manage env vars (Complete Guide)

User-Level Environment Variables

~/.bashrc (interactive bash)

- name: Set user env vars
  ansible.builtin.lineinfile:
    path: "/home/{{ username }}/.bashrc"
    regexp: '^export {{ item.key }}='
    line: 'export {{ item.key }}="{{ item.value }}"'
  loop:
    - { key: EDITOR, value: vim }
    - { key: HISTSIZE, value: "10000" }

~/.profile (login shells, all sh-compatible)

- name: Add to PATH permanently
  ansible.builtin.lineinfile:
    path: "/home/{{ username }}/.profile"
    regexp: 'export PATH=.*myapp'
    line: 'export PATH="$HOME/.local/bin:/opt/myapp/bin:$PATH"'

Remove Environment Variables

- name: Remove env var from /etc/environment
  ansible.builtin.lineinfile:
    path: /etc/environment
    regexp: '^OLD_VAR='
    state: absent
  become: true

Blockinfile for Multiple Variables

- name: Set app environment block
  ansible.builtin.blockinfile:
    path: /etc/environment
    marker: "# {mark} ANSIBLE MANAGED - MyApp"
    block: |
      APP_HOME="/opt/myapp"
      APP_ENV="production"
      DB_HOST="db.example.com"
      DB_PORT="5432"
  become: true

Where to Set Variables

| File | Scope | When Loaded | |------|-------|-------------| | /etc/environment | All users | PAM login | | /etc/profile.d/*.sh | All users | Login shell | | /etc/profile | All users | Login shell | | ~/.bashrc | Single user | Interactive bash | | ~/.profile | Single user | Login shell | | ~/.bash_profile | Single user | Bash login | | systemd unit Environment= | Service only | Service start |

For Systemd Services

- name: Set env for service
  ansible.builtin.lineinfile:
    path: /etc/systemd/system/myapp.service.d/override.conf
    regexp: '^Environment=.*DB_HOST'
    line: 'Environment="DB_HOST=db.example.com"'
    create: true
  become: true
  notify:
    - daemon reload
    - restart myapp

FAQ

Why doesn't my variable take effect immediately?

Changes to /etc/environment, .bashrc, etc. only apply to new shell sessions. Use environment: in Ansible tasks for immediate effect in the same play.

/etc/environment vs /etc/profile.d/ — which?

/etc/environment: Simple KEY=VALUE, no shell syntax, loaded by PAM • /etc/profile.d/: Full shell script, supports export, PATH manipulation, conditionals

How do I verify the variable was set?

- command: "bash -lc 'echo $APP_HOME'"
  register: check
- debug: msg="{{ check.stdout }}"

Related Articles

Ansible become guideAnsible inventory file structureAnsible environment variables guide

Category: troubleshooting

Watch the video: Ansible Set Environment Variables: lineinfile for /etc/environment & .bashrc — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home