目的
Azure Application Insightsにotelcol-contribを使ってOpenTelemetryでテレメトリを送ることを確かめます。
具体的にはAzure Cloud Shell 上のCurlでHTTPリクエストを発行し、Azure Cloud Shell 上のotelcol-contrib に送り、そこからexporterによりEntra ID認証をしてApplication Insightsに送り、反映されることを確認します。
アプリケーションの場合はパッケージが用意されているのでそれに従い設定すればよいですが、この確認のためにアプリを書きたくなかったので今回この手順で試してみました。
前提
- サービスプリンシパルを使った認証で行う
- サブスクリプションに対する所有者(共同作成者 + ユーザアクセス管理者)の権限が必要
- リソースグループを含めたリソースの作成、role-assignmentを行うため
作業
Azure Portalを開き、Cloud Shellを起動しBashでセッションを起動して始めます。
変数を準備する
# 必要に応じて変更
LOCATION="japaneast"
PREFIX="oteltest$RANDOM"
RG_NAME="rg-${PREFIX}"
LAW_NAME="law-${PREFIX}"
APPINSIGHTS_NAME="appi-${PREFIX}"
SP_NAME="sp-${PREFIX}"
echo "RG_NAME=${RG_NAME}"
echo "LAW_NAME=${LAW_NAME}"
echo "APPINSIGHTS_NAME=${APPINSIGHTS_NAME}"
echo "SP_NAME=${SP_NAME}"
echo "LOCATION=${LOCATION}"
現在のサブスクリプション確認、設定値取得
異なる場合は az account set -s "サブスクリプション名" で変更し再実行
read SUBSCRIPTION_ID SUBSCRIPTION_NAME TENANT_ID < <(
az account show \
--query "{id:id,name:name,tenantId:tenantId}" \
-o tsv
)
echo "SUBSCRIPTION_ID=${SUBSCRIPTION_ID}"
echo "SUBSCRIPTION_NAME=${SUBSCRIPTION_NAME}"
echo "TENANT_ID=${TENANT_ID}"
リソースが作成できるようproviderを登録
初回のみ、LogAnalytics WorkspaceとApplication Insightsリソースを作成するために以下のProviderを登録しておく必要がある
az provider register -n Microsoft.OperationalInsights
az provider register -n microsoft.insights
リソースグループ作成
read RG_ID < <(
az group create \
--name "${RG_NAME}" \
--location "${LOCATION}" \
--query "id" \
-o tsv
)
echo "RG_ID=${RG_ID}"
Application Insights 用の Log Analytics Workspace 作成
read WORKSPACE_ID < <(
az monitor log-analytics workspace create \
--resource-group "${RG_NAME}" \
--workspace-name "${LAW_NAME}" \
--location "${LOCATION}" \
--query "id" \
-o tsv
)
echo "WORKSPACE_ID=${WORKSPACE_ID}"
Application Insights 作成
read APPINSIGHTS_ID APPINSIGHTS_CONNECTION_STRING INSTRUMENTATION_KEY < <(
az monitor app-insights component create \
--app "${APPINSIGHTS_NAME}" \
--resource-group "${RG_NAME}" \
--location "${LOCATION}" \
--workspace "${WORKSPACE_ID}" \
--query "{id:id,connectionString:connectionString,instrumentationKey:instrumentationKey}" \
-o tsv
)
echo "APPINSIGHTS_ID=${APPINSIGHTS_ID}"
echo "APPINSIGHTS_CONNECTION_STRING=${APPINSIGHTS_CONNECTION_STRING}"
echo "INSTRUMENTATION_KEY=${INSTRUMENTATION_KEY}"
Application Insights のローカル認証を無効化
今回は Application Insights のローカル認証を無効化し、Entra ID 認証でテレメトリを取り込む構成を試します。InstrumentationKeyだけの認証をできないようにします。
az resource update \
--ids "${APPINSIGHTS_ID}" \
--set properties.DisableLocalAuth=true \
-o none
az resource show \
--ids "${APPINSIGHTS_ID}" \
--query "properties"
Service Principalを作成
今回はサービスプリンシパルで作業します。
read AZURE_CLIENT_ID AZURE_CLIENT_SECRET AZURE_TENANT_ID < <(
az ad sp create-for-rbac \
--name "${SP_NAME}" \
--skip-assignment \
--query "{appId:appId,password:password,tenant:tenant}" \
-o tsv
)
echo "AZURE_CLIENT_ID=${AZURE_CLIENT_ID}"
echo "AZURE_TENANT_ID=${AZURE_TENANT_ID}"
Service Principalに権限を付与
ここは実務ではManaged IDに対して作業することになるはずです。
# Service PrincipalのObject ID取得
read SP_OBJECT_ID < <(
az ad sp show \
--id "${AZURE_CLIENT_ID}" \
--query "id" \
-o tsv
)
echo "SP_OBJECT_ID=${SP_OBJECT_ID}"
# Service Principalに権限を付与
# Monitoring Metrics Publisher=3913510d-42f4-4e42-8a64-420c390055eb
read ROLE_ASSIGNMENT_ID < <(
az role assignment create \
--assignee-object-id "${SP_OBJECT_ID}" \
--assignee-principal-type ServicePrincipal \
--role "Monitoring Metrics Publisher" \
--scope "${APPINSIGHTS_ID}" \
--query "id" \
-o tsv
)
echo "ROLE_ASSIGNMENT_ID=${ROLE_ASSIGNMENT_ID}"
設定値の控えを取る
設定値を控えておきます。次のotelcol起動時にこの値を環境変数として設定すればそのまま使えます。
cat << __EOF__
export APPLICATIONINSIGHTS_CONNECTION_STRING="${APPINSIGHTS_CONNECTION_STRING}"
export AZURE_TENANT_ID="${AZURE_TENANT_ID}"
export AZURE_CLIENT_ID="${AZURE_CLIENT_ID}"
export AZURE_CLIENT_SECRET="${AZURE_CLIENT_SECRET}"
__EOF__
otelcol-contribの導入
Cloud Shell上に一時的にいれます。
otelcol-contrib に同梱されている Azure Monitor exporter と azureauth extension を利用します。
mkdir -p ~/otelcol-ai
cd ~/otelcol-ai
# https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/latest # で、tag_name値を確認してバージョンを合わせる
OTELCOL_VERSION=v0.154.0
# Cloud Shell上のArchがx86_64なのでamd64バイナリを利用
OTEL_TGZ="otelcol-contrib_${OTELCOL_VERSION#v}_linux_amd64.tar.gz"
OTEL_URL="https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/${OTELCOL_VERSION}/${OTEL_TGZ}"
echo "OTELCOL_VERSION=${OTELCOL_VERSION}"
echo "OTEL_URL=${OTEL_URL}"
curl -fL "${OTEL_URL}" -o "${OTEL_TGZ}"
tar -xzf "${OTEL_TGZ}" && rm "${OTEL_TGZ}"
# コマンド実行できることを確認
./otelcol-contrib --version
otelcolの設定ファイルを作成し検証
debugとazuremonitorを利用し手出力するようにします。ただ、デフォルトで起動してしまう prometheus exporter のポート番号を8889にずらしています。(Cloud Shell上の8888ポートがぶつかったため)
マネージドIDを扱う場合は、extensions.azure_auth.managed_identity を指定するようです。
# 先ほど採取した環境変数の値を設定(同じセッションなら流れでこのまま実行してもよい)
export APPLICATIONINSIGHTS_CONNECTION_STRING="${APPINSIGHTS_CONNECTION_STRING}"
export AZURE_TENANT_ID="${AZURE_TENANT_ID}"
export AZURE_CLIENT_ID="${AZURE_CLIENT_ID}"
export AZURE_CLIENT_SECRET="${AZURE_CLIENT_SECRET}"
cat << '__YAML__' > otelcol-azuremonitor.yaml
extensions:
azure_auth:
service_principal:
tenant_id: ${env:AZURE_TENANT_ID}
client_id: ${env:AZURE_CLIENT_ID}
client_secret: ${env:AZURE_CLIENT_SECRET}
scopes:
- https://monitor.azure.com/.default
receivers:
otlp:
protocols:
http:
endpoint: 127.0.0.1:4318
processors:
batch:
timeout: 5s
exporters:
debug:
verbosity: detailed
azuremonitor:
connection_string: ${env:APPLICATIONINSIGHTS_CONNECTION_STRING}
auth:
authenticator: azure_auth
maxbatchinterval: 5s
sending_queue:
enabled: true
service:
extensions:
- azure_auth
telemetry:
logs:
level: debug
metrics:
readers:
- pull:
exporter:
prometheus:
host: 127.0.0.1
port: 8889
pipelines:
traces:
receivers:
- otlp
processors:
- batch
exporters:
- debug
- azuremonitor
metrics:
receivers:
- otlp
processors:
- batch
exporters:
- debug
- azuremonitor
logs:
receivers:
- otlp
processors:
- batch
exporters:
- debug
- azuremonitor
__YAML__
./otelcol-contrib validate --config otelcol-azuremonitor.yaml
validateコマンドの結果、何も出力されなければOK。
環境変数が未設定だとエラーが出る(Error: extensions::azure_auth::service_principal: empty "tenant_id" field など)
otelcolを起動
cd ~/otelcol-ai
./otelcol-contrib --config otelcol-azuremonitor.yaml 2>&1 | tee otelcol.log
待ち受け状態になればOK。ポート番号が使用中だったり問題があると終了するので注意。
別セッションでcurlで送る
新しいセッションを開始し、curlでotelcolに送り、Application Insightsに送られることを確認します。
もし curlで接続できない場合は、同一セッションで otelcol をバックグラウンド起動して curl してください。
# ダミーデータ作成。処理時間約1秒かかったテレメトリを送る
START_TIME=$(date -d "1 second ago" +%s%N)
END_TIME=$(date +%s%N)
TRACE_ID=$(openssl rand -hex 16)
SPAN_ID=$(openssl rand -hex 8)
# otelcolへ送信
curl -i \
-X POST http://127.0.0.1:4318/v1/traces \
-H "Content-Type: application/json" \
--data-binary @- << __JSON__
{
"resourceSpans": [
{
"resource": {
"attributes": [
{
"key": "service.name",
"value": {
"stringValue": "curl-to-otelcol-to-azuremonitor"
}
},
{
"key": "deployment.environment",
"value": {
"stringValue": "cloudshell"
}
}
]
},
"scopeSpans": [
{
"scope": {
"name": "manual-curl"
},
"spans": [
{
"traceId": "${TRACE_ID}",
"spanId": "${SPAN_ID}",
"name": "curl-generated-span",
"kind": "SPAN_KIND_SERVER",
"startTimeUnixNano": "${START_TIME}",
"endTimeUnixNano": "${END_TIME}",
"attributes": [
{
"key": "http.request.method",
"value": {
"stringValue": "GET"
}
},
{
"key": "url.path",
"value": {
"stringValue": "/curl/test"
}
},
{
"key": "http.response.status_code",
"value": {
"intValue": "200"
}
}
],
"status": {
"code": "STATUS_CODE_OK"
}
}
]
}
]
}
]
}
__JSON__
echo
echo "TRACE_ID=${TRACE_ID}"
echo "SPAN_ID=${SPAN_ID}"
curlのHTTPリクエストが200で正常終了しています。
また、otelcol側も以下のようなazuremonitorexporterのログが確認できればApplication Insights側にも送られているはずです。ここが400等の場合はリクエストデータ不備の可能性があります。
2026-06-23T00:13:02.440Z debug azuremonitorexporter@v0.154.0/factory.go:151 Response: 200 {"resource": {"service.instance.id": "12f7fa2d-fd32-4943-b9fc-cd35fd635e6a", "service.name": "otelcol-contrib", "service.version": "0.154.0"}, "otelcol.component.id": "azuremonitor", "otelcol.component.kind": "exporter", "otelcol.signal": "metrics"}
うまくいくとApplication Insights上に確認でき、取り込まれたことがわかります。
後始末
# Azure リソース削除
az group delete \
--name "${RG_NAME}" \
--yes \
--no-wait
# Service Principal の削除
az ad sp delete \
--id "${AZURE_CLIENT_ID}"
