Vertex DevOps
Tip
Add code provided in this page is available in the repo example.
💻 Dev: Compile and run to fasten your dev cycle
When developing a vertex pipeline locally, you may want to iterate quickly. The process is often the following:
- write new code and test its integration in the pipeline workflow code in a notebook
- script this new code in vertex/lib/
- modify associated component(s) in vertex/componentsand pipelines invertex/pipelines
- run the pipeline with dev settings to test the new code on Vertex
The latest may include:
- rebuilding the base image
- compiling the pipeline
- running the pipeline
Build base image
You can use this generic Dockerfile:
FROM python:3.10-slim-buster
ARG PROJECT_ID
ENV PROJECT_ID=${PROJECT_ID}
COPY requirements.txt .
RUN python3 -m pip install --upgrade pip
RUN python3 -m pip install -r requirements.txt
COPY vertex .
ENV PYTHONPATH "${PYTHONPATH}:."
Then build it with docker or Cloud Build. For the latest, here is a sample cloudbuild.yaml:
# This config file is meant to be used from a local dev machine to submit a vertex base image build to Cloud Build.
# This generic image will then be used in all the Vertex components of your pipeline.
steps:
  # Build base image
  - name: 'gcr.io/cloud-builders/docker'
    args: [
      'build',
      '-t', '${_GAR_IMAGE_PATH}',
      '-f', 'vertex/deployment/Dockerfile',
      '--build-arg', 'PROJECT_ID=${PROJECT_ID}',
      '--build-arg', 'GCP_REGION=${_GCP_REGION}',
      '--build-arg', 'GAR_LOCATION=${_GAR_LOCATION}',
      '--build-arg', 'GAR_PIPELINES_REPO_ID=${_GAR_PIPELINES_REPO_ID}',
      '--build-arg', 'VERTEX_STAGING_BUCKET_NAME=${_VERTEX_STAGING_BUCKET_NAME}',
      '--build-arg', 'VERTEX_SERVICE_ACCOUNT=${_VERTEX_SERVICE_ACCOUNT}',
      '.',
    ]
    id: build-base-image
substitutions:
  _GAR_IMAGE_PATH: '${_GAR_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${_GAR_DOCKER_REPO_ID}/${_GAR_VERTEX_BASE_IMAGE_NAME}:${_TAG}'
  _GCP_REGION: '${GCP_REGION}'
  _GAR_PIPELINES_REPO_ID: '${GAR_PIPELINES_REPO_ID}'
  _VERTEX_STAGING_BUCKET_NAME: '${VERTEX_STAGING_BUCKET_NAME}'
  _VERTEX_SERVICE_ACCOUNT: '${VERTEX_SERVICE_ACCOUNT}'
options:
  logging: CLOUD_LOGGING_ONLY
  dynamic_substitutions: true
images:
- '${_GAR_IMAGE_PATH}'
tags:
  - vertex-${_GAR_DOCKER_REPO_ID}-base-image-local-${_TAG}
Then you can trigger the build manually using this make command:
export $(cat .env | xargs)
make build-base-image
This command includes the following:
.PHONY: build-base-image
build-base-image:
    @gcloud builds submit --config ./vertex/deployment/cloudbuild_local.yaml \
    --substitutions=_GCP_REGION=${GCP_REGION},_GAR_LOCATION=${GAR_LOCATION},_GAR_DOCKER_REPO_ID=${GAR_DOCKER_REPO_ID},_GAR_VERTEX_BASE_IMAGE_NAME=${GAR_VERTEX_BASE_IMAGE_NAME},_TAG=${TAG},_GAR_PIPELINES_REPO_ID=${GAR_PIPELINES_REPO_ID},_VERTEX_STAGING_BUCKET_NAME=${VERTEX_STAGING_BUCKET_NAME},_VERTEX_SERVICE_ACCOUNT=${VERTEX_SERVICE_ACCOUNT}
Compile and run
Now that you have a base image, you can compile your pipeline and trigger a run that will use the latest version of your docker base image
vertex-deployer deploy --compile --run --env-file .env --config-name my_config.json --skip-validation
✅ CI: Check your pipelines and config integrity
Check your pipelines locally
You can check pipelines integrity and config integrity using the following command:
vertex-deployer check --all
To check a specific pipeline:
vertex-deployer check my_pipeline
Add to CI
You can add a github workflow checking your pipelines integrity using the following file:
name: Check pipelines
on:
  pull_request:
    branches:
      - '*'
  workflow_call:
