Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible playbook to execute commands from user shell

I'm attempting to run a relatively simple Ansible playbook to provision an Ubuntu VM via Vagrant. Roughly it follows 3 steps:

  1. Update and install essential packages
  2. Install rbenv to a specified user's home
  3. Install the specified Ruby version via rbenv for specified user

The first two steps are fine but third I'm struggling with. Using others playbooks as a reference (one for rbenv and nvm) I have created the following basic playbook:

---
- hosts: all
  vars:
    user: joe_bloggs
    ruby_version: 2.1.5

  tasks:

    #
    # System
    #

    - name: Update apt cache
      sudo: yes
      apt: update_cache=yes cache_valid_time=86400

    - name: Upgrade existing system packages
      sudo: yes
      apt: upgrade=dist

    - name: Install essential system packages
      sudo: yes
      apt: name={{ item }} state=latest
      with_items:
        - git
        - curl
        - openssl
        - build-essential

    - name: Add user
      sudo: yes
      user: name={{user}} shell=/bin/bash groups=sudo

    #
    # rbenv
    #

    - name: Install rbenv | Clone repo
      sudo: yes
      sudo_user: "{{ user }}"
      git: repo=https://github.com/sstephenson/rbenv.git dest=~/.rbenv accept_hostkey=yes update=yes

    - name: Install rbenv | Create plugins directory
      sudo: yes
      sudo_user: "{{ user }}"
      file: path=~/.rbenv/plugins/ mode=0755 state=directory

    - name: Install rbenv | Install ruby-build plugin
      sudo: yes
      sudo_user: "{{ user }}"
      git: repo=git://github.com/sstephenson/ruby-build.git dest=~/.rbenv/plugins/ruby-build accept_hostkey=yes

    - name: Install rbenv | Add path to profile
      sudo: yes
      sudo_user: "{{ user }}"
      lineinfile: line='export PATH="$HOME/.rbenv/bin:$PATH"' regexp="\$HOME\/\.rbenv\/bin:\$PATH" dest=~/.bashrc

    - name: Install rbenv | Enable shims in profile
      sudo: yes
      sudo_user: "{{ user }}"
      lineinfile: line='eval "$(rbenv init -)"' regexp="rbenv init \-" dest=~/.bashrc

    - name: Install Ruby | Install version
      sudo: yes
      sudo_user: "{{ user }}"
      shell: rbenv install {{ ruby_version }} executable=/bin/bash

    - name: Install Ruby | Set default version and rehash
      sudo: yes
      sudo_user: "{{ user }}"
      shell: rbenv global {{ ruby_version }} && rbenv rehash executable=/bin/bash

Running the above playbook I encounter an error:

stderr: /bin/bash: rbenv: command not found

Is there an elegant way to run a command via Ansible as a user, using their shell and environment variables loaded?

I have attempted adding the -i sudo flag and commands like sudo -iu {{user}} rbenv install ... but I've had no luck yet.

I am able to run the Ruby install by specifying the full path to the rbenv executable but that technique isn't always appropriate (some tools may not provide a single executable).

like image 767
i_like_robots Avatar asked Nov 10 '22 18:11

i_like_robots


1 Answers

I had this same issue whilst trying to install ruby-2.2.3 with rbenv using Ansible 2.1 on a vagrant box.

rbenv was installed on a user on ubuntu called rails who has no sudo rights but when ansible connects to my ubuntu box, it looses the env. $PATH defined in /home/rails/.bashrc it was defaulting to just the ansible_env.PATH

Assuming you have installed rbenv following these steps:

git clone git://github.com/sstephenson/rbenv.git .rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc

git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

to get the path working, I needed to set it manually, so for that particular task I did:

- name: install rubies
  become_user: rails
  environment: 
    PATH: "{{ ansible_env.PATH }}:/home/rails/.rbenv/shims:/home/rails/.rbenv/bin "
  shell: '{{ rbenv_shell }} -lc "rbenv install {{ item[0] }}"'
  with_together
    - "{{ rubies }}"
    - "{{ ruby_installed.results }}"
  ...

This will append the path to your rbenv command to ansible_env.PATH lookup and get it working as expected.

like image 117
Kingsley Ijomah Avatar answered Nov 12 '22 08:11

Kingsley Ijomah