# Connect to Compute Engine using SSH keys and Cloud Build

**Goal:**  
Allow **Cloud Build** to SSH into a **Compute Engine VM** (e.g. abc`-dev`) using a **fixed SSH key stored in Secret Manager**, instead of generating a new key on every build.

We’ll use this flow:

Cloud Build ➝ Service Account ➝ Secret Manager (SSH key) ➝ SSH to VM

#### 1. Create a dedicated CI/CD service account

1. Go to **IAM &amp; Admin → Service Accounts**.
2. Click **Create service account**.
3. Name it something like:
    
    
    - Service account name: `cicd-deployer`
    - ID: `cicd-deployer`
    - Description: `Cloud Build deployer for abc-dev`
4. Click **Create and continue**.

#### 2. Grant project-level roles to the service account

Still in the creation flow (or edit later), grant these roles **at project level**:

**Required:**

- `roles/cloudbuild.builds.builder` – so it can run Cloud Build steps
- `roles/compute.instanceAdmin.v1` – to SSH / manage instances
- `roles/compute.osAdminLogin` – admin-level login on VM via SSH
- `roles/secretmanager.secretAccessor` – to read SSH keys from Secret Manager

**Optional but useful:**

- `roles/logging.logWriter` (if you use additional logging)
- `roles/iam.serviceAccountUser` (if other things need to impersonate it)

Click **Done**.

You now have:

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-cicd-deployer%40abcbd-"><div class="sticky top-9"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs">  
</div></div></div><div class="overflow-y-auto p-4" dir="ltr">`cicd-deployer@abcbd-456500.iam.gserviceaccount.com`</div></div>---

#### 2. Configure Cloud Build trigger to use this service account

1. Go to **Cloud Build → Triggers**.
2. Edit your trigger (the one for this repo).
3. In **Advanced**:
    
    
    - **Service account**: select  
        `cicd-deployer@abcbd-456500.iam.gserviceaccount.com`
    - **Logging**: choose **Cloud Logging only** (or ensure your YAML has `options: logging: CLOUD_LOGGING_ONLY`).

Save the trigger.

Now all builds for this trigger run **as `cicd-deployer`**.

Now we will proceed to authenticate and run actions

STEP 1 — Generate SSH key locally (only once)

```shell
ssh-keygen -t rsa -b 2048 -f ~/.ssh/cb_abc_key -C cb_abc_key
```

STEP 2 — Upload both keys to Secret Manager

```shell
gcloud secrets create cb-abc-key \
  --replication-policy="automatic" \
  --data-file="$HOME/.ssh/cb_abc_key" \
  --project=abcbd-456500

gcloud secrets create cb-abc-key-pub \
  --replication-policy="automatic" \
  --data-file="$HOME/.ssh/cb_abc_key.pub" \
  --project=abcbd-456500

```

STEP 3 — Grant Cloud Build access to secrets

```shell
gcloud secrets add-iam-policy-binding cb-abc-key \
  --member="serviceAccount:cicd-deployer@abcbd-456500.iam.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor" \
  --project=abcbd-456500

gcloud secrets add-iam-policy-binding cb-abc-key-pub \
  --member="serviceAccount:cicd-deployer@abcbd-456500.iam.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor" \
  --project=abcbd-456500

```

STEP 4 — Add the PUBLIC key to the VM (UI method)

Go to:

**Compute Engine → VM instances → abc-dev → Edit → SSH Keys**

Click **Add item**

```shell
<contents of cb_abc_key.pub>
```

FIX — Add the username to the SSH key inside VM

But your SSH public key was added only for your user, not for **root**.

Google Compute Engine **does NOT allow login as root using SSH keys** by default.

#### ✔ You must specify a Linux username

#### ❌ You cannot SSH directly as root

Your public key should **begin with**:

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-ssh-rsa-aaaab3...-yo"><div class="sticky top-9"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs">  
</div></div></div><div class="overflow-y-auto p-4" dir="ltr">`ssh-rsa AAAAB3... yourusername`</div></div>#### Update SSH key in GCP UI

Go to:

➡ **Compute Engine → VM instances → abc-dev → Edit → SSH Keys**

Remove the old entry  
Add the NEW public key:

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-ssh-rsa-aaaab3...%3D%3D-"><div class="overflow-y-auto p-4" dir="ltr">`ssh-rsa AAAAB3...== gkibria`</div></div>Click **Save**.

This authorizes SSH for the Linux user: `<span class="hljs-attribute">gkibria</span>`

FINAL WORKING YAML

```yaml
options:
  logging: CLOUD_LOGGING_ONLY
steps:
  - name: 'gcr.io/cloud-builders/gcloud'
    id: "SSH to VM"
    entrypoint: /bin/sh
    args:
      - "-c"
      - |
          echo "📥 Loading SSH keys from Secret Manager..."

          mkdir -p /builder/home/.ssh

          gcloud secrets versions access latest \
            --secret=cb-abc-key > /builder/home/.ssh/id_rsa
          chmod 600 /builder/home/.ssh/id_rsa

          gcloud secrets versions access latest \
            --secret=cb-abc-key-pub > /builder/home/.ssh/id_rsa.pub
          chmod 644 /builder/home/.ssh/id_rsa.pub

          echo "🔐 Connecting to VM abc-dev..."

          gcloud compute ssh gkibria@abc-dev \
            --project=abc-456500 \
            --zone=us-central1-f \
            --ssh-key-file=/builder/home/.ssh/id_rsa \
            --command="echo Connected OK; whoami; hostname"

```