env:
  PYTHON_VERSION: "3.10"
jobs:
  check-pipelines:
    name: Check Vertex Pipelines
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ env.PYTHON_VERSION }}
          cache: 'pip'
      - name: Install requirements
        run: |
          python3 -m pip install -r requirements.txt
      - name: Check pipelines
        run: |
          export PYTHONPATH=.
          vertex-deployer check --all
Add to pre-commit hooks
You can add a pre-commit hook checking your pipelines integrity using a local hook:
repos:
  - repo: local
    hooks:
    - id: vertex-deployer-check
      name: check pipelines
      entry: vertex-deployer check -a
      pass_filenames: false
      language: system
🚀 CD: Deploy your pipelines in a standardized manner
Once you have a valid pipeline, you want to deploy it on Vertex. To automate deployment when merging to develop or main, you have multiple options.
- use CloudBuild and CloudBuild triggers
- use Github Action to trigger CloudBuild job
- 🚧 use Github Action only
Note
To use cloudbuild for CD, please update you Dockerfile with all these arguments.
This will allow you to use vertex-deployer from your base image in CloudBuild.
FROM python:3.10-slim-buster
ARG PROJECT_ID
ARG GCP_REGION
ARG GAR_LOCATION
ARG GAR_PIPELINES_REPO_ID
ARG VERTEX_STAGING_BUCKET_NAME
ARG VERTEX_SERVICE_ACCOUNT
ENV PROJECT_ID=${PROJECT_ID}
ENV GCP_REGION=${GCP_REGION}
ENV GAR_LOCATION=${GAR_LOCATION}
ENV GAR_PIPELINES_REPO_ID=${GAR_PIPELINES_REPO_ID}
ENV VERTEX_STAGING_BUCKET_NAME=${VERTEX_STAGING_BUCKET_NAME}
ENV VERTEX_SERVICE_ACCOUNT=${VERTEX_SERVICE_ACCOUNT}
COPY requirements.txt .
RUN python3 -m pip install --upgrade pip
RUN python3 -m pip install -r requirements.txt
COPY vertex .
ENV PYTHONPATH "${PYTHONPATH}:."
CloudBuild
You can use the following cloudbuild.yaml to trigger a deployment on Vertex when merging to develop or main:
steps:
  # Build base image
  - name: 'gcr.io/cloud-builders/docker'
    args: [
      'build',
      '-t', '${_GAR_IMAGE_PATH}',
      '-f', 'vertex/deployment/Dockerfile',
      '--build-arg', 'PROJECT_ID=${PROJECT_ID}',
      '--build-arg', 'GCP_REGION=${_GCP_REGION}',
      '--build-arg', 'GAR_LOCATION=${_GAR_LOCATION}',
      '--build-arg', 'GAR_PIPELINES_REPO_ID=${_GAR_PIPELINES_REPO_ID}',
      '--build-arg', 'VERTEX_STAGING_BUCKET_NAME=${_VERTEX_STAGING_BUCKET_NAME}',
      '--build-arg', 'VERTEX_SERVICE_ACCOUNT=${_VERTEX_SERVICE_ACCOUNT}',
      '.',
    ]
    id: build-base-image
  # schedule pipeline: compile, upload, schedule
  - name: '${_GAR_IMAGE_PATH}'
    entrypoint: 'bash'
    args:
      - '-c'
      - |
        vertex-deployer -log DEBUG deploy dummy_pipeline \
          --compile \
          --upload \
          --run \
          --enable-caching \
          --config-name config_test.json \
          --tags ${_TAG} \
          --schedule --delete-last-schedule --cron '*-*-19-*-*'
    dir: '.'
    id: schedule-dummy-pipeline
    waitFor: ['build-base-image']
substitutions:
  _GAR_IMAGE_PATH: '${_GAR_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${_GAR_DOCKER_REPO_ID}/${_GAR_VERTEX_BASE_IMAGE_NAME}:${_TAG}'
options:
  logging: CLOUD_LOGGING_ONLY
  dynamic_substitutions: true
