Keywords: Ansible | Environment Variables | Linux Configuration
Abstract: This article provides an in-depth exploration of various methods for setting Linux environment variables using Ansible, covering both task-level temporary variables and system-level permanent configurations. Through analysis of best practices and common pitfalls, it presents solutions based on the lineinfile module for permanent variable setup and the environment keyword application at task, block, and playbook levels. With detailed code examples, the article explains variable scoping, persistence mechanisms, and practical deployment scenarios to help readers master flexible and reliable environment management strategies.
Fundamental Concepts of Environment Variable Configuration
Environment variables serve as crucial mechanisms for passing configuration information and runtime parameters in Linux systems and automated configuration management. Ansible, as a popular configuration management tool, offers multiple approaches to set environment variables on remote hosts, addressing diverse operational requirements.
Task-Level Environment Variable Setup
The environment keyword enables definition of temporary environment variables within individual tasks, with validity limited to the task execution period. This approach suits independent operations requiring specific environmental configurations.
- hosts: dev
tasks:
- name: Echo environment variable value
shell: "echo $MY_ENV_VARIABLE"
environment:
MY_ENV_VARIABLE: test_value
- name: Echo environment variable again
shell: "echo $MY_ENV_VARIABLE"
Execution results demonstrate that the first task successfully outputs "test_value", while the second task produces an empty string, confirming the scope limitations of environment variables. This method's advantage lies in its non-interference with other system components, ensuring task isolation.
Playbook and Block-Level Environment Variables
Since Ansible version 1.1, the environment keyword can be applied at playbook or block levels, providing unified environment configuration for multiple related tasks. This proves particularly valuable in complex workflows requiring shared environmental settings.
- hosts: testing
environment:
http_proxy: http://proxy.example.com:8080
roles:
- php
- nginx
By elevating environment variable definitions to higher hierarchy levels, centralized configuration management and code reuse become achievable. It's important to note that these variables remain effective only within the current execution context and don't persist in the system.
Permanent Environment Variable Configuration
For environment variables requiring cross-session persistence, modification of system configuration files becomes necessary. Different Linux distributions utilize various configuration file locations, such as ~/.profile, /etc/environment, or script files within the /etc/profile.d/ directory.
Ansible's lineinfile module provides reliable management of these configuration files:
- name: Configure system environment variables
lineinfile:
path: "/etc/environment"
state: present
regexp: "^{{ item.key }}="
line: "{{ item.key }}={{ item.value}}"
with_items: "{{ os_environment }}"
become: yes
Corresponding variable definitions:
os_environment:
- key: DJANGO_SETTINGS_MODULE
value: websec.prod_settings
- key: DJANGO_SUPER_USER
value: admin
Importance of Configuration File Selection
Selecting appropriate configuration files is critical for environment variable activation timing. .bash_profile and /etc/profile load during login sessions, while .bashrc loads in non-login shells. Since Ansible typically executes tasks using non-login shells, modifying .bashrc ensures immediate variable availability in subsequent tasks within the same playbook.
- name: Add path to bashrc
lineinfile:
dest: /root/.bashrc
line: 'export PATH=$PATH:path-to-mysql/bin'
regexp: 'export PATH=\$PATH:path-to-mysql/bin'
state: present
- name: Source bashrc configuration
shell: source /root/.bashrc
- name: Start MySQL client
shell: mysql -e "show databases"
Advanced Application Scenarios
In complex development environments, management of language-specific version managers like nvm for Node.js or rbenv for Ruby becomes frequent. These tools depend on specific environment variables for proper operation.
- hosts: application
environment:
NVM_DIR: /var/local/nvm
PATH: /var/local/nvm/versions/node/v4.2.1/bin:{{ ansible_env.PATH }}
tasks:
- name: Check for package.json
stat:
path: '{{ node_app_dir }}/package.json'
register: packagejson
- name: Run npm installation
npm:
path: '{{ node_app_dir }}'
when: packagejson.stat.exists
Security Considerations
Environment variables typically transmit in clear text, depending on the shell plugin used. Therefore, passing sensitive information like passwords or API keys through environment variables is not recommended. For confidential data, Ansible Vault or other secure credential management solutions should be employed.
Best Practices Summary
Select appropriate environment variable setting methods based on usage scenarios: employ task-level environment keyword for temporary tasks, use block-level or playbook-level definitions for related task groups, and utilize the lineinfile module for system-level configuration file modifications. Proper understanding of various methods' scope and persistence characteristics enables construction of more robust and maintainable automated deployment workflows.