Installing specific apt version with ansible - ansible

I used an ansible playbook to install git:
---
- hosts: "www"
tasks:
- name: Update apt repo
apt: update_cache=yes
- name: Install dependencies
apt: name={{item}} state=installed
with_items:
- git
I checked the installed versions:
$ git --version
git version 1.9.1
But adding these to the ansible playbook: apt: name=git=1.9.1 state=installed
and rerunning results in the following error:
fatal: [46.101.94.110]: FAILED! => {"cache_update_time": 0,
"cache_updated": false, "changed": false, "failed": true, "msg":
"'/usr/bin/apt-get -y -o "Dpkg::Options::=--force-confdef" -o
"Dpkg::Options::=--force-confold" install 'git=1.9.1'' failed:
E: Version '1.9.1' for 'git' was not found\n", "stderr": "E: Version
'1.9.1' for 'git' was not found\n", "stdout": "Reading package
lists...\nBuilding dependency tree...\nReading state
information...\n", "stdout_lines": ["Reading package lists...",
"Building dependency tree...", "Reading state information..."]}

Git package with that specific version is as follows:
git=1:1.9.1-1ubuntu0.2
Your task should be:
apt: name=git=1:1.9.1-1ubuntu0.2 state=present
Regards

You don't need two tasks for updating cache and installing. Your playbook should look like:
---
- hosts: "www"
tasks:
- name: Install dependencies
apt:
name:
- git=1:1.9.1-1ubuntu0.2
state: installed
update_cache: yes
note that Ansible supports wildcarding so you don't necessarily need the full version string

Related

How to use ansible pip executable `/usr/local/bin/python3 -m pip`?

