管理者設定 - 継続的インテグレーション

[管理] メニューの [プラットフォーム] セクションにある [継続的インテグレーション] ページでは、Looker の継続的インテグレーション(CI)機能の設定を構成できます。LookML プロジェクトの品質と信頼性を確保するために、Looker(Google Cloud コア)CI 設定を構成します。CI は、クエリエラーを防ぎ、SQL、データテスト、コンテンツ、LookML の問題を本番環境に到達する前に特定します。また、LookML リポジトリに pull リクエストが送信されたときに CI バリデータが自動的に実行されるように構成して、開発ワークフローを効率化することもできます。

継続的インテグレーションのコンプライアンス機能

Looker CI は、FedRAMP High、FedRAMP Moderate、DoD 影響レベル 5(IL5)の認可境界に含まれていません。

Looker インスタンスで Looker CI 設定を有効にする前に、認証機関に相談して、Looker CI のコンプライアンス オファリングが組織固有のセキュリティ要件と規制要件を満たしているかどうかを確認してください。

Looker(Google Cloud コア)インスタンスの場合、利用可能になる各 Assured Workloads コントロール パッケージは、そのパッケージの変更要件とプロセスが満たされると、Looker CI 機能をデフォルトのサービスとして追加します。

継続的インテグレーションを有効にする

Looker の継続的インテグレーション(CI)機能を使用すると、LookML プロジェクトでテストを実行して、より信頼性が高く、効率的で、ユーザーフレンドリーなデータ エクスペリエンスを提供できます。CI バリデータを使用すると、SQL、データテスト、コンテンツ、LookML の問題を本番環境に移行する前に特定し、LookML を検証して、ユーザーのクエリエラーを防ぐことができます。また、LookML リポジトリへの スケジュールまたは pull リクエストの送信時に自動的に実行されるように CI バリデータを設定することもできます。

Looker 管理者は、[継続的インテグレーションを有効にする] 切り替えを使用して、インスタンスで CI を有効にできます。

Looker CI ユーザー

インスタンスで継続的インテグレーションを有効にすると、Looker は Looker CI ユーザーロールを持つ 10 人の Looker CI ユーザーを Looker CI ユーザー ユーザー グループに自動的に作成します。Looker 管理者は、[ユーザー] 管理ページの [サービス アカウント] タブで Looker CI ユーザーを表示できます。

インスタンスで アクセス権付与を使用して Explore へのアクセスを制御している場合、Looker CI ユーザーはこれらのアクセス権付与に含まれている必要があります。管理者設定 - ユーザー属性のドキュメント ページで説明されているように、関連するユーザー属性の値を Looker CI ユーザー グループに割り当てることで、CI ユーザーを含めることができます。

統合

継続的インテグレーションを使用すると、リモート Git リポジトリで pull リクエストや commit が発生したときに、CI スイートを自動的に実行できます。継続的インテグレーションを構成して、次の Git プロバイダと統合できます。

  • GitHub(Looker CI GitHub アプリを使用)
  • GitLab(Looker API と GitLab CI を使用)
  • Bitbucket(Looker API と Bitbucket Pipelines を使用)
  • GitHub Actions(Looker API と GitHub Actions を使用)

GitHub

LookML プロジェクトのリモート リポジトリとしてクラウドベースの GitHub リポジトリがある場合は、LookML デベロッパーが LookML リポジトリに pull リクエストを送信したときに CI スイートを自動的に実行するように継続的インテグレーションを構成できます。

Private Service Connect でプライベート接続またはハイブリッド接続を使用する Looker(Google Cloud コア)インスタンス、または VPC Service Controls 境界内のインスタンスの場合、ネットワーキング構成で GitHub との間で送受信されるトラフィックを許可する必要があります。ほとんどの場合、Looker(Google Cloud コア)インスタンスを構成して GitHub に接続するときに、このネットワーク構成はすでに設定されています。アウトバウンド接続の構成の詳細については、Private Service Connect を使用した外部サービスへの Looker(Google Cloud コア)アウトバウンド アクセスのドキュメント ページをご覧ください。

リポジトリで CI スイートを自動的に実行するには、継続的インテグレーションに次の権限が必要です。

  • リポジトリのメタデータと pull リクエストに対する読み取りアクセス権
  • リポジトリのコミット ステータス、リポジトリフック、ワークフローに対する読み取り / 書き込みアクセス権

