New Relic Azure統合設定とAzure Monitor連携

はじめに

Azure環境でのインフラ監視は、Virtual Machine上のInfrastructure Agentと、Azureサービスの統合監視を組み合わせることで、包括的な可視性を実現できます。New RelicのAzure統合により、Azure Monitor、SQL Database、App Service、AKSなどのAzureサービスの詳細メトリクスを統一されたダッシュボードで監視できます。

本記事では、Infrastructure AgentのAzure環境での設定から、Azure統合の有効化、Azure Monitorとの連携まで、実践的な設定手順を詳しく解説します。また、サービスプリンシパルの適切な設定とセキュリティ考慮事項についても併せて説明します。

Azure統合監視の基本概念

Infrastructure AgentとAzure統合の関係

Infrastructure AgentはAzure Virtual Machine、Container Instances、オンプレミスサーバーのホストレベル監視を担当し、Azure統合はAzureマネージドサービスの監視を担当します。この2つを組み合わせることで、アプリケーションスタック全体の監視が可能になります。

監視対象の範囲

Azure環境でのNew Relic監視では、以下の情報を収集できます。

Infrastructure Agentによる監視

  • Azure VMのシステムメトリクス
  • アプリケーションプロセスの詳細情報
  • カスタムメトリクスとログ

Azure統合による監視

  • Azure Monitorメトリクス
  • Application Insightsテレメトリ
  • Log Analyticsデータ
  • SQL Database、App Service、AKS等のサービスメトリクス

Azure VMでのInfrastructure Agent設定

サービスプリンシパルの作成

Azure統合に必要なサービスプリンシパルをAzure CLIで作成します。

bash
# Azure CLIでログイン
az login

# サブスクリプション確認
az account show

# New Relic用サービスプリンシパルの作成
az ad sp create-for-rbac \
  --name "NewRelicInfrastructure" \
  --role "Reader" \
  --scopes "/subscriptions/YOUR_SUBSCRIPTION_ID"

# 結果の例
# {
#   "appId": "12345678-1234-5678-9012-123456789012",
#   "displayName": "NewRelicInfrastructure",
#   "password": "YOUR_SECRET_PASSWORD",
#   "tenant": "87654321-4321-8765-2109-876543210987"
# }

Azure VM Extension を使用した自動インストール

Azure VM拡張機能を使用してInfrastructure Agentを自動インストールします。

bash
# Linux VM へのインストール
az vm extension set \
  --resource-group "myResourceGroup" \
  --vm-name "myVM" \
  --name "CustomScript" \
  --publisher "Microsoft.Azure.Extensions" \
  --settings '{
    "fileUris": ["https://raw.githubusercontent.com/your-repo/newrelic-install.sh"],
    "commandToExecute": "bash newrelic-install.sh YOUR_LICENSE_KEY"
  }'

カスタムスクリプトでのインストール

Azure VM起動時に実行するインストールスクリプトです。

bash
#!/bin/bash
# newrelic-install.sh - Azure VM用インストールスクリプト

NEW_RELIC_LICENSE_KEY="$1"

if [ -z "$NEW_RELIC_LICENSE_KEY" ]; then
    echo "Usage: $0 <NEW_RELIC_LICENSE_KEY>"
    exit 1
fi

# Azure メタデータ取得
AZURE_METADATA_URL="http://169.254.169.254/metadata/instance?api-version=2021-02-01"
METADATA=$(curl -s -H "Metadata:true" "$AZURE_METADATA_URL")

VM_NAME=$(echo $METADATA | jq -r '.compute.name')
RESOURCE_GROUP=$(echo $METADATA | jq -r '.compute.resourceGroupName')
SUBSCRIPTION_ID=$(echo $METADATA | jq -r '.compute.subscriptionId')
LOCATION=$(echo $METADATA | jq -r '.compute.location')
VM_SIZE=$(echo $METADATA | jq -r '.compute.vmSize')

# OS判定とパッケージ管理
if [ -f /etc/redhat-release ]; then
    # RHEL/CentOS
    curl -o /etc/yum.repos.d/newrelic-infra.repo \
         https://download.newrelic.com/infrastructure_agent/linux/yum/el/7/x86_64/newrelic-infra.repo
    yum -q makecache -y --disablerepo='*' --enablerepo='newrelic-infra'
    yum install newrelic-infra -y