My playbook
- name: "Install python package 'requests'"
pip:
name: requests
executable: /usr/local/bin/python3 -m pip
become: yes
Which errors with:
TASK [Install python package 'requests'] **************************
fatal: [integration]: FAILED! => changed=false
cmd: '''/usr/local/bin/python3 -m pip'' install requests'
msg: '[Errno 2] No such file or directory'
rc: 2
stderr: ''
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
I didn't install pip or pip3 in the managed node, that is why executable: pip3 would not work.
As per documentation, the recommended way to achieve this is to use the easy_install module in order to make pip available on the managed node, and then, use the builtin module pip, normally.
Please note that the easy_install module can only install Python libraries. Thus this module is not able to remove libraries. It is generally recommended to use the ansible.builtin.pip module which you can first install using community.general.easy_install.
So, in a two tasks:
- name: Install or update pip
community.general.easy_install:
name: pip
state: latest
become: yes
- name: Install python package 'requests'
ansible.builtin.pip:
name: requests
become: yes

Ansible yum module does not see repositories with option installroot

I would like to install the base CentOS to a specify directory, example to /var/centos. The directory is empty. I usage the next command in yum:
yum --disablerepo='*' --enablerepo='base,updates' --releasever=7 --installroot=/var/centos groupinstall #core
This command installs the base system without any problems. I want to do the same through Ansible.
In Ansible I usage the next task:
- name: Install base CentOS
yum:
state: latest
name: "#core"
installroot: "/var/centos/"
disablerepo: "*"
enablerepo: "base,updates"
releasever: "7"
When executing a playbook I receive an error:
Cannot find a valid baseurl for repo: base/$releasever/x86_64
As I understand, the yum don't see any repo.
I make list:
- name: Install base CentOS
yum:
list: repos
installroot: "/var/centos/"
When I execute the task I receive nothing.
Why doesn't yum module see repos?
Updated.
Before performing the Install base task, I executed the command - rpm --root /var/centos --force --nodeps -ivh http://mirror.centos.org/centos/7/os/x86_64/Packages/centos-release-7-6.1810.2.el7.centos.x86_64.rpm, after that everything worked.
The final playbook:
vars:
root_path: "/var/centos/"
tasks:
- name: Install package centos-release-7-6.1810.2.el7.centos.x86_64.rpm
shell: rpm --root {{ root_path }} --force --nodeps -ivh http://mirror.centos.org/centos/7/os/x86_64/Packages/centos-release-7-6.1810.2.el7.centos.x86_64.rpm
- name: Install base CentOS
yum:
state: installed
name:
- "#core"
installroot: "{{ root_path }}"
disablerepo: "*"
enablerepo: "base,updates"
releasever: "7"

Supress Ansible warning (at least for aptitude install)

How can I install aptitude package without ansible warning:
TASK [... : APT: Install aptitude package] ********************************************************************************
[WARNING]: Could not find aptitude. Using apt-get instead
my install code looks like:
- name: "APT: Install aptitude package"
apt:
name: aptitude
# vars:
# ACTION_WARNINGS: false << DOES NOT WORK
Fixed (specifically) for the aptitude install:
- name: "APT: Install aptitude package"
apt:
name: aptitude
force_apt_get: yes
based on https://github.com/ansible/ansible/blob/stable-2.8/lib/ansible/modules/packaging/os/apt.py#L1059
Or use module_defaults in your playbook, if you do not want to pollute your system with aptitude:
---
- hosts: ...
module_defaults:
apt:
force_apt_get: yes
tasks:
- ...

Changing user and installing ruby

My Ansible server is communicating as root user with agent but I need to install ruby as different user i.e deploy. So I am trying to switch the user to deploy using 'become' to install ruby but I am facing issue. Its seems that when i am trying to switch the user and running the command its unable to use .bashrc file of deploy user. Below is my YML file
---
- hosts: test1
become: true
tasks:
- name: adding node.js repository
shell: curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
- name: adding yarn pubkey
shell: curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
- name: adding yarn repo
shell: echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
- name: update cache
apt: update_cache=true
- name: install all the below list of packages
apt: name={{ item }} update_cache=true
with_items:
- git-core
- curl
- zlib1g-dev
- build-essential
- libssl-dev
- libreadline-dev
- libyaml-dev
- libsqlite3-dev
- sqlite3
- libxml2-dev
- libxslt1-dev
- libcurl4-openssl-dev
- software-properties-common
- libffi-dev
- nodejs
- yarn
- name: change to deploy home directory
shell: cd
become: true
become_user: deploy
- name: getting repo from git
shell: git clone https://github.com/rbenv/rbenv.git ~/.rbenv
become: true
become_user: deploy
- name: copy path
shell: echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
become: true
become_user: deploy
- name: copy eval
shell: echo 'eval "$(rbenv init -)"' >> ~/.bashrc
become: true
become_user: deploy
- name: execute shell
shell: exec $SHELL
become: true
become_user: deploy
- name: ruby repo
shell: git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
become: true
become_user: deploy
- name: copy paths
shell: echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
become: true
become_user: deploy
- name: shell execute
shell: exec $SHELL
become: true
become_user: deploy
- name: install ruby
shell: rbenv install 2.4.4
become: true
become_user: deploy
- name: set global
shell: rbenv global 2.4.4
become: true
become_user: deploy
I am getting the below error:
TASK [install ruby] ***************
fatal: [host1]: FAILED! => {"changed": true, "cmd": "rbenv install
2.4.4", "delta": "0:00:00.003186", "end": "2018-09-25 15:43:23.224716", "msg": "non-zero return code", "rc": 127, "start":
"2018-09-25 15:43:23.221530", "stderr": "/bin/sh: 1: rbenv: not
found", "stderr_lines": ["/bin/sh: 1: rbenv: not found"], "stdout":
"", "stdout_lines": []}
But when I am providing the path manually in command for rbenv its working fine. As shown below:
- name: install ruby
shell: /home/deploy/.rbenv/bin/rbenv install 2.4.4
become: true
become_user: deploy
Can you please tell me why its behaving like this?
I need to install bundler also using gem. I am switching to user 'deploy' but its going to check the root user directory instead of deploy user and giving error. Please refer the below YML part for gem and error:
- name: install bundler
shell: gem install bundler
become: true
become_user: deploy
Below is the error for bundler:
TASK [install bundler] *********
fatal: [host1]: FAILED! => {"changed": true, "cmd": "gem install
bundler", "delta": "0:00:02.396195", "end": "2018-09-25
16:21:18.703899", "msg": "non-zero return code", "rc": 1, "start":
"2018-09-25 16:21:16.307704", "stderr": "ERROR: While executing gem
... (Gem::FilePermissionError)\n You don't have write permissions
for the /var/lib/gems/2.3.0 directory.", "stderr_lines": ["ERROR:
While executing gem ... (Gem::FilePermissionError)", " You don't
have write permissions for the /var/lib/gems/2.3.0 directory."],
"stdout": "", "stdout_lines": []}
Please help me to fix the issue.
Thanks.
That playbook does not do what you think it does, because every one of those tasks is effectively its own ssh connection. So, this:
- name: change to deploy home directory
shell: cd
become: true
become_user: deploy
- name: execute shell
shell: exec $SHELL
... is equivalent to ssh root#the-host "su deploy -c 'cd; exit'"; ssh root#the-host "su deploy -c 'exec $SHELL; exit'" and so forth.
You'll very like also want to move all of those tasks that run as deploy into their own playbook or role, and include them with those become: true and become: deploy at the include or role level to keep from repeating that text all over the tasks.
But even if you don't do that, the shortest path to success is to collapse all 10 of those steps into just one shell: | block to rescue your sanity and reinforce that they all need to happen in the same shell session
- name: install ruby using rbenv
become: true
become_user: deploy
shell: |
set -e # <-- stop running this script if something fails
cd $HOME
export ... # etc etc
args:
creates: /home/deploy/.rbenv/versions/2.4.4/bin/ruby
Optionally including that args: creates: business will give ansible a fighting chance to skip that step if it has already provisioned rbenv. You will, of course, likely want to update that to guard the step in a way that is more relevant to what you're trying to do.

How to run Ansible tasks as a specific user

Part of the Ansible playbook I'm currently writing involves creating a new user as root, installing rvm for that specific user, then switching to them in order to run rvm. It doesn't seem to take, however. Here's what I'm currently running.
---
- name: Install pexpect
yum:
name: pexpect
state: latest
- name: Create rvm group
group:
name: rvm
state: present
- name: Create rvmuser
user:
name: rvmuser
state: present
group: rvm
password: "{{vault_rvm_password}}"
- name: Download signing key
shell: "command curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -"
become: True
become_user: rvmuser
- name: RVM single-user install
shell: "curl -L https://get.rvm.io | bash -s stable"
become: True
become_user: rvmuser
- name: Install Ruby
shell: "rvm install 2.2.1"
become: True
become_user: rvmuser
(These particular shell steps appear to be the preferred way of installing a specific version of Ruby; I tried using yum to install an RPM, but then gem fails.)
Basically, when it gets to the "Install Ruby" step, it fails because it can't find rvm, which is a strong indication that it's still trying to run the command as root. Here's the error:
TASK [ruby : Install Ruby] *****************************************************
fatal: [10.121.250.21]: FAILED! => {"changed": true, "cmd": "rvm install 2.2.1", "delta": "0:00:00.007545", "end": "2017-04-12 16:14:35.974732", "failed": true, "rc": 127, "start": "2017-04-12 16:14:35.967187", "stderr": "/bin/sh: rvm: command not found", "stdout": "", "stdout_lines": [], "warnings": []}
Am I doing this incorrectly, or is something else going wrong behind the scenes?
EDIT: The user is being created correctly, I've confirmed. After running the top five steps, I can SSH into the machine, switch to rvmuser and see that which rvm returns a path.
That looks like a path issue, i.e. the newly created rvmuser does not have rvm in its $PATH:
Try full path to rvm in this task:
- name: Install Ruby
shell: "rvm install 2.2.1"
become: True
become_user: rvmuser

Resources