I'm wondering if it is possible to overwrite the executable value set in your ansible.cfg file within a playbook. Something like below...
---
- name: 'New Server Setup'
hosts: 'all'
gather_facts: false
pre_tasks:
- name: 'setup : installing python for ansible'
raw: 'test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)'
changed_when: false
- setup: # aka gather_facts
tags: setup
user: root
become: yes
become_method: sudo
executable: '/bin/bash'
roles:
- setup
I've tried everything I can think of and nothing seems to work.
As per ansible,
Starting in version 2.1 this can be overridden by the inventory var ansible_shell_executable.
Related
I'm trying create a Ansible playbook that will read contents of a file and use those contents to install packages on a target machine.
In simpler terms, I want to run this command converted to an ansible playbook
cat ./meta/install-list/apt | xargs apt install -y
./meta/install-list/apt
neofetch
tmux
git
./ansible/playbooks/apt.yaml
- hosts: all
become: true
tasks:
- name: Extract APT packages to install
command: cat ../../meta/install-list/apt
register: _pkgs
delegate_to: localhost
run_once: true
- name: Install APT packages
apt:
name: "{{ _pkgs.stdout_lines }}"
state: latest
./ansible.cfg
[defaults]
inventory = ./ansible/inventory/hosts.yaml
./ansible/inventory/hosts.yaml
---
all:
children:
group-machines:
hosts:
target-machine.local
Command to run playbook
ansible-playbook --ask-become-pass ./ansible/playbooks/apt.yaml --limit group-machine
When running the command, it gets stuck on Extract APT packages to install
NOTE:
these files mentioned above are to be only on machine that is running the command. If possible, I'd like to prevent copying files to target machines and then running the playbooks tasks
PS: new to ansible
I don't see anything in your "Extract APT packages to install" task that should cause it to get stuck... but you don't need that task in any case; you can combine your two tasks into a single task like this:
- hosts: all
become: true
tasks:
- name: Install APT packages
apt:
name: "{{ packages }}"
state: latest
vars:
packages: "{{ lookup('file', '../../meta/install-list/apt').splitlines() }}"
Here we're using a file lookup to read the contents of a file. Lookups always run on the local (control) host.
Note that you could write the above like this as well...
- hosts: all
become: true
tasks:
- name: Install APT packages
apt:
name: "{{ lookup('file', '../../meta/install-list/apt').splitlines() }}"
state: latest
...but I like to keep longer jinja expressions in vars in order to keep the rest of the arguments more readable.
The above answer is more than enough by #Zeitounator. But if you do some formatting to your original file of package list as below
packages:
- neofetch
- tmux
- git
After that you can simply run the playbook like below
- hosts: all
become: true
vars_files: ../../meta/install-list/apt
tasks:
- name: Install APT packages
apt:
name: "{{ packages }}"
state: latest
Now suppose if you are lazy enough to not want to do the formatting then below playbook also will do the trick. Its much cleaner and scalable in my opinion.
---
- name: SHow the packages list
hosts: localhost
become: true
tasks:
- name: View the packages list file
shell: cat ../../meta/install-list/apt
register: output
- name: Install the package
apt:
name: "{{ output.stdout_lines }}"
state: latest
I'm working on a project that is still running Python 2. I'm trying to use Ansible to set up new test servers. The base Linux installation that I start with only has Python 3, so I need my very first "bootstrap" playbook to use Python 3, but then I want subsequent playbooks to use Python 2.
I can specify the version of python in my inventory file like this:
[test_server:vars]
ansible_python_interpreter=/usr/bin/python3
[test_server]
test_server.example.com
But then I have to go edit the inventory file to make sure that I'm using Python 3 for the bootstrap playbook, and then edit it again for the rest of my playbooks. That seems odd. I've tried a few different versions of changing ansible_python_interpreter within my playbooks, like
- hosts: test_server
ansible_python_interpreter: /usr/bin/python
and
- hosts: test_server
tasks:
- name: install pip
ansible_python_interpreter: /usr/bin/python
apt:
name: python-pip
but ansible complains that
ERROR! 'ansible_python_interpreter' is not a valid attribute for a Task
Even though https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html says that
You can still set ansible_python_interpreter to a specific path at any variable level (for example, in host_vars, in vars files, in playbooks, etc.).
What's the invocation to do this correctly?
Q: "What's the invocation to do this correctly?"
- hosts: test_server
tasks:
- name: install pip
ansible_python_interpreter: /usr/bin/python
apt:
name: python-pip
ERROR! 'ansible_python_interpreter' is not a valid attribute for a Task
A: ansible_python_interpreter is not a Playbook keyword. It is a variable and must be declared as such. For example, in the scope of a task
- hosts: test_server
tasks:
- name: install pip
apt:
name: python-pip
vars:
ansible_python_interpreter: /usr/bin/python
, or in the scope of a playbook
- hosts: test_server
vars:
ansible_python_interpreter: /usr/bin/python
tasks:
- name: install pip
apt:
name: python-pip
, or in any other suitable place. See Variable precedence: Where should I put a variable?
See:
INTERPRETER_PYTHON
INTERPRETER_PYTHON_FALLBACK
Notes:
Quoting from Changelog core 2.14:
configuration entry INTERPRETER_PYTHON_DISTRO_MAP is now 'private' and won't show up in normal configuration queries and docs, since it is not 'settable' this avoids user confusion.
Search _INTERPRETER_PYTHON_DISTRO_MAP in ansible/lib/ansible/config/base.yml to see current value of INTERPRETER_PYTHON_DISTRO_MAP
my loginuser is user1 and i want to execute the playbook with root. how can i do this. if i use in cmdline it does not work like this
ansible-playbook main.yaml -i hosts --user=git -k --become-user=root --ask-become-pass --become-method=su
Please tell me how to implement this.
name: Install and Configure IEM
hosts: rhel
ansible_become: yes
ansible_become_method: su
ansible_become_user: root
ansible_become_pass: passw0rd
tasks:
- name: Creating masthead file path
file: path=/etc/opt/BESClient state=directory
- name: Creating install directory
I use :
deploy.yml
- name: Todo something
hosts: all
become: yes
become_user: root
become_method: su
When you execute the playbook pass the password as an extra var.
--extra-vars='ansible_become_pass=password'
From Ansible docs:
you can set those in the playbook as #Raul-Hugo, with become_user and become_user;
alternatively, it can also be done in the inventory, which allows setting per host or group. But then the variables get "ansible_" prefix: ansible_become_user, ansible_become_user, etc. That's why the playbook you gave in your question did not work: it used variable names that are used in the inventory.
You can become root like below and install the packages
tasks:
- name: install apache package
become: yes
become_user: root
yum:
name: httpd
state: present
- name: ensure apache is running
become: yes
become_user: root
service:
name: httpd
state: started
All the above answers caused Ansible to try to login as root from the beginning. but in this case, the user you request is git so the below example worked for me:
- name: Install and Configure IEM
hosts: rhel
tasks:
- name: Creating masthead file path
file: path=/etc/opt/BESClient state=directory
remote_user: git
become: yes # when not specifying `become_user` it's "root"
This will cause it to login as git and after the login - switch to root
I have just begun with ansible and I'm finding trouble with playbook syntax trying to provision a vagrant file. Below is my ansible playbook
---
- hosts: all
tasks:
- name: update apt cache
apt: update_cache=yes
become: yes
become_method: sudo
- name: create a directory for projects
file: path=/home/projects
state=directory
- name: create a directory for our project
file: path=/home/projects/myproject
state=directory
- name: install git
apt: name=git
become: yes
become_method: sudo
- name: initiaite git
command: git init
args:
chdir: /home/projects/myproject
- name: pull git
git: repo=https://github.com/path/to/repo.git
dest=/home/projects/myproject
- name: install mysql
apt: name=mysql-server
become: yes
become_method: sudo
- name: create mysql db for project
mysql_db: name=mydb
encoding=utf8
- name: create user and assign privileges
mysql_user: name=foo
password=bar
priv=mydb.*,GRANT
- name: install pip
apt: name=pip
become: yes
become_method: sudo
- name: install virtualenv
pip: name=virtualenv
become: yes
become_method: sudo
- name: Create the initial virtualenv
command: virtualenv /home/projects/myproject/venv -p python2.7 creates="/home/projects/myproject/venv"
- name: install requirements
pip:
requirements=/home/projects/myproject/requirements.txt
virtualenv=/home/projects/bankproblem/venv
My trouble is with the 4th task where I'm trying to install git.
ERROR: Syntax Error while loading YAML script, playbook.yml
Note: The error may actually appear before this position: line 21, column 1
become_method: sudo
^
Ansible failed to complete successfully. Any error output should be
visible above. Please fix these errors and try again.`
Someone please explain to me what's happening.
My Vagrantfile
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "trusty-server-cloudimg-amd64-vagrant-disk1.box"
config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64- vagrant-disk1.box"
config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.provision :ansible do |ansible|
ansible.playbook = "playbook.yml"
end
end
P.S. Please neglect the naive way the playbook is written as my intention is to simply get started with.
It was simply that
I had to make sure unnecessary white spaces aren't there and
The arguments to a task had to be in a single line separated by spaces, for instance,
Instead of
git: repo=https://github.com/path/to/repo.git
dest=/home/projects/myproject
I needed to use
git: repo=https://github.com/path/to/repo.git dest=/home/projects/myproject
Silly me! No more syntax errors now.
I am trying to run an extremely simple playbook to test a new Ansible setup.
When using the 'new' Ansible Privilege Escalation config options in my ansible.cfg file:
[defaults]
host_key_checking=false
log_path=./logs/ansible.log
executable=/bin/bash
#callback_plugins=./lib/callback_plugins
######
[privilege_escalation]
become=True
become_method='sudo'
become_user='tstuser01'
become_ask_pass=False
[ssh_connection]
scp_if_ssh=True
I get the following error:
fatal: [webserver1.local] => Internal Error: this module does not support running commands via 'sudo'
FATAL: all hosts have already failed -- aborting
The playbook is also very simple:
# Checks the hosts provisioned by midrange
---
- name: Test su connecting as current user
hosts: all
gather_facts: no
tasks:
- name: "sudo to configued user -- tstuser01"
#action: ping
command: /usr/bin/whoami
I am not sure if there is something broken in Ansible 1.9.1 or if I am doing something wrong. Surely the 'command' module in Ansible allows running commands as sudo.
The issue is with configuration; I also took it as an example and got the same problem. After playing awhile I noticed that the following works:
1) deprecated sudo:
---
- hosts: all
sudo: yes
gather_facts: no
tasks:
- name: "sudo to root"
command: /usr/bin/whoami
2) new become
---
- hosts: all
become: yes
become_method: sudo
gather_facts: no
tasks:
- name: "sudo to root"
command: /usr/bin/whoami
3) using ansible.cfg:
[privilege_escalation]
become = yes
become_method = sudo
and then in a playbook:
---
- hosts: all
gather_facts: no
tasks:
- name: "sudo to root"
command: /usr/bin/whoami
since you "becoming" tstuser01 (not a root like me), please play a bit, probably user name should not be quoted too:
become_user = tstuser01
at least this is the way I define remote_user in ansible.cfg and it works... My issue resolved, hope yours too
I think you should use the sudo directive in the hosts section so that subsequent tasks can run with sudo privileges unless you explicitly specified sudo:no in a task.
Here's your playbook that I've modified to use sudo directive.
# Checks the hosts provisioned by midrange
---
- hosts: all
sudo: yes
gather_facts: no
tasks:
- name: "sudo to configued user -- tstuser01"
command: /usr/bin/whoami