elif [ -f /etc/debian_version ]; then
    # Ubuntu/Debian
    curl -fsSL https://download.newrelic.com/infrastructure_agent/gpg/newrelic-infra.gpg | apt-key add -
    echo "deb https://download.newrelic.com/infrastructure_agent/linux/apt $(lsb_release -cs) main" | \
         tee /etc/apt/sources.list.d/newrelic-infra.list
    apt-get update
    apt-get install newrelic-infra -y
fi

# 設定ファイル作成
cat > /etc/newrelic-infra.yml << EOF
license_key: ${NEW_RELIC_LICENSE_KEY}
display_name: ${VM_NAME}
verbose: 1

# Azure固有設定
custom_attributes:
  environment: production
  azure_subscription_id: ${SUBSCRIPTION_ID}
  azure_resource_group: ${RESOURCE_GROUP}
  azure_location: ${LOCATION}
  azure_vm_size: ${VM_SIZE}
  deployment_method: vm_extension

# Azure Monitor統合設定
enable_azure_monitor: true
azure_region: ${LOCATION}

# ログ設定
log_level: info
log_file: /var/log/newrelic-infra/newrelic-infra.log
EOF

# サービス開始
systemctl enable newrelic-infra
systemctl start newrelic-infra

echo "New Relic Infrastructure Agent installation completed"

ARM テンプレート

Infrastructure Agentを含むAzure VMをARM テンプレートで展開する例です。

