Fábio Caramelo
Fábio Caramelo

Reputation: 149

blockinline module not respecting insertafter

I'm using a task to add environment variables in ~/.bash_profile. The first task is to add java, ant, and oracle home, then it comes the PATH and then the rest of the variables not belonging into the PATH.

The first task to add the homes:

- name: Add environment variables in bash_profile
  become: yes
  blockinfile:
    path: "{{ bash_profile }}"
    insertafter: "^# User specific environment and startup programs"
    content: export {{ item.env_name }}={{ item.env_dir }}
    marker: ""
    state: present
  with_items:
  - { env_name: "{{ ant_home }}", env_dir: "{{ ant_home_dir }}" }
  - { env_name: "{{ java_home }}", env_dir: "{{ java_home_dir }}" }
  - { env_name: "{{ oracle_home }}", env_dir: "{{ oracle_home_dir }}" }
  - { env_name: "{{ lib_path_home }}", env_dir: "{{ lib_path_home_dir }}" }

It deploys the variables as expected, inserting after the commented line already available in the bash file

The second task is dedicated to the PATH where I create the line and then delete the original PATH

- name: Add PATH variable
  become: yes
  lineinfile:
    path: "{{ bash_profile }}"
    regexp: '^\PATH=$PATH:$HOME/.local/bin:$HOME/bin'
    line: 'PATH=$PATH:$HOME/.local/bin:$HOME/bin:{{ ant_path_dir }}:{{ java_path_dir }}:{{ oracle_path_dir }}'

- name: remove PATH variable
  become: yes
  lineinfile:
    path: "{{ bash_profile }}"
    line: 'PATH=$PATH:$HOME/.local/bin:$HOME/bin'
    state: absent

This will get the PATH line, add the declared homes and bins and deletes the original path since it would not add anything in front of the original one and it creates a second line

The last task is the one where I having problens with the blockinfile module, spicifically in the insertafter parameter

- name: Add the rest of the environment variables in bash_profile
  blockinfile:
    path: "{{ bash_profile }}"
    insertafter: "^PATH=$PATH:$HOME/.local/bin:$HOME/bin:$ANT_HOME/bin:$JAVA_HOME/bin:$ORACLE_HOME/bin"
    content: export {{ item.env_name_1 }}={{ item.env_dir_1 }}
    marker: ""
  with_items:
  - { env_name_1: "{{ dynamo_home }}", env_dir_1: "{{ dynamo_home_dir }}" }
  - { env_name_1: "{{ atgjre_home }}", env_dir_1: "{{ atgjre_home_dir }}" }
  - { env_name_1: "{{ weblogic_home }}", env_dir_1: "{{ weblogic_home_dir }}" }
  - { env_name_1: "{{ node_env_home }}", env_dir_1: "{{ node_env_home_dir }}" }
  - { env_name_1: "{{ endeca_home }}", env_dir_1: "{{ endeca_home_dir }}" }

With this 3 taks I need to edit the bash_profile to add all the necessaries variables that are requiered and the final aspect of the file would be:

ANT_HOME
JAVA_HOME
ORACLE_HOME

PATH:

REST OF THE HOMES

And the actual result is:

ANT_HOME
JAVA_HOME
ORACLE_HOME

REST OF THE HOMES

PATH:

Upvotes: 0

Views: 2443

Answers (1)

Anant Naugai
Anant Naugai

Reputation: 556

I recommend making few changes:

1) use lineinfile instead of blockinfile as you're not exactly inserting block of text. You don't need to use insertafter for the final task as the default behaviour for this module is append.

2) use regexp option. This ensures idempotency i.e. if the required line exists ansible won't change or add those lines when you re-run the play. You don't need to worry about bash_profile getting polluted with loads of entries.

3) For task 2 ("Add PATH variable"), add the insertbefore option. Just to make sure that you have the new path before the export PATH statement.

For lininfile ansible doc see: https://docs.ansible.com/ansible/latest/modules/lineinfile_module.html?highlight=lineinfile

Here's the refactored play

---
- name: Bash profile play
  hosts: 127.0.0.1
  connection: local
  become_user: root
  become: yes
  tasks:
    - name: Add environment variables in bash_profile
      become: yes
      lineinfile:
        path: "{{ bash_profile }}"
        insertafter: "^# User specific environment and startup programs"
        regexp: "^export {{ item.env_name }}={{ item.env_dir }}"
        line: export {{ item.env_name }}={{ item.env_dir }}
        state: present
      with_items:
        - { env_name: "{{ java_home }}", env_dir: "{{ java_home_dir }}" }
        - { env_name: "{{ maven_home }}", env_dir: "{{ maven_home_dir }}" }

    - name: Add PATH variable
      become: yes
      lineinfile:
        path: "{{ bash_profile }}"
        insertbefore: "^export PATH"
        regexp: '^PATH=.+'
        line: 'PATH=$PATH:$HOME/bin:{{ java_path_dir }}:{{ maven_path_dir }}'

    - name: Add the rest of the environment variables in bash_profile
      lineinfile:
        path: "{{ bash_profile }}"
        regexp: "^export {{ item.env_name_1 }}={{ item.env_dir_1 }}"
        line: export {{ item.env_name_1 }}={{ item.env_dir_1 }}
        state: present
      with_items:
        - { env_name_1: "{{ dynamo_home }}", env_dir_1: "{{ dynamo_home_dir }}" }
        - { env_name_1: "{{ atgjre_home }}", env_dir_1: "{{ atgjre_home_dir }}" }
...

Upvotes: 2

Related Questions