😎

Meraki API と Aruba New Central API を使って、ファームウェア更新を“能動的に検知”する仕組み

に公開

🧭 はじめに

この記事では、Meraki や Aruba といったネットワーク機器のファームウェア更新を自動で検知・通知・スケジュール させる仕組みを、Google Cloud(Cloud Functions+Scheduler)と Python で構築した話を紹介します。

ネットワーク機器の運用をしていると、「ファームウェア、ちゃんと最新だっけ?」と定期的に確認するの、結構面倒ですよね。
この仕組みで、その手間を自動化してしまいましょう。


🎯 やってほしいこと

ネットワーク機器のファームウェアアップデートを
「管理画面を見に行かなくても」能動的に検知し、可能なら自動でスケジュールまで設定したい ですよね。

この記事で実現するのは、以下の通りです:

  • Meraki/Aruba 機器の 現行バージョン (currentVersion) と 推奨版との差分 を検知
  • 「新しい推奨版が出たよ(上流更新)」や「推奨版と違うよ(不一致)」を Slack に通知
  • Meraki は API 経由で 更新スケジュールを自動設定
  • Aruba は検知のみ(APIが自動スケジュールに未対応のため)

🧩 背景と前提

なぜこの仕組みが必要なのか、Meraki と Aruba の「思想」の違いから見ていきます。

Meraki のファームウェア思想

Meraki はちょっと特殊で、各ファームウェアに 「End of Firmware Maintenance(EFM)」 が設定されています。
EFM(保守終了日)が来る前に最新版へ更新することが推奨されており、“基本、常に最新版を使ってね” という運用思想がベースにあります。

この思想に対応するため、Meraki 運用では「EFM期限を迎える前に、計画的に自動更新」できるのが理想です。
APIによる自動検知・スケジュール設定は、まさにそのための仕組みというわけです。

📘 Meraki公式ドキュメント

💡 注意点 (割り切り)

  • Staged Upgrade(段階的アップグレード)は、今回の仕組みでは考慮外としています。
  • Meraki は一度 API でアップグレード予約を設定すると、GUI/API からキャンセルできないケース があります(仕様です…)。
  • そのため本設計では、「スケジュール設定したら、あとは実行を待つ。問題があれば実行後にロールバックで対処する」という割り切りにしています。

Aruba API について

Aruba Central API は、今ちょうど過渡期です。大きく2系統あります。

系列 Python SDK 概要
v1系 pycentral 1.x 旧API。レスポンス形式が古く、段階的に廃止(Deprecated)予定。
v2系 pycentral 2.0ax(アルファ版) 「New Central API」。構造が整理され、今後はこちらが主流に。

今回は、将来性を見越して v2 (α版) を利用します。
firmware-detailsdevice-inventory というエンドポイントから
推奨版 (recommendedVersion) と現行版 (softwareVersion) の差分を取得します。

残念ながら、v2 (α版) 時点ではスケジュール設定 API がまだ提供されていないため、「通知のみ」で対応します。


Meraki と Aruba の設計ポリシー差

まとめると、両者のポリシーにはこんな違いがあります。

項目 Meraki Aruba
ファームウェア思想 最新安定版への追従(EFMで更新推奨) 推奨版提示型(ベンダーが「これがオススメ」と提示)
APIによるスケジュール設定 PUT /networks/{id}/firmwareUpgrades ❌ 未対応(v2 α版時点。今後に期待!)
自動スケジュール戦略 検知後、ネットワーク・製品単位で設定(例: MX=土曜2時, MS/CS=土曜4時) 検知のみ
キャンセル操作 ほぼ不可(割り切りが必要) N/A

🏗️ システム構成

GCP 上に、サーバレスでシンプルな構成を組みます。

GCP上のアーキテクチャ

  1. Cloud Scheduler が毎日決まった時間に Cloud Functions を(OIDC認証で)叩きます。
  2. Cloud Functions (Python) が起動し、Meraki と Aruba の API からファームウェア情報を取得します。
  3. Cloud Storage (GCS) に保存されている state.json(=前回実行時の情報)と今回取得した情報を比較します。
  4. 差分(新しい推奨版、現行版との不一致など)があれば、Slack に通知します。
  5. Meraki で更新があれば、そのまま API で更新スケジュールも設定します。
  6. 最後に、今回の状態を state.json として GCS に上書き保存します。

⚙️ 環境構築

requirements.txt

google-cloud-storage
google-cloud-logging
meraki
pycentral>=2.0a6
requests

環境変数設定( .env.yaml またはデプロイ時)