json
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "newRelicLicenseKey": {
      "type": "secureString",
      "metadata": {
        "description": "New Relic License Key"
      }
    },
    "vmName": {
      "type": "string",
      "defaultValue": "newrelic-vm",
      "metadata": {
        "description": "Name of the VM"
      }
    },
    "vmSize": {
      "type": "string",
      "defaultValue": "Standard_B2s",
      "allowedValues": [
        "Standard_B1s",
        "Standard_B2s",
        "Standard_D2s_v3",
        "Standard_D4s_v3"
      ]
    },
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Admin username"
      }
    },
    "sshKeyData": {
      "type": "string",
      "metadata": {
        "description": "SSH public key"
      }
    }
  },
  "variables": {
    "vnetName": "newrelic-vnet",
    "subnetName": "default",
    "nsgName": "newrelic-nsg",
    "publicIPName": "newrelic-pip",
    "nicName": "newrelic-nic"
  },
  "resources": [
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2021-02-01",
      "name": "[variables('vnetName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": ["10.0.0.0/16"]
        },
        "subnets": [
          {
            "name": "[variables('subnetName')]",
            "properties": {
              "addressPrefix": "10.0.1.0/24"
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Network/networkSecurityGroups",
      "apiVersion": "2021-02-01",
      "name": "[variables('nsgName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "securityRules": [
          {
            "name": "SSH",
            "properties": {
              "priority": 1001,
              "protocol": "TCP",
              "access": "Allow",
              "direction": "Inbound",
              "sourceAddressPrefix": "*",
              "sourcePortRange": "*",
              "destinationAddressPrefix": "*",
              "destinationPortRange": "22"
            }
          },
          {
            "name": "HTTPS-Outbound",
            "properties": {
              "priority": 1002,
              "protocol": "TCP",
              "access": "Allow",
              "direction": "Outbound",
              "sourceAddressPrefix": "*",
              "sourcePortRange": "*",
              "destinationAddressPrefix": "*",
              "destinationPortRange": "443"
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2021-02-01",
      "name": "[variables('publicIPName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "publicIPAllocationMethod": "Dynamic"
      }
    },
    {
      "type": "Microsoft.Network/networkInterfaces",
      "apiVersion": "2021-02-01",
      "name": "[variables('nicName')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
        "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPName'))]",
        "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "subnet": {
                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), variables('subnetName'))]"
              },
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPName'))]"
              }
            }
          }
        ],
        "networkSecurityGroup": {
          "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]"
        }
      }
    },
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2021-03-01",
      "name": "[parameters('vmName')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
      ],
      "identity": {
        "type": "SystemAssigned"
      },
      "properties": {
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "osProfile": {
          "computerName": "[parameters('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "linuxConfiguration": {
            "disablePasswordAuthentication": true,
            "ssh": {
              "publicKeys": [
                {
                  "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]",
                  "keyData": "[parameters('sshKeyData')]"
                }
              ]
            }
          }
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "Canonical",
            "offer": "0001-com-ubuntu-server-focal",
            "sku": "20_04-lts-gen2",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "FromImage",
            "managedDisk": {
              "storageAccountType": "Premium_LRS"
            }
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
            }
          ]
        }
      }
    },
    {
      "type": "Microsoft.Compute/virtualMachines/extensions",
      "apiVersion": "2021-03-01",
      "name": "[concat(parameters('vmName'), '/NewRelicAgent')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]"
      ],
      "properties": {
        "publisher": "Microsoft.Azure.Extensions",
        "type": "CustomScript",
        "typeHandlerVersion": "2.1",
        "settings": {
          "script": "[base64(concat('#!/bin/bash\n\n# New Relic Infrastructure Agent Installation Script\n\nNEW_RELIC_LICENSE_KEY=\"', parameters('newRelicLicenseKey'), '\"\n\n# Install prerequisites\napt-get update\napt-get install -y curl jq\n\n# Get Azure metadata\nAZURE_METADATA_URL=\"http://169.254.169.254/metadata/instance?api-version=2021-02-01\"\nMETADATA=$(curl -s -H \"Metadata:true\" \"$AZURE_METADATA_URL\")\n\nVM_NAME=$(echo $METADATA | jq -r \".compute.name\")\nRESOURCE_GROUP=$(echo $METADATA | jq -r \".compute.resourceGroupName\")\nSUBSCRIPTION_ID=$(echo $METADATA | jq -r \".compute.subscriptionId\")\nLOCATION=$(echo $METADATA | jq -r \".compute.location\")\nVM_SIZE=$(echo $METADATA | jq -r \".compute.vmSize\")\n\n# Install New Relic Infrastructure Agent\ncurl -fsSL https://download.newrelic.com/infrastructure_agent/gpg/newrelic-infra.gpg | apt-key add -\necho \"deb https://download.newrelic.com/infrastructure_agent/linux/apt focal main\" | tee /etc/apt/sources.list.d/newrelic-infra.list\napt-get update\napt-get install newrelic-infra -y\n\n# Create configuration file\ncat > /etc/newrelic-infra.yml << EOF\nlicense_key: ${NEW_RELIC_LICENSE_KEY}\ndisplay_name: ${VM_NAME}\nverbose: 1\n\ncustom_attributes:\n  environment: production\n  azure_subscription_id: ${SUBSCRIPTION_ID}\n  azure_resource_group: ${RESOURCE_GROUP}\n  azure_location: ${LOCATION}\n  azure_vm_size: ${VM_SIZE}\n  deployment_method: arm_template\n\nlog_level: info\nEOF\n\n# Start and enable service\nsystemctl enable newrelic-infra\nsystemctl start newrelic-infra\n\necho \"New Relic Infrastructure Agent installation completed\"'))]"
        }
      }
    }
  ],
  "outputs": {
    "vmId": {
      "type": "string",
      "value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]"
    },
    "publicIpAddress": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPName'))).ipAddress]"
    }
  }
}

Azure統合の設定

New RelicでのAzure統合有効化

New Relicダッシュボードでの設定に必要な情報を準備します。

bash
# Azure統合に必要な情報の取得
az account show --query '{subscriptionId:id, tenantId:tenantId}'

# サービスプリンシパル情報(前述で作成したもの)
# - Application ID (Client ID)
# - Client Secret
# - Tenant ID
# - Subscription ID

PowerShellを使用したAzure統合設定

PowerShellスクリプトでAzure統合を自動化する例です。

powershell
# Azure-NewRelic-Integration.ps1

param(
    [Parameter(Mandatory=$true)]
    [string]$SubscriptionId,
    
    [Parameter(Mandatory=$true)]
    [string]$NewRelicAccountId,
    
    [Parameter(Mandatory=$true)]
    [string]$NewRelicApiKey
)

