# Azure Monitor

Azure Monitor collects telemetry from your Azure resources and applications.
Relyance AI queries its Log Analytics workspaces to map the internal services,
connections and endpoints your systems actually talk to.

### What you'll need

- An Entra ID (Azure AD) app registration with a client secret.
- The **Tenant ID** and **Subscription ID** the Log Analytics workspaces live in.

### Permissions Relyance needs

| Permission | Used for |
| --- | --- |
| `Data.Read` | running queries against a Log Analytics workspace (`/v1/workspaces/:workspaceId/query`) |
| `User.Read` | reading the app's own directory profile during sign-in |

Relyance also lists the workspaces available to the app
(`providers/Microsoft.OperationalInsights/workspaces`), so the app registration
needs a read role — **Log Analytics Reader** on the subscription, or on each
workspace individually — in addition to the API permissions above. Everything
requested is read-only.

### In Microsoft Azure

1. In **Entra ID › App registrations**, click **New registration** and name it
   e.g. `Relyance Integration`.
2. Copy the **Application (client) ID** and the **Directory (tenant) ID** from the
   Overview page.
3. Under **Certificates & secrets**, create a **New client secret** and copy its
   **Value** immediately — it is shown only once.
4. Under **API permissions**, add **Log Analytics API › Data.Read** and
   **Microsoft Graph › User.Read**, then grant admin consent for the tenant.
5. In the subscription (or each workspace) **Access control (IAM)**, assign the
   app the **Log Analytics Reader** role.

### In the Relyance AI application

1. Log in to your Relyance account.
2. Navigate to **Settings › Integrations**, open the **Infrastructure
   Integrations** view, and find the **Azure Monitor** card.
3. Click **Add Connection**, give it a name, and click **Add**.
4. On the **Overview** step, select the features you want and click **Continue**.
5. On the **Connection** step, set the rescan frequency, then click **Continue**.
6. On the **Authentication** step, choose **Custom** under **Authentication
   Method** and open the **Account Details** JSON editor. It is a JSON *array*, so
   one connection can cover several subscriptions — add an object per
   subscription, with `product` naming the internal product its telemetry belongs
   to:

    ```json
    [
      {
        "tenant_id": "",
        "subscription_id": "",
        "client_id": "",
        "client_secret": "",
        "product": ""
      }
    ]
    ```
7. Click **Authenticate**, then **Finish**.
8. Confirm the connection shows **Connected**.

### Verify the connection is really working

1. A failure at **Authenticate** is usually the client secret — check it was
   copied before leaving the Azure page, and that it has not expired. Azure
   secrets carry an expiry date, so a connection that worked for months can stop
   for this reason alone; record the date on the connection's **Credentials
   expiry** field and Relyance will remind you.
2. Connected but nothing discovered generally means admin consent was not granted
   for `Data.Read`, or the app has no read role on the workspaces — listing
   workspaces and querying them are authorised separately.

<!-- terraform-examples:begin (generated from the integration catalog; do not hand-edit) -->

## Manage this integration with Terraform

Connections for this integration can be managed as code with the [Relyance Terraform provider](https://registry.terraform.io/providers/Relyance/relyance/latest). Non-secret fields go in `auth.params`; secret fields go in `auth.secrets_wo`, which is write-only — never stored in Terraform state. Rotate secrets by bumping `auth.secrets_wo_version`.

```hcl
resource "relyance_integration_connection" "azure_monitor" {
  vendor = "azure_monitor"
  name   = "<your connection name>"

  auth = {
    method = "account-credentials"
    # NOTE: accounts carries credentials (client_secret) but is not flagged
    # secret, so it goes in params and IS written to Terraform state in
    # cleartext. Keep state in an encrypted remote backend with restricted
    # access, and rotate the credential if state was ever committed.
    params = {
      accounts = jsonencode([
        {
          client_id = ""
          client_secret = ""
          product = ""
          subscription_id = ""
          tenant_id = ""
        }
      ])
    }
  }

  scans = { "data-inspection" = { enabled = true } }
}
```

<!-- terraform-examples:end -->
