JINSテックブログ
📌

煩雑なシステムライセンス管理を、API連携で解消する

に公開

この投稿は、2025年JINSのアドベントカレンダー3日目の記事です。

自己紹介

JINSでネットワークエンジニアをやっているh0ri0です。
データエンジニアとして入社しましたが、IT知識の幅を広げるためネットワークエンジニアに転身しました。
今回はネットワークの運用回りのライセンス管理をもっと楽にしたいなということで取り組んだことをご紹介します。

1. はじめに:なぜライセンス管理は大変なのか?

弊社はアイウェアの製造小売事業を主たる事業としていますが、グローバルに展開する中でその業務を支えるITインフラは多岐にわたります。その中でも、特にライセンス管理は、ITインフラ担当者にとって頭を悩ませる課題の一つです。

  • ライセンス枯渇のリスク: 新規のユーザーやデバイスが増加する際、ライセンスが意図せず枯渇してしまうと、業務の停滞やセキュリティリスクに直結します。
  • 管理の分散: 利用しているクラウドサービスやネットワークサービスごとに管理画面が分かれており、それぞれのシステムで状況を確認する必要があるため、手間がかかり、確認漏れが発生しやすい状況でした。

本記事では、この煩雑なライセンス管理を、Google Apps Script (GAS) を活用した API連携 によって一元化し、解消した取り組みをご紹介します。

2. 解決策の全体像と採用技術

複数のシステムに分散していたライセンス情報を一つの場所に集約し、可視化することを目標としました。
それぞれのシステムに都度ログインし確認するのが面倒だったのでそれを解消するのが目的です。
今回はCisco MerakiとCato Cloudを対象としました。

💡 解決策の全体像

  • データ取得: 各システムの API を利用し、ライセンス状況のJSONデータを取得します。
  • データ処理・集約: 取得したデータを Google Apps Script (GAS) で加工し、標準化します。
  • 可視化と予測: データを Google スプレッドシート に書き込み、グラフ化や関数による枯渇予測ダッシュボードを作成します。

🛠️ 採用技術

  • Googleスプレッドシート: 簡易的なデータベースとして機能し、グラフや関数によるダッシュボード構築が容易
  • Google App Script: Google Workspace環境との親和性が高く、UrlFetchAppによる外部API連携が容易

このアーキテクチャは、特別なサーバーや外部DBを用意する必要がなく、Google Workspace環境内で完結するため、迅速かつ追加コストなく実現できるのが最大のメリットです。

3. Cato Client / Meraki API連携の実装ステップ

実際にライセンス情報を取得するために使用した、GASコードの核となる部分をハイライトして紹介します。APIを利用するにあたって、各サービス側でAPIを使用出来るようAPIキーの生成などは事前に行ってください。

1. Meraki API連携: 複数リージョンのデータを集約

Merakiのライセンス情報は、organization(組織)ごとに分散しているため、複数のAPIエンドポイントからデータを取得し、一つのシートに統合する必要があります。

organizationオブジェクトに定義した複数のURLに対して UrlFetchApp.fetch() を実行し、結果をまとめています。

AppSCriptのコードも生成AIで殆ど作成が出来、適宜修正を指示することですぐにコードを作ることが出来ました。下記コードも不完全な一部のみ記載しているので、生成AIでコードをお試しください。

【GASコード1 - Merakiのハイライト】

// 複数のAPIエンドポイントを設定
const organizations = {
  "JP": "https://api.meraki.com/api/v1/organizations/...",
  "US": "https://api.meraki.com/api/v1/organizations/...",
  // ... 他のリージョン
};
// 
  const options = {
    'method': 'get',
    'headers': {
      'Authorization': 'Bearer ' + apiKey
    }
  };

// ... API実行部分
const allRawData = [];
const allHeaders = new Set(["organization"]);