これらの権限は、Looker IDE で LookML プロジェクトの Git 接続を設定するときには設定されません。CI 実行に pull リクエスト トリガーを使用する場合は、LookML プロジェクトを Git 接続で設定する必要があります(Git 接続の設定とテストのページを参照)。また、CI GitHub アプリの構成セクションの説明に従って CI GitHub アプリを構成する必要があります。

GitHub の表

[継続的インテグレーション] 管理ページの [GitHub] テーブルには、Looker インスタンスの LookML プロジェクト用に構成されている GitHub リポジトリが一覧表示されます。これらの GitHub リポジトリは、Git 接続の設定とテストのドキュメント ページで説明されているように、LookML デベロッパーによって構成されています。

リストされている各 GitHub リポジトリについて、リポジトリが CI GitHub アプリで構成されているかどうかが表に示されます。

CI GitHub アプリを構成する

リポジトリの CI GitHub アプリケーションを付与する手順は次のとおりです。

  1. Looker の [継続的インテグレーション] 管理ページで、[GitHub アプリを構成] ボタンをクリックします。ブラウザ ウィンドウが開き、GitHub アプリのウェブページが表示されます。
  2. LookML が保存されている GitHub アカウントを選択します。
  3. [リポジトリへのアクセス] セクションで、[すべてのリポジトリ] を選択して、リソース所有者が所有するすべての Git リポジトリで CI 統合を許可するか、[選択したリポジトリのみ] を選択して、継続的インテグレーションで使用するリポジトリを選択します。
  4. [保存] をクリックします。

Looker CI GitHub アプリケーションがリポジトリに正常に付与されると、Looker の [継続的インテグレーション] 管理ページの GitHub テーブルで、リポジトリのステータスが [インストール済み] と表示されます。

GitLab

Looker API と公式の Looker Python SDK(looker-sdk)を使用して、GitLab CI から Looker の継続的インテグレーション実行をトリガーできます。

GitLab CI パイプラインから Looker CI 実行をトリガーするには、次の手順を行います。

  1. GitLab で CI/CD 変数を構成します
  2. GitLab CI 用の Python スクリプトを作成します
  3. GitLab CI ワークフローを構成します

GitLab で CI/CD 変数を構成する

