Below is my playbook
- name: Play 1.5 - Check each target
hosts: all_hosts
ignore_unreachable: yes
ignore_errors: yes
gather_facts: true
tasks:
- raw: "echo {{ inventory_hostname }} is UNREACHABLE"
delegate_to: localhost
when: <Need help with the when condition here>
I need help with the when condition in the above playbook.
When i run the play against unreachable hosts the debug output clearly shows that the output is in JSON format and there must a variable that captures inventory_host connection status
Please see the output below:
TASK [Gathering Facts] *************************************************************************************************************************************************
task path: /app/Ansible/playbook/check/check.yml:55
<10.9.80.111> Attempting python interpreter discovery
<10.9.80.111> ESTABLISH SSH CONNECTION FOR USER: root
<10.9.80.111> SSH: EXEC ssh -o 'IdentityFile="/app/automation/ssh_keys/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o StrictHostKeyChecking=no 10.9.80.111 '/bin/sh -c '"'"'echo PLATFORM; uname; echo FOUND; command -v '"'"'"'"'"'"'"'"'/usr/bin/python'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.6'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.5'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python2.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python2.6'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/libexec/platform-python'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/bin/python3'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python'"'"'"'"'"'"'"'"'; echo ENDFOUND && sleep 0'"'"''
<10.9.80.111> (255, '', 'ssh: connect to host 10.9.80.111 port 22: Connection timed out\r\n')
[WARNING]: Unhandled error in Python interpreter discovery for host 10.9.80.111: Failed to connect to the host via ssh: ssh: connect to host 10.9.80.111 port 22:
Connection timed out
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/setup.py
Pipelining is enabled.
<10.9.80.111> ESTABLISH SSH CONNECTION FOR USER: root
<10.9.80.111> SSH: EXEC ssh -o 'IdentityFile="/app/axmw/misc_automation/ssh_keys/axmw_id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o StrictHostKeyChecking=no 10.9.80.111 '/bin/sh -c '"'"'/usr/bin/python && sleep 0'"'"''
fatal: [10.9.80.111]: UNREACHABLE! => {
"changed": false,
"msg": "Data could not be sent to remote host \"10.9.80.111\". Make sure this host can be reached over ssh: ssh: connect to host 10.9.80.111 port 22: Connection timed out\r\n",
"skip_reason": "Host 10.9.80.111 is unreachable",
"unreachable": true
}
META: ran handlers
From the output above i want to get the variable that has the below values:
fatal: [10.9.80.111]: UNREACHABLE! => {
"changed": false,
"msg": "Data could not be sent to remote host \"10.9.80.111\". Make sure this host can be reached over ssh: ssh: connect to host 10.9.80.111 port 22: Connection timed out\r\n",
"skip_reason": "Host 10.9.80.111 is unreachable",
"unreachable": true
Thus, I wish to capture the unreachable": true status from there.
Can someone please guide ?
you can use changed_when , when the changed is false, get the unreachable host
- name: Test connection and gather facts
hosts: all
serial: 1
gather_facts: true
ignore_unreachable: yes
become: false
tasks:
- name: Test connection
shell: hostname
register: connection_output
ignore_unreachable: yes
- debug: var=connection_output.changed
ignore_errors: yes
- name: print the list of unreachable servers
lineinfile:
line: "{{ connection_output.msg }}"
dest: "/tmp/AnsibleConnectionCheck.txt"
insertafter: EOF
become: false
delegate_to: 127.0.0.1
run_once: true
ignore_errors: yes
changed_when: False
Today I just finished this playbook :) Hope it will helpful for you!
Thank you so much Yvette Lau! I've been looking for this everywhere. Here is my implementation of the same logic with win_ping:
---
- hosts: all
gather_facts: no
become: yes
tasks:
- name: Win_Ping
win_ping:
register: WinPingResult
ignore_unreachable: yes
- debug: var=WinPingResult.changed
ignore_errors: yes
- name: Printing errors
debug:
msg: "{{ WinPingResult.msg }}"
run_once: yes
changed_when: False
Related
Am trying to use Ansible via Google IAP tunnel to update my VM's. I have followed the below repo
https://github.com/joeheaton/ansible-gcp
I get the below error. while running the playbook:
TASK [Gathering Facts] *********************************************************
fatal: [10.170.0.25]: UNREACHABLE! => ***"changed": false, "msg": "[Errno -3] Try again", "unreachable": true***
PLAY RECAP *********************************************************************
10.170.0.25 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
Below is my workflow file:
name: 'Ansible Config STG'
on:
workflow_dispatch:
inputs:
logLevel:
description: environment
required: true
default: stg
jobs:
playbook-dev:
name: 'Ansible Install'
runs-on: ubuntu-latest
environment: stg
container: gcr.io/google.com/cloudsdktool/cloud-sdk:286.0.0-alpine
env:
ANSIBLE_HOST_KEY_CHECKING: "False"
ANSIBLE_BECOME: "True"
OS_LOGIN_SSH_TTL: "1h"
ANSIBLE_REMOTE_USER: to-be-calculated-during-job
defaults:
run:
shell: bash
steps:
- name: Checkout
uses: actions/checkout#v2
- name: Config file
run: |
ls -al
- name: Set up Ansible & SSH
run: |
apk add ansible --update
echo $STG_PRIVATE_KEY > account.json
gcloud auth activate-service-account --key-file=account.json --project=test-staging
pip3 install requests google-auth
apk add jq --update
mkdir ~/.ssh
echo $FTP_SERVER_KEY_STG > ~/.ssh/id_rsa
ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa <<< y
chmod 600 ~/.ssh/id_rsa
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
gcloud compute os-login ssh-keys add --key-file ~/.ssh/id_rsa.pub --ttl $OS_LOGIN_SSH_TTL
export ANSIBLE_REMOTE_USER="sa_$(cat account.json | jq -r '.client_id')"
export ANSIBLE_HOST_KEY_CHECKING=False
export GOOGLE_APPLICATION_CREDENTIALS="account.json"
ansible-playbook -v -i inventory.gcp.yaml test.playbook.yml
env:
STG_PRIVATE_KEY: ${{ secrets.GOOGLE_PRIVATE_KEY_TF_STG }}
FTP_SERVER_KEY: ${{ secrets.FTP_SERVER_KEY_STG }}
Any suggestions or help would be really appreciated.
(There are already a few questions about this, but no solution worked for me)
On the servers I work on, we have to "sudo su - webapps" and then run our commands as webapps.
Ansible does not provide a native way to do this I believe (sudo only is available but the sysadmins restricted the list of commands I can run it with, su is available with Ansible but does not work on its own on the servers).
I've tried
https://www.coveros.com/ansible-privledge-escalation-using-sudo-su/
[privilege_escalation]
become_exe=sudo su -
With playbook :
---
- hosts:
- test
become: yes
become_user: webapps
become_method: su
tasks:
- name: Updates file
copy:
src: a.txt
dest: dest/a.txt
Running it gives :
SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o
ControlPersist=60s -o KbdInteractiveAuthentication=no -o
PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey
-o PasswordAuthentication=no -o 'User="myUser"' -o ConnectTimeout=10 -o ControlPath=/Users/lmoreau/.ansible/cp/d895b40f7e -tt myServer '/bin/sh -c '"'"'sudo su - webapps -c '"'"'"'"'"'"'"'"'/bin/sh -c
'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'echo
BECOME-SUCCESS-nxilvumwmfikgyuisutwiwobidrgqpao ; /usr/bin/python
/var/tmp/ansible-tmp-1583355901.6967812-200466745901442/AnsiballZ_setup.py'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"''"'"'"'"'"'"'"'"'
&& sleep 0'"'"''
...
"msg": "Timeout (12s) waiting for privilege escalation prompt: \r\nWe
trust you have received the usual lecture from the local
System\r\nAdministrator. It usually boils down to these three
things:\r\n\r\n #1) Respect the privacy of others.\r\n #2) Think
before you type.\r\n #3) With great power comes great
responsibility.\r\n\r\n"
Alternative attempt with :
[privilege_escalation]
become_exe=’sudo su - ‘
"module_stdout": "/bin/sh: ’sudo: command not found\r\n",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
Without overriding the become_exe:
"su" method gives "Timeout (12s) waiting for privilege escalation
prompt: "
"sudo" method gives "msg": "Missing sudo password"
Note : I do not have the password of the account I want to become, and am not supposed to have any.
How can I do the same as what I do by hand with Ansible ?
Use this:
- hosts: application
become: yes
become_exe: "sudo su - webapps"
become_method: su
tasks:
This question already has answers here:
Ansible Command module says that '|' is illegal character
(2 answers)
Closed 5 years ago.
Below yaml playbook restarts the jboss server but doesnt get back control to execute next ansible command. I have also used wait for module to stop waiting for current command result and go for next command. But still ansbile hangs on current command indefinitely . Please let me know when I went wrong?
---
- hosts: test1
tasks:
- name: simple command
become: true
command: whoami
register: output
- debug:
msg: "I gave the command whoami and the out is '{{output.stdout}}'"
- name: change to jboss user
become: true
become_user: jboss
command: whoami
register: output
- debug:
msg: "I gave the command whoami and the out is '{{output.stdout}}'"
- name: start jboss server as jboss user
become: true
become_user: jboss
command: sh /usr/jboss/bin/run.sh -c XXXXXXXX -b x.x.x.x &
when: inventory_hostname in groups['test1']
register: restartscript
- debug:
msg: "output of server restart command is '{{restartscript.stdout}}'"
- name: waiting for server to come back
local_action:
module: wait_for
timeout=20
host=x.x.x.x
port=8080
delay=6
state=started
terminal output message
ESTABLISH SSH CONNECTION FOR USER: XXXXXXXXXXX
SSH: EXEC sshpass -d12 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o User=XXXXXXXXX -o ConnectTimeout=10 -o ControlPath=/home/tcprod/XXXXXXXXXX/.ansible/cp/ansible-ssh-%h-%p-%r -tt X.X.X.X '/bin/sh -c '"'"'sudo -H -S -p "[sudo via ansible, key=hvgwnsbxpkxvbcmtcfvvsplfphdrevxg] password: " -u jboss /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-hvgwnsbxpkxvbcmtcfvvsplfphdrevxg; /usr/bin/python /tmp/ansible-tmp-XXXXXXXXX.XX-XXXXXXXXXXXXXX/command.py'"'"'"'"'"'"'"'"' && sleep 0'"'"''
The & is not allowed in Ansible "command".
command: sh /usr/jboss/bin/run.sh -c XXXXXXXX -b x.x.x.x &
Try removing it or use shell instead of command.
From Ansible documentation about command:
The given command [...] will not
be processed through the shell, so variables like $HOME and operations
like "<", ">", "|", ";" and "&" will not work (use the shell module if
you need these features).
I am trying to learn ansible, and am following the o'riley Ansible Up and running book.
In the getting started section of the book, it asks me to install ansible, virtualbox and vagrant and then via CLI run:
vagrant init ubuntu/trusty64
vagrant up
Afterwards I can ssh into the VM via vagrant ssh or via:
ssh vagrant#127.0.0.1 -p 2222 -i /Users/XXX/playbooks/.vagrant/machines/default/virtualbox/private_key
Next is creating the hosts file which looks like this:
testserver ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 \ ansible_ssh_user=vagrant \ ansible_ssh_private_key_file=.vagrant/machines/default/virtualbox/private_key
Lastly is running this command:
ansible testserver -i hosts -m ping
Which gets me:
testserver | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh.",
"unreachable": true
}
Adding -vvv gets me:
No config file found; using defaults
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: None
<127.0.0.1> SSH: EXEC ssh -C -q -o ControlMaster=auto -o ControlPersist=60s -o Port=2222 -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/Users/XXX/.ansible/cp/ansible-ssh-%h-%p-%r 127.0.0.1 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1468541275.7-255802522359895 `" && echo ansible-tmp-1468541275.7-255802522359895="` echo $HOME/.ansible/tmp/ansible-tmp-1468541275.7-255802522359895 `" ) && sleep 0'"'"''
testserver | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh.",
"unreachable": true
}
I tried modifying ansible_ssh_private_key_file in the hosts file to point to the full path of the private key, but that still didn't work:
ansible testserver -i hosts -m ping -vvv
No config file found; using defaults
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: None
<127.0.0.1> SSH: EXEC ssh -C -q -o ControlMaster=auto -o ControlPersist=60s -o Port=2222 -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/Users/XXX/.ansible/cp/ansible-ssh-%h-%p-%r 127.0.0.1 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1468541370.61-137685863794569 `" && echo ansible-tmp-1468541370.61-137685863794569="` echo $HOME/.ansible/tmp/ansible-tmp-1468541370.61-137685863794569 `" ) && sleep 0'"'"''
testserver | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh.",
"unreachable": true
}
This is my Ansible version:
ansible --version
ansible 2.1.0.0
config file =
configured module search path = Default w/o override
Anyone have any ideas why ansible isn't connecting to my vagrant VM?
I don't see any of your inventory variables past the first one taking effect in the ssh command. Does your inventory file really look like this?
testserver ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 \ ansible_ssh_user=vagrant \ ansible_ssh_private_key_file=.vagrant/machines/default/virtualbox/private_key
You shouldn't have backslashes in there. The direct reformatting is
testserver ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_ssh_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/default/virtualbox/private_key
However, in the long run you probably want to split these out into separate host_vars files.
I have this simple task in my role:
- name: Updating the /etc/hosts
lineinfile: dest=/etc/hosts line="192.168.99.100 {{ item }}"
with_items:
- domain1.com
- domain2.com
tags: etc
When I run my Ansible playbook:
robe:ansible-develop robe$ ansible-playbook -i inventory develop-env.yml -vvvv --extra-vars "user=`whoami`" --tags etc --become-user=robe --ask-become-pass
SUDO password:
PLAY [127.0.0.1] **************************************************************
GATHERING FACTS ***************************************************************
<127.0.0.1> REMOTE_MODULE setup
<127.0.0.1> EXEC ['/bin/sh', '-c', 'mkdir -p /tmp/ansible-tmp-1446050161.27-256837595805154 && chmod a+rx /tmp/ansible-tmp-1446050161.27-256837595805154 && echo /tmp/ansible-tmp-1446050161.27-256837595805154']
<127.0.0.1> PUT /var/folders/x1/dyrdksh50tj0z2szv3zx_9rc0000gq/T/tmpMYjnXz TO /tmp/ansible-tmp-1446050161.27-256837595805154/setup
<127.0.0.1> EXEC ['/bin/sh', '-c', 'chmod a+r /tmp/ansible-tmp-1446050161.27-256837595805154/setup']
<127.0.0.1> EXEC /bin/sh -c 'sudo -k && sudo -H -S -p "[sudo via ansible, key=rqphpqfpcbsifqtnwflmmlmpwrcnkpqe] password: " -u robe /bin/sh -c '"'"'echo BECOME-SUCCESS-rqphpqfpcbsifqtnwflmmlmpwrcnkpqe; LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 /usr/bin/python /tmp/ansible-tmp-1446050161.27-256837595805154/setup'"'"''
<127.0.0.1> EXEC ['/bin/sh', '-c', 'rm -rf /tmp/ansible-tmp-1446050161.27-256837595805154/ >/dev/null 2>&1']
ok: [127.0.0.1]
TASK: [docker-tool-box | Updating the /etc/hosts] *****************************
<127.0.0.1> REMOTE_MODULE lineinfile dest=/etc/hosts line="192.168.99.100 ptxrt.com"
<127.0.0.1> EXEC ['/bin/sh', '-c', 'mkdir -p /tmp/ansible-tmp-1446050161.49-9492873099893 && chmod a+rx /tmp/ansible-tmp-1446050161.49-9492873099893 && echo /tmp/ansible-tmp-1446050161.49-9492873099893']
<127.0.0.1> PUT /var/folders/x1/dyrdksh50tj0z2szv3zx_9rc0000gq/T/tmpyLOGd6 TO /tmp/ansible-tmp-1446050161.49-9492873099893/lineinfile
<127.0.0.1> EXEC ['/bin/sh', '-c', u'chmod a+r /tmp/ansible-tmp-1446050161.49-9492873099893/lineinfile']
<127.0.0.1> EXEC /bin/sh -c 'sudo -k && sudo -H -S -p "[sudo via ansible, key=nofwziqxytbhjwhluhtzdfcqclqjuypv] password: " -u robe /bin/sh -c '"'"'echo BECOME-SUCCESS-nofwziqxytbhjwhluhtzdfcqclqjuypv; LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 /usr/bin/python /tmp/ansible-tmp-1446050161.49-9492873099893/lineinfile'"'"''
<127.0.0.1> EXEC ['/bin/sh', '-c', 'rm -rf /tmp/ansible-tmp-1446050161.49-9492873099893/ >/dev/null 2>&1']
failed: [127.0.0.1] => (item=ptxrt.com) => {"failed": true, "item": "ptxrt.com"}
msg: The destination directory (/private/etc) is not writable by the current user.
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit #/Users/robe/develop-env.retry
127.0.0.1 : ok=1 changed=0 unreachable=0 failed=1
I don't understand why the error msg said:
msg: The destination directory (/private/etc) is not writable by the current user.
The correct directory should be /etc/hosts.
Any clue?
I am working on MacOS.
My playbook is:
- hosts: 127.0.0.1
connection: local
become: yes
become_method: sudo
become_user: "{{user}}"
roles:
- role-1
- role-2
I put the become_user by command line. So all my roles are running with become. And it still doesn't work.
On OSX the /etc/ folder is actually a symlink to the /private/etc/ folder - hence the error. (Ansible is just transparently following the symlink).
As for the error you're going to need to run the task with become: yes (sudo permissions) to be able to write to /etc/hosts/
Edit based on update and commments
To get the correct privileges to edit the hosts file you need to be root. Setting become: yes on the task is good enough for this for OSX as Ansible will default to sudo as the become method and root as the user.
To specify the sudo password you can do one of two things.
Use --ask-become-pass on the command line and Ansible will prompt you when it needs it
Use the ansible_become_pass variable on the group or host in the inventory file. E.g. localhost ansible_become_pass=batman
Note that the Ansible docs recommend against 2 and using 1 so as not to store your password in plain text.