0

I'm creating an Ansible role to create a user and install rbenv to run my Rails application.

As part of the rbenv installation, you need to modify the PATH and add a line initializing rbenv shims to .bash_profile. I would like to make this role idempotent. Thus, I would like to check if the PATH and rbenv shim initializer are already present in .bash_profile.

I have the following:

- name: Clone rbenv repo
 git: repo=https://github.com/rbenv/rbenv.git
 dest=/home/{{ rails_app_user }}/.rbenv
 force=yes
 update=no
- name: Check if rbenv exists in PATH
 shell: grep 'export PATH="$HOME/.rbenv/bin:$PATH"' /home/{{ rails_app_user }}/.bash_profile
 register: rbenv_path_exists
- name: Add rbenv to PATH
 shell: echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> /home/{{ rails_app_user }}/.bash_profile
 when: rbenv_path_exists.stdout_lines.count == 0
- name: Check if rbenv shims are installed
 shell: grep 'eval "$(rbenv init -)"' /home/{{ rails_app_user }}/.bash_profile
 register: rbenv_shim_exists
- name: Install rbenv shims
 shell: echo 'eval "$(rbenv init -)"' >> /home/{{ rails_app_user }}/.bash_profile
 when: rbenv_shim_exists.stdout_lines.count == 0

However, it seems that grep returns 1 when no match is found, causing Ansible to think a fatal error occurred, terminating the playbook. I tried appending ignore_errors: yes below the PATH and shims check. However, that seems to cause the variables to not be properly registered, causing the PATH and shim installation steps to be skipped due to the when clause.

Output when using ignore_errors: yes:

TASK [rails : Check if rbenv exists in PATH] ***********************************
fatal: [172.16.171.133]: FAILED! => {"changed": true, "cmd": "grep 'export PATH=\"$HOME/.rbenv/bin:$PATH\"' /home/app/.bash_profile", "delta": "0:00:00.005480", "end": "2016-01-30 04:08:01.971000", "failed": true, "rc": 1, "start": "2016-01-30 04:08:01.965520", "stderr": "", "stdout": "", "stdout_lines": [], "warnings": []}
...ignoring
TASK [rails : Add rbenv to PATH] ***********************************************
skipping: [172.16.171.133]

What would an idiomatic way to accomplish this?

asked Jan 30, 2016 at 9:16

1 Answer 1

1

In general with Ansible you should only really shell out if you can't possibly achieve things with the provided modules. The modules will help make things automatically idempotent and happily handle flagging to Ansible whether anything was changed or if it failed - something that can be done with the shell module but requires a lot of work with changed_when and failed_when.

In your case you can achieve this by using the lineinfile module. A rough go at your particular case might look something like this:

- name: Add rbenv to PATH
 lineinfile: 
 dest: /home/{{ rails_app_user }}/.bash_profile
 regexp: ^export .* rbenv/bin
 line: export PATH="$HOME/.rbenv/bin:$PATH" 
- name: Install rbenv shims
 lineinfile: 
 dest: /home/{{ rails_app_user }}/.bash_profile
 regexp: '^eval .* rbenv init'
 line: 'eval "$(rbenv init -)"'
answered Jan 30, 2016 at 14:36
Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what I was looking for!

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.