for (const organization in organizations) {
  try {
    const response = UrlFetchApp.fetch(organizations[organization], options);
    const data = JSON.parse(response.getContentText());
    
    // データ構造が異なるAPIレスポンスでも、processDataでフラット化しヘッダーを統合
    const processedData = processData(Array.isArray(data) ? data : [data]);
    
    if (processedData.length > 0) {
      allRawData.push({ organization: organization, data: processedData });
      // すべてのキーをヘッダーとしてSetに追加(重複排除)
      Object.keys(processedData[0]).forEach(key => allHeaders.add(key));
    }
  } catch (e) {
    Logger.log(`APIの実行中にエラーが発生しました (${organization}): ` + e.message);
  }
}

2. Cato Cloud API連携: GraphQLによる時系列データの蓄積

Cato Networksは GraphQL APIを採用しています。Merakiと異なり、一度の実行で必要な情報(ZTNAユーザーの allocated、available、total)を取得できます。

【GASコード2 - Cato Cloudのハイライト】

// GraphQLクエリの定義
const graphqlQuery = `
  query MyQuery {
    licensing(accountId: "xxx") { //アカウントIDを設定
      licensingInfo {
        globalLicenseAllocations {
          ztnaUsers {
            allocated
            available
            total
          }
        }
      }
    }
  }
`;

// リクエストペイロードにクエリを含めてPOST
const options = {
  'method': 'POST',
  'contentType': 'application/json',
  'headers': {
    'x-api-key': apiKey
  },
  'payload': JSON.stringify({
    query: graphqlQuery // GraphQLクエリをペイロードとして送信
  })
};

// ... API実行後
// 日付とデータをまとめて最終行に追記 (時系列データとして蓄積)
const today = new Date();
const rowData = [
  Utilities.formatDate(today, SpreadsheetApp.getActiveSpreadsheet().getSpreadsheetTimeZone(), "yyyy-MM-dd"),
  ztnaUsers.allocated,
  ztnaUsers.available,
  ztnaUsers.total
];

sheet.getRange(lastRow + 1, 1, 1, rowData.length).setValues([rowData]);

Cato Cloudのデータは時系列で蓄積することで、後述するライセンスの消費傾向の分析に利用できるようにしています。

4. 構築されたダッシュボードの紹介と効果

データが取得出来るようになったので、スプレッドシートの関数でCatoのライセンス枯渇予測を実現しました。

枯渇予測日の算出: A列の日付をとC列のライセンス残数をソースとして、ライセンス残数が0になる予測日を算出する。

💡 スプレッドシートの関数例: =TREND(FILTER(A:A, ISNUMBER(A:A)), FILTER(C:C, ISNUMBER(C:C)), 0)

ざっくりした予測はこれで見てるようになるので、年度初めなどの一括で増えるイベントのみ気を付けておくことでライセンスの枯渇を避けることが出来ました。

✨ 取り組みによる効果

  • 一元化による効率化: 複数の管理画面を巡回する必要がなくなり、ライセンス確認にかかる時間を大幅に削減。
  • リスクの事前排除: 枯渇予測により、常に先手でライセンス管理が可能になり、業務停止リスクを排除。
  • IT資産の最適化: ライセンスの利用状況が可視化されたことで、過剰なライセンス保有を防ぎ、コスト最適化にも繋がる。

5. まとめと今後の展望

今回は時間やお金を掛けずに手持ちのツール(Google WorkspaceとAPI)を組み合わせることで、業務上の課題を解決してみました。

ITエンジニアの業務は、時にインフラの裏側を支える地味な作業に見えるかもしれませんが、こうした「守りのIT」の効率化こそが、事業成長を裏側から支える重要な取り組みであると確信しています。

🚀 今後の展望
ネットワークデバイスの一括更新などAPIを活用した取り組みを進めています。
運用管理をミスなく工数を抑える取り組みは継続し、より生産的な活動に集中して取り組めるよう今後も取り組んでいきます。


明日はOnamiさんの「Figma MCPで画面実装を効率化!AIに「意図」を伝えるデザインのコツ」の記事です。

JINSテックブログ
JINSテックブログ

Discussion