38

I need to set the variables like JAVA_HOME and update PATH. There are a number of ways of doing this. One way is to update the /etc/environment variable and include a line for JAVA_HOME using the lineinfile module and then run the command source /etc/environment directly on the guest OS (CentOS in my case).

Another way is to execute the export command e.g.

export JAVA_HOME=/usr/java/jre1.8.0_51
export PATH=$PATH:$JAVA_HOME

Is there a cleaner way to do this as all these require manipulating files and running commands directly on the OS to update the environment variables?

techraf
  • 64,883
  • 27
  • 193
  • 198
dshenoy
  • 753
  • 1
  • 5
  • 11
  • Did you figure out anyway for the same? I was having a problem where I launch a server from ansible and want to export the IP of the created instance to the shell for another script to use. Can you help me out on that? Thanks in advance. – polavishnu Nov 09 '16 at 04:04

3 Answers3

35

Yes, there is a cleaner way. You can set environment variables per task:

  tasks:
  - shell: echo JAVA_HOME is $JAVA_HOME
    environment:
      JAVA_HOME: /usr/java/jre1.8.0_51
    register: shellout
  - debug: var=shellout

Output:

TASK: [shell echo JAVA_HOME is $JAVA_HOME] ********************************** 
changed: [localhost]

TASK: [debug var=shellout] **************************************************** 
ok: [localhost] => {
    "var": {
        "shellout": {
            "changed": true, 
            "cmd": "echo JAVA_HOME is \"$JAVA_HOME\"", 
            "delta": "0:00:00.005797", 
            "end": "2015-08-07 06:32:47.295061", 
            "invocation": {
                "module_args": "echo JAVA_HOME is \"$JAVA_HOME\"", 
                "module_name": "shell"
            }, 
            "rc": 0, 
            "start": "2015-08-07 06:32:47.289264", 
            "stderr": "", 
            "stdout": "JAVA_HOME is /usr/java/jre1.8.0_51", 
            "stdout_lines": [
                "JAVA_HOME is /usr/java/jre1.8.0_51"
            ], 
            "warnings": []
        }
    }
}

If you set the environment variable like above in a task, it is only available for this specific task. In subsequent tasks it does not exist unless you define it again.

Though you can define env vars per play as well:

- hosts:
  - localhost
  gather_facts: no
  environment:
    JAVA_HOME: /usr/java/jre1.8.0_51
  tasks:
     ...

Now it's gonna be available for all tasks of this play.

See Setting the Environment and FAQ: How can I set the PATH or any other environment variable for a task or entire playbook? in the docs.


Another example with a script task:

  tasks:
  - script: /tmp/script.sh
    environment:
      JAVA_HOME: /usr/java/jre1.8.0_51
    register: shellout
  - debug: var=shellout

Where the script simply has this content:

#!/bin/sh

echo JAVA_HOME is $JAVA_HOME
udondan
  • 57,263
  • 20
  • 190
  • 175
  • The following gives me an error "ERROR: JAVA_HOME is not a legal parameter in an Ansible task or handler" and from the documenation, there doesn't seem to be an indication of the standard variables. - name: Set path shell: ls environment: JAVA_HOME: /usr/java/jre1.8.0_51 Any suggestions on other methods or alternatives? – dshenoy Aug 02 '15 at 19:40
  • I just tested it again and it works for me. Make sure you have the correct yml indention. The error sounds like it might be at the same width as `environment` but it needs to be a subelement of `environment`. [Here](http://docs.ansible.com/ansible/faq.html#how-can-i-set-the-path-or-any-other-environment-variable-for-a-task-or-entire-playbook) is another Ansible doc which shows this should work: – udondan Aug 02 '15 at 20:13
  • Thank you again. I'm still not getting this to work. Can you provide another example without the "-shell" command? The Ansible documentation doesn't give an example to create and set a new environment variable clearly. Ideally, I'd like to get more examples to see how this works? – dshenoy Aug 06 '15 at 18:14
  • Somehow is seem to forget to paste the link in my previous comment... -> http://docs.ansible.com/ansible/faq.html#how-can-i-set-the-path-or-any-other-environment-variable-for-a-task-or-entire-playbook – udondan Aug 07 '15 at 04:37
  • The environment parameter is global and should be working with any task. I'll try to find another easy example, shell was just simply to test. BTW, it should also work on play level, not only on task level. – udondan Aug 07 '15 at 04:38
  • I added an example with a `script` task. Im sorry, I can't think of any easy to reproduce example other than `shell` and `script`. But environment is a global feature and should work with any task. If you still get an error like you described above, there rather is a indention error in your yml. Another idea i had was, you might be trying to use the env var on a separate tasks. If defined per task it's only available on that task where it was defined, not on subsequent tasks. You can define it for the whole play though. Added example for that too. – udondan Aug 07 '15 at 05:04
  • @DeepakShenoy: I had the very same problem, double-check the indentation of the `environment:` row - it has to be the same level as `shell:` or `register:` – Ikar Pohorský Jul 13 '16 at 07:38
  • What about if the OS requires the variable because the application you're provisioning reads for it, any other options other than export? – eco Feb 13 '18 at 20:52
18

I found that a workaround to do this was to use the lineinfile command in Ansible:

- name: Set JAVA_HOME
  lineinfile: dest=/etc/environment state=present regexp='^JAVA_HOME' >
     line='JAVA_HOME=/opt/jre1.8.0_51/bin'

While this is not ideal, it allows you to create new environmental variables. Of course, you should use variables to construct your directory path. I have included the explicit path to simplify my example.

dshenoy
  • 753
  • 1
  • 5
  • 11
13

Update to the lineinfile approach. The JAVA_HOME value should not include the bin directory. The following worked for centos:

- name: Set JAVA_HOME
  lineinfile:
    dest: /etc/environment
    state: present
    regexp: '^JAVA_HOME'
    line: 'JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk'
glennop
  • 131
  • 1
  • 5