iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
💚

Deploy to Cloud Run Jobs from GitHub Actions Using Buildpacks (No Dockerfile Required) [GCP]

に公開

About This Article

By using Buildpacks with Cloud Run Jobs on GCP, you can deploy directly from GitHub Actions using only your source code, without the need for a Dockerfile.

In this example, we will write a simple Python script that hits an API and displays the response.

Overview

Cloud Run is a fully managed GCP service that allows you to run applications by simply writing code in any programming language, containerizing it, and deploying that container image to Google Cloud.
Generally, this requires you to create your own Dockerfile. However, by using Buildpacks, your source code is automatically containerized without needing to write a Dockerfile. This allows you to set up an execution environment easily, even without deep infrastructure knowledge.

Target Audience

I hope this article helps those who have a vague understanding of Cloud Run but have never run it before, by guiding them through a simple execution to understand how it works.
Note that this article does not cover the detailed differences between services and jobs, or other fine-grained Cloud Run configurations.

Sample Repository

The sample code used in this article is managed in the following repository:
https://github.com/bby-kanta/cloud_run_cd_sample

Steps

https://cloud.google.com/run/docs/quickstarts/jobs/build-create-python?hl=ja
Basically, we will follow the official quickstart documentation.

1. Create the Source Code

First, let's create the Python script. In this example, we will implement a simple script that hits an API and prints the response to the logs.

https://fourtonfish.com/hellosalut?lang=ja
This is the API endpoint we will be hitting. Providing a language parameter returns a greeting from that country.

{"code":"ja","hello":"こんにちは"}

Here is the actual response that will be returned.

Create a directory and move into it.

$ mkdir cloud_run_cd_sample
$ cd cloud_run_cd_sample
$ mkdir cloudrun
$ cd cloudrun
$ touch {main.py,Procfile,requirements.txt}
cloudrun/main.py
import requests
import sys


HELLOSALUT_API_URL = "https://fourtonfish.com/hellosalut"

# Define main script
def main():
    """
    Just hit the Hello, salut! API and print the response.
    * An API that returns a greeting for the region based on country code or global IP
    """
    params = {
        "lang": "ja",
    } 

    response = requests.get(HELLOSALUT_API_URL, params=params)

    if response.status_code != 200:
        raise Exception("Request failed with status code: " + str(response.status_code))

    if response.status_code == 200:
        data = response.json()
        print(data)

if __name__ == "__main__":
    try:
        main()
    except Exception as err:
        message = (
            f"Task failed: {str(err)}"
        )
        print(message)
        sys.exit(1)
cloudrun/Procfile
web: python3 main.py
cloudrun/requirements.txt
requests==2.31.0

Buildpacks automatically detect that this is a Python application and determine the application dependencies from the requirements.txt file. Finally, it refers to the Procfile to determine how to start this Python server.

2. Deploy via CLI first to confirm operation without GitHub Actions

With Buildpacks, you can deploy to Cloud Run just like this. Since CI/CD often runs into trouble due to factors like environment variable configuration, let's deploy easily using the gcloud CLI before proceeding to the GitHub Actions CD mentioned in the article title. If you have not configured the gcloud CLI, please refer to the following to install it.
*Skip this step if you do not need to verify the operation.
https://cloud.google.com/sdk/docs/install?hl=ja

Deploy to Cloud Run using gcloud CLI

gcloud run jobs deploy your-jobs-name \
    --source . \
    --tasks 1 \
    --max-retries 5 \
    --region asia-northeast1 \
    --project=【GCP Project Name】

Run this command while the directory cloudrun you created earlier is your current directory.
Replace your-jobs-name with the display name for your Cloud Run Job. Please enter a name of your choice.
--source specifies the path to the source code directory.
--tasks specifies the number of tasks to run numerically. Set this to 2 or more if you want to run tasks in parallel.
--max-retries specifies the number of retries when a task fails.
--region specifies the region to deploy to.

If deployment is successful
When the deployment is successful, Job [your-jobs-name] has successfully been deployed. will be displayed.

Verify deployment in the Google Cloud Console