# 事前に GCS バケットを作成しておく
export PROJECT_ID="your-gcp-project-id"
export REGION="asia-northeast1"
export FUNC_NAME="network-firmware-monitor"
export GCS_BUCKET_NAME="network-firmware-monitor" # 作成したバケット名
export SERVICE_ACCOUNT_EMAIL="scheduler-invoker@${PROJECT_ID}.iam.gserviceaccount.com" # Schedulerが使うSA

# 実行時に Cloud Functions に設定する環境変数
# (Secret Manager の利用を強く推奨します)
export MERAKI_API_KEY="xxx"
export ARUBA_API_KEY="xxx"
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/xxxx"

🚀 デプロイ手順 (gcloud CLI)

Cloud Functions は 非公開(認証必須) でデプロイし、Cloud Scheduler からの OIDC 認証済みリクエストのみを受け付けるようにします。

# 1. Cloud Functions を非公開でデプロイ
# (APIキーなどは --set-env-vars ではなく Secret Manager を使うのがベストプラクティスです)
gcloud functions deploy $FUNC_NAME \
  --project=$PROJECT_ID \
  --region=$REGION \
  --runtime=python313 \
  --trigger-http \
  --no-allow-unauthenticated \
  --entry-point=main \
  --set-env-vars GCS_BUCKET_NAME=$GCS_BUCKET_NAME,SLACK_WEBHOOK_URL=$SLACK_WEBHOOK_URL,MERAKI_API_KEY=$MERAKI_API_KEY,ARUBA_API_KEY=$ARUBA_API_KEY

# 2. Cloud Scheduler のサービスアカウントに Functions の起動権限を付与
gcloud functions add-iam-policy-binding $FUNC_NAME \
  --region=$REGION \
  --project=$PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
  --role="roles/cloudfunctions.invoker"

# 3. Cloud Functions のトリガーURLを取得
FUNCTION_URL=$(gcloud functions describe $FUNC_NAME --region=$REGION --project=$PROJECT_ID --format='value(httpsTrigger.url)')

# 4. Cloud Scheduler を設定(毎朝9時実行)
gcloud scheduler jobs create http firmware-monitor-job \
  --schedule="0 9 * * *" \
  --uri="${FUNCTION_URL}" \
  --oidc-service-account-email="${SERVICE_ACCOUNT_EMAIL}" \
  --http-method=POST \
  --project=$PROJECT_ID

※ Cloud Scheduler のデフォルトSA (scheduler-invoker@...) がない場合は、事前に gcloud services enable cloudscheduler.googleapis.com を実行するか、専用のSAを作成してください。


🧪 Meraki ファームウェアスケジュール確認(CLI)

「ちゃんとスケジュール設定されたかな?」と不安なときは、CLI (curl + jq) で確認できます。

# Meraki APIキー
export MERAKI_KEY="xxxx"
# 確認したい Meraki Network ID のリスト
NIDS=("L_123456789012345" "L_234567890123456")

for NID in "${NIDS[@]}"; do
  echo "# Network: ${NID}"
  curl -sS -X GET "[https://api.meraki.com/api/v1/networks/$](https://api.meraki.com/api/v1/networks/$){NID}/firmwareUpgrades" \
    -H "Accept: application/json" \
    -H "X-Cisco-Meraki-API-Key: ${MERAKI_KEY}" \
  | jq -r '
      .products
      | to_entries[]
      | select(.value.nextUpgrade.time != null)
      | [.key, .value.nextUpgrade.time, .value.nextUpgrade.toVersion.shortName]
      | @tsv' \
  | awk -F'\t' 'BEGIN{print "family\tUTC_time\tversion"} {print}'
done

出力例

(設定されているものだけが family ごとに表示されます)

# Network: L_123456789012345
family          UTC_time                  version
wireless        2025-11-02T07:29:00Z     MR 32.1.4

family と機器のマッピング

family 実際の機器
appliance MX (セキュリティ/SD-WAN)
switch MS (スイッチ)
switchCatalyst CS (Catalyst スイッチ)
wireless MR (アクセスポイント)
camera MV (カメラ)
cellularGateway MG (セルラールーター)
sensor MT (センサー)

💬 Slack通知テンプレート例

requests ライブラリを使って、シンプルに Slack Webhook に POST します。

import os
import requests

