Github Hosted Runners and Their Access to GCP VPC


TL; DR: Given plenty of free time of Github hosted runners, I’m tempted to use it instead of running self-hosted ones in my GCP environment. Here are some options to grant network access to my GCP VPC.

Prerequisites: Google Workload Identity Federation for Github Runners

Option , grab the public IP of the runner on-the-fly and grant/revoke access using Google’s firewall rules.

jobs:
  ssh-test:
    runs-on: [ ubuntu-latest ]
    permissions:
      contents: 'read'
      id-token: 'write'
    steps:      
      # prerequisite steps here
      - name: Temporary firewall rule
        run: |
          RUNNER_IP=$(curl -s  https://httpbin.org/ip |jq -r '.origin')
          gcloud compute firewall-rules create gha-runner-to-bastion \
            --allow=tcp:22 \
            --source-ranges="$RUNNER_IP/32" \
            --description="Allowing the GH runner to access to bastion" \
            --project=my-gcp-project \
            --network=my-gcp-vpc \
            --target-service-accounts=gha-runner@my-gcp-project.iam.gserviceaccount.com
      - name: SSH Setup
        id: ssh_setup
        run: |
          mkdir -p ~/.ssh
          echo "$SSH_PK" > ~/.ssh/google_compute_engine
          chmod 600 ~/.ssh/google_compute_engine
          ssh-keygen -y -f ~/.ssh/google_compute_engine > ~/.ssh/google_compute_engine.pub
          read instance_name instance_zone <<<$(gcloud compute instances list --filter=labels.app=bastion --format "value(name,zone)" |head -n1)
          echo "BASTION=${instance_name}" >> $GITHUB_ENV
          echo "ZONE=${instance_zone}" >> $GITHUB_ENV
        env:
          SSH_PK : ${{secrets.SSH_PK}}      
      # steps to do ssh stuff here
      - name: Clean up
        run: |
          gcloud compute firewall-rules delete gha-runner-to-bastion \
            --project=my-gcp-project --quiet   

Option , use Google IAP(Identity Aware Proxy) tunnel, which I think it’s better

jobs:
  ssh-test:
    runs-on: [ ubuntu-latest ]
    permissions:
      contents: 'read'
      id-token: 'write'
    steps:
      # prerequisite steps here including the SSH setup step
      - name: Open IAP
        run: |
          CLOUDSQL_PORT=3306

          # SSH Tunneling...
          gcloud compute ssh ${BASTION} --zone=${ZONE} --ssh-key-file=~/.ssh/google_compute_engine -- \
            -fN -L "1$CLOUDSQL_PORT:$CLOUDSQL_HOST:$CLOUDSQL_PORT" \
            -M -S bastion-socket \
            -o UserKnownHostsFile=/dev/null \
            -o StrictHostKeyChecking=no      
      # do stuff with the SSH tunnel here
      - name: Close IAP
        run: |
          gcloud compute ssh ${BASTION} --zone=${ZONE} -- \
            -S bastion-socket -O exit

🙂