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
Related
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.).
Here is my playbook.yaml
pre_tasks:
- name: Install required ansible-galaxy roles
local_action: shell ansible-galaxy install -r requirements.yaml
roles:
- role: gantsign.golang
vars:
golang_version: "1.16.3"
golang_install_dir: "/opt/go/{{ golang_version }}"
And my requirements.yaml
---
- src: gantsign.golang
However the pre_task never seems to be executed, so the role is not found and provisioning fails.
Any idea why?
ERROR! the role 'gantsign.golang' was not found in /home/pkaramol/ansible
The error appears to be in '/home/pkaramol/ansible/airflow-playbook.yaml': line 33, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
roles:
- role: gantsign.golang
^ here
It looks as if ansible is trying to find the roles before starting the playbook. For some reason I am pretty sure I had done this process before (i.e. having a pre_task with local_action taking over role installation but I cannot seem to get it working now...)
edit: I have confirmed that this is the case, because when leaving only the pre_task with the local role installation it actually runs
As you can read in that documentation: https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#using-roles-at-the-play-level
When you use the roles option at the play level, Ansible treats the roles as static imports and processes them during playbook parsing. Ansible executes your playbook in this order ...
So The role itself need to be found and load before the playbook start running.
So if you want to use galaxy on pre_tasks, try to dynamically include your role on tasks section of your play: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/include_role_module.html#include-role-module
pre_tasks:
- name: Install required ansible-galaxy roles
local_action: shell ansible-galaxy install -r requirements.yaml
tasks:
- name: include my roles
include_role:
name: gantsign.golang
I have a requirement to setup an application and for that I need to install Nginx as root and then run another Java application as a different application user.
The condition for this is, I have a privileged user "priv_suer" which has sudo and I'm running the playbook as this user as I need to install and configure Nginx. But my application user is different from this user "app_user" which is unprivileged application only user.
The issue I'm facing is, this app_user needs password to become app_user. So in my case I need two passwords one is to become root and another one to become app_user.
I referred Understanding privilege escalation: become and only option I could find was "ansible_become_password".
Can anyone help me with this?
I think that privilege escalation can help. My solution is:
Declare different groups for servers running your Java applications and servers you want to install Nginx. In your case, the two groups can share the same servers.
Here below I give an example of inventory.yml file:
all:
children:
app:
hosts:
127.0.0.1:
vars:
ansible_become_pass: app_user#123
ansible_python_interpreter: /usr/bin/python3
ansible_user: app_user
nginx:
hosts:
127.0.0.1:
vars:
ansible_become_pass: root#123
ansible_python_interpreter: /usr/bin/python3
ansible_user: root
An example of playbook is as follow:
- hosts: app
tasks:
- name: Install Java app
become: yes
- hosts: nginx
tasks:
- name: Install NGINX
become: yes
Finally, run your ansible playbook with an inventory provided using -i option:
ansible-playbook -i etc/ansible/inventory.yml etc/ansible/playbook.yml
The current case is this:
I have a playbook which provisions a bunch of servers and installs apps to these servers.
One of these apps already has it's own ansible playbook which I wanted to use. Now my problem arises from this playbook, as it's limited to hosts: [prod] and the host groups I have in the upper-level playbook are different.
I know I could just use add_host to add the needed hosts to a prod group, but that is a solution which I don't like.
So my question is: Is there a way to add the current hosts to a new host group in the include statement?
Something like - include: foo.yml prod={{ ansible_host_group }}
Or can I somehow include only the tasks from a playbook?
No, there's no direct way to do this.
Now my problem arises from this playbook, as it's limited to
hosts: [prod]
You can setup host's more flexible via extra vars:
- name: add role fail2ban
hosts: '{{ target }}'
remote_user: root
roles:
- fail2ban
Run it:
ansible-playbook testplaybook.yml --extra-vars "target=10.0.190.123"
ansible-playbook testplaybook.yml --extra-vars "target=webservers"
Is this workaround suitable for you?
I am trying to run an Ansible playbook against a server using an account other than the one I am logged on the control machine. I tried to specify an ansible_user in the inventory file according to the documentation on Inventory:
[srv1]
192.168.1.146 ansible_connection=ssh ansible_user=user1
However Ansible called with ansible-playbook -i inventory playbook.yml -vvvv prints the following:
GATHERING FACTS ***************************************************************
<192.168.1.146> ESTABLISH CONNECTION FOR USER: techraf
What worked for me was adding the remote_user argument to the playbook:
- hosts: srv1
remote_user: user1
Now the same Ansible command connects as user1:
GATHERING FACTS ***************************************************************
<192.168.1.146> ESTABLISH CONNECTION FOR USER: user1
Also adding remote_user variable to ansible.cfg makes Ansible use the intended user instead of the logged-on one.
Are the ansible_user in inventory file and remote_user in playbook/ansible.cfg for different purposes?
What is the ansible_user used for? Or why doesn't Ansible observe the setting in the inventory?
You're likely running into a common issue: the published ansible docs are for the development version (2.0 right now), and we don't keep the old ones around. It's a big point of contention... Assuming you're using something pre-2.0, the inventory var name you need is ansible_ssh_user. ansible_user works in 2.0 (as does ansible_ssh_user- it gets aliased in).
I usually add my remote username in /etc/ansible/ansible.cfg as follows:
remote_user = MY_REMOTE_USERNAME
This way it is not required to configure ansible_user in the inventory file for each host entry.