1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Googleサイトを利用して社内にダッシュボードを公開する

Posted at

はじめに

KCCS デジタルプラットフォーム部の林です。

Databricksでダッシュボードを公開する際の悩みとして、閲覧するユーザがワークスペースのアカウントを所持している必要があるということが挙げられます。
少人数であればワークスペースにアクセス権を付与すれば良いですが、人数が多くなってきたりアクセスするメンバーの入れ替わりが激しいと管理も大変です。

そういった悩みを解決するために「外部ユーザ向け埋め込み」という機能が提供されており、この機能を利用することでDatabricksのアカウントを持たないユーザにもダッシュボードを公開することができます。

今回はGoogleサイトを利用し、社内のユーザへダッシュボードを共有する方法を紹介します。

構成

フロントエンド:Googleサイト
Webアプリケーション:Google Apps Script(GAS)
ダッシュボード:AI/BIダッシュボード

フロントエンドとしてGoogleサイトを利用し、公開範囲を社内に限定します。
Databricksとの認証およびiframeの組み立てをGASで行い、Googleサイトで公開する形としています。

設定手順

サービスプリンシパルの作成と権限付与

サービスプリンシパル作成:
Databricksのコンソールより 設定 > IDとアクセス > サービスプリンシパル から作成します。
サービスプリンシパルが作成されたら詳細画面のシークレットタブよりシークレットの作成を行います。
シークレット作成時にシークレットの有効期限を入力するとシークレットが作成されるので、作成されたシークレットの値をコピーしておいてください。
※シークレットの値は一度ウインドウを閉じてしまうと再表示されないため注意

権限付与:
ダッシュボード: 「共有」設定 からサービスプリンシパルに 「実行可能」 権限を付与します。
SQL Warehouse: 使用するウェアハウスの 「権限」 でサービスプリンシパルに 「使用可能」 権限を付与します。

埋め込みダッシュボードの許可
コンソールより 設定 > セキュリティ の 外部アクセスにある 「埋め込みダッシュボード」 を設定します。
「許可」に設定すると全てのドメインで埋め込みが許可されますが、ドメインを制限したい場合は「承認済みドメインを許可」を選択し、アクセスを許可するドメインを追加します。
今回の場合は以下のドメインを追加します。
script.google.com, *.googleusercontent.com, sites.google.com

GASの作成

Googleドライブに接続し、「新規」から「Google Apps Script」を作成します。

プロジェクト名を入力し、コードを作成します。
なお、今回はわかりやすくするためにシークレット情報などを直接コードに記載していますが、本番利用する場合などはプロパティを利用して変数化するようにしましょう。

DB_HOSTにはワークスペースの接続先URL、CLIENT_IDとCLIENT_SECRETには先ほど作成したサービスプリンシパルのアプリケーションIDとシークレットの値を、DASHBOARD_IDとWORKSPACE_IDには公開するダッシュボードのIDとワークスペースのIDを入力します。
DASHBOARD_IDとWORKSPACE_IDがわからないという場合はダッシュボードの「共有」設定にある「< > ダッシュボードを埋め込む」の埋め込みコードに記載されていますので、そちらを確認してください。

GASのコード

const DB_HOST = "https://dbc-XXXX-XXXX.cloud.databricks.com";
const CLIENT_ID = "xxx... (アプリケーションIDを入力)";
const CLIENT_SECRET = "xxx... (シークレットの値を入力)";
const DASHBOARD_ID = "xxx... (ダッシュボードID)";
const WORKSPACE_ID = "xxx... (ワークスペースID)";

function doGet() {
  try {
    // --- 初期アクセストークンの取得 ---
    const tokenResponse = UrlFetchApp.fetch(`${DB_HOST}/oidc/v1/token`, {
      method: "post",
      payload: {
        grant_type: "client_credentials",
        client_id: CLIENT_ID,
        client_secret: CLIENT_SECRET,
        scope: "all-apis"
      }
    });
    const allApiToken = JSON.parse(tokenResponse.getContentText()).access_token;

    // --- 埋め込み用構成情報 の取得 ---
    const viewerId = "external_viewer_001"; // 任意の識別子
    const tokenInfoUrl = `${DB_HOST}/api/2.0/lakeview/dashboards/${DASHBOARD_ID}/published/tokeninfo?external_viewer_id=${viewerId}`;
    
    const infoResponse = UrlFetchApp.fetch(tokenInfoUrl, {
      method: "get",
      headers: { Authorization: `Bearer ${allApiToken}` }
    });
    const tokenInfo = JSON.parse(infoResponse.getContentText());

    // --- スコープ付きトークンの取得 ---
    const { authorization_details, ...otherParams } = tokenInfo;
    const basicAuth = Utilities.base64Encode(`${CLIENT_ID}:${CLIENT_SECRET}`);

    const scopedResponse = UrlFetchApp.fetch(`${DB_HOST}/oidc/v1/token`, {
      method: "post",
      headers: { 
        "Authorization": `Basic ${basicAuth}`,
        "Content-Type": "application/x-www-form-urlencoded"
      },
      payload: {
        grant_type: "client_credentials",
        ...otherParams,
        authorization_details: JSON.stringify(authorization_details)
      }
    });
    const embedToken = JSON.parse(scopedResponse.getContentText()).access_token;

    // --- URLの組み立て ---
    const embedUrl = `${DB_HOST}/embed/dashboardsv3/${DASHBOARD_ID}?o=${WORKSPACE_ID}&token=${embedToken}`;
    
    const html = `
      <!DOCTYPE html>
      <html>
      <head>
        <style>body { margin: 0; padding: 0; overflow: hidden; }</style>
      </head>
      <body>
        <iframe src="${embedUrl}" width="100%" height="100%" frameborder="0" 
                style="position:absolute;top:0;left:0;width:100%;height:100%;"></iframe>
      </body>
      </html>
    `;
    
    return HtmlService.createHtmlOutput(html)
      .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
      .setTitle("AI/BI Dashboard");

  } catch (e) {
    console.error(e.toString());
    return HtmlService.createHtmlOutput(`<b>認証エラー:</b><br>${e.message}`);
  }
}

アプリケーションデプロイ
コードが完成したらアプリケーションのデプロイを行います。
画面上部のデプロイボタンから「新しいデプロイ」を実行、デプロイタイプで「ウェブアプリ」を選択し、アクセスできるユーザを社内の全員に設定し、デプロイを行います。
※アクセス制限の範囲については自社のGoogleアカウントの設定に依存します

デプロイを実行するとデータへのアクセス許可が求められるため、アクセスの承認を行います。
デプロイが完了するとアクセス用のURLが発行されるので、コピーしておきます。

Googleサイト作成

Googleサイトのページを立ち上げ、挿入の「埋め込む」を選択します。
URLの入力欄が表示されるので、デプロイ時に表示されたGASのURLを入力します。

ページの作成が完了したら公開ボタンを実行し、サイトのアドレスと公開範囲を設定します。
サイトの公開が完了したら公開サイトのリンクをコピーしてブラウザからアクセスしてください。

最初にアクセスした際はアクセス権限を設定するページが表示されていますので、Googleアカウントのアクセス許可を付与します。
アクセス許可が完了するとダッシュボードが表示されます。

サンプルの NYC Taxi Trip Analysis を表示
スクリーン ショット 2026-01-15 に 15.26.13 午後.png

まとめ

Googleサイトを利用してDatabricksアカウントを持たない社内のユーザにダッシュボードを公開する方法を紹介しました。
多くのメンバーがダッシュボードへアクセスできるようになるので、社内でも活用していきたいと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?