Open Cloud Run Jobs in the Google Cloud Console ( https://console.cloud.google.com/run/jobs?hl=ja ).
You can confirm that the deployment is complete because your-jobs-name that you deployed earlier exists. It has only been deployed, so the status is No executions.

Run the job to confirm that the API response is returned

Click your-jobs-name to enter the job details screen.
Click Execute.


An execution history entry will be added.
Next, click the execution ID.


Click the Logs tab.
You can see {'code': 'ja', 'hello': 'こんにちは'} in the logs, confirming that it is working as expected.

Since we have verified everything from deployment to job execution, we will now proceed with CD from GitHub Actions.
Deploying source code from a local machine is convenient, but it is recommended to configure CD because there is no guarantee that the latest changes are reflected.

3. Deploy using GitHub Actions

We will now configure CD with GitHub Actions. Specifically, we will set it up so that when code is merged into the main branch, it is automatically deployed from the source code to the Cloud Run Job.

Authentication from GitHub to GCP

I will omit the details of how to authenticate from GitHub to GCP, as the procedure for setting up authentication can be quite long.
However, the following article provides a very clear explanation of how to perform authentication using OIDC, which eliminates the need for tokens. Please refer to it.
https://zenn.dev/kou_pg_0131/articles/gh-actions-oidc-gcp

Permissions required for the Service Account

Whether using token-based authentication or the aforementioned OIDC, you must create an appropriate service account during the procedure.
Below are the permissions required for the service account to deploy from GitHub Actions (see documentation here).
Once you have created the service account, please make note of its email address, as you will use it for GitHub Actions.

  • Artifact Registry Writer
  • Cloud Build Editor
  • Cloud Run Developer
  • Service Account User
  • Storage Admin

How to set up GitHub Actions

Return to the project's root directory (cloud_run_cd_sample in this article) and create the following files.

mkdir .github
mkdir .github/workflows
touch .github/workflows/cloud-run-jobs-build.yml

Add the following environment variables to your GitHub repository:

  • GCS_PROJECT_ID
    • Your GCP project ID
  • GCS_WIP
    • Information for the Workload Identity Pool created for GitHub
    • projects/<Project Number>/locations/global/workloadIdentityPools/<Pool ID>/providers/<Provider ID>
  • GCS_SERVICE_ACCOUNT_EMAIL
    • The email address of the service account created for GitHub
.github/workflows/cloud-run-jobs-build.yml
name: Deploy to Cloud Run Job

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - uses: google-github-actions/auth@v2
        with:
          project_id: "${{ vars.GCS_PROJECT_ID }}"
          workload_identity_provider: "${{ vars.GCS_WIP }}"
          service_account: "${{ vars.GCS_SERVICE_ACCOUNT_EMAIL }}"

      - name: Setup Google Cloud
        uses: google-github-actions/setup-gcloud@v2
        with:
          project_id: ${{ vars.GCS_PROJECT_ID }}

      - name: Cloud Run Jobs Deploy
        run: |
          gcloud run jobs deploy your_job_name \
            --source ./cloudrun \
            --tasks 1 \
            --max-retries 5 \
            --region asia-northeast1 \
            --project ${{ vars.GCS_PROJECT_ID }}
  - uses: google-github-actions/auth@v2
    with:
      project_id: "${{ vars.GCS_PROJECT_ID }}"
      workload_identity_provider: "${{ vars.GCS_WIP }}"
      service_account: "${{ vars.GCS_SERVICE_ACCOUNT_EMAIL }}"

This is the part that authenticates with GCP from GitHub Actions.
Use google-github-actions/auth to perform authentication.

  - name: Setup Google Cloud
    uses: google-github-actions/setup-gcloud@v2
    with:
      project_id: ${{ vars.GCS_PROJECT_ID }}

This part enables the use of gcloud commands.

  - name: Cloud Run Jobs Deploy
    run: |
      gcloud run jobs deploy your-job-name \
        --source ./cloudrun \
        --tasks 1 \
        --max-retries 5 \
        --region asia-northeast1 \
        --project ${{ vars.GCS_PROJECT_ID }}

This is the actual deployment of the source code.
It is the same command used in "Deploying to Cloud Run via gcloud CLI".

With this, once you merge to main, it will automatically deploy from the source code.

Referenced Articles

https://cloud.google.com/blog/ja/products/serverless/build-and-deploy-an-app-to-cloud-run-with-a-single-command
https://dev.classmethod.jp/articles/google-cloud-buildpacks/

Discussion