Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Ansible Dynamic Inventory work with Google Cloud Platform (Google Compute Engine), GCP

I used Ansible to create a gce cluster following the guideline at: https://docs.ansible.com/ansible/latest/scenario_guides/guide_gce.html

And at the end of the GCE creations, I used the add_host Ansible module to register all instances in their corresponding groups. e.g. gce_master_ip

But then when I try to run the following tasks after the creation task, they would not work:

- name: Create redis on the master
  hosts: gce_master_ip
  connection: ssh
  become: True
  gather_facts: True
  vars_files:
    - gcp_vars/secrets/auth.yml
    - gcp_vars/machines.yml
  roles:
    - { role: redis, tags: ["redis"] }

Within the auth.yml file I already provided the service account email, path to the json credential file and the project id. But apparently that's not enough. I got errors like below:

UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Permission denied (publickey).\r\n", "unreachable": true}

This a typical ssh username and credentials not permitted or not provided. In this case I would say I did not setup anything of the username and private key for the ssh connection that Ansible will use to do the connecting.

Is there anything I should do to make sure the corresponding credentials are provided to establish the connection?

During my search I think one question just briefly mentioned that you could use the gcloud compute ssh... command. But is there a way I could specify in Ansible to not using the classic ssh and use the gcloud one?

like image 213
Tim Raynor Avatar asked Dec 13 '22 15:12

Tim Raynor


1 Answers

To have Ansible SSH into a GCE instance, you'll have to supply an SSH username and private key which corresponds to the the SSH configuration available on the instance.

So the question is: If you've just used the gcp_compute_instance Ansible module to create a fresh GCE instance, is there a convenient way to configure SSH on the instance without having to manually connect to the instance and do it yourself?

For this purpose, GCP provides a couple of ways to automate and manage key distribution for GCE instances. For example, you could use the OS Login feature. To use OS Login with Ansible:

  1. When creating the instance using Ansible, Enable OS Login on the target instance by setting the "enable-oslogin" metadata field to "TRUE" via the metadata parameter.
  2. Make sure the Service Account attached to the instance that runs Ansible have both the roles/iam.serviceAccountUser and roles/compute.osLoginAdmin permissions.
  3. Either generate a new or choose an existing SSH keypair that will be deployed to the target instance.
  4. Upload the public key for use with OS Login: This can be done via gcloud compute os-login ssh-keys add --key-file [KEY_FILE_PATH] --ttl [EXPIRE_TIME] (where --ttl specifies how long you want this public key to be usable - for example, --ttl 1d will make it expire after 1 day)
  5. Configure Ansible to use the Service Account's user name and the private key which corresponds to the public key uploaded via the gcloud command. For example by overriding the ansible_user and ansible_ssh_private_key_file inventory parameters, or by passing --private-key and --user parameters to ansible-playbook.

The service account username is the username value returned by the gcloud command above.

Also, if you want to automatically set the enable-oslogin metadata field to "TRUE" across all instances in your GCP project, you can simply add a project-wide metadata entry. This can be done in the Cloud Console under "Compute Engine > Metadata".

like image 187
Brandon DeRosier Avatar answered Jan 13 '23 13:01

Brandon DeRosier