Terraform Google Bastion Host Module

repository·main·Indexed 41 days ago

https://github.com/terraform-google-modules/terraform-google-bastion-host

A Terraform module that automates the deployment of a secure Google Cloud bastion host. It integrates with Identity-Aware Proxy (IAP) and OS Login to provide controlled, identity-based SSH access to internal VPC resources without exposing public IP addresses. Supports Managed Instance Groups (MIG), custom IAM bindings, and provides migration paths for v5.0 and v9.0.

Tokens
6.2K
Snippets
15
Records
20
Agent score
51%

What's inside Terraform Google Bastion Host

  1. Deploy a Bastion Host via IAP and OS Login

    main

    This module provisions a Google Compute Engine (GCE) bastion host designed for secure access to internal VMs using IAP Tunneling and OS Login.

    It automates the following:

    • Creation of a dedicated service account for the bastion.
    • Provisioning of a GCE instance.
    • Creation of a firewall rule to allow TCP:22 SSH access from IAP ranges.
    • IAM bindings for IAP and OS Login for specified members.
    module "iap_bastion" {
      source = "terraform-google-modules/bastion-host/google"
    
      project = var.project
      zone    = var.zone
      network = google_compute_network.net.self_link
      subnet  = google_compute_subnetwork.net.self_link
      members = [
        "group:devs@example.com",
        "user:me@example.com",
      ]
    }
  2. Deploy the IAP Tunneling Example

    main

    To deploy the IAP Tunneling example, which creates a testing VM with firewall and IAM bindings for Identity-Aware Proxy (IAP) connections, follow these steps:

    1. Create a terraform.tfvars file containing the required configuration variables.
    2. Execute terraform apply to provision the resources.
    members = ["user:me@example.com"]
    project = "my-project"
    instance = "instance-1"
    zone     = "us-central1-a"
    region   = "us-central1"
    terraform apply
  3. SSH to a VM instance using IAP Tunneling

    main

    Once the IAP Tunneling infrastructure is deployed, you can access the VM instance via SSH without a public IP address by using the gcloud compute ssh command. This tunnels the connection through IAP.

    To connect:

    1. Authenticate with Google Cloud using gcloud auth login.
    2. Use gcloud compute ssh specifying the instance name, zone, and project.

    When successful, you will see a message indicating that the connection is defaulting to IAP tunneling because no external IP address was found. If OS Login is enabled, your username will appear with an ext_ prefix (e.g., ext_me_example_com).

    gcloud auth login
    gcloud compute ssh instance-1 --zone us-central1-a --project my-project
  4. Deploy a Bastion Group using Managed Instance Groups (MIG)

    main

    This example demonstrates how to set up a group of bastion hosts managed by a Managed Instance Group (MIG). To deploy, you must provide the required variables in a terraform.tfvars file and run the Terraform apply command.

    Required Variables:

    • project_id: The GCP Project ID where the instances and IAP tunneling will be configured.
    • members: A list of users, service accounts, or groups allowed access, using the standard GCP format (e.g., user:email@example.com).
    # terraform.tfvars
    members = ["user:me@example.com"]
    project_id = "my-project"
    terraform apply
  5. Migrate from v4.x to v5.x

    main

    The v5.0 release of the Google Bastion Host module introduces a breaking change regarding how external IP addresses are configured.

    To upgrade from version 4 to version 5, you must rename the ephemeral_ip input variable to external_ip. This change was made to support both ephemeral and static external IP configurations.

    module "iap_bastion" {
      source   = "terraform-google-modules/bastion-host/google"
    - version  = "v4.1"
    + version  = "v5.0"
    
    - ephemeral_ip = true
    + external_ip = true
    
    }
  6. Deploy the Two Service Example

    main

    To deploy this example, which demonstrates a shared bastion host providing access to two different services (Service A and Service B) with different user permissions, follow these steps:

    1. Create a terraform.tfvars file containing the required variables.
    2. Run terraform apply using the variable file.

    Note: This example uses a firewall rule that allows the bastion service account to communicate with the network on port 22. In production, you should scope this rule to specific target hosts.

    # terraform.tfvars
    project = "my-project"
    user_a = "user:me@example.com"
    user_b = "user:someone@example.com"
    network = "projects/my-project/global/networks/default"
    subnet = "projects/rcanty-project-0529/regions/us-west1/subnetworks/default"
    terraform apply -var-file terraform.tfvars
  7. Migrate to terraform-google-bastion-host v9.x

    main

    The v9.0 release of the Google Bastion Host module is a backwards incompatible release. When upgrading to v9.x, you must address the following breaking changes:

    1. Update Terraform Version: Ensure your environment is running at least Terraform v1.3.
    2. Check region Variable: The region variable now defaults to us-central1 instead of null for instance templates. If you rely on a specific region, ensure it is explicitly defined to avoid unintended deployments in us-central1.
  8. Access the Bastion Host via IAP and OS Login

    main

    Once the bastion host is deployed, you can access it using gcloud compute ssh. This example is configured to use Identity-Aware Proxy (IAP) for tunneling and OS Login for user authentication.

    When successful, your shell prompt will indicate you are logged in with an OS Login identity (prefixed with ext_, e.g., ext_me_example_com). You should also see a confirmation in the standard output that IAP tunneling is being used instead of a public IP address.

    Verification: Look for the following line in your terminal output: External IP address was not found; defaulting to using IAP tunneling.

    gcloud auth login
    gcloud compute ssh bastion-vm
  9. Requirements for terraform-google-bastion-host

    main

    Software

    • [Terraform][terraform] >= v1.3
    • [Terraform Provider for GCP][terraform-provider-gcp]

    Required Google Cloud APIs

    The following APIs must be enabled in your project:

    • storage-api.googleapis.com (Google Cloud Storage JSON API)
    • compute.googleapis.com (Compute Engine API)
    • iap.googleapis.com (Cloud Identity-Aware Proxy API)
    • oslogin.googleapis.com (OS Login API)
  10. Deploy the Simple Bastion Host Example

    main

    To deploy a basic network, subnet, and bastion host using this module, follow these steps:

    1. Create a terraform.tfvars file containing your required variables. At minimum, you must provide project_id and a list of members who should have access.
    2. Execute the deployment using the terraform apply command, referencing your variables file.

    Note: This specific example creates a firewall rule that allows the bastion to communicate with the rest of the network on port 22 using the bastion's service account email. For production environments, you should scope this rule down to specific target hosts.

    # terraform.tfvars
    members = ["user:me@example.com"]
    project_id = "my-project"
    terraform apply -var-file terraform.tfvars
  11. Configure Bastion Host Access Permissions

    main

    The module sets up permissions for the bastion's service account, but you must manually grant access to the users who need to connect.

    Required IAM Roles

    Grant one of the following roles to your users:

    • roles/compute.osLogin: Standard access (does not grant administrator permissions).
    • roles/compute.osAdminLogin: Administrator access.

    External Users

    If a user does not share the same domain as your organization, you must also grant them roles/compute.osLoginExternalUser. This prevents unauthorized external SSH access at the project level.

  12. SSH to private VMs through the bastion host

    main

    Once the bastion host is deployed, follow these steps to tunnel SSH traffic from your local machine to private VMs using the bastion as a jump host.

    1. Authenticate and Configure gcloud

    Login to Google Cloud and set your project, region, and zone:

    gcloud auth login
    gcloud config set project <project-id>
    gcloud config set compute/region us-west1
    gcloud config set compute/zone us-west1-a

    2. Access the Bastion Host

    Generate/use Google Compute Engine SSH keys and connect to the bastion VM:

    gcloud compute ssh bastion-vm

    3. Configure SSH Agent Forwarding

    Exit the bastion session, then start the SSH agent and add your private key. This allows the bastion to use your local keys to authenticate to the internal VMs:

    eval "$(ssh-agent -s)"
    ssh-add ~/.ssh/google_compute_engine

    4. Tunnel to Private VMs

    Use the --ssh-flag="-A" flag to enable agent forwarding, which allows you to SSH from the bastion to the target private VM in a single command:

    gcloud compute ssh bastion-vm --ssh-flag="-A" --command "ssh <private-vm-name>" -- -t
    gcloud compute ssh bastion-vm --ssh-flag="-A" --command "ssh priv-host-a-1" -- -t