GitLab プロジェクトで、[Settings] > [CI/CD] > [Variables] に移動し、次の CI/CD 変数を作成します。機密性の高い値を保護するため、各変数を [マスク済み] に設定します。

  • LOOKERSDK_BASE_URL: Looker インスタンスの API URL(例: https://example.cloud.looker.com
  • LOOKERSDK_CLIENT_ID: Looker の [Users] 管理ページで生成された API3 クライアント ID
  • LOOKERSDK_CLIENT_SECRET: Looker の [Users] 管理ページから生成された対応する API3 クライアント シークレット

GitLab CI 用の Python スクリプトを作成する

リポジトリに run_looker_ci.py という名前の Python スクリプトを作成します。このスクリプトは、Looker SDK を使用して CI 実行をトリガーし、実行が完了するまでポーリングします。

import os
import sys
import time
import looker_sdk
from looker_sdk import models as mdls

# Retrieve required settings from environment variables
project_id = os.getenv("LOOKER_PROJECT_ID")
suite_id = os.getenv("LOOKER_SUITE_ID")

# GitLab CI specific environment variables
branch = os.getenv("CI_COMMIT_REF_NAME")
commit = os.getenv("CI_COMMIT_SHA")

if not all([project_id, suite_id, branch, commit]):
    print("Error: Missing required environment variables (LOOKER_PROJECT_ID, LOOKER_SUITE_ID, or GitLab vars).")
    sys.exit(1)

# Initialize the Looker SDK.
# The SDK automatically picks up LOOKERSDK_BASE_URL, LOOKERSDK_CLIENT_ID, and LOOKERSDK_CLIENT_SECRET.
print("Initializing Looker SDK...")
try:
    sdk = looker_sdk.init40()
except Exception as e:
    print(f"Failed to initialize Looker SDK: {e}")
    sys.exit(1)

# Configure the request body
print(f"Starting Looker CI run for project '{project_id}', suite '{suite_id}'...")
print(f"Branch: {branch} | Commit: {commit}")

request_body = mdls.CreateContinuousIntegrationRunRequest(
    suite_id=suite_id,
    branch=branch,
    commit=commit
)

# Trigger the CI run
try:
    run = sdk.create_continuous_integration_run(
        project_id=project_id,
        body=request_body
    )
    run_id = getattr(run, "run_id", getattr(run, "id", None))
    print(f"Looker CI run created successfully. Run ID: {run_id}")
except looker_sdk.error.SDKError as e:
    print(f"Failed to create Looker CI run: {e}")
    sys.exit(1)

# Poll for completion
run_status = run.status
terminal_statuses = ["cancelled", "error", "passed", "failed"]

while run_status not in terminal_statuses:
    print(f"Run {run_id} status is '{run_status}'. Waiting 15 seconds...")
    time.sleep(15)
    
    try:
        run = sdk.get_continuous_integration_run(
            project_id=project_id,
            run_id=run_id
        )
        run_status = run.status
    except looker_sdk.error.SDKError as e:
        print(f"Error while polling Looker CI run status: {e}")
        sys.exit(1)

print(f"Final Looker CI run status: {run_status}")

if run_status != "passed":
    print("Looker CI run did not pass. Failing the GitLab CI job.")
    sys.exit(1)

print("Looker CI run passed successfully!")

GitLab CI ワークフローを構成する

リポジトリのルート ディレクトリで、looker-sdk をインストールして run_looker_ci.py を実行するように .gitlab-ci.yml パイプライン構成ファイルを作成または更新します。

stages:
  - test

looker-ci:
  stage: test
  image: python:3.10
  variables:
    LOOKER_PROJECT_ID: "LOOKER_PROJECT_ID"
    LOOKER_SUITE_ID: "LOOKER_SUITE_ID"
  script:
    - pip install looker-sdk
    - python run_looker_ci.py
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

次のように置き換えます。

  • LOOKER_PROJECT_ID: テストする Looker プロジェクトの ID
  • LOOKER_SUITE_ID: 実行する CI スイートの ID

Bitbucket

Looker API と公式の Looker Python SDK(looker-sdk)を使用すると、Bitbucket Pipelines から Looker の継続的インテグレーション実行をトリガーできます。

Bitbucket Pipelines から Looker CI 実行をトリガーするには、次の手順を行います。

  1. Bitbucket でリポジトリ変数を構成します
  2. Bitbucket Pipelines 用の Python スクリプトを作成します
  3. Bitbucket Pipelines ワークフローを構成します

Bitbucket でリポジトリ変数を構成する

Bitbucket リポジトリで、[リポジトリ設定] > [リポジトリ変数] に移動し、次のリポジトリ変数を作成します。機密性の高い値を保護するため、各変数を [Secured] に設定します。

  • LOOKERSDK_BASE_URL: Looker インスタンスの API URL(例: https://example.cloud.looker.com
  • LOOKERSDK_CLIENT_ID: Looker の [Users] 管理ページで生成された API3 クライアント ID
  • LOOKERSDK_CLIENT_SECRET: Looker の [ユーザー] 管理ページから生成された対応する API3 クライアント シークレット

Bitbucket Pipelines 用の Python スクリプトを作成する

リポジトリに run_looker_ci.py という名前の Python スクリプトを作成します。このスクリプトは、Looker SDK を使用して CI 実行をトリガーし、実行が完了するまでポーリングします。

import os
import sys
import time
import looker_sdk
from looker_sdk import models as mdls

# Retrieve required settings from environment variables
project_id = os.getenv("LOOKER_PROJECT_ID")
suite_id = os.getenv("LOOKER_SUITE_ID")

# Bitbucket Pipelines specific environment variables
branch = os.getenv("BITBUCKET_BRANCH")
commit = os.getenv("BITBUCKET_COMMIT")

if not all([project_id, suite_id, branch, commit]):
    print("Error: Missing required environment variables (LOOKER_PROJECT_ID, LOOKER_SUITE_ID, or Bitbucket vars).")
    sys.exit(1)

# Initialize the Looker SDK.
# The SDK automatically picks up LOOKERSDK_BASE_URL, LOOKERSDK_CLIENT_ID, and LOOKERSDK_CLIENT_SECRET.
print("Initializing Looker SDK...")
try:
    sdk = looker_sdk.init40()
except Exception as e:
    print(f"Failed to initialize Looker SDK: {e}")
    sys.exit(1)

# Configure the request body
print(f"Starting Looker CI run for project '{project_id}', suite '{suite_id}'...")
print(f"Branch: {branch} | Commit: {commit}")

request_body = mdls.CreateContinuousIntegrationRunRequest(
    suite_id=suite_id,
    branch=branch,
    commit=commit
)

# Trigger the CI run
try:
    run = sdk.create_continuous_integration_run(
        project_id=project_id,
        body=request_body
    )
    run_id = getattr(run, "run_id", getattr(run, "id", None))
    print(f"Looker CI run created successfully. Run ID: {run_id}")
except looker_sdk.error.SDKError as e:
    print(f"Failed to create Looker CI run: {e}")
    sys.exit(1)

# Poll for completion
run_status = run.status
terminal_statuses = ["cancelled", "error", "passed", "failed"]

while run_status not in terminal_statuses:
    print(f"Run {run_id} status is '{run_status}'. Waiting 15 seconds...")
    time.sleep(15)
    
    try:
        run = sdk.get_continuous_integration_run(
            project_id=project_id,
            run_id=run_id
        )
        run_status = run.status
    except looker_sdk.error.SDKError as e:
        print(f"Error while polling Looker CI run status: {e}")
        sys.exit(1)

print(f"Final Looker CI run status: {run_status}")

if run_status != "passed":
    print("Looker CI run did not pass. Failing the Bitbucket Pipeline.")
    sys.exit(1)

print("Looker CI run passed successfully!")

Bitbucket Pipelines ワークフローを構成する

リポジトリのルート ディレクトリで、looker-sdk をインストールして run_looker_ci.py を実行するように bitbucket-pipelines.yml ファイルを作成または更新します。

image: python:3.10

pipelines:
  pull-requests:
    '**':
      - step:
          name: Looker CI
          script:
            - export LOOKER_PROJECT_ID="LOOKER_PROJECT_ID"
            - export LOOKER_SUITE_ID="LOOKER_SUITE_ID"
            - pip install looker-sdk
            - python run_looker_ci.py

次のように置き換えます。

  • LOOKER_PROJECT_ID: テストする Looker プロジェクトの ID
  • LOOKER_SUITE_ID: 実行する CI スイートの ID

GitHub Actions

Looker API と公式の Looker Python SDK(looker-sdk)を使用して、GitHub Actions から Looker の継続的インテグレーション実行をトリガーできます。

GitHub Actions ワークフローから Looker CI 実行をトリガーする手順は次のとおりです。

  1. GitHub でリポジトリ シークレットを構成します
  2. GitHub Actions 用の Python スクリプトを作成します
  3. GitHub Actions ワークフローを構成します

GitHub でリポジトリ シークレットを構成する

GitHub リポジトリで、[Settings] > [Secrets and variables] > [Actions] に移動し、次のリポジトリ シークレットを作成します。

  • LOOKERSDK_BASE_URL: Looker インスタンスの API URL(例: https://example.cloud.looker.com
  • LOOKERSDK_CLIENT_ID: Looker の [Users] 管理ページで生成された API3 クライアント ID
  • LOOKERSDK_CLIENT_SECRET: Looker の [ユーザー] 管理ページから生成された対応する API3 クライアント シークレット

GitHub Actions 用の Python スクリプトを作成する

リポジトリに run_looker_ci.py という名前の Python スクリプトを作成します。このスクリプトは、Looker SDK を使用して CI 実行をトリガーし、実行が完了するまでポーリングします。

import os
import sys
import time
import looker_sdk
from looker_sdk import models as mdls

# Retrieve required settings from environment variables
project_id = os.getenv("LOOKER_PROJECT_ID")
suite_id = os.getenv("LOOKER_SUITE_ID")

# GitHub Actions specific environment variables
# GITHUB_HEAD_REF is the branch name for PRs. 
# GITHUB_REF_NAME can be used as a fallback for non-PR events.
branch = os.getenv("GITHUB_HEAD_REF") or os.getenv("GITHUB_REF_NAME")
# GITHUB_PR_SHA is the head commit SHA for PRs.
# GITHUB_SHA can be used as a fallback for non-PR events.
commit = os.getenv("GITHUB_PR_SHA") or os.getenv("GITHUB_SHA")

if not all([project_id, suite_id, branch, commit]):
    print("Error: Missing required environment variables (LOOKER_PROJECT_ID, LOOKER_SUITE_ID, or GitHub vars).")
    sys.exit(1)

# Initialize the Looker SDK.
# The SDK automatically picks up LOOKERSDK_BASE_URL, LOOKERSDK_CLIENT_ID, and LOOKERSDK_CLIENT_SECRET.
print("Initializing Looker SDK...")
try:
    sdk = looker_sdk.init40()
except Exception as e:
    print(f"Failed to initialize Looker SDK: {e}")
    sys.exit(1)

# Configure the request body
print(f"Starting Looker CI run for project '{project_id}', suite '{suite_id}'...")
print(f"Branch: {branch} | Commit: {commit}")

request_body = mdls.CreateContinuousIntegrationRunRequest(
    suite_id=suite_id,
    branch=branch,
    commit=commit
)

# Trigger the CI run
try:
    run = sdk.create_continuous_integration_run(
        project_id=project_id,
        body=request_body
    )
    run_id = getattr(run, "run_id", getattr(run, "id", None))
    print(f"Looker CI run created successfully. Run ID: {run_id}")
except looker_sdk.error.SDKError as e:
    print(f"Failed to create Looker CI run: {e}")
    sys.exit(1)

# Poll for completion
run_status = run.status
terminal_statuses = ["cancelled", "error", "passed", "failed"]

while run_status not in terminal_statuses:
    print(f"Run {run_id} status is '{run_status}'. Waiting 15 seconds...")
    time.sleep(15)
    
    try:
        run = sdk.get_continuous_integration_run(
            project_id=project_id,
            run_id=run_id
        )
        run_status = run.status
    except looker_sdk.error.SDKError as e:
        print(f"Error while polling Looker CI run status: {e}")
        sys.exit(1)

print(f"Final Looker CI run status: {run_status}")

if run_status != "passed":
    print("Looker CI run did not pass. Failing the GitHub Action.")
    sys.exit(1)

print("Looker CI run passed successfully!")

GitHub Actions ワークフローを構成する

リポジトリで、次の構成を使用して .github/workflows/looker-ci.yml にワークフロー ファイルを作成します。

name: Looker CI
on:
  pull_request:
    branches:
      - main

jobs:
  run-looker-ci:
    runs-on: ubuntu-latest


    env:
      # Automatically picked up by the Looker SDK
      LOOKERSDK_BASE_URL: ${{ secrets.LOOKERSDK_BASE_URL }}
      LOOKERSDK_CLIENT_ID: ${{ secrets.LOOKERSDK_CLIENT_ID }}
      LOOKERSDK_CLIENT_SECRET: ${{ secrets.LOOKERSDK_CLIENT_SECRET }}


      # Passed directly to the script
      LOOKER_PROJECT_ID: "LOOKER_PROJECT_ID"
      LOOKER_SUITE_ID: "LOOKER_SUITE_ID"
      GITHUB_PR_SHA: ${{ github.event.pull_request.head.sha }}

    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.10'

      - name: Install Dependencies
        run: |
          python -m pip install --upgrade pip
          pip install looker-sdk

      - name: Run Looker CI
        run: python run_looker_ci.py

次のように置き換えます。

  • LOOKER_PROJECT_ID: テストする Looker プロジェクトの ID
  • LOOKER_SUITE_ID: 実行する CI スイートの ID

dbt Cloud の構成

dbt Cloud を使用している場合は、dbt Cloud CI ジョブが完了したときに CI スイートを自動的に実行するように継続的インテグレーションを構成できます。CI スイートを実行すると、dbt モデルの変更によって LookML プロジェクトが破損しないようにすることができます。

dbt Cloud インテグレーションを構成するには、[dbt Cloud の構成] セクションで次の手順を行います。

  1. [dbt Cloud ホスト URL] フィールドに、dbt Cloud アカウントの URL を入力します。
  2. [dbt Cloud API Key] フィールドに、dbt Cloud サービス アカウント トークンを入力します。
  3. [Test Connection] をクリックします。Looker は、dbt Cloud アカウントに接続できることを確認し、dbt Cloud アカウント ID を取得します。
  4. [保存] をクリックします。

ユーザー属性

継続的インテグレーションで検証実行中にオーバーライドできるユーザー属性を構成できます。ユーザー属性は、dbt Cloud インテグレーションと組み合わせて使用され、Looker が dbt Cloud CI ジョブによって作成された一時スキーマを指すようにします。

CI のユーザー属性のデフォルトを構成するには、[ユーザー属性] セクションで次の手順を行います。

  1. [ユーザー属性] フィールドで、プルダウン リストからユーザー属性を選択します。ユーザー属性が選択されていない場合、Looker は CI 実行用にデータベース接続の [プライマリ データセット] フィールドで定義されているユーザー属性を使用します。
  2. [CI 実行の値] フィールドに、CI 実行でこのユーザー属性に使用する値を入力します。
  3. [保存] をクリックします。

複数のユーザー属性と値のペアを追加できます。[ユーザー属性] セクションで構成された各ユーザー属性は、CI Suite 構成でオーバーライドとして選択できます。

ユーザー属性と値のペアを削除するには、[削除] をクリックします。