# Azure Load Balancer

# Introduction

<div id="bkmrk-este-plugin-de-disco"><div>This Azure Load Balancer discovery plugin for Pandora FMS is designed to automate the monitoring of **Azure Load Balancer** resources in an Azure subscription. The plugin dynamically discovers the available Load Balancers, retrieves their main metrics through Azure Monitor, and generates agents and modules in Pandora FMS.</div><div>The plugin can work in two ways: by creating one agent for each discovered Load Balancer, or by sending all modules to a single agent configured by the user. It also allows filtering by resource group, applying custom prefixes, controlling the discovered entities cache, and selecting module groups according to the type of metric to monitor.</div><div>The implemented metrics are based on the metrics used for Azure Load Balancer, including availability, health probe status, traffic, SYN packets, SNAT port usage, and backend pool host count.</div></div>

# Prerequisites

- The plugin is distributed as a compiled binary that already contains all the required dependencies, so it does not require installing Python or additional libraries on the server where it runs.
- An Azure subscription with **Azure Load Balancer** resources that can be queried by the plugin is required.
- Azure credentials through a **Service Principal** with read permissions over the subscription or over the resource group to be monitored are required.
- The Service Principal must be able to list network resources and query Azure Monitor metrics.
- In test environments, the **Mock Azure API URL** field can be used to point to a mock container that simulates Azure Load Balancer responses.

# Parameters

**Advanced mode**

<table border="1" id="bkmrk-azure-load-balancer-advanced-params"><tbody><tr><td>--conf</td><td>path to the configuration file generated by the Discovery task.</td></tr></tbody></table>

**Configuration file (--conf)**

```ini
agents_group_id = ID of the Pandora FMS agent group where the agents will be created.
interval = monitoring interval of the task in seconds.
subscription_id = Azure subscription identifier.
tenant_id = Azure Active Directory tenant identifier.
client_id = Service Principal application identifier.
client_secret = Service Principal secret.
resource_group = Azure resource group to monitor, optional. If left empty, Load Balancers from the whole subscription are discovered.
threads = maximum number of execution threads.
target_agent = target agent when one agent is not created for each Load Balancer.
modules_prefix = optional prefix for module names.
scan_load_balancers = enables automatic Load Balancer discovery.
agent_per_load_balancer = creates one agent for each discovered Load Balancer.
lb_agent_prefix = optional prefix for the name of the agents created per Load Balancer.
entities_list = path to the temporary file where discovered entities are stored.
enable_entities_interval = enables periodic refresh of the entities file.
entities_interval = entities file refresh interval.
time_window = time window used to query Azure Monitor metrics.
check_availability_modules = enables availability modules.
check_traffic_modules = enables traffic modules.
check_snat_modules = enables SNAT modules.
check_backend_pool_host_count = enables the backend pool host count module.
check_load_balancer_count = enables the Load Balancer count module.
metric_interval = Azure Monitor metric granularity in ISO-8601 format, for example PT1M.
metric_timeout = timeout in seconds for Azure API calls. If 0 or a negative value is configured, the plugin will use 30 seconds.
max_retries = maximum number of retries for temporary API errors, including HTTP 429 rate limiting.
mock_api_url = optional Azure mock URL for local testing. In production, it must be left empty.


```

**Example**

```ini
[CONF]
agents_group_id = 10
interval = 300
subscription_id = 00000000-0000-0000-0000-000000000000
tenant_id = 11111111-1111-1111-1111-111111111111
client_id = 22222222-2222-2222-2222-222222222222
client_secret = my_client_secret
resource_group = rg-production
threads = 1
target_agent = Azure Load Balancer
modules_prefix =
scan_load_balancers = 1
agent_per_load_balancer = 1
lb_agent_prefix = Azure LB 
entities_list = /tmp/tmp_discovery.azure_load_balancer.entities
enable_entities_interval = 0
entities_interval = 86400
time_window = 300
check_availability_modules = 1
check_traffic_modules = 1
check_snat_modules = 1
check_backend_pool_host_count = 1
check_load_balancer_count = 1
metric_interval = PT1M
metric_timeout = 30
max_retries = 3
mock_api_url =


```

**Example using a local mock**

```ini
[CONF]
agents_group_id = 10
interval = 300
subscription_id = test-subscription
tenant_id = test-tenant
client_id = test-client
client_secret = test-secret
resource_group =
threads = 1
target_agent = Azure Load Balancer
modules_prefix =
scan_load_balancers = 1
agent_per_load_balancer = 1
lb_agent_prefix = Azure LB 
entities_list = /tmp/azure_lb_mock.entities
enable_entities_interval = 0
entities_interval = 86400
time_window = 300
check_availability_modules = 1
check_traffic_modules = 1
check_snat_modules = 1
check_backend_pool_host_count = 1
check_load_balancer_count = 1
metric_interval = PT1M
metric_timeout = 30
max_retries = 3
mock_api_url = http://azure-load-balancer-mock:8080


```

