Run Same Ansible Playbook for Different Local Users - ansible

I would like to use an ansible playbook to setup identical configurations for two different users on my localhost (i.e., admin & brian). Currently, the "common" role installs programs that are accessible by both users. In addition, I have settings that are user specific (e.g., desktop wallpaper). When I run my playbook, the user specific settings are updated from one user but not the other. For example, if I run my playbook the wallpaper for brian is changed but the wallpaper for admin is left untouched. I am aware of become_user, but do not want to that for every task that I run. Is it possible to define the hosts file or playbook in such a way that I can simply specify the users on localhost I want the playbook to run against?
I have tried
Is there anyway to run multiple Ansible playbooks as multiple users more efficiently? on the per role level but am getting the following error:
fatal: [localhost]: FAILED! => {"changed": false, "module_stderr": "/usr/bin/python2: can't open file '/home/brian/.ansible/tmp/ansible-tmp-1525409723.54-208533437554058/apt.py': [Errno 13] Permission denied\n", "module_stdout": "", "msg": "MODULE FAILURE", "rc": 2}
site.yml
---
- name: ansible master playbook
hosts: localhost
connection: local
roles:
- role: common
roles/common/tasks/main.yml
---
- import_tasks: gsettings.yml
roles/common/tasks/gsettings.yml
---
- name: Use 12 hr. clock format
dconf:
key: "/org/gnome/desktop/interface/clock-format"
value: "'12h'"

In Ansible you have the option to launch the playbook as:
ansible-playbook playbooks/playbook.yml --user user
Please note that specifying a user can sometime conflict with a user defined in /etc/ansible/hosts.
(From Ansible documentation)

My solution was to simply log into each user on my local machine and run my ansible playbooks locally. An underlying issue with using the dconf module to change gsettings appears to be that D-Bus for the other user is not set, so the gsettings for the other user do not stick. See related questions below.
https://askubuntu.com/questions/655238/as-root-i-can-use-su-to-make-dconf-changes-for-another-user-how-do-i-actually
http://docs.ansible.com/ansible/latest/modules/dconf_module.html
Access another user's D-Bus session

Related

Ansible: Host localhost is unreachable