# Azure にログイン
Connect-AzAccount

# サブスクリプション設定
Set-AzContext -SubscriptionId $SubscriptionId

# New Relic用リソースグループの作成
$resourceGroupName = "NewRelic-Integration-RG"
$location = "East US"

New-AzResourceGroup -Name $resourceGroupName -Location $location

# サービスプリンシパルの作成
$sp = New-AzADServicePrincipal -DisplayName "NewRelic-Integration-SP"

# Reader ロールの割り当て
New-AzRoleAssignment -ObjectId $sp.Id -RoleDefinitionName "Reader" -Scope "/subscriptions/$SubscriptionId"

# 結果の表示
Write-Host "Azure Integration Configuration:"
Write-Host "Subscription ID: $SubscriptionId"
Write-Host "Tenant ID: $((Get-AzContext).Tenant.Id)"
Write-Host "Application ID: $($sp.ApplicationId)"
Write-Host "Client Secret: $($sp.PasswordCredentials.SecretText)"

# New Relic API呼び出し用の設定
$headers = @{
    'Api-Key' = $NewRelicApiKey
    'Content-Type' = 'application/json'
}

$body = @{
    cloudLinkAccount = @{
        name = "Azure Production Account"
        authLabel = "azure-integration"
        accountId = $NewRelicAccountId
    }
    cloudProvider = "azure"
    azureIntegration = @{
        applicationId = $sp.ApplicationId
        clientSecret = $sp.PasswordCredentials.SecretText
        subscriptionId = $SubscriptionId
        tenantId = (Get-AzContext).Tenant.Id
    }
} | ConvertTo-Json -Depth 3

# New Relic統合の有効化(API v2使用)
$apiUrl = "https://api.newrelic.com/v2/accounts/$NewRelicAccountId/cloud_link_accounts"

try {
    $response = Invoke-RestMethod -Uri $apiUrl -Method Post -Headers $headers -Body $body
    Write-Host "Azure integration successfully configured in New Relic"
    Write-Host "Integration ID: $($response.cloudLinkAccount.id)"
}
catch {
    Write-Error "Failed to configure Azure integration: $($_.Exception.Message)"
}

Azure Monitor との高度な連携

Log Analytics Workspace との統合

Azure Monitor LogsをNew Relicに転送するAzure Functionの設定です。

javascript
// Azure Function - Log Analytics to New Relic forwarder
const axios = require('axios');

module.exports = async function (context, req) {
    const newRelicEndpoint = 'https://log-api.newrelic.com/log/v1';
    const licenseKey = process.env.NEW_RELIC_LICENSE_KEY;
    
    if (!licenseKey) {
        context.res = {
            status: 400,
            body: "NEW_RELIC_LICENSE_KEY environment variable not set"
        };
        return;
    }
    
    try {
        // Azure Monitor Logs のデータを受信
        const logData = req.body;
        
        // New Relic形式に変換
        const transformedLogs = logData.map(log => ({
            timestamp: new Date(log.TimeGenerated).getTime(),
            message: log.Message || log.Description,
            attributes: {
                'azure.subscription_id': log.SubscriptionId,
                'azure.resource_group': log.ResourceGroup,
                'azure.resource_name': log.ResourceName,
                'azure.resource_type': log.ResourceType,
                'azure.category': log.Category,
                'azure.operation_name': log.OperationName,
                'azure.severity': log.SeverityLevel,
                'azure.correlation_id': log.CorrelationId
            }
        }));
        
        // New Relic にログを送信
        const headers = {
            'Content-Type': 'application/json',
            'X-License-Key': licenseKey
        };
        
        const response = await axios.post(
            newRelicEndpoint,
            { logs: transformedLogs },
            { headers }
        );
        
        context.log(`Successfully forwarded ${transformedLogs.length} logs to New Relic`);
        
        context.res = {
            status: 200,
            body: `Processed ${transformedLogs.length} log entries`
        };
        
    } catch (error) {
        context.log.error('Error processing logs:', error);
        
        context.res = {
            status: 500,
            body: `Error processing logs: ${error.message}`
        };
    }
};

