Automating the Launch and Update of a Website Using Cloud Run and GitHub Actions: Part 2

Automating the Launch and Update of a Website Using Cloud Run and GitHub Actions: Part 2


Contributed by : Adil Shahzad

Part 1: Launching and Updating a Website Using Cloud Run: Part 1

GitHub Repo Source Code : https://github.com/GDGCloudLahore/cloud-run-sample



Hello Cloud Enthusiasts ??,

Welcome back to another installment of the GDG Cloud Lahore series! Previously, we delved into building and deploying images to Cloud Run ??. Today, we're going to explore how to automate this process using GitHub Actions ???. We'll be utilizing the code provided above, so please feel free to clone it and practice alongside us. If you encounter any issues, don't hesitate to ask questions in the comment section ??. We also welcome any feedback on topics you'd like us to cover in future series related to GDG Cloud Lahore ??.

What is Cloud Run?

Write code your way by deploying any container that listens for requests or events. Build applications in your favorite language, with your favorite dependencies and tools, and deploy them in seconds.

Cloud Run abstracts away all infrastructure management by automatically scaling up and down from zero almost instantaneously — depending on traffic. Cloud Run only charges you for the exact resources you use.

Cloud Run makes app development and deployment simpler and faster. And it’s fully integrated with Cloud Code, Cloud Build, Cloud Monitoring, and Cloud Logging for an enhanced end-to-end developer experience.

What are GitHub Actions?

GitHub Actions makes it easy to automate all your software workflows, now with world-class CI/CD. Build, test, and deploy your code right from GitHub. Make code reviews, branch management, and issue triaging work the way you want.

GitHub Action has a free tier of 2,000 minutes per month.

Developer Workflow for CI/CD and Getting Started With It

The CI/CD pipeline starts when a developer submits new code to GitHub. This action triggers automated workflows within GitHub Actions, where the code is built into a Docker image. Once the image is successfully built, it’s pushed to a Docker image registry. From there, the image is deployed to Cloud Run, making the updated application available for users. This seamless process ensures that code changes are efficiently and reliably delivered as live updates.

name: Build and Deploy to Google Cloud Run

on:
  push:
    branches:
      - main
  workflow_dispatch:

env:
  PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
  SERVICE_NAME: ${{ secrets.CLOUD_RUN_SERVICE_NAME }}
  GCR_HOSTNAME: gcr.io
  GCR_REGISTRY: us-west3-docker.pkg.dev
  GCR_IMAGE: gdgcloudlahore-419421
  GCR_REGION: us-west3

jobs:
  setup-build-publish-deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # Necessary to fetch all tags and history
      
      - name: Determine new version
        id: versioning
        run: |
          git fetch --tags
          # Check if any tags exist
          if [ $(git tag | wc -l) -eq 0 ]; then
            echo "No tags found. Please create an initial tag."
            exit 1  # Exit with error if no tags are found
          else
            LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
          fi
          echo "Latest tag is $LATEST_TAG"
          # Prepare the next tag without the 'v' prefix
          NEXT_TAG=$(echo $LATEST_TAG | sed 's/v//g' | awk -F. '{$NF = $NF + 1;} 1' | sed 's/ /./g')
          echo "Attempting new tag $NEXT_TAG"
          # Check if the NEXT_TAG already exists
          if git rev-parse "v$NEXT_TAG" >/dev/null 2>&1; then
            echo "New tag v$NEXT_TAG already exists. Using the latest tag $LATEST_TAG instead."
            # If NEXT_TAG exists, we stick with LATEST_TAG and do not create a new one.
            echo "NEW_TAG=$LATEST_TAG" >> $GITHUB_ENV
          else
            echo "New tag is $NEXT_TAG"
            # Add 'v' prefix when creating the tag in git
            git tag "v$NEXT_TAG"
            git push origin "v$NEXT_TAG"
            # Use the successfully created new tag without the 'v' prefix in the workflow.
            echo "NEW_TAG=$NEXT_TAG" >> $GITHUB_ENV
          fi


      - name: Set up Cloud SDK
        uses: google-github-actions/[email protected]
        with:
          version: 'latest'
          service_account_email: ${{ secrets.GCP_SA_EMAIL }}
          service_account_key: ${{ secrets.GCP_SA_KEY }}
          project_id: ${{ env.PROJECT_ID }}
          export_default_credentials: true

      - name: Login to GCR
        uses: docker/login-action@v3
        with:
          registry: gcr.io
          username: _json_key
          password: ${{ secrets.GCP_SA_KEY}}

      - name: Setup Project 
        run: |
          gcloud auth configure-docker ${GCR_REGISTRY}

      - name: Build  image Build and Tag
        run: |
          DOCKER_BUILDKIT=0
          docker build -t ${GCR_REGISTRY}/${{ secrets.GCP_PROJECT_ID }}/${GCR_IMAGE}/helloworld:${{ env.NEW_TAG }} .

               
      - name: Docker Push to Google Registry
        run: |
          docker push ${GCR_REGISTRY}/${{ secrets.GCP_PROJECT_ID }}/${GCR_IMAGE}/helloworld:${{ env.NEW_TAG }}

      - name: Deploying Cloud Run with Latest image
        run: |
          gcloud run deploy helloworld \
          --region ${GCR_REGION} \
          --image ${GCR_REGISTRY}/${{ secrets.GCP_PROJECT_ID }}/${GCR_IMAGE}/helloworld:${{ env.NEW_TAG }} \
          --platform managed \
          --allow-unauthenticated \
          --project ${{ secrets.GCP_PROJECT_ID }}

        

