はじめに
プライベート可用性テストとは
Azure を利用されている皆さん、Application Insights の可用性テストは使っていますか?
外形監視目的で利用されることが多い便利な機能ですが、プライベート環境からのアクセスのみを前提とした Web サイトやアプリケーションに対して、可用性テストは利用できません。
今回は、プライベート環境内のリソースに対する可用性テスト(以降「プライベート可用性テスト」と呼びます)を、Azure Functions を使って安価に実装してみました。
安価に?
なぜ安価にとしているのか。
理由はズバリ、2024年11月に Azure Functions Flex 従量課金プランの VNet 統合が GA されたからです。
Azure Functions を利用したプライベート可用性テストについては、以前から複数のブログなどで紹介されていましたが、当時 Azure Functions の VNet 統合がサポートされていたのは Premium といった高価なプランのみであり、可用性テストのために Premium を採用するにはハードルが高すぎました。
しかし、Flex 従量課金プランの VNet 統合が使えるようになり、プライベート可用性テストを実装するハードルがかなり下がりました。
以前はコスト面で二の足を踏んでいた方も、「今はプライベート可用性テストを安く実装できるよ」ということを知ってもらえれば幸いです。
構成
アーキテクチャ
構成は非常にシンプルで、 VNet 統合を有効化した Functions と可用性テストの実行結果の送信先となる Application Insights だけです。
可用性テスト用のコードを Functions にデプロイし、 Timer Trigger を使って定期実行します。実行結果は Application Insights に送信されます。
加えて、今回はテスト対象のサンプルアプリケーション基盤として Azure Container Instances ( ACI ) を使っています。
処理フロー
実装する可用性テストの処理フローは以下の通りです。
- 環境変数の取得・検証 : Functions は環境変数を設定できるため、テスト対象の宛先を環境変数にて指定
- 可用性テストの実行 : Timer Trigger にて定期的に HTTP リクエストを実行
- Application Insights への結果送信 : HTTP リクエストの結果を Application Insights に送信
実装
それでは、以下の順でプライベート可用性テストを実装していきます。
- Azure リソースの作成
- コードの実装
- コードのデプロイ
- 動作確認
Azure リソース
今回は Azure ポータルを使って各リソースを作成していきます。
前提
以下のリソースは作成済とします。
- VNet および Subnet : Functions (と今回は ACI)を統合する
- Application Insights : 可用性テストの結果送信先
Azure Container Instances
可用性テストの実行先として ACI を作成します。動作確認用に作成するリソースですので、既存のアプリケーションがある場合は不要です。
デフォルトのイメージを指定し、サイズも最小限とします。
プライベート可用性テストですので、 ACI もプライベートとします。
ネットワークの種類はプライベートとし、作成した VNet と ACI を統合するサブネットを選択します。
ログの設定は無効化しておきます。
ACI ができました。
VNet 統合が設定されていれば OK です。
Azure Functions
コードの実行基盤となる Functions を作成します。
まず初めに、プランを選択します。
従量課金かつ VNet 統合がサポートされているフレックス従量課金を選択します。
次に、各パラメータを指定します。
ランタイムには Python 3.12 を使います。
仮想ネットワーク統合を有効にするをオンにし、作成した VNet と
Functions を統合するサブネットを選択します。
作成した Application Insights を選択します。
Functions ができました。
こちらも VNet 統合が設定されていれば OK です。
最後に、可用性テストの宛先(今回は ACI のプライベート IP )を環境変数として設定します。
これで Azure リソースの設定は完了です。
Functions コード
リソース作成が完了したので、 Functions にデプロイする可用性テスト用のコードを紹介します。
今回は Python を使用していますが、 Functions に対応しており Application Insights の API がサポートされている言語であれば何でもよいかと思います。
ファイル構成は以下です。
availability-test/
├── function_app.py # メインの実装
├── host.json # Functions ホスト設定
└── requirements.txt # Python 依存パッケージ
メインとなるコードは以下になります。今回は非常にシンプルな実装としています。
import logging
import os
import json
import time
import uuid
import requests
import azure.functions as func
app = func.FunctionApp()
def perform_availability_test(target_url: str, timeout: int = 30):
"""可用性テストを実行してApplication Insightsに送信"""
test_id = str(uuid.uuid4())
start_time = time.time()
success = False
status_code = None
error_message = None
try:
logging.info(f"可用性テスト開始: {target_url}")
# HTTPリクエストを実行
response = requests.get(target_url, timeout=timeout)
status_code = response.status_code
success = status_code < 400
if not success:
error_message = f"HTTP {status_code}"
logging.info(f"テスト完了: status={status_code}")
except Exception as e:
error_message = str(e)
logging.error(f"テスト失敗: {error_message}")
# 所要時間を計算
duration_ms = (time.time() - start_time) * 1000
# Application Insightsに送信
send_to_appinsights(test_id, target_url, success, duration_ms, error_message)
return {
'success': success,
'duration_ms': duration_ms,
'status_code': status_code
}
def send_to_appinsights(test_id: str, target_url: str, success: bool, duration_ms: float, error_message: str = None):
"""Application Insightsに可用性データを送信"""
connection_string = os.getenv('APPLICATIONINSIGHTS_CONNECTION_STRING')
if not connection_string:
logging.warning("APPLICATIONINSIGHTS_CONNECTION_STRING が設定されていません")
return
# Instrumentation Keyを抽出
try:
ikey = connection_string.split("InstrumentationKey=")[1].split(";")[0]
except (IndexError, AttributeError):
logging.error(f"接続文字列からInstrumentation Keyを抽出できません: {connection_string}")
return
# durationをISO 8601形式に変換 (例: 00:00:01.2340000)
duration_seconds = duration_ms / 1000.0
hours = int(duration_seconds // 3600)
minutes = int((duration_seconds % 3600) // 60)
seconds = duration_seconds % 60
duration_str = f"{hours:02d}:{minutes:02d}:{seconds:09.6f}"
# 可用性結果のペイロードを作成
payload = {
"name": "Microsoft.ApplicationInsights.AvailabilityResult",
"time": time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime()),
"iKey": ikey,
"tags": {
"ai.operation.id": test_id,
"ai.operation.name": f"Availability Test - {target_url}",
"ai.location.ip": "0.0.0.0"
},
"data": {
"baseType": "AvailabilityData",
"baseData": {
"ver": 2,
"id": test_id,
"name": "Availability Test",
"duration": duration_str,
"success": success,
"runLocation": "Azure Functions",
"message": error_message or "",
"properties": {
"TargetUrl": target_url
}
}
}
}
try:
# Application Insights REST APIに送信
response = requests.post(
"https://dc.applicationinsights.azure.com/v2/track",
json=payload,
headers={"Content-Type": "application/json"},
timeout=10
)
if response.status_code == 200:
logging.info("Application Insightsに送信成功")
else:
logging.warning(f"Application Insights送信失敗: {response.status_code} - {response.text}")
except Exception as e:
logging.error(f"Application Insights送信エラー: {e}")
@app.timer_trigger(
schedule="0 */5 * * * *", # 5分ごとに実行
arg_name="myTimer",
run_on_startup=False,
use_monitor=False
)
def availability_test_timer(myTimer: func.TimerRequest) -> None:
"""タイマートリガーで定期的に可用性テストを実行"""
logging.info('可用性テスト実行開始')
# 環境変数から監視対象URLを取得
target_url = os.getenv('TARGET_URL')
if not target_url:
logging.error('TARGET_URL 環境変数が設定されていません')
return
# 可用性テストを実行
result = perform_availability_test(target_url)
logging.info(f'可用性テスト完了: {result}')
以下は Functions のホスト設定ファイルです。
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": false
}
}
}
}
最後に、Python のパッケージファイルです。こちらも最小限です。
azure-functions
requests
コードデプロイ
以下を実行することで、Functions にコードをデプロイできます。
> az login
> func azure functionapp publish <Function名> --python
Getting site publishing info...
~~~
[2025-10-20T16:36:43.350Z] The deployment was successful!
Functions in fnc-availabilitytest-01:
availability_test_timer - [timerTrigger]
デプロイには以下が必要です
- Azure CLI
- Azure Functions Core Tools v4
動作確認
可用性テストが正常に動いていることを確認してみます。
Application Insights の「有効 ( Availability ) 」メニューを見ると、CUSTOMと表示された可用性テストが表示され、5分おきにテストが実行されていることが確認できました。
Functions の方も見てみましょう。
Timer Trigger が正常に実行されていることが確認できました。
料金比較
今回の構成で実際にどれくらいコストがかかるのか、Premium プランと比較してみます。
前提
今回の構成および動作確認の結果から、以下を前提に料金を算出してみましょう。
なお、価格は2025年10月時点とします。
- 5分ごとに実行(月間 8,640回)
- 1回の実行時間 : 約2秒
- メモリ : 512 MB
Flex 従量課金プラン
月額コスト : $0(無料)
以下の通り、無料枠(250,000実行 + 100,000 GB-s/月)内に収まります。
実行回数:8,640回/月 → 無料枠内
実行時間:8,640回 × 2秒 × 0.5GB = 8,640 GB-s → 無料枠内
Premium プラン(EP1)
月額コスト : $178.85
Premium プランは最低1インスタンスが常時稼働するため、たとえ軽量なワークロードでも固定費が発生します。
コスト比較
| プラン | 月額 | 年間 |
|---|---|---|
| Flex 従量課金 | $0 | $0 |
| Premium(EP1) | $178.85 | $2,146 |
比較するまでもありませんが、 Flex 従量課金の方が圧倒的に安いです。というか、無料です。
まとめ
本記事では、Azure Functions Flex 従量課金プランの VNet 統合機能を活用して、プライベート可用性テストを安価に実装する方法を紹介しました。
以下に要点をまとめます。
- コスト削減 : 従来の Premium プランと比較して、Flex 従量課金プランを使うことで大幅なコスト削減が可能
- シンプルな構成 : VNet 統合した Functions と Application Insights のみで実装可能
- 柔軟な監視 : 環境変数で監視対象を設定することで、複数の環境やエンドポイントにも対応可能
- 標準的な可視化 : Application Insights 標準機能として可用性テストの結果が表示されるため、既存の監視フローに統合しやすい
2024年11月の Flex 従量課金プランの VNet 統合 GA により、これまでコスト面で導入が難しかったプライベート可用性テストが、現実的な選択肢となりました。
プライベート環境の監視要件がある方は、本記事の実装を参考にしてみてください。
We Are Hiring!