Application Insights 統合

Application InsightsからNew Relicへのテレメトリ転送設定です。

json
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "functionAppName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Azure Function App"
      }
    },
    "newRelicLicenseKey": {
      "type": "secureString",
      "metadata": {
        "description": "New Relic License Key"
      }
    }
  },
  "variables": {
    "storageAccountName": "[concat(uniquestring(resourceGroup().id), 'azfunc')]",
    "hostingPlanName": "[concat(parameters('functionAppName'), '-plan')]"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2021-04-01",
      "name": "[variables('storageAccountName')]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage"
    },
    {
      "type": "Microsoft.Web/serverfarms",
      "apiVersion": "2021-02-01",
      "name": "[variables('hostingPlanName')]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Y1",
        "tier": "Dynamic"
      }
    },
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2021-02-01",
      "name": "[parameters('functionAppName')]",
      "location": "[resourceGroup().location]",
      "kind": "functionapp",
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
      ],
      "properties": {
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
        "siteConfig": {
          "appSettings": [
            {
              "name": "FUNCTIONS_WORKER_RUNTIME",
              "value": "node"
            },
            {
              "name": "FUNCTIONS_EXTENSION_VERSION",
              "value": "~4"
            },
            {
              "name": "AzureWebJobsStorage",
              "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2021-04-01').keys[0].value)]"
            },
            {
              "name": "NEW_RELIC_LICENSE_KEY",
              "value": "[parameters('newRelicLicenseKey')]"
            }
          ]
        }
      }
    }
  ]
}

Terraform を使用したAzure統合

TerraformでAzure統合を自動化する設定例です。

hcl
# main.tf
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0"
    }
    newrelic = {
      source  = "newrelic/newrelic"
      version = "~> 3.0"
    }
  }
}

# Azure Provider設定
provider "azurerm" {
  features {}
}

# New Relic Provider設定
provider "newrelic" {
  account_id = var.newrelic_account_id
  api_key    = var.newrelic_api_key
  region     = "US"
}

# Azure AD Application
resource "azuread_application" "newrelic" {
  display_name = "NewRelic-Integration"
  owners       = [data.azuread_client_config.current.object_id]
}

# Service Principal
resource "azuread_service_principal" "newrelic" {
  application_id               = azuread_application.newrelic.application_id
  app_role_assignment_required = false
  owners                       = [data.azuread_client_config.current.object_id]
}

# Service Principal Password
resource "azuread_service_principal_password" "newrelic" {
  service_principal_id = azuread_service_principal.newrelic.object_id
  end_date_relative    = "17520h" # 2 years
}

# Role Assignment
resource "azurerm_role_assignment" "newrelic_reader" {
  scope                = data.azurerm_subscription.current.id
  role_definition_name = "Reader"
  principal_id         = azuread_service_principal.newrelic.object_id
}

# New Relic Azure Integration
resource "newrelic_cloud_azure_link_account" "azure" {
  account_id      = var.newrelic_account_id
  application_id  = azuread_application.newrelic.application_id
  client_secret   = azuread_service_principal_password.newrelic.value
  subscription_id = data.azurerm_subscription.current.subscription_id
  tenant_id       = data.azuread_client_config.current.tenant_id
  name            = "Azure Production Account"
}