Alright, let's break down this GitHub Actions workflow into an easy-to-understand explanation:

  • The Trigger: Just by pushing your code to GitHub, you activate the GitHub Actions.
  • Preparing the Environment: It sets up a workspace on an Ubuntu virtual machine to get the job done.
  • Getting the Code: The workflow grabs the latest version of your website's code.
  • Accessing Cloud Services: It securely logs in to Google Cloud with special access credentials, ensuring that only your workflow can make changes to your site.
  • Building the Image: Your code is packed into a Docker image, which is like a blueprint for your website that can be replicated exactly anywhere.
  • Storing the Blueprint: This image is then uploaded to Google's storage, ready to be used.
  • Going Live: Finally, the workflow sends a command to Cloud Run to update your website with this new blueprint, which is now ready for visitors.

How is Authentication of GitHub Action and GCP Working?

The diagram you're looking at represents a secure handshake between GitHub and Google Cloud to make sure that updates or deployments are done safely and automatically. When you trigger a GitHub Actions workflow, GitHub confirms its identity to Google Cloud using what's called an OIDC provider. Google Cloud then checks this identity and, if everything looks good, it gives GitHub a temporary pass — sort of like a VIP badge — that lets GitHub access your cloud resources. This badge is only good for the job at hand and expires right after, keeping your cloud resources secure.

Authentication

Creating a Service Account

The GitHub runner operates in their own data center, so we need to authenticate the calls to our GCP project. GitHub also provides the capability to have the actions running within your own environment, but that will be a topic for another post. To achieve this, we will create a Service Account and add the keys to the GitHub Secrets section.

  • In the Cloud Console, go to the Service Accounts page.
  • Click 'Select a project,' choose your project, and click 'Open.'
  • Click 'Create Service Account.'
  • Enter a service account name—we will use 'github-action-deploy.'

Save it.

In the next page, click on the service account name and click on Add Key

Click on Create a new key and leave it to the JSON format and click create. You should download a JSON key.

Add the Service Account credentials to GitHub

  1. On your GitHub repository page, navigate to “Settings” and then to “Secrets.” The values you add here will function as environment variables within the GitHub Action.
  2. Click on “New secret” and name it GCP_SA_KEY. Then, paste the content of the service account key you previously downloaded into the value section.
  3. Click on “New secret” again and add the name GCP_SA_EMAIL. Paste the service account email you just created into the value section.
  4. Lastly, to keep your GCP project ID secure and not exposed within your code, click on “New secret” one more time and add the name GCP_PROJECT_ID. Copy and paste the project ID from your GCP Console into the value section.

You will also need to enable the Cloud Run API and Container Registry API:

  1. Go to the Cloud Console API Library.
  2. From the projects list, select the project you want to use.
  3. In the API Library, select the Cloud Run API
  4. On the API page, click ENABLE.
  5. Select Container Registry API
  6. Click ENABLE

Now, once you have configured the GitHub secrets and Google Cloud API connections, the next step is to create the Google Cloud Registry. You can create it manually and pass the value to the GitHub Action workflow. You can manually trigger the GitHub action, and it will first create a new version tag, then log in to GCR using your service connection authentication, set your registry, build and tag your registry image with the latest tag, and then push it to GCR images. Finally, you can deploy the image to Cloud Run. Once you receive the following output, it means your Cloud Run is up and running, and whenever a change is made to GitHub, it will automatically be pushed to Cloud Run. The next step is to lock the main/master branch and restrict developers from pushing changes directly. Instead, they should create a pull request, and after review, you can merge it to the master and deploy your code to the Cloud Run. You can also set up different environments, i.e., Dev, QA, and Production, and set up your Cloud Run environment accordingly. Here is the final output from the GitHub actions:

Here you can see the website version is up and running


Clean UP

  1. Delete your Cloud Run instance.
  2. Remove the Service Account IAM permissions.
  3. Delete the Service Account.
  4. Delete the Image from the registry.
  5. Delete your GitHub Repo if you don’t need it anymore.
  6. Delete the project in case you will not use it anymore.

So…

You could see the GitHub Actions integrates smoothly with GCP. You also have an option to use your own runner inside your own environment if you are concern about security and data on someone's server.

Cloud Run is pretty straight forward as well, and I do recommend you have a try if serverless is an option for you — and you don’t want to care about servers.

You can also see a fully working version on GitHub : https://github.com/GDGCloudLahore/cloud-run-sample

Please feel free to comment and let me know if you have any questions.

References

https://cloud.google.com/run/docs/quickstarts/build-and-deploy

https://docs.github.com/en/actions/getting-started-with-github-actions

https://cloud.google.com/resource-manager/docs/creating-managing-projects



要查看或添加评论,请登录

GDG Cloud Lahore的更多文章

社区洞察

其他会员也浏览了