# Create Service Principal

A Service Principal with the `Reader` role over a subscription can be created from Azure CLI:

```bash
az ad sp create-for-rbac \
  --name pandora-azure-lb-discovery \
  --role Reader \
  --scopes /subscriptions/<SUBSCRIPTION_ID>


```

The output will return values similar to these:

```json
{
  "appId": "<CLIENT_ID>",
  "displayName": "pandora-azure-lb-discovery",
  "password": "<CLIENT_SECRET>",
  "tenant": "<TENANT_ID>"
}


```

The correspondence with the plugin fields is:

```text
tenant       -> Azure Tenant ID
appId        -> Azure Client ID
password     -> Azure Client Secret
subscription -> Azure Subscription ID


```

# Requirements

<div id="bkmrk-para-que-el-plugin-p"><div>For the plugin to discover Load Balancers and query their metrics, it is recommended to use a Service Principal with read permissions.</div></div><div id="bkmrk-"></div>The plugin needs read permissions to: - List **Microsoft.Network/loadBalancers** resources.
- Read backend pool configuration.
- Query Azure Monitor metrics associated with the resource.

In most environments, the `Reader` role over the subscription or over the resource group will be enough. If the permission is limited to a single resource group, it is also recommended to configure the **Resource group** field in the Discovery task.

# Manual execution

The plugin execution format is as follows:

```bash
./pandora_azure_load_balancer --conf <path to configuration file>

```

Example:

```bash
./pandora_azure_load_balancer --conf /etc/pandora/azure_load_balancer.conf

```

In Discovery mode, Pandora FMS automatically generates the temporary configuration file and executes the binary with the `--conf` parameter.

The execution returns JSON output with summary information and monitoring data in the `monitoring_data` field, so it can be consumed by the Discovery server.

# Discovery

This plugin can be integrated with Pandora FMS *Discovery*.

To do this, the corresponding `.disco` package must be uploaded from the Pandora FMS library or from the console plugin system.

Once loaded, Azure Load Balancer resources can be monitored by creating *Discovery* tasks from the corresponding Cloud/Application Discovery section.

For each task, the following data will be requested in the **Azure Base** step:

- **Azure Subscription ID:** identifier of the Azure subscription where Load Balancers will be discovered.
- **Azure Tenant ID:** identifier of the Azure Active Directory tenant used by the Service Principal.
- **Azure Client ID:** application identifier of the Service Principal.
- **Azure Client Secret:** Service Principal secret.
- **Resource group:** optional filter to limit discovery to one resource group. If left empty, Load Balancers from the whole subscription are discovered.

In the **Azure Load Balancer Detailed** step, additional options can be configured:

- **Max threads:** maximum number of threads used to process the discovered Load Balancers.
- **Target agent:** target agent where all modules will be stored when agent creation per Load Balancer is not enabled.
- **Custom module prefix:** optional prefix for all generated module names.
- **Scan Load Balancers:** enables automatic Load Balancer discovery.
- **Create agent per Load Balancer:** if enabled, each Load Balancer generates its own agent. If disabled, all modules are sent to the agent indicated in **Target agent**.
- **Custom Load Balancer agent prefix:** optional prefix for agents created per Load Balancer. For example, `Azure LB ` will create agents such as `Azure LB my-load-balancer`.
- **Enable entities file re-scan interval:** enables periodic refresh of the temporary discovered entities file.
- **Re-scan entities file interval:** interval used to rebuild the entities cache when re-scan is enabled.
- **Metric time window:** time window used to query Azure Monitor metrics. It should normally match or be slightly higher than the task interval.
- **Availability metrics:** creates availability modules: `data path availability` and `health probe status`.
- **Traffic metrics:** creates traffic modules: `byte count`, `packet count`, and `SYN count`.
- **SNAT metrics:** creates SNAT modules: `allocated SNAT ports`, `used SNAT ports`, and `SNAT connection count`.
- **Backend pool host count:** creates the backend pool configured hosts count module.
- **Load Balancer count:** creates the discovered Load Balancer resource count module.
- **Azure Monitor metric interval:** Azure Monitor granularity in ISO-8601 format. Default is `PT1M`.
- **Azure API timeout:** timeout in seconds for each Azure call. If `0` or a negative value is configured, the plugin will use `30` seconds.
- **Azure API max retries:** maximum number of retries for temporary API errors, including HTTP 429 rate limiting.

Successfully completed tasks will have an execution summary with information similar to:

- **Total agents:** total number of agents generated by the task.
- **Targets up:** number of Load Balancers available or correctly discovered.
- **Targets down:** number of previously stored Load Balancers that no longer appear in the current discovery.
- **Load Balancers discovered:** number of Load Balancers discovered in the current execution.

# Agents and modules generated by the plugin

The plugin creates a `connection` module for each monitored Load Balancer. This module is always created, with value `1` when the resource is available and `0` when the resource stored in the entities cache no longer appears in Azure.

