SSH 認証鍵を使用してビルドから GitHub にアクセスする

このチュートリアルでは、Cloud Build で Secret Manager を使用して、ビルドから限定公開 GitHub リポジトリにアクセスする方法について説明します。Secret Manager は、API キー、パスワード、その他の機密データを安全に保存する Google Cloud サービスです。

SSH 認証鍵を作成する

  1. ターミナル ウィンドウを開きます。

  2. workingdir という名前で新しいディレクトリを作成し、そのディレクトリに移動します。

    mkdir workingdir
    cd workingdir
    
  3. 新しい GitHub SSH キーを作成します。github-email は GitHub のメールアドレスです。

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

    このコマンドは、パスフレーズなしで新しい SSH 認証鍵 workingdir/id_github を作成します。SSH 認証鍵がパスフレーズで保護されている場合、Cloud Build はその鍵を使用できません。

シークレット マネージャーに秘密 SSH 認証鍵を保存する

SSH 認証鍵を作成すると、環境内に id_github ファイルが作成されます。誰でもこのファイルでアカウントを認証できるため、ビルドで使用する前にファイルをシークレット マネージャーに保存する必要があります。

Secret Manager に SSH 認証鍵を保存するには:

  1. Google Cloud コンソールの [Secret Manager] ページに移動します。

    [Secret Manager] ページに移動

  2. [シークレット マネージャー] ページで、[シークレットを作成] をクリックします。

  3. [Secret の作成] ページの [名前] に、Secret の名前を入力します。

  4. [シークレット値] フィールドで [アップロード] をクリックし、workingdir/id_github ファイルをアップロードします。

  5. [リージョン] セクションは変更しません。

  6. [シークレットを作成] ボタンをクリックします。

これにより、id_github ファイルがシークレット マネージャーにアップロードされます。

公開 SSH 認証鍵を非公開リポジトリのデプロイキーに追加する

  1. GitHub にログインします。

  2. 右上にあるプロフィール写真をクリックし、[プロフィール] をクリックします。

  3. プロフィールページで [リポジトリ] をクリックし、リポジトリの名前をクリックします。

  4. リポジトリで [設定] をクリックします。

  5. サイドバーで [Deploy Keys] をクリックし、[Add deploy key] をクリックします。

  6. タイトルを入力し、workingdir/id_github.pub の公開 SSH 認証鍵を貼り付けます。

  7. このキーにリポジトリへの書き込みアクセス権を付与する場合は、[Allow write access] を選択します。書き込みアクセス権を持つデプロイ鍵を使用すると、デプロイからリポジトリに push できます。

  8. [Add key] をクリックします。

  9. ディスクから SSH 認証鍵を削除します。

    rm id_github*
    

権限を付与する

ビルドに使用しているサービス アカウントに、Secret Manager へのアクセス権を付与する必要があります。

  1. Google Cloud コンソールで、 Cloud Build の [権限] ページに移動します。

    [権限] に移動

  2. プルダウン リストから、ロールを変更するサービス アカウントを選択します。

  3. Secret Manager Secret Accessor ロールのステータスを [有効] に設定します。

公開 SSH 認証鍵を既知のホストに追加する

ほとんどのマシンには、リモートホスト用の既知のキーを含む known_hosts という名前のファイルがあります。多くの場合、このキーは初めてリモートホストに接続するときに回収されますが、手動で追加することもできます。このファイルのキーは、リモートホストの ID を確認し、なりすましから保護するために使用されます。

Cloud Build が GitHub に接続するには、Cloud Build のビルド環境の known_hosts ファイルに公開 SSH 認証鍵を追加する必要があります。これを行うには、キーを一時的な known_hosts.github ファイルに追加し、known_hosts.github の内容を Cloud Build のビルド環境の known_hosts ファイルにコピーします。

workingdir ディレクトリに known_hosts.github という名前のファイルを作成し、このファイルに公開 SSH 認証鍵を追加します。

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

ビルドを構成する次のセクションで、known_hosts.github の内容を Cloud Build のビルド環境の known_hosts ファイルにコピーする手順を Cloud Build 構成ファイルに追加します。

ビルドを構成する

ビルドを構成するには:

  1. cloudbuild.yaml という名前のビルド構成ファイルを 2 つのステップで作成します。最初のgcloud ステップで、Secret Manager の SSH 認証鍵にアクセスし、ssh というボリュームに id_rsa として known_hosts.github のコピーとともに保存します。ボリュームは、ビルドステップ全体でファイルを永続化するために使用されます。2 番目の git ステップでは、id_rsa の鍵を使用して 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'
    

上記のコマンドのプレースホルダ値を次のように置き換えます。

  • GIT_USERNAME: リポジトリ オーナーの GitHub ユーザー名。
  • GIT_REPOSITORY: アクセスしたい GitHub リポジトリの名前。
  • PROJECT_ID: シークレットを保存している Google Cloud プロジェクトの ID。
  • SECRET_NAME: Secret Manager で作成したシークレットの名前。

上記のスニペットで使用されている YAML の複数行文字列については、YAML の複数行をご覧ください。

ビルドの送信

ビルドを送信するには、次のコマンドを実行します。

gcloud builds submit --config=cloudbuild.yaml .

出力は次のようになります。

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