images:
- '${_GAR_IMAGE_PATH}'
tags:
  - vertex-${_GAR_DOCKER_REPO_ID}-deployment-example-${_TAG}
Use CloudBuild trigger [PREFERRED OPTION]
Then, you'll need to link your repo to CloudBuild and create a trigger for each branch you want to deploy on Vertex. The documentation to link your repo is available here.
Then, you can create create a trigger using this make command:
export $(cat .env | xargs)
make create-trigger-cd
This command includes the following:
.PHONY: create-trigger-cd
create-trigger-cd:
    @gcloud builds triggers create github \
    --repo-owner="artefactory" \
    --repo-name="test-vertex-deployer" \
    --name="test-vertex-deployer-trigger" \
    --branch-pattern="main" \
    --build-config=./vertex/deployment/cloudbuild_cd.yaml \
    --project=${PROJECT_ID} \
    --substitutions=_GCP_REGION=${GCP_REGION},_GAR_LOCATION=${GAR_LOCATION},_GAR_DOCKER_REPO_ID=${GAR_DOCKER_REPO_ID},_GAR_VERTEX_BASE_IMAGE_NAME=${GAR_VERTEX_BASE_IMAGE_NAME},_TAG=${TAG},_GAR_PIPELINES_REPO_ID=${GAR_PIPELINES_REPO_ID},_VERTEX_STAGING_BUCKET_NAME=${VERTEX_STAGING_BUCKET_NAME},_VERTEX_SERVICE_ACCOUNT=${VERTEX_SERVICE_ACCOUNT}
Github Action + CloudBuild
You can also use Github Action to trigger CloudBuild job. You'll need to setup GCp authentication from your repo using Workload Identity Federation.
# This workflow deploys a pipeline to Vertex AI Pipelines.
#
# Workflow Steps:
#
# 1. Check pipelines and config integrity
# 2. Authenticate to Google Cloud using Workload Identity Federation (WIF)
# 3. Submit cloud build job to build docker image and deploy pipeline
#
# For more details on setting up Workload Identity Federation for GitHub, visit https://github.com/google-github-actions/auth#setting-up-workload-identity-federation
#
# Your WIF service account must have the following IAM roles:
# - roles/artifactregistry.writer
# - roles/storage.admin
# - roles/cloudbuild.builds.builder
name: Deploy pipelines
on:
  push:
    branches:
      - main
env:
  PYTHON_VERSION: "3.10"
  PROJECT_ID: "my-project"
  GCP_REGION: "europe-west1"
  TAG: "latest"
  # Google Artifact Registry
  GAR_LOCATION: "europe-west1"
  GAR_DOCKER_REPO_ID: "demo-docker"
  GAR_PIPELINES_REPO_ID: "test-pipelines"
  GAR_VERTEX_BASE_IMAGE_NAME: "base-image"
  # Vertex AI
  VERTEX_STAGING_BUCKET_NAME: "my-project-vertex-staging"
  VERTEX_SERVICE_ACCOUNT: "my-service-account@my-project.iam.gserviceaccount.com"
jobs:
  check-pipelines:
      name: Check Pipelines
      uses: ./.github/workflows/check_pipelines.yaml
  deploy-pipelines:
    name: Deploy pipelines
    needs: check-pipelines
    runs-on: ubuntu-latest
    concurrency: deploy-pipelines
    permissions:
      id-token: write
      contents: write
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0
    - name: Set up Python ${{ env.PYTHON_VERSION }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ env.PYTHON_VERSION }}
        cache: 'pip'
    - name: Install requirements
      run: |
        python3 -m pip install --upgrade pip
        python3 -m pip install -r requirements.txt
    - name: 'Authenticate to Google Cloud'
      uses: 'google-github-actions/auth@v1'
      with:
        token_format: 'access_token'
        workload_identity_provider: '${{ secrets.WIF_PROVIDER }}' # e.g. - projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider
        service_account: '${{ secrets.WIF_SERVICE_ACCOUNT }}' # e.g. - my-service-account@my-project.iam.gserviceaccount.com
    - name: Trigger Cloud Build
      run: |
        export PROJECT_ID=vertex-deployer-sandbox-3a8a
        make deploy-pipeline
🚧 Github Action only
Warning
This is a work in progress. Please use CloudBuild for CD. Docker build and push to GCR example is not yet implemented.