Baeldung Pro – Ops – NPI EA (cat = Baeldung on Ops)
announcement - icon

Learn through the super-clean Baeldung Pro experience:

>> Membership and Baeldung Pro.

No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.

1. Overview

The use of environment variables is common in Ansible to make deployments flexible and secure.

In this tutorial, we’ll discuss how to set both temporary and permanent environment variables using Ansible. The version of Ansible we use in the examples is 2.12.0.

2. Setting Temporary Environment Variables

In this section, we’ll see how to set a temporary environment variable to be used within a playbook.

2.1. Example Playbook

We’ll use the following playbook, playbook_env.yml:

$ vi +"set number" playbook_env.yml
 1 ---
 2   - name: Play1
 3     hosts: localhost
 4     environment:
 5       ENV_VARIABLE: PLAY_LEVEL
 6
 7     tasks:
 8     - name: Task1
 9       command: "echo Environment variable: $ENV_VARIABLE"
10       environment:
11         ENV_VARIABLE: TASK_LEVEL
12       register: print_environment_variable
13
14     - debug:
15         var: print_environment_variable.stdout_lines
16
17     - name: Task2
18       command: "echo Environment variable: $ENV_VARIABLE"
19       register: print_environment_variable
20
21     - debug:
22         var: print_environment_variable.stdout_lines

The +”set number” option of vi displays line numbers.

In addition to the playbook, we’ll use the following inventory file:

$ cat inventory
localhost ansible_connection=local

Let’s discuss the playbook shortly in the following subsection.

2.2. Dissection of the Playbook

The playbook has a single play, Play1, which is shown on lines 2-5. The play uses the environment keyword, which defines an environment variable for an action to be taken. Its name is ENV_VARIABLE, and its value is PLAY_LEVEL. This environment variable is accessible from all tasks within the play, as it’s defined at the play level.

The first task, namely Task1 (Lines 8-12), also uses the environment keyword to define an environment variable having the name ENV_VARIABLE and value TASK_LEVEL. We define this environment variable at the task level. Since its name is the same as the name of the one at the play level, the value at the task level overrides the value at the play level.

When we execute this task, we run the echo Environment variable: $ENV_VARIABLE command to display the environment variable’s value. We create a variable, print_environment_variable, to save the output of the echo command (Line 12). We save the variable using the keyword register. Then, we print this variable using the built-in debug module and its var parameter (Lines 14-15).

The other task, Task2 (Lines 17-19), runs the same echo command to display the environment variable’s value. However, it prints the environment variable defined at the play level, as we’ll see shortly. We capture the output of the echo command and print it in the same manner as in Task1 (Lines 21-22).

2.3. Running the Playbook

Having discussed the playbook shortly, let’s now run the playbook using the ansible-playbook command:

$ ansible-playbook playbook_env.yml -i inventory

PLAY [Play1] *******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Task1] *******************************************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "print_environment_variable.stdout_lines": [
        "Environment variable: TASK_LEVEL"
    ]
}

TASK [Task2] *******************************************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "print_environment_variable.stdout_lines": [
        "Environment variable: PLAY_LEVEL"
    ]
}

PLAY RECAP *********************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

The -i option specifies the inventory file to be used. As is apparent from the output, the value of the environment variable in Task1 is TASK_LEVEL as expected. Similarly, the value of the environment variable in Task2 is PLAY_LEVEL.

However, there isn’t any environment variable, ENV_VARIABLE, in the system:

$ env | grep ENV_VARIABLE

We used the env command to display the environment variables defined and filtered the output using the grep ENV_VARIABLE command. Therefore, the temporary environment variables defined within the playbook are only valid within the playbook. They don’t have an effect on the system.

3. Setting Permanent Environment Variables

In this section, we’ll see how to set a permanent environment variable for a user. For this purpose, we’ll use the .bashrc file, a Bash shell script that sets variables, functions, and aliases. It runs on every interactive shell launch. It’s in the home directory of a user.

It’s also possible to set an environment variable for all users. For example, we can use /etc/default for this purpose.

3.1. Example Playbook

We’ll use the following playbook, playbook_env_persistent.yml:

$ vi +"set number" playbook_env_persistent.yml
1 ---
2   - name: Ansible define a persistent environment variable
3     hosts: localhost
4
5     tasks:
6     - name: Set environment variable in config file
7       lineinfile:
8         path: /home/baeldung/.bashrc
9         line: 'export ENV_VARIABLE=SYSTEM_LEVEL'

We’ll use the same inventory file.

Let’s discuss the playbook briefly in the following subsection.

3.2. Dissection of the Playbook

We define an environment variable, ENV_VARIABLE, in /home/baeldung/.bashrc by using the built-in lineinfile module (Lines 7-9).

The built-in lineinfile module is useful for changing a single line in a file or adding a single line to a file. The path parameter specifies the file to edit, which is /home/baeldung/.bashrc in our case. The line parameter, on the other hand, specifies the line to insert into the file. It’s the export ENV_VARIABLE=SYSTEM_LEVEL command. By default, it’s appended to the end of the file using only these two parameters.

3.3. Running the Playbook

Now, let’s run the playbook:

$ ansible-playbook playbook_env_persistent.yml -i inventory

PLAY [Ansible define a persistent environment variable] ***********************************************************************

TASK [Gathering Facts] ********************************************************************************************************
ok: [localhost]

TASK [Set environment variable in config file] ********************************************************************************
changed: [localhost]

PLAY RECAP ********************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

According to the output, the tasks ran successfully. Let’s check the last line of /home/baeldung/.bashrc using the tail command:

$ tail -1 /home/baeldung/.bashrc
export ENV_VARIABLE=SYSTEM_LEVEL

The last line of the file contains the export command we appended, as expected. Let’s also verify that the environment variable, ENV_VARIABLE, is defined using the echo command in a new terminal:

$ echo $ENV_VARIABLE
SYSTEM_LEVEL

The environment variable is defined and has the expected value.

4. Conclusion

In this article, we discussed how to set both temporary and permanent environment variables using Ansible. Firstly, we learned that we can use the environment keyword to define temporary environment variables within an Ansible playbook, both at play and task levels. We saw that if we use the same name for an environment variable at the play and task levels simultaneously, the one at the task level overrides the other one.

Then, we learned that we must export an environment variable in one of the configuration scripts to have a permanent effect. We used .bashrc in the example. We saw that we can use the built-in lineinfile module for appending the export statement to the end of the file.

Although we didn’t use a block in the example playbooks, in addition to play and task levels, it’s also possible to define environment variables at a block level.