# Azure gateway

# Introduction

<div id="bkmrk-this-discovery-plu"><div>This Azure Application Gateway discovery plugin for Pandora FMS is designed to automate the monitoring of **Azure Application Gateway** resources in an Azure subscription. The plugin dynamically discovers the available Application Gateways, collects their main metrics through Azure Monitor and generates agents and modules in Pandora FMS.</div><div>The plugin can work in two modes: creating one agent for each discovered Application Gateway, or sending all modules to a single agent configured by the user. It also supports resource group filtering, custom prefixes, discovered entity cache control, metric group selection and module filtering with allow and deny regular expressions.</div><div>The implemented metrics are based on Azure Application Gateway metrics, including performance, requests, backend health, latency, traffic, security, capacity, WebSocket, WAF and resource count metrics.</div></div>

# Prerequisites

- The plugin is distributed as a compiled binary that already contains all required dependencies, so Python or additional libraries are not required on the server where it runs.
- An Azure subscription with **Azure Application Gateway** resources available for monitoring is required.
- Azure credentials must be provided through a **Service Principal** with read permissions over the subscription or over the resource group to be monitored.
- 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 that simulates Azure Application Gateway responses. In production it must be left empty.

# Parameters

**Advanced mode**

<table border="1" id="bkmrk-azure-application-gateway-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 = Pandora FMS agent group ID where the agents will be created.
interval = task monitoring interval 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 = optional Azure resource group to monitor. If left empty, Application Gateways from the whole subscription are discovered.
target_agent = target agent used when one agent per Application Gateway is not created.
agent_per_application_gateway = creates one agent per discovered Application Gateway.
application_gateway_agent_prefix = optional prefix for the agents created per Application Gateway.
modules_prefix = optional prefix for module names.
scan_application_gateways = enables automatic Application Gateway discovery.
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 in seconds.
time_window = time window in minutes used to query Azure Monitor metrics.
metric_interval = Azure Monitor metric granularity in ISO-8601 format, for example PT1M.
metric_timeout = timeout in seconds for Azure API calls. If set to 0 or a negative value, the plugin uses 30 seconds.
max_retries = maximum number of retries for temporary API errors, including HTTP 429 rate limiting.
output_format = output format. Use json for Discovery and xml for manual tests.
module_allow_list_file = optional file with allowed module regular expressions, one per line.
module_deny_list_file = optional file with denied module regular expressions, one per line.
check_performance_modules = enables performance modules.
check_request_modules = enables request modules.
check_backend_modules = enables backend modules.
check_latency_modules = enables latency modules.
check_traffic_modules = enables traffic modules.
check_security_modules = enables security modules.
check_capacity_modules = enables capacity modules.
check_waf_modules = enables WAF modules.
check_websocket_modules = enables WebSocket modules.
check_application_gateway_count = enables the Application Gateway count module.
mock_api_url = optional Azure mock URL for local testing. It must be left empty in production.

```

**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
target_agent = Azure Application Gateways
agent_per_application_gateway = 1
application_gateway_agent_prefix = Azure Application Gateway 
modules_prefix =
scan_application_gateways = 1
entities_list = /tmp/tmp_discovery.azure_application_gateway.entities
enable_entities_interval = 1
entities_interval = 3600
time_window = 5
metric_interval = PT1M
metric_timeout = 30
max_retries = 2
output_format = json
module_allow_list_file =
module_deny_list_file =
check_performance_modules = 1
check_request_modules = 1
check_backend_modules = 1
check_latency_modules = 1
check_traffic_modules = 1
check_security_modules = 1
check_capacity_modules = 1
check_waf_modules = 1
check_websocket_modules = 1
check_application_gateway_count = 1
mock_api_url =

```

# Create Service Principal

An Azure 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-application-gateway-discovery \
  --role Reader \
  --scopes /subscriptions/<SUBSCRIPTION_ID>

```

The command returns an output similar to this:

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

```

The mapping 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-for-the-plugin-to"><div>To discover Application Gateways and query their metrics, it is recommended to use a Service Principal with read permissions.</div></div><div id="bkmrk-"></div>The plugin requires read permissions to: - List **Microsoft.Network/applicationGateways** resources.
- Read the basic Application Gateway configuration, including SKU and resource group.
- Query Azure Monitor metrics associated with the resource.

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

# Manual execution

The plugin execution format is:

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

```

Example:

```bash
./pandora_azure_gateway --conf /etc/pandora/azure_application_gateway.conf

