Acceder a GitHub desde una compilación mediante claves SSH

En este tutorial se muestra cómo usar Secret Manager con Cloud Build para acceder a repositorios privados de GitHub desde una compilación. Secret Manager es un Google Cloud servicio que almacena de forma segura claves de API, contraseñas y otros datos sensibles.

Crear una clave SSH

  1. Abre una ventana de terminal.

  2. Crea un directorio llamado workingdir y accede a él:

    mkdir workingdir
    cd workingdir
    
  3. Crea una clave SSH de GitHub, donde github-email es tu dirección de correo de GitHub:

    ssh-keygen -t rsa -b 4096 -N '' -f id_github -C github-email
    

    Este comando crea una clave SSH workingdir/id_github sin contraseña para tu clave SSH. Cloud Build no puede usar tu clave SSH si está protegida con una contraseña.

Almacena la clave SSH privada en Secret Manager

Cuando crees una clave SSH, se creará un archivo id_github en tu entorno. Como cualquier persona puede autenticarse en tu cuenta con este archivo, debes almacenarlo en Secret Manager antes de usarlo en una compilación.

Para almacenar tu clave SSH en Secret Manager, sigue estos pasos:

  1. Ve a la página Secret Manager en la Google Cloud consola:

    Ve a la página Secret Manager.

  2. En la página Secret Manager, haz clic en Crear secreto.

  3. En la página Crear secreto, en Nombre, escribe un nombre para el secreto.

  4. En el campo Valor secreto, haz clic en Subir y sube tu archivo workingdir/id_github.

  5. No modifiques la sección Regiones.

  6. Haz clic en el botón Crear secreto.

Se subirá el archivo id_github a Secret Manager.

Añade la clave pública SSH a las claves de implementación de tu repositorio privado

  1. Inicia sesión en GitHub.

  2. En la esquina superior derecha, haz clic en tu foto de perfil y, a continuación, en Tu perfil.

  3. En la página de tu perfil, haz clic en Repositorios y, a continuación, en el nombre del repositorio.

  4. En tu repositorio, haz clic en Configuración.

  5. En la barra lateral, haz clic en Deploy Keys (Claves de implementación) y, a continuación, en Add deploy key (Añadir clave de implementación).

  6. Proporciona un título y pega tu clave pública SSH de workingdir/id_github.pub.

  7. Selecciona Permitir acceso de escritura si quieres que esta clave tenga acceso de escritura al repositorio. Una clave de implementación con acceso de escritura permite que una implementación inserte contenido en el repositorio.

  8. Haz clic en Añadir clave.

  9. Elimina la clave SSH de tu disco:

    rm id_github*
    

Conceder permisos

Debes conceder permiso para acceder a Secret Manager a la cuenta de servicio que estés usando para la compilación.

  1. En la Google Cloud consola, ve a la página Permisos de Cloud Build:

    Ve a Permisos.

  2. En la lista desplegable, selecciona la cuenta de servicio cuyos roles quieras cambiar.

  3. Cambia el estado del rol Secret Manager Secret Accessor a Habilitar.

Añadir la clave pública SSH a los hosts conocidos

La mayoría de los equipos contienen un archivo llamado known_hosts, que contiene claves conocidas de hosts remotos. Las claves suelen recogerse de los hosts remotos al conectarse a ellos por primera vez, pero también se pueden añadir manualmente. Las claves de este archivo se usan para verificar la identidad del host remoto y protegerlo frente a la suplantación de identidad.

Para que Cloud Build se conecte a GitHub, debes añadir la clave pública SSH al archivo known_hosts en el entorno de compilación de Cloud Build. Para ello, añade la clave a un archivo known_hosts.github temporal y, a continuación, copia el contenido de known_hosts.github en el archivo known_hosts del entorno de compilación de Cloud Build.

En el directorio workingdir, crea un archivo llamado known_hosts.github y añade la clave pública SSH a este archivo:

ssh-keyscan -t rsa github.com > known_hosts.github