# Azure Service Integrations
resource "newrelic_cloud_azure_integrations" "azure_integrations" {
  account_id         = var.newrelic_account_id
  linked_account_id  = newrelic_cloud_azure_link_account.azure.id

  app_gateway {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  app_service {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  containers {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  cosmosdb {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  functions {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  key_vault {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  load_balancer {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  redis_cache {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  sql {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  sql_managed {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  storage {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  virtual_machine {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }

  virtual_networks {
    metrics_polling_interval = 300
    resource_groups         = ["production-rg"]
  }
}

# Data Sources
data "azurerm_subscription" "current" {}
data "azuread_client_config" "current" {}

# Variables
variable "newrelic_account_id" {
  description = "New Relic Account ID"
  type        = string
}

variable "newrelic_api_key" {
  description = "New Relic API Key"
  type        = string
  sensitive   = true
}

# Outputs
output "service_principal_id" {
  description = "Service Principal Object ID"
  value       = azuread_service_principal.newrelic.object_id
}

output "application_id" {
  description = "Azure Application ID"
  value       = azuread_application.newrelic.application_id
}

運用とベストプラクティス

タグベースの監視設定

Azureリソースのタグを活用した効率的な監視設定です。

yaml
# Infrastructure Agent でのAzureタグ活用設定
license_key: YOUR_LICENSE_KEY
display_name: production-vm-01

# Azure タグの自動取得
enable_azure_tags: true
azure_tags_include:
  - Environment
  - Application
  - Team
  - CostCenter
  - Owner

# タグベースの条件付き設定
conditional_config:
  - condition: "tags.Environment == 'production'"
    config:
      verbose: 0
      metrics_process_sample_rate: 15
  - condition: "tags.Environment == 'development'"
    config:
      verbose: 1
      metrics_process_sample_rate: 60

コスト最適化設定

Azure統合のコストを最適化するための設定です。

hcl
# コスト最適化されたAzure統合設定
resource "newrelic_cloud_azure_integrations" "cost_optimized" {
  account_id        = var.newrelic_account_id
  linked_account_id = newrelic_cloud_azure_link_account.azure.id

  # 重要なサービスのみ有効化
  virtual_machine {
    metrics_polling_interval = 600  # 10分間隔
    resource_groups         = ["production-rg"]
  }

  app_service {
    metrics_polling_interval = 600
    resource_groups         = ["production-rg"]
  }

  sql {
    metrics_polling_interval = 900  # 15分間隔
    resource_groups         = ["production-rg"]
  }

  # 開発環境は除外
  # storage, redis_cache, etc. は必要に応じて有効化
}

セキュリティ考慮事項

最小権限の原則

より厳密な権限設定を適用するカスタムロール定義です。

json
{
  "Name": "New Relic Integration Reader",
  "IsCustom": true,
  "Description": "Minimal permissions for New Relic Azure integration",
  "Actions": [
    "Microsoft.Compute/virtualMachines/read",
    "Microsoft.Compute/virtualMachineScaleSets/read",
    "Microsoft.Storage/storageAccounts/read",
    "Microsoft.Storage/storageAccounts/listKeys/action",
    "Microsoft.Sql/servers/read",
    "Microsoft.Sql/servers/databases/read",
    "Microsoft.Web/sites/read",
    "Microsoft.KeyVault/vaults/read",
    "Microsoft.Network/loadBalancers/read",
    "Microsoft.Network/applicationGateways/read",
    "Microsoft.Insights/metrics/read",
    "Microsoft.Insights/metricDefinitions/read"
  ],
  "NotActions": [],
  "DataActions": [],
  "NotDataActions": [],
  "AssignableScopes": [
    "/subscriptions/YOUR_SUBSCRIPTION_ID"
  ]
}

Private Endpoint 設定

セキュアな通信のためのPrivate Endpoint設定です。

json
{
  "type": "Microsoft.Network/privateEndpoints",
  "apiVersion": "2021-02-01",
  "name": "newrelic-private-endpoint",
  "location": "[resourceGroup().location]",
  "properties": {
    "subnet": {
      "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet-name', 'subnet-name')]"
    },
    "privateLinkServiceConnections": [
      {
        "name": "newrelic-connection",
        "properties": {
          "privateLinkServiceId": "/subscriptions/subscription-id/resourceGroups/rg-name/providers/Microsoft.Network/privateLinkServices/newrelic-pls",
          "groupIds": ["newrelic"]
        }
      }
    ]
  }
}

まとめ

Azure環境でのNew Relic Infrastructure Agent導入とAzure統合設定により、Virtual MachineからAzureマネージドサービスまでの包括的な監視が実現できます。適切なサービスプリンシパル設定とリソースグループベースの管理により、セキュリティを保ちながら効率的な運用が可能になります。

ARM テンプレートやTerraformを活用したInfrastructure as Codeアプローチにより、一貫性のある監視環境を大規模に展開できるでしょう。次回は、GCP統合設定について詳しく解説します。


関連記事: AWS統合設定関連記事: GCP統合設定