```

In Discovery mode, Pandora FMS automatically generates the temporary configuration file and runs 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. If `xml` is selected, the plugin generates XML output for manual tests.

# Discovery

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

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

Once uploaded, Azure Application Gateway resources can be monitored by creating *Discovery* tasks from the Cloud/Application Discovery section.

Each task asks for the following data in the **Azure Base** step:

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

The **Application Gateway Options** step contains additional options:

- **Target agent:** target agent where all modules are stored when one agent per Application Gateway is not enabled.
- **Create one agent per Application Gateway:** when enabled, each Application Gateway creates its own agent. When disabled, all modules are sent to the agent configured in **Target agent**.
- **Application Gateway agent prefix:** optional prefix for agents created per Application Gateway. For example, `Azure Application Gateway ` creates agents such as `Azure Application Gateway agw-production`.
- **Modules prefix:** optional prefix for all generated module names.
- **Scan Application Gateways:** enables automatic Application Gateway discovery.
- **Entities file:** temporary file where discovered resource cache is stored.
- **Enable entities file re-scan interval:** enables periodic refresh of the temporary discovered entities file.
- **Entities re-scan interval:** interval used to rebuild the entity cache when re-scan is enabled.
- **Mock Azure API URL:** optional URL for local tests. It must be left empty in production.

The **Metrics** step contains metric and filtering options:

- **Metrics time window:** time window used to query Azure Monitor metrics.
- **Azure metric interval:** Azure Monitor granularity in ISO-8601 format. Default value is `PT1M`.
- **Metric timeout:** timeout in seconds for each Azure call. If set to `0` or a negative value, the plugin uses `30` seconds.
- **Max retries:** maximum number of retries for temporary API errors, including HTTP 429 rate limiting.
- **Output format:** output format generated by the plugin. `JSON` must be used for Discovery.
- **Performance modules:** creates CPU, current connections, throughput and new connections per second modules.
- **Request modules:** creates failed requests, HTTP status and total requests modules.
- **Backend modules:** creates healthy hosts, unhealthy hosts, requests per healthy host and backend HTTP status modules.
- **Latency modules:** creates backend connection time, first byte response time, last byte response time, total time and client RTT modules.
- **Traffic modules:** creates bytes sent and bytes received modules.
- **Security modules:** creates TLS protocol, backend TLS negotiation error and rejected connections modules.
- **Capacity modules:** creates compute units, capacity units, estimated billed capacity units and fixed billable capacity units modules. These metrics apply to v2 SKUs.
- **WAF modules:** creates WAF matched, blocked, request, rule, bot protection, challenge and penalty box modules. These metrics apply to WAF SKUs.
- **WebSocket modules:** creates WebSocket active connections and WebSocket close status code modules.
- **Application Gateway count module:** creates the discovered Application Gateway count module.
- **Modules allow regexp:** allows defining allowed module regular expressions, one per line. If configured, only modules whose final name matches one expression are created.
- **Modules deny regexp:** allows defining denied module regular expressions, one per line. If a module matches this list, it is not created.

Successful tasks include an execution summary similar to:

- **application\_gateways\_discovered:** number of Application Gateways discovered in the current execution.
- **application\_gateways\_vanished:** number of previously stored Application Gateways that no longer appear in the current discovery.
- **modules:** total number of generated modules.
- **errors:** number of errors detected during execution.
- **scan\_source:** scan origin, `azure` when Azure is queried or `entities_cache` when the cache is reused.

# Agents and modules generated

The plugin creates an `Application Gateway Connection` module for each monitored Application Gateway. This module has value `1` when the resource is available and value `0` when a resource stored in the entity cache no longer appears in Azure.

If **Create one agent per Application Gateway** is enabled, one agent is created for each discovered Application Gateway. The agent name is built using the configured **Application Gateway agent prefix** plus the Application Gateway name.

Example:

```text
Application Gateway agent prefix: Azure Application Gateway 
Application Gateway name: agw-production-frontend
Agent name: Azure Application Gateway agw-production-frontend