En la siguiente sección, cuando configures la compilación, añadirás instrucciones al archivo de configuración de Cloud Build para copiar el contenido de known_hosts.github en el archivo known_hosts del entorno de compilación de Cloud Build.

Configurar la compilación

Para configurar la compilación, haz lo siguiente:

  1. Crea un archivo de configuración de compilación llamado cloudbuild.yaml con dos pasos: el primer paso gcloud accede a la clave SSH en Secret Manager y la guarda como id_rsa en un volumen llamado ssh, junto con una copia de known_hosts.github. El volumen se usa para conservar los archivos en los pasos de compilación. En el segundo paso git se usa la clave de id_rsa para conectarse al repositorio en git@github.com:git-username/git-repository.

    # Access the id_github file from Secret Manager, and setup SSH
    steps:
    - name: 'gcr.io/cloud-builders/git'
      secretEnv: ['SSH_KEY']
      entrypoint: 'bash'
      args:
      - -c
      - |
        echo "$$SSH_KEY" >> /root/.ssh/id_rsa
        chmod 400 /root/.ssh/id_rsa
        cp known_hosts.github /root/.ssh/known_hosts
      volumes:
      - name: 'ssh'
        path: /root/.ssh
    
    # Clone the repository
    - name: 'gcr.io/cloud-builders/git'
      args:
      - clone
      - --recurse-submodules
      - git@github.com:GIT_USERNAME/GIT_REPOSITORY
      volumes:
      - name: 'ssh'
        path: /root/.ssh
    
    availableSecrets:
      secretManager:
      - versionName: projects/PROJECT_ID/secrets/SECRET_NAME/versions/latest
        env: 'SSH_KEY'
    

Sustituye los valores de los marcadores de posición de los comandos anteriores por los siguientes:

  • GIT_USERNAME: nombre de usuario de GitHub del propietario del repositorio.
  • GIT_REPOSITORY: el nombre del repositorio de GitHub al que quieres acceder.
  • PROJECT_ID: El ID del Google Cloud proyecto en el que has almacenado tus secretos.
  • SECRET_NAME: nombre del secreto que has creado en Secret Manager.

Para obtener información sobre las cadenas multilínea de YAML que se usan en el fragmento de código anterior, consulta Cadenas multilínea de YAML.

Enviar la compilación

Para enviar la compilación, ejecuta el siguiente comando:

gcloud builds submit --config=cloudbuild.yaml .

El resultado debería ser similar al siguiente:

Creating temporary tarball archive of 3 file(s) totalling 4.1 KiB before compression.
Uploading tarball of [.] to [gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/[PROJECT-ID]/builds/871b68bc---].
Logs are available at [https://console.cloud.google.com/cloud-build/builds/871b68bc---?project=[PROJECT-ID]].
----------------------------- REMOTE BUILD OUTPUT ------------------------------
starting build "871b68bc-cefc-4411-856c-2a2b7c7d2487"

FETCHSOURCE
Fetching storage object: gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz#1504288640827178
Copying gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz#1504288640827178...
/ [1 files][  3.9 KiB/  3.9 KiB]
Operation completed over 1 objects/3.9 KiB.
BUILD
Step #0: Already have image (with digest): gcr.io/cloud-builders/gcloud
Starting Step #0
Finished Step #0
Step #1: Already have image (with digest): gcr.io/cloud-builders/git
Starting Step #1
Step #1: # github.com SSH-2.0-libssh_0.7.0
Finished Step #1
Step #2: Already have image (with digest): gcr.io/cloud-builders/git
Starting Step #2
Step #2: Cloning into '[REPOSITORY-NAME]'...
Step #2: Warning: Permanently added the RSA host key for IP address 'XXX.XXX.XXX.XXX' to the list of known hosts.
Finished Step #2
PUSH
DONE
-----------------------------------------------------------------------------------------------------------------

ID                                    CREATE_TIME                DURATION  SOURCE                                                                              IMAGES  STATUS
871b68bc-cefc-4411-856c-2a2b7c7d2487  XXXX-XX-XXT17:57:21+00:00  13S       gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz  -                                 SUCCESS