If **Create agent per Load Balancer** is enabled, one agent is created for each discovered Load Balancer. The agent name is built using the prefix configured in **Custom Load Balancer agent prefix** plus the Load Balancer name.

Example:

```text
Custom Load Balancer agent prefix: Azure LB 
Load Balancer name: lb-production-frontend
Agent name: Azure LB lb-production-frontend


```

If **Create agent per Load Balancer** is disabled, all modules are sent to the agent indicated in **Target agent**. In this mode, the Load Balancer name is added as a prefix to each module name to avoid collisions.

The available modules are:

```bash
connection: Azure Load Balancer resource status (1=UP, 0=DOWN). Always monitored (generic_proc).
allocated SNAT ports: Number of SNAT ports allocated in the selected period (generic_data).
backend pool host count: Number of hosts configured in the Load Balancer backend pools (generic_data).
byte count: Bytes transmitted in the selected period (generic_data_inc).
health probe status: Average status of the Load Balancer health probes (generic_data).
packet count: Packets transmitted in the selected period (generic_data_inc).
SNAT connection count: New SNAT connections created in the selected period (generic_data_inc).
load balancer count: Discovered Load Balancer resource count (generic_data).
SYN count: SYN packets transmitted in the selected period (generic_data_inc).
used SNAT ports: Number of SNAT ports used in the selected period (generic_data).
data path availability: Average availability of the Load Balancer data path (generic_data).


```

> The `byte count`, `packet count`, `SNAT connection count`, and `SYN count` modules are `generic_data_inc` type. Since they are incremental counters, Pandora FMS may need two executions before displaying the calculated data correctly.

**Module type mapping**

<table id="bkmrk-azure-load-balancer-module-types"><thead><tr><th>Metric</th><th>Pandora FMS module type</th><th>Unit</th><th>Description</th></tr></thead><tbody><tr><td>connection</td><td>`generic\_proc`</td><td></td><td>Azure Load Balancer resource status. Value 1 if available and 0 if it is not discovered in the current execution.</td></tr><tr><td>allocated SNAT ports</td><td>`generic\_data`</td><td>ports</td><td>Number of SNAT ports allocated during the selected window.</td></tr><tr><td>backend pool host count</td><td>`generic\_data`</td><td>hosts</td><td>Number of hosts configured in backend pools. It is calculated from the Load Balancer configuration.</td></tr><tr><td>byte count</td><td>`generic\_data\_inc`</td><td>bytes</td><td>Bytes transmitted. Pandora FMS calculates the rate from the incremental counter.</td></tr><tr><td>health probe status</td><td>`generic\_data`</td><td>%</td><td>Average status of health probe checks.</td></tr><tr><td>packet count</td><td>`generic\_data\_inc`</td><td>packets</td><td>Packets transmitted. Pandora FMS calculates the rate from the incremental counter.</td></tr><tr><td>SNAT connection count</td><td>`generic\_data\_inc`</td><td>connections</td><td>New SNAT connections created in the selected window.</td></tr><tr><td>load balancer count</td><td>`generic\_data`</td><td>count</td><td>Discovered Load Balancer resource count. The plugin reports 1 for each Load Balancer.</td></tr><tr><td>SYN count</td><td>`generic\_data\_inc`</td><td>packets</td><td>SYN packets transmitted. Pandora FMS calculates the rate from the incremental counter.</td></tr><tr><td>used SNAT ports</td><td>`generic\_data`</td><td>ports</td><td>Number of SNAT ports used during the selected window.</td></tr><tr><td>data path availability</td><td>`generic\_data`</td><td>%</td><td>Average availability of the Load Balancer data path.</td></tr></tbody></table>

The plugin can assign stable identifiers to agents and modules to make later identification easier from the console, dashboards, extensions, or SQL queries. The recommended external identifier for these data is the Azure `resource_id` or the Load Balancer name.

Recommended format:

- **Agent:** `azure_load_balancer:target:<sanitized_resource_id>` — identifies the monitored Load Balancer.
- **Connection module:** `azure_load_balancer:metric_connection:<sanitized_resource_id>`.
- **Metric modules:** `azure_load_balancer:metric_<metric_name>:<sanitized_resource_id>`.

These markers must be stable and must not depend only on the visible agent or module name, because those fields may change due to prefix configuration.

**Discovered entities cache**

The plugin uses a temporary `entities_list` file to store discovered Load Balancers. This logic makes it possible to detect resources that existed in previous executions and later disappeared from Azure.

When a Load Balancer is stored in the entities file but no longer appears in the current discovery, the plugin keeps its agent and generates the `connection` module with value `0`. This allows Pandora FMS to alert on the disappearance of the resource instead of silently removing it from monitoring.

If **Enable entities file re-scan interval** is enabled, the entities file is cleaned and rebuilt when the interval configured in **Re-scan entities file interval** is exceeded. If left disabled, the list of discovered entities is kept to allow detection of disappearances.