```

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

The available modules are:

```bash
Application Gateway Connection: Azure Application Gateway resource status (1=UP, 0=DOWN). Created as generic_proc.
CPU Utilization: Application Gateway CPU usage.
Current Connections: Number of current connections.
Failed Requests: Number of failed requests.
HTTP Status: HTTP status code count.
Throughput: Average Application Gateway throughput.
Total Requests: Total number of requests.
Healthy Host Count: Number of healthy backend hosts.
Unhealthy Host Count: Number of unhealthy backend hosts.
Average Request Count Per Healthy Host: Average request count per healthy backend host.
Backend Connect Time: Backend connection time.
Backend First Byte Response Time: Time to first backend response byte.
Backend Last Byte Response Time: Time to last backend response byte.
Application Gateway Total Time: Total time processed by Application Gateway.
Client RTT: Client round trip time.
Bytes Sent: Bytes sent.
Bytes Received: Bytes received.
TLS Protocol: TLS protocol count.
Compute Units: Compute units. Only applies to v2 SKUs.
Capacity Units: Capacity units. Only applies to v2 SKUs.
Estimated Billed Capacity Units: Estimated billed capacity. Only applies to v2 SKUs.
Fixed Billable Capacity Units: Fixed billable capacity. Only applies to v2 SKUs.
New Connections Per Second: New connections per second. Only applies to v2 SKUs.
Backend HTTP Status: HTTP status codes returned by backend servers.
WAF Matched Count: WAF matches. Only applies to WAF SKUs.
WAF Blocked Requests: Requests blocked by WAF. Only applies to WAF SKUs.
WAF Blocked Count: WAF block count. Only applies to WAF SKUs.
WAF Total Requests: Total requests processed by WAF. Only applies to WAF SKUs.
WAF Security Rule: WAF security rule matches. Only applies to WAF SKUs.
WAF Custom Rule: WAF custom rule matches. Only applies to WAF SKUs.
WAF Bot Protection: WAF bot protection events. Only applies to WAF SKUs.
Backend TLS Negotiation Error: Backend TLS negotiation errors.
Rejected Connections: Rejected connections.
Application Gateway Count: Discovered Application Gateway resource count.
WAF JS Challenge Request Count: WAF JS challenge requests. Only applies to WAF SKUs.
WAF Penalty Box Hits: WAF penalty box hits. Only applies to WAF SKUs.
WAF Penalty Box Size: WAF penalty box size. Only applies to WAF SKUs.
WebSocket Active Connections: Active WebSocket connections.
WebSocket Specific Close Status Code: WebSocket close status codes.
WAF Captcha Challenge Request Count: WAF CAPTCHA challenge requests. Only applies to WAF SKUs.

```

**Module type mapping**

<table id="bkmrk-azure-application-gateway-module-types"><thead><tr><th>Metric</th><th>Pandora FMS module type</th><th>Azure aggregation</th><th>Description</th></tr></thead><tbody><tr><td>Application Gateway Connection</td><td>`generic\_proc`</td><td></td><td>Azure Application Gateway resource status. Value 1 when available and 0 when it is not discovered in the current execution.</td></tr><tr><td>CPU Utilization</td><td>`generic\_data`</td><td>Average</td><td>Application Gateway CPU usage.</td></tr><tr><td>Current Connections</td><td>`generic\_data`</td><td>Average</td><td>Current connections.</td></tr><tr><td>Failed Requests</td><td>`generic\_data`</td><td>Total</td><td>Failed requests.</td></tr><tr><td>HTTP Status</td><td>`generic\_data`</td><td>Total</td><td>HTTP status count.</td></tr><tr><td>Throughput</td><td>`generic\_data`</td><td>Average</td><td>Average throughput.</td></tr><tr><td>Total Requests</td><td>`generic\_data`</td><td>Total</td><td>Total requests.</td></tr><tr><td>Backend and latency metrics</td><td>`generic\_data`</td><td>Average or Total</td><td>Backend, latency, traffic, security, capacity, WAF and WebSocket metrics returned by Azure Monitor.</td></tr></tbody></table>

**Allow and deny regexp**

The module filter is applied to the final module name, after the prefix configured in **Modules prefix** has been applied. Each textarea line is interpreted as a regular expression.

Example **Modules allow regexp**:

```text
CPU|Throughput
Backend.*

```

With this configuration, only modules whose name matches `CPU|Throughput` or `Backend.*` are created.

Example **Modules deny regexp**:

```text
Bytes
WAF.*

```

With this configuration, all modules whose name contains `Bytes` or starts with `WAF` are discarded.

If both filters are configured, the module must match the allow filter and must not match the deny filter. The deny filter can be used to discard specific modules even when the general group is enabled.

**Discovered entity cache**

The plugin uses a temporary `entities_list` file to store discovered Application Gateways. This logic allows the plugin to detect resources that existed in previous executions and later disappeared from Azure.

When an Application Gateway is stored in the entity file but no longer appears in the current discovery, the plugin keeps its agent and generates the `Application Gateway Connection` module with value `0`. This allows Pandora FMS to alert about the missing resource instead of silently removing it from monitoring.

If **Enable entities file re-scan interval** is enabled, the entities file is refreshed when the interval configured in **Entities re-scan interval** is exceeded. If it is disabled, the discovered entity list is preserved to detect disappeared resources.