def post_slack(msg: str, color: str = "#2eb886"):
    """Slack に通知を送信する"""
    webhook_url = os.environ.get("SLACK_WEBHOOK_URL")
    if not webhook_url:
        print("Slack Webhook URL が設定されていません。")
        return

    payload = {
        "attachments": [
            {
                "fallback": "Network Firmware Monitor",
                "color": color, # 色を変えると通知の見栄えが変わる
                "title": "📡 Network Firmware Monitor",
                "text": msg,
                "mrkdwn_in": ["text"] # メッセージ内で *bold* などが使えるように
            }
        ]
    }
    try:
        requests.post(webhook_url, json=payload)
    except Exception as e:
        print(f"Slack への通知に失敗しました: {e}")

通知例

✅ 更新スケジュール完了 (Meraki)

:bell: [Meraki] 新しい安定版がリリースされました
MR 32.1.4 → 次回メンテナンス枠 (2025-11-09T04:00:00Z) でスケジュール済み

⚠️ 不一致検知 (Meraki or Aruba)

:warning: [Aruba] 現行ファームウェアが推奨版と異なります
対象: グループA
現在: 10.10.1000 / 推奨: 10.11.0001
(※ Aruba は手動での更新対応が必要です)

🚫 手動対応(Meraki キャンセル不可)

:no_entry: [Meraki] ファームウェア予約キャンセルは不可です
Network: L_123456789012345
UIからロールバック or 次回メンテナンスをお待ちください

🧱 実装スケルトン(抜粋)

実際に API を叩く部分のイメージです。merakipycentral のライブラリがよしなにやってくれます。

from meraki import DashboardAPI
from pycentral.base import ArubaCentralBase

# === Meraki の処理イメージ ===
db = DashboardAPI(api_key=MERAKI_API_KEY, suppress_logging=True)
NETWORK_ID = "L_1234567890" # 対象のネットワークID

# ファームウェア情報を取得
fw_info = db.networks.getNetworkFirmwareUpgrades(NETWORK_ID)

# 現行バージョン
print(fw_info["products"]["wireless"]["currentVersion"]["shortName"])
# → MR 31.1.8

# 利用可能な(推奨)バージョン
# availableVersions はリストで、 "stable" が推奨版
stable_version = next(
    (v for v in fw_info["products"]["wireless"]["availableVersions"] if v["releaseType"] == "stable"),
    None
)
if stable_version:
    print(stable_version["shortName"])
    # → MR 32.1.4

# スケジュール設定 (例: 2025年11月9日 AM4時 JST)
# JST (UTC+9) の場合、UTC で 11月8日 19:00 を指定する
db.networks.updateNetworkFirmwareUpgrades(
    NETWORK_ID,
    products={"wireless": {"nextUpgrade": {"time": "2025-11-08T19:00:00Z"}}}
)


# === Aruba の処理イメージ ===
central = ArubaCentralBase(token=ARUBA_API_KEY) # トークン管理は SDK がやってくれる

# ファームウェア詳細を取得 (推奨版などが含まれる)
details = central.command("GET", "network-monitoring/v1alpha1/firmware-details")
print(details["recommendedVersion"])

# 実際の機器インベントリ (現行版が含まれる)
inventory = central.command("GET", "device-inventory/v1alpha1/devices")
for device in inventory.get("devices", []):
    print(f"Device {device['serial']}: {device['softwareVersion']}")


🔭 今後の展開

今回は「まず動くもの」を作りましたが、まだ改善の余地はあります。

  • 安定版自動追従ロジックの強化
    • 「リリースから N 日間様子を見る」といったバッファ機能。
  • Meraki の Staged Upgrade(段階更新)対応
    • 特定のタグが付いた機器から順次更新する、より高度な運用への対応。
  • GCS state.json の差分整合性チェック
    • state が壊れたり、Functions が二重起動した(ないとは思うが)場合のエラーハンドリング。
  • Slack通知を Block Kit 対応に
    • よりリッチでインタラクティブな通知(「今すぐ実行しますか?」ボタンとか)。
  • Aruba API のスケジュール設定対応
    • Aruba API が進化してスケジュール設定が解放されたら、即対応する!

🧩 まとめ

  • Meraki は「EFMによる最新版追従」が基本ポリシー。API での自動化と相性が良い。
  • Aruba は「推奨版提示型」だが、スケジュール API は(現状)未対応。検知・通知までを自動化する。
  • GCP(Cloud Functions + Scheduler)と Python (meraki, pycentral ライブラリ) を使えば、サーバレスで安価に “ネットワーク機器ファームウェアの自動検知・通知” の仕組みが実現できました。

日々の面倒な確認作業はクラウドと API に任せて、SRE/エンジニアはもっとクリエイティブな仕事に集中したいですね!

Discussion