0
votes

I have followed the Google Cloud Platform Guide for Ansible (http://docs.ansible.com/ansible/latest/guide_gce.html) and I can successfully create an instance from a playbook, but when I try to run the ansible commands directly, it gives me a Permission Denied message.

I can run 'gce.py --list' from the inventory directory and it lists all my instances, but when i try to run 'ansible all -i inventory -m setup' it gives me permission denied. I have set the gce.ini correctly and have even set all of the env variables as the guide suggests but no luck. Any ideas? Here is my trace

jonathan@devopsbox:~/ansible$ ansible all -i inventory -m setup -vvv ansible 2.4.0.0 config file = /home/jonathan/ansible/ansible.cfg configured module search path = [u'/home/jonathan/.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 python version = 2.7.13 (default, Jan 19 2017, 14:48:08) [GCC 6.3.0 20170118] Using /home/jonathan/ansible/ansible.cfg as config file Parsed /home/jonathan/ansible/inventory/gce.py inventory source with script plugin META: ran handlers Using module file /usr/lib/python2.7/dist packages/ansible/modules/system/setup.py ESTABLISH SSH CONNECTION FOR USER: None SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s > -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/home/jonathan/.ansible/cp/3d50765225 xxx.xxx.xxx.xxx '/bin/sh -c '"'"'echo ~ && sleep 0'"'"'' (255, '', 'Permission denied (publickey).\r\n') myinstancename | UNREACHABLE! => { "changed": false, "msg": "Failed to connect to the host via ssh: Permission denied (publickey).\r\n", "unreachable": true }

It says user:none. Does that mean it is not passing in my account email/pem_file_path/proj_id? It is set in gce.ini.

I also set in .bashrc the following: GCE_INI_PATH GCE_EMAIL GCE_PROJECT GCE_CREDENTIALS_FILE

I have tried basically everything but no luck. Running Ansible 2.4 on Ubuntu 17.04:

ansible --version ansible 2.4.0.0 config file = /home/jonathan/ansible/ansible.cfg configured module search path = [u'/home/jonathan/.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 python version = 2.7.13 (default, Jan 19 2017, 14:48:08) [GCC 6.3.0 20170118]

2
You have to tell ansible/ssh what credentials file to use (via ssh_config or ssh-agent or group_vars).Konstantin Suvorov
I didn't see anything in the documentation about this. it only mentioned setting the GCE email and credentials file path to the json file. Is this a not documented requirement? Are there any tutorials for setting this up with Google Cloud and dynamic inventory?user3208751
This has nothing in common with GCE or ansible dynamic inventory – it's usual SSH authentication question.Konstantin Suvorov
@KonstantinSuvorov thanks for the tip. It turns out all i had to do was run gcloud compute ssh... to generate the keys. afterwards everything worked. The ansible documentation could have been more clear on this.user3208751

2 Answers

0
votes

Answer from the comments:

You have to tell ansible/ssh what credentials file to use (via ssh_config or ssh-agent or group_vars).

-

Thanks for the tip. It turns out all i had to do was run gcloud compute ssh... to generate the keys. Afterwards everything worked. The Ansible documentation could have been more clear on this.

0
votes

After spending ages on the issue, I was able to tunnel ansible tasks through gcoud ssh, the solution follows:

create misc/gssh.sh

#!/bin/bash
host="${@: -2: 1}"
cmd="${@: -1: 1}"

socket="/tmp/ansible-ssh-${host}-22-iap"
ZONE=$(gcloud compute instances list --filter="name:${host}" --format='value(zone)')
gcloud_args="
--tunnel-through-iap
--zone=${ZONE}
--quiet
--no-user-output-enabled
--
-C
-o ControlMaster=auto
-o ControlPersist=20
-o PreferredAuthentications=publickey
-o KbdInteractiveAuthentication=no
-o PasswordAuthentication=no
-o ConnectTimeout=20"

exec gcloud compute ssh "$host" $gcloud_args -o ControlPath="$socket" "$cmd"

also change some settings in ansible.cfg

[ssh_connection]
pipelining = True
ssh_executable = ./misc/gssh.sh
transfer_method = piped

[defaults]
gathering = False # optional
strategy = free # important

also have gcp.yaml like:

---
plugin: gcp_compute
projects:
  - <PROJECT NAME>
auth_kind: serviceaccount
service_account_file: /opt/ansible/inventory/service-account.json
hostnames:
  - name
compose:
  ansible_host: name

Ansible will read the configuration file ansible.cfg and will know that it has to tunnel all the commands via gcloud connection created in gssh.sh. Hence, any manual ssh key generation and authentication is not required.

Hope this saves someone a bit of research time.


EDIT 1: Zone fetching slows down the process, which can be solved by hardcoding zone in gssh.sh; just replace

ZONE=$(gcloud compute instances list --filter="name:${host}" --format='value(zone)')

by

ZONE=<zone name>

eg.

ZONE="us-central1-a"