How to use OS Login for SSH access to VMs on GCP

on
jan 28, 2022
in

A few weeks ago I blogged about how to use Terraform to automatically provision SSH keys for a VM on GCP.
One of the recommendations I gave at the end was using OS Login, instead of managing keys for each individual machine.
In this blog post we will take a look at OS Login and how it can help you to keep your SSH keys clean.

What is OS Login

OS Login simplifies SSH key management by using IAM roles to grant or revoke SSH keys.
This removes the need for manually provisioning, managing and eventually removing these keys.
Since dangling keys pose a security risk, not having them at all is a great feature!

Generate an RSA key pair

First you need an RSA key pair that you can add to an IAM user later on.

ssh-keygen -t rsa
ssh-add `~/.ssh/id_rsa`

The default location (~/.ssh/id_rsa) is fine, but you can use any other location of course.

Configuring OS Login in Terraform

Let’s write some Terraform code to tell Google Cloud to add the public key to our IAM user.
This can be done by retrieving the email address for the currently authenticated user:

data "google_client_openid_userinfo" "me" {}

resource "google_os_login_ssh_public_key" "cache" {
  user = data.google_client_openid_userinfo.me.email
  key  = file("~/.ssh/id_rsa.pub")
}

We also need to make sure that the IAM user is allowed to use OS Login:

resource "google_project_iam_member" "project" {
  project = "<gcp_project_id>"
  role    = "roles/compute.osAdminLogin"
  member  = "user:${data.google_client_openid_userinfo.me.email}"
}

If you are project owner or editor, this role is configured automatically.

Create a VM with OS Login enabled

Now we can create a new compute engine instance.
We also create a static IP address that we can get the value of using a Terraform output when it is time to connect.

resource "google_compute_address" "static_ip" {
  name = "debian-vm"
}

output "static_ip" {
  value = google_compute_address.static_ip.address
}

resource "google_compute_firewall" "allow_ssh" {
  name          = "allow-ssh"
  network       = "default"
  target_tags   = ["allow-ssh"]
  source_ranges = ["0.0.0.0/0"]

  allow {
    protocol = "tcp"
    ports    = ["22"]
  }
}

resource "google_compute_instance" "debian_vm" {
  name         = "debian"
  machine_type = "f1-micro"
  tags         = ["allow-ssh"]

  metadata = {
    enable-oslogin: "TRUE"
  }

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = "default"

    access_config {
      nat_ip = google_compute_address.static_ip.address
    }
  }
}

Notice the enable-oslogin: "TRUE" metadata flag. This is the key to making this work.

Let’s connect

ssh -i ~/.ssh/id_rsa <username>@$(terraform output --raw static_ip)

Note: the username that the VM will recognize is your IAM email address transformed into snake case, for example christerbeke@binx.io -> christerbeke_binx_io.

And there you have it! SSH access to your virtual machine, without having to manage and rotate SSH keys per machine.

Conclusion

When using SSH to connect to your virtual machines on Google Cloud, use the OS Login feature instead of separate SSH keys.
OS Login manages a single key that is associated with your IAM user and thus enhances security.

Bonus

Next to enhanced security, OS Login also comes with these two handy features:

  1. The enable-oslogin flag can be set on project level as well, so you don’t need to repeat it for every single machine.
  2. Because it works via IAM, your uid will be same on all machines!
Chris ter Beke has been using Google Cloud Platform for over 6 years. He has built multiple SaaS platforms using technologies like Terraform, Kubernetes, Python, and automated CI/CD pipelines.
Share this article: Tweet this post / Post on LinkedIn