In my job there is a playbook developed in the following way that is executed by ansible tower.
This is the file that ansible tower executes and calls a playbook
report.yaml:
- hosts: localhost
gather_facts: false
connection: local
tasks:
- name: "Execute"
include_role:
name: 'fusion'
main.yaml from fusion role:
- name: "hc fusion"
include_tasks: "hc_fusion.yaml"
hc_fusion.yaml from fusion role:
- name: "FUSION"
shell: ansible-playbook roles/fusion/tasks/fusion.yaml --extra-vars 'fusion_ip_ha={{item.ip}} fusion_user={{item.username}} fusion_pass={{item.password}} fecha="{{fecha.stdout}}" fusion_ansible_become_user={{item.ansible_become_user}} fusion_ansible_become_pass={{item.ansible_become_pass}}'
fusion.yaml from fusion role:
- hosts: localhost
vars:
ansible_become_user: "{{fusion_ansible_become_user}}"
ansible_become_pass: "{{fusion_ansible_become_pass}}"
tasks:
- name: Validate
ignore_unreachable: yes
shell: service had status
delegate_to: "{{fusion_user}}#{{fusion_ip_ha}}"
become: True
become_method: su
This is a summary of the entire run.
Previously it worked but throws the following error.
stdout: PLAY [localhost] \nTASK [Validate] [1;31mfatal: [localhost -> gandalf#10.66.173.14]: UNREACHABLE! => {\"changed\": false, \"msg\": \"Failed to connect to the host via ssh: Warning: Permanently added '10.66.173.14' (RSA) to the list of known hosts.\ngandalf#10.66.173.14: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password), \"skip_reason\": \"Host localhost is unreachable\"
When I execute ansible-playbook roles/fusion/tasks/fusion.yaml --extra-vars XXXXXXXX from the command line with user awx it works.
Also I validated the connection from the server where ansible tower is running to where you want to connect with the ssh command and if it allows me to connect without requesting a password with the user awx
fusion.yaml does not explicitly specify connection plugin, thus default ssh type is being used. For localhost this approach usually brings a number of related problems (ssh keys, known_hosts, loopback interfaces etc.). If you need to run tasks on localhost you should define connection plugin local just like in your report.yaml playbook.
Additionally, as Zeitounator mentioned, running one ansible playbook from another with shell model is a really bad practice. Please, avoid this. Ansible has a number of mechanism for code re-use (includes, imports, roles etc.).

Ansible Playbook Error: The powershell shell family is incompatible with the sudo become plugin

I am working on a simple playbook that will ultimately be able to start/stop/restart windows services and I ran into an issue:
fatal: [mspdbwn1w01]: FAILED! => {
"msg": "The powershell shell family is incompatible with the sudo become plugin"
}
Below is the playbook:
- name: Add Host
hosts: localhost
connection: local
strategy: linear
tasks:
- name: Add Temp Host
add_host:
name: "{{ win_client }}"
group: temp
- name: Target Server
connection: winrm
hosts: temp
tasks:
- name: Stop a service
win_service:
name: "{{ service }}"
state: stopped
Google hasn't been much help, and I've tried everything I could find, every variation of become*.
I don't know if it matters, but due to the nature of the environment I work in, I have 2 separate users to log into *nix hosts vs. windows hosts.
Any assistance or guideance would be greatly appreciated.
Your system seems to use sudo as the default become method, which is not compatible with PowerShell. For Windows (and PowerShell), you can use runas as the become method. Add:
become_method: runas
to your playbook or task. You can get a list of all available become methods with:
ansible-doc -t become -l
Example:
doas Do As user
dzdo Centrify's Direct Authorize
enable Switch to elevated permissions on a network device
ksu Kerberos substitute user
machinectl Systemd's machinectl privilege escalation
pbrun PowerBroker run
pfexec profile based execution
pmrun Privilege Manager run
runas Run As user
sesu CA Privileged Access Manager
su Substitute User
sudo Substitute User DO
You can view the documentation for a particular become method with:
ansible-doc -t become runas
If you still get erros, pay attention to the error message, as it most probably is a different one. Using privilege escalation requires the definition of a username and a password for this purpose, for example.

Run local command with Ansible and share variable in the remote context

I have the following logic that I would like to implement with Ansible:
Before to update some operating system packages, I want to check some other remote dependencies, which involve querying some endpoints and decide if the next version is good or not.
The script new_version_available returns 0 if there is something new and 1 if there isn't something new.
To avoid install unnecessary packages in production, or open unnecessary ports in my firewall in the DMZ, I would like to run this script locally in my host and if it succeeds, then we run the next task remotely.
tasks:
- name: Check if there is new version available
command: "{{playbook_dir}}/new_version_available"
delegate_to: 127.0.0.1
register: new_version_available
ignore_errors: False
- name: Install our package
command:
cmd: '/usr/bin/our_installer update'
warn: False
when: new_version_available is succeeded
Which gives me the following error:
fatal: [localhost -> 127.0.0.1]: FAILED! => {"changed": false, "cmd": "/home/foo/ansible-deploy-bar/new_version_available", "msg": "[Errno 2] No such file or directory", "rc": 2}
That means that my command cannot be found, however my script exists and i have permission to access it.
My Development environment where I'm testing the playbook, is running in a virtual machine, via NAT, where forward the Guest port 22 to my host 2222, so if i want to login in my VM I do ssh root#localhost -p 2222. My inventory looks like:
foo:
hosts:
localhost:2222
My Question is:
What would be the Ansible way to achieve what I want, i.e run some command locally and pass the results to a register and use it as condition in a task? Run the command and pass the result as environment variable to Ansible?
I'm using this documentation as support https://docs.ansible.com/ansible/latest/user_guide/playbooks_delegation.html

How to fix "Could not match supplied host pattern, ignoring: bigip" errors, works in Ansible, NOT Tower

I am running Ansible Tower v3.4.1 with Ansible v2.7.6 on an ubuntu 16.04 VM running on VirtualBox. I run a playbook that works when I run it from the command line using "ansible-playbook" but fails when I try to run it from Ansible Tower. I know I must have something misconfigured in ansible tower but I can't find it.
I get this warning no matter what changes I make to the inventory (hosts) file.
$ ansible-playbook 2.7.6
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/var/lib/awx/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/dist-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 2.7.12 (default, Nov 12 2018, 14:36:49) [GCC 5.4.0 20160609]
Using /etc/ansible/ansible.cfg as config file
SSH password:
**/tmp/awx_74_z6yJB4/tmpVlXGCX did not meet host_list requirements**, check plugin documentation if this is unexpected
Parsed /tmp/awx_74_z6yJB4/tmpVlXGCX inventory source with script plugin
PLAYBOOK: addpool.yaml *********************************************************
1 plays in addpool.yaml
[WARNING]: **Could not match supplied host pattern, ignoring: bigip**
PLAY [Sample pool playbook] ****************************************************
17:05:43
skipping: no hosts matched
I have enabled inventory plugins for YAML, and made my hosts file into a hosts.yml file.
Here's my hosts file:
192.168.68.253
192.168.68.254
192.168.1.165
[centos]
dad2 ansible_ssh_host=192.168.1.165
[bigip]
bigip1 ansible_host=192.168.68.254
bigip2 ansible_host=192.168.68.253
Here's my playbook:
---
- name: Sample pool playbook
hosts: bigip
connection: local
tasks:
- name: create web servers pool
bigip_pool:
name: web-servers2
lb_method: ratio-member
password: admin
user: admin
server: '{{inventory_hostname}}'
validate_certs: no
I replaced hosts: bigip with hosts: all and specified the inventory in Tower as bigip which contains only the two hosts I want to change. This seems to provide the output I am looking for.
For the ansible-playbook command line, I added --limit bigip and this seems to provide the output I am looking for.
So things appear to be working, I just don't know whether this is best practice use.
If you get the error below while running a playbook with the command
ansible-playbook -i test-project/inventory.txt playbook.yml
{"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.31.24.10 port 22: Connection timed out", "unreachable": true}
The solution is to add, in the file ansible.cfg:
[defaults]
inventory=/etc/ansible/hosts
I think you need to remove the connection: local.
You have specified in hosts: bigip that you want these tasks to only run on hosts in the bigip group. You then specify connection: local which causes the task to run on the controller node (i.e. localhost), rather than the nodes in the bigip group. Localhost is not a member of the bigip group, and so none of the tasks in the play will trigger.
Check for special characters in absolute path of hosts file or playbook. Incase if you directly copied the path from putty, try copy and paste it from notepad or any editor
For me the issue was the format of the /etc/ansible/hosts file. You should use the :children suffix in order to use groups of groups like this:
[dev1]
dev_1 ansible_ssh_host=192.168.1.55 ansible_connection=ssh ansible_ssh_user={{username}} ansible_ssh_pass={{password}}
[dev2]
dev_2 ansible_ssh_host=192.168.1.68 ansible_connection=ssh ansible_ssh_user={{username}} ansible_ssh_pass={{password}}
[devs:children]
dev1
dev2
Reference: here

Ansible playbook does not run tasks in roles

I have a simple ansible roles with one task, but the problem is when i run it
the tasks are not actually started
It worked when I tried my task without roles and not sure why its happening when I try using roles.
Version of ansible: ansible 2.2.3.0
This is my run.yml
- name: add user to general purpose
hosts: localhosts
roles:
- adduser
cd adduser/tasks/main.yml
- name: Create user
shell: sudo adduser tom
Running
ansible-playbook run.yml -vvv
This is the output
Using /etc/ansible/ansible.cfg as config file
[WARNING]: provided hosts list is empty, only localhost is available
PLAYBOOK: run.yml
**************************************************************
1 plays in run.yml
PLAY RECAP
*********************************************************************
It is because you have a typo in your hosts: field; the name is localhost not localhosts (as there is no such thing as a plural of the local host)
Also, while this isn't what you asked, it is bad news to (a) manually use sudo in a module (b) call adduser unconditionally, as it will bomb the second time you run that playbook. The thing you want is to tell ansible that task needs elevated privileges and then make use of the user: module to allow ansible to ensure there is such a user by the end of that role:
- name: Create user
become: yes
user:
name: tom
The benefit of being more declarative is (a) that's how ansible works (b) it allows ansible to be idempotent across runs

Resources