Reputation: 272
I've created a VM in GCP with some OpenTofu and now I'd like to manage it with Ansible.
I'd like to use "Application Default Credentials" so I can avoid making extraneous service accounts. It should be supported in the gcp_compute
-plugin. but I'm getting the following error and I don't know how to troubleshoot further:
$ ansible -i gcp_compute.gcp.yml vm-xyz -m ping
...
vm-xyz | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ubuntu@<external-ip>: Permission denied (publickey).",
"unreachable": true
}
I authenticate using,
$ gcloud auth application-default login
And have configured:
# ansible.cfg
[inventory]
enable_plugins = gcp_compute
# gcp_compute.gcp.yml
plugin: gcp_compute
projects:
- myproject
auth_kind: application
hostnames:
- name
compose:
ansible_host: networkInterfaces[0].accessConfigs[0].natIP
Similar to the example in: https://docs.ansible.com/ansible/latest/collections/google/cloud/gcp_compute_instance_module.html
I tested enabling OS Logins, but that didn't do anything other than infer my username when I regularly SSH'd to the machine using gcloud compute ssh ...
I can successfully run
$ ansible -i gcp_compute.gcp.yml --list-hosts all
...
hosts (1):
vm-zyx
And I also successfully get a tsunami of information from:
$ ansible-inventory --list -i gcp_compute.gcp.yml
So I know that I'm properly authenticated.
It's probably trivial to use a ServiceAccount, that's not the question I'm asking about.
I'm specifically asking, how do I use auth_kind: application
to SSH to a VM running in GCP, with Ansible.
I've looked in the docs, I've looked on Google, there are no references to using "auth_kind: application" other than the docs saying that "it's supported" .. and It ~works. I can print the inventory. I just can't access or configure anything.
Everyone uses service accounts, even for just running stuff from their own machines, because I guess, it works..
This blogpost is doing wild things with SSH Wrappers, for IAP SSH access on internal IPs: https://medium.com/google-cloud/gaining-secure-access-to-bastion-hosts-from-ansible-using-iap-7c92e7ebf4da
This blogpost has "auth_kind: application" (YES!) .. but is otherwise absolutely sparse on information about how to get it to work.. https://alexdutton.co.uk/blog/authenticating-to-google-cloud-as-oneself-within-ansible/
My current workaround is to use gcloud compute ssh
to exchange an SSH key with the VM like so:
$ gcloud compute ssh \
--ssh-key-expire-after=1h \
--project=myproject \
--zone=myzone \
username@vm-xyz
And then use the key/username in my ansible.cfg:
# ansible.cfg
[inventory]
private_key_file = "/home/<user>/.ssh/google_compute_engine"
user = "<username>"
And manully register the host, (no gcp_compute
-plugin)
# hosts.yml
all:
hosts:
vm-xyz:
ansible_host: <external-ip>
$ ansible -i hosts.yml vm-xyz -m ping
vm-xyz | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3.10"
},
"changed": false,
"ping": "pong"
}
.. and honestly, that works. It's just.. The other thing was also supposed to just work.
Upvotes: 0
Views: 33
Reputation: 47
Your authentication using Application Default Credentials (ADC) is working for inventory fetching, but SSH access fails because ADC doesn't automatically provide SSH credentials. Here's what's happening and how you can fix it:
ADC does not manage SSH keys
gcloud auth application-default login
only grants access to GCP APIs but does not automatically add SSH keys to your instances.gcloud compute ssh
does manage SSH keys by automatically adding them to the VM metadata before connecting.Ansible requires an SSH key to authenticate
gcp_compute
plugin retrieves instance details but doesn't configure SSH access.Since you don't want to use a service account, the best way is to configure OS Login or manually inject SSH keys.
OS Login lets GCP manage SSH access using IAM roles.
Enable OS Login on your VM:
gcloud compute instances add-metadata vm-xyz --metadata enable-oslogin=TRUE
Ensure your user has the necessary IAM roles:
gcloud projects add-iam-policy-binding myproject \
--member=user:<your-email>@gmail.com \
--role=roles/compute.osLogin
gcloud projects add-iam-policy-binding myproject \
--member=user:<your-email>@gmail.com \
--role=roles/compute.osAdminLogin
Now, your Google account email becomes the SSH username, and Ansible should connect using:
[defaults]
remote_user=<your-email>@gmail.com
private_key_file=~/.ssh/google_compute_engine
If OS Login is not an option, manually inject your SSH key using:
gcloud compute instances add-metadata vm-xyz \
--metadata ssh-keys="$(whoami):$(cat ~/.ssh/google_compute_engine.pub)"
This allows Ansible to SSH in using:
[defaults]
remote_user=$(whoami)
private_key_file=~/.ssh/google_compute_engine
After setting up OS Login or injecting keys:
ansible -i gcp_compute.gcp.yml vm-xyz -m ping
If OS Login is enabled, it should work with auth_kind: application
.
Upvotes: -2