Creación de un conector sin código de extracción para Microsoft Sentinel

Codeless Connector Framework (CCF) proporciona a los asociados, usuarios avanzados y desarrolladores la capacidad de crear conectores personalizados para ingerir datos en Microsoft Sentinel.

Los conectores pueden ser conectores de recogida o de sondeo, o conectores de envío, en función del origen de los datos y de la preferencia del desarrollador. Este artículo se centra en los conectores de extracción, que se basan en sondeos y capturan periódicamente datos a través de las API. Para obtener información sobre los conectores de inserción, consulte Creación de un conector sin código push para Microsoft Sentinel.

Los conectores creados con CCF son totalmente SaaS, sin requisitos para las instalaciones de servicio. También incluyen supervisión del estado y compatibilidad total con Microsoft Sentinel.

Siga estos pasos para crear el conector CCF y conectar el origen de datos a Microsoft Sentinel:

  • Crear el conector de datos
  • Creación de la plantilla de ARM
  • Desplegar el conector
  • Conectar Microsoft Sentinel al origen de datos e iniciar la ingesta de datos

Cada paso incluye un conector sin código de ejemplo que se va a compilar a lo largo del proceso.

Si es un socio de desarrollo de software y necesita soporte técnico para crear un conector de datos CCF, póngase en contacto con Microsoft Sentinel Partners en AzureSentinelPartner@microsoft.com para obtener ayuda.

Mejoras con respecto a la versión anterior de CCF

La versión inicial del CCF se anunció en el blog de Microsoft Tech Community en enero de 2022. Desde entonces, la plataforma se ha mejorado y ya no se recomienda la versión heredada . Esta nueva versión del CCF tiene las siguientes mejoras clave:

  1. Mejor compatibilidad con varios tipos de autenticación y paginación.

  2. Admite reglas de recopilación de datos estándar (DCR).

  3. Las partes de configuración de la interfaz de usuario y la conexión del conector sin código ahora son independientes. Esto permite la creación de conectores con varias conexiones que no eran posibles anteriormente.

Prerequisites

Antes de crear un conector, comprenda el origen de datos y cómo Microsoft Sentinel debe conectarse.

  1. Punto de conexión de recopilación de datos (DCE)

    Un DCE es un requisito para un DCR. Solo se crea un DCE por implementación de DCR del área de trabajo del análisis de registros. Cada DCR implementado para un área de trabajo de Microsoft Sentinel usa el mismo DCE. Para obtener más información sobre cómo crear uno o si necesita uno nuevo, consulte Puntos de conexión de recopilación de datos en Azure Monitor.

  2. Esquema de las tablas de salida.

    Es importante comprender la forma del flujo de datos y los campos que desea incluir en la tabla de salida. Haga referencia a la documentación del origen de datos o analice suficientes ejemplos de salida.

Investigue los siguientes componentes y compruebe la compatibilidad con ellos en la referencia de la API del conector de datos:

  1. Estructura de solicitud y respuesta HTTP al origen de datos

  2. Autenticación requerida por el origen de datos.
    Por ejemplo, si el origen de datos requiere un token firmado con un certificado, la referencia de LA API del conector de datos especifica que no se admite la autenticación de certificados.

  3. Opciones de paginación en el origen de datos

Probar las API

Prueba tus componentes con una herramienta de prueba de API, como una de las siguientes:

Caution

Para escenarios que usan datos sensibles, como credenciales, secretos, tokens de acceso o claves de API, utiliza una herramienta que proteja tus datos. Elige una herramienta que funcione offline o localmente, que no sincronice tus datos con la nube y que no requiera que inicies sesión en una cuenta online. Estas salvaguardas reducen el riesgo de exponer datos sensibles.

Crear el conector de datos

Tip

Si es un proveedor de software independiente (ISV) y necesita soporte técnico al compilar una integración de Microsoft Sentinel mediante el marco de conector sin código de Microsoft Sentinel, es posible que el equipo de Microsoft App Assure pueda ayudar. Para interactuar con el equipo de App Assure, envíe un correo electrónico a azuresentinelpartner@microsoft.com.

Hay cuatro componentes necesarios para construir el conector de datos CCF.

  1. Definición de tabla de salida
  2. Regla de recopilación de datos (DCR)
  3. Interfaz de usuario del conector de datos
  4. Reglas de conexión del conector de datos

Cada componente tiene una sección que detalla el proceso para crearlo y validarlo. Tome el JSON de cada componente para el empaquetado final de la plantilla de ARM.

Definición de tabla de salida

Tip

Omita este paso si los datos solo se ingieren en tablas estándar de Log Analytics. Algunos ejemplos de tablas estándar son CommonSecurityLog y ASimDnsActivityLogs. Para obtener más información sobre la lista completa de tipos de datos estándar admitidos, consulte Compatibilidad de transformación de datos con conectores de datos personalizados.

Si el origen de datos no se ajusta al esquema de una tabla estándar, tiene dos opciones:

  • Creación de una tabla personalizada para todos los datos
  • Crear una tabla personalizada para algunos datos y dividir los datos conformes en una tabla estándar

Use la interfaz de usuario de Log Analytics para un método sencillo para crear una tabla personalizada junto con un DCR. Si crea la tabla personalizada mediante la Tables API u otro método programático, agregue manualmente el sufijo _CL al nombre de la tabla. Para obtener más información, consulte Creación de una tabla personalizada.

Para obtener más información sobre cómo dividir los datos en más de una tabla, consulte los datos de ejemplo y la tabla personalizada de ejemplo creada para esos datos.

Regla de recopilación de datos

Las reglas de recopilación de datos (DCR) definen el proceso de recopilación de datos en Azure Monitor. Los DCR especifican qué datos se deben recopilar, cómo transformar esos datos y dónde enviar esos datos.

  • Solo hay una DCR que se implementa por conector de datos.
  • Un DCR debe tener un DCE correspondiente en la misma región.
  • Cuando se implementa el conector de datos CCF, el DCR se crea si aún no existe.

Consulte la información más reciente sobre dcr en estos artículos:

Para ver un tutorial sobre cómo crear un DCE, incluido el uso de datos de ejemplo para crear la tabla personalizada y la DCR, consulte Tutorial: Enviar datos a Azure Monitor Logs con la API de ingesta de registros (Azure Portal). Use el proceso de este tutorial para comprobar que los datos se ingieren correctamente en la tabla con el DCR.

Para comprender cómo crear un DCR complejo con varios flujos de datos, consulte la sección de ejemplo de DCR.

Interfaz de usuario del conector de datos

Este componente representa la interfaz de usuario del conector de datos en la galería de conectores de datos de Microsoft Sentinel. Cada conector de datos puede tener solo una definición de interfaz de usuario.

Compile la interfaz de usuario del conector de datos con la API de definición del conector de datos. Use la referencia de definiciones del conector de datos como complemento para explicar los elementos de la API con más detalle.

Notas:

  1. La propiedad kind del conector de sondeo de la API siempre debe ser Customizable.
  2. Dado que se trata de un tipo de conector de sondeo de API, establezca el tipo de connectivityCriteria en hasDataConnectors.
  3. En el ejemplo instructionSteps se incluye un botón de tipo ConnectionToggleButton. Este botón ayuda a desencadenar la implementación de reglas de conector de datos en función de los parámetros de conexión especificados.

Use una herramienta de prueba de API para llamar a la API de definiciones del conector de datos para crear la interfaz de usuario del conector de datos y validarla en la galería de conectores de datos.

Para obtener información de un ejemplo, consulte la sección Ejemplo de referencia de definiciones de conector de datos.

Reglas de conexión de datos

Actualmente hay tres tipos de reglas de conexión de datos posibles para definir el conector de datos CCF.

Use una herramienta de pruebas de API para llamar a la API del conector de datos para crear el conector de datos que combina las reglas de conexión y los componentes anteriores. Compruebe que el conector ahora está conectado en la interfaz de usuario.

Entrada confidencial segura

Independientemente de la autenticación que use el conector de datos CCF, siga estos pasos para asegurarse de que la información confidencial se mantiene segura. El objetivo es pasar las credenciales de la plantilla de ARM al CCF sin dejar objetos confidenciales legibles en el historial de implementaciones.

Creación de la etiqueta de credenciales en la interfaz de usuario del conector

La definición del conector de datos crea un elemento de interfaz de usuario para solicitar credenciales de seguridad. Por ejemplo, si su conector de datos se autentica con una fuente de registros mediante OAuth, la sección de definición de su conector de datos incluye el tipo OAuthForm en las instrucciones. Esto configura la plantilla de ARM para solicitar las credenciales.

"instructions": [
    {
        "type": "OAuthForm",
        "parameters": {
        "UsernameLabel": "Username",
        "PasswordLabel": "Password",
        "connectButtonLabel": "Connect",
        "disconnectButtonLabel": "Disconnect"
        }
    }
],

Almacenar entrada confidencial

Una sección de la plantilla de implementación de ARM proporciona un lugar para que el administrador implemente el conector de datos para escribir la contraseña. Use securestring para mantener la información confidencial protegida en un objeto que no es legible después de la implementación. Para obtener más información, consulte Recomendaciones de seguridad para parámetros.

"mainTemplate": {
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "[variables('dataConnectorCCPVersion')]",
    "parameters": {
        "Username": {
            "type": "securestring",
            "minLength": 1,
            "metadata": {
                "description": "Enter the username to connect to your data source."
        },
        "Password": {
            "type": "securestring",
            "minLength": 1,
            "metadata": {
                "description": "Enter the API key, client secret or password required to connect."
            }
        },
    }
}

Utilice los objetos securestring

Por último, CCF utiliza los objetos de credenciales en la sección del conector de datos.

"auth": {
    "type": "OAuth2",
    "ClientSecret": "[[parameters('Password')]",
    "ClientId": "[[parameters('Username')]",
    "GrantType": "client_credentials",
    "TokenEndpoint": "https://api.contoso.com/oauth/token",
    "TokenEndpointHeaders": {
        "Content-Type": "application/x-www-form-urlencoded"
    },
    "TokenEndpointQueryParameters": {
        "grant_type": "client_credentials"
    }
}

Note

La extraña sintaxis del objeto de credenciales "ClientSecret": "[[parameters('Password')]", no es un error tipográfico. Para crear la plantilla de implementación, que también usa parámetros, escape los parámetros en esa sección con un [ inicial adicional. Esto permite a los parámetros asignar un valor en función de la interacción del usuario con el conector.

Para obtener más información, consulte Caracteres de escape de expresiones de plantilla.

Creación de la plantilla de implementación

Empaquete manualmente una plantilla de administración de recursos de Azure (ARM) con los ejemplos de código de plantilla de ejemplo como guía. Estos ejemplos de código están organizados por secciones de la plantilla de ARM que debe ensamblar.

Si estás creando un conector de datos CCF de Google Cloud Platform (GCP), empaqueta la plantilla de implementación mediante la plantilla de CCF de GCP de ejemplo. Para obtener información sobre cómo rellenar la plantilla CCF de GCP, consulte Referencia de reglas de conexión del conector de datos de GCP.

Además de las plantillas de ejemplo, las soluciones publicadas disponibles en el centro de contenido de Microsoft Sentinel usan el CCF para sus conectores de datos. Revise las soluciones siguientes como más ejemplos de cómo unir los componentes en una plantilla de ARM.

RestApiPoller Ejemplos de conectores de datos CCF

GCP Ejemplos de conectores de datos CCF

Desplegar el conector

Implemente el conector sin código como una plantilla personalizada.

Tip

Elimine los recursos que creó en los pasos anteriores. La DCR y la tabla personalizada se crean con la implementación. Si no quita esos recursos antes de implementarlos, es más difícil comprobar la plantilla.

  1. Copie el contenido de la plantilla de implementación de ARM.
  2. Siga las instrucciones de Edición e implementación de la plantilla del artículo Inicio rápido: Creación e implementación de plantillas de ARM mediante el Azure Portal.

Mantenga el aislamiento de red para el origen de los registros

Si el origen de registro requiere aislamiento de red, configure una lista de permitidos de direcciones IP públicas usadas por el CCF.

Azure redes virtuales usan etiquetas de servicio para definir controles de acceso de red. Para el CCF, esa etiqueta de servicio es Diving.

Para encontrar el rango de IP actual asociado a la etiqueta de servicio Scuba, consulte Uso de la API de detección de etiquetas de servicio.

Comprobación del conector sin código

Ver el conector sin código en la galería de conectores de datos. Abra el conector de datos y complete los parámetros de autenticación necesarios para conectarse. Una vez conectado correctamente, se crean la DCR y las tablas personalizadas. Vea el recurso DCR en el grupo de recursos y las tablas personalizadas del área de trabajo de análisis de registros.

Note

Puede tardar hasta 30 minutos en ver que los datos comienzan a ingerirse.

Example

Cada paso para compilar el conector sin código se representa en las secciones de ejemplo siguientes.

Para mostrar un origen de datos complejo con ingesta en más de una tabla, en este ejemplo se incluye un esquema de tabla de salida y un DCR con varios flujos de salida. El ejemplo de DCR reúne estos elementos junto con sus transformaciones de KQL. Los ejemplos de reglas de conexión y definición de la interfaz de usuario del conector de datos continúan desde este mismo origen de datos de ejemplo. Por último, la plantilla de solución usa todos estos componentes de ejemplo para mostrar de principio a fin cómo crear el conector de datos CCF de ejemplo.

Datos de ejemplo

Un origen de datos devuelve el siguiente JSON al conectarse a su punto de conexión.

[
        {
        "ts": "3/6/2023 8:15:15 AM",
        "eventType": "Alert",
        "deviceMac": "bc:27:c6:21:1c:70",
        "clientMac": "",
        "srcIp": "10.12.11.106",
        "destIp": "121.93.178.13",
        "protocol": "tcp/ip",
        "priority": "0",
        "message": "This is an alert message"
        },
        {
        "ts": "3/6/2023 8:14:54 AM",
        "eventType": "File",
        "srcIp": "178.175.128.249",
        "destIp": "234.113.125.105",
        "fileType": "MS_EXE",
        "fileSizeBytes": 193688,
        "disposition": "Malicious"
        }
]

Esta respuesta contiene eventTypealerta y archivo. Los eventos de archivo se van a ingerir en la tabla estándar normalizada, AsimFileEventLogs, mientras que los eventos de alerta se van a ingerir en una tabla personalizada.

Tabla personalizada de ejemplo

Para obtener más información sobre la estructura de esta tabla, consulte Tables API. Los nombres de tabla de registro personalizados deben tener un _CL sufijo.

{
"properties": {
    "schema": {
        "name": "ExampleConnectorAlerts_CL",
        "columns": [
        {
          "name": "TimeGenerated",
          "type": "datetime"
        },
        {
          "name": "SourceIP",
          "type": "string"
        },
        {
          "name": "DestIP",
          "type": "string"
        },
        {
          "name": "Message",
          "type": "string"
        },
        {
          "name": "Priority",
          "type": "int"
        }
        ]
      }
    }
}

Regla de recopilación de datos de ejemplo

La siguiente DCR define una única secuencia Custom-ExampleConnectorInput mediante el origen de datos de ejemplo y transforma la salida en dos tablas.

  1. El primer flujo de datos dirige eventType = Alert a la tabla personalizada ExampleConnectorAlerts_CL .
  2. El segundo flujo de datos dirige eventType = File a la tabla estándar normalizada.ASimFileEventLogs

Para obtener más información sobre la estructura de este ejemplo, vea Estructura de una regla de recopilación de datos.

Para crear esta DCR en un entorno de prueba, siga la API de reglas de recopilación de datos. Los elementos del ejemplo de {{double curly braces}} indican variables que requieren valores para facilitar su uso con una herramienta de pruebas de API. Al crear este recurso en la plantilla de ARM, las variables expresadas aquí se intercambian por parámetros.

{
  "location": "{{location}}",
  "properties": {
    "dataCollectionEndpointId": "/subscriptions/{{subscriptionId}}/resourceGroups/{{resourceGroupName}}/providers/Microsoft.Insights/dataCollectionEndpoints/{{dataCollectionEndpointName}}",
    "streamDeclarations": {
      "Custom-ExampleConnectorInput": {
        "columns": [
          {
            "name": "ts",
            "type": "datetime"
          },
          {
            "name": "eventType",
            "type": "string"
          },
          {
            "name": "deviceMac",
            "type": "string"
          },
          {
            "name": "clientMac",
            "type": "string"
          },
          {
            "name": "srcIp",
            "type": "string"
          },
          {
            "name": "destIp",
            "type": "string"
          },
          {
            "name": "protocol",
            "type": "string"
          },
          {
            "name": "priority",
            "type": "string"
          },
          {
            "name": "message",
            "type": "string"
          },
          {
            "name": "fileType",
            "type": "string"
          },
          {
            "name": "fileSizeBytes",
            "type": "int"
          },
          {
            "name": "disposition",
            "type": "string"
          }
        ]
      }
    },
    "destinations": {
      "logAnalytics": [
        {
          "workspaceResourceId": "/subscriptions/{{subscriptionId}}/resourcegroups/{{resourceGroupName}}/providers/microsoft.operationalinsights/workspaces/{{workspaceName}}",
          "name": "{{uniqueFriendlyDestinationName}}"
        }
      ]
    },
    "dataFlows": [
      {
        "streams": [
          "Custom-ExampleConnectorInput"
        ],
        "destinations": [
          "{{uniqueFriendlyDestinationName}}"
        ],
        "transformKql": "source | where eventType == \"Alert\" | project TimeGenerated = ts, SourceIP = srcIp, DestIP = destIp, Message = message, Priority = priority \n",
        "outputStream": "Custom-ExampleConnectorAlerts_CL"
      },
      {
        "streams": [
          "Custom-ExampleConnectorInput"
        ],
        "destinations": [
          "{{uniqueFriendlyDestinationName}}"
        ],
        "transformKql": "source | where eventType == \"File\" | project-rename TimeGenerated = ts, EventOriginalType = eventType, SrcIpAddr = srcIp, DstIpAddr = destIp, FileContentType = fileType, FileSize = fileSizeBytes, EventOriginalSeverity = disposition \n",
        "outputStream": "Microsoft-ASimFileEventLogs"
      }
    ]
  }
}

Definición de interfaz de usuario del conector de datos de ejemplo

Este ejemplo se encuentra en la referencia de definiciones del conector de datos.

Reglas de conexión del conector de datos de ejemplo

Este ejemplo se encuentra en la referencia de conectores de datos.

Plantilla de ARM de ejemplo

Compile la plantilla de implementación de ARM con la estructura siguiente, que incluye las 4 secciones de componentes JSON necesarios para compilar el conector de datos CCF:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {},
    "resources": [],
}

Unir las secciones junto con un editor compatible con JSON, como Visual Studio Code, para minimizar los errores de sintaxis, como comas y corchetes de cierre y paréntesis.

Para guiar el proceso de creación de plantillas, los comentarios aparecen en los metadatosdescription o en línea con // la notación de comentarios. Para obtener más información, consulte Procedimientos recomendados de plantilla de ARM: comentarios.

Considere la posibilidad de usar el kit de herramientas de prueba de plantillas de ARM (arm-ttk) para validar la plantilla que compila. Para obtener más información, consulte arm-ttk.

Plantilla de ARM de ejemplo: parámetros

Para obtener más información, vea Parámetros en plantillas de ARM.

Advertencia

Use securestring para todas las contraseñas y todos los secretos en objetos que se pueden leer después de implementar el recurso. Para obtener más información, consulte Proteger la entrada confidencial y Recomendaciones de seguridad para los parámetros.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "location": {
            "type": "string",
            "minLength": 1,
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "Not used, but needed to pass the arm-ttk test, 'Location-Should-Not-Be-Hardcoded'. Instead the `workspace-location` derived from the log analytics workspace is used."
            }
        },
        "workspace-location": {
            "type": "string",
            "defaultValue": "",
            "metadata": {
                "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]"
            }
        },
        "subscription": {
            "defaultValue": "[last(split(subscription().id, '/'))]",
            "type": "string",
            "metadata": {
                "description": "subscription id where Microsoft Sentinel is configured"
            }
        },
        "resourceGroupName": {
            "defaultValue": "[resourceGroup().name]",
            "type": "string",
            "metadata": {
                "description": "resource group name where Microsoft Sentinel is configured"
            }
        },
        "workspace": {
            "defaultValue": "",
            "type": "string",
            "metadata": {
                "description": "the log analytics workspace enabled for Microsoft Sentinel"
            }
        }
    },
    // Next is the variables section here
}

Plantilla de ARM de ejemplo: variables

Estas variables recomendadas ayudan a simplificar la plantilla. Use más o menos según sea necesario. Para obtener más información, consulte Variables en plantillas de ARM.

    "variables": {
        "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
        "_solutionName": "Solution name", // Enter your solution name 
        "_solutionVersion": "3.0.0", // must be 3.0.0 or above
        "_solutionAuthor": "Contoso", // Enter the name of the author
        "_packageIcon": "<img src=\"{LogoLink}\" width=\"75px\" height=\"75px\">", // Enter the http link for the logo. NOTE: This field is only recommended for Azure Global Cloud.
        "_solutionId": "azuresentinel.azure-sentinel-solution-azuresentinel.azure-sentinel-MySolution", // Enter a name for your solution with this format but exchange the 'MySolution' portion
        "dataConnectorVersionConnectorDefinition": "1.0.0",
        "dataConnectorVersionConnections": "1.0.0",
        "_solutionTier": "Community", // This designates the appropriate support - all custom data connectors are "Community"
        "_dataConnectorContentIdConnectorDefinition": "MySolutionTemplateConnectorDefinition", // Enter a name for the connector
        "dataConnectorTemplateNameConnectorDefinition": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnectorDefinition')))]",
        "_dataConnectorContentIdConnections": "MySolutionTemplateConnections", // Enter a name for the connections this connector makes
        "dataConnectorTemplateNameConnections": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnections')))]",
        "_logAnalyticsTableId1": "ExampleConnectorAlerts_CL" // Enter the custom table name - not needed if you are ingesting data into standard tables
		// Enter more variables as needed "":""
    },
    // Next is the resources sections here

Plantilla de ARM de ejemplo: recursos

Hay 5 recursos de implementación de ARM en esta guía de plantilla, que albergan los 4 componentes de construcción del conector de datos de CCF.

  1. contentTemplates (un recurso primario)
  2. dataConnectorDefinitions : para obtener más información, consulte Interfaz de usuario del conector de datos.
  3. metadatos
  4. contentTemplates
  5. contentPackages
    "resources": [
        // resource section 1 - contentTemplates
        {
            "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
            "apiVersion": "2023-04-01-preview",
            "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('dataConnectorTemplateNameConnectorDefinition'), variables('dataConnectorVersionConnectorDefinition'))]",
            "location": "[parameters('workspace-location')]",
            "dependsOn": [
                "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
            ],
            "properties": {
                "contentId": "[variables('_dataConnectorContentIdConnectorDefinition')]",
                "displayName": "[concat(variables('_solutionName'), variables('dataConnectorTemplateNameConnectorDefinition'))]",
                "contentKind": "DataConnector",
                "mainTemplate": {
                    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                    "contentVersion": "[variables('dataConnectorVersionConnectorDefinition')]",
                    "parameters": {},
                    "variables": {},
                    "resources": [
                        {
                            "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnectorDefinition')))]",
                            "apiVersion": "2022-01-01-preview",
                            "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
                            "properties": {
                                "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentIdConnectorDefinition'))]",
                                "contentId": "[variables('_dataConnectorContentIdConnectorDefinition')]",
                                "kind": "DataConnector",
                                "version": "[variables('dataConnectorVersionConnectorDefinition')]",
                                "source": {
                                    "sourceId": "[variables('_solutionId')]",
                                    "name": "[variables('_solutionName')]",
                                    "kind": "Solution"
                                },
                                "author": {
                                    "name": "[variables('_solutionAuthor')]"
                                },
                                "support": {
                                    "name": "[variables('_solutionAuthor')]",
                                    "tier": "[variables('_solutionTier')]"
                                },
                                "dependencies": {
                                    "criteria": [
                                        {
                                            "version": "[variables('dataConnectorVersionConnections')]",
                                            "contentId": "[variables('_dataConnectorContentIdConnections')]",
                                            "kind": "ResourcesDataConnector"
                                        }
                                    ]
                                }
                            }
                        },
                        {
                            "name": "MyDCRV1", // Enter your DCR name
                            "apiVersion": "2021-09-01-preview",
                            "type": "Microsoft.Insights/dataCollectionRules",
                            "location": "[parameters('workspace-location')]",
                            "kind": null,
                            "properties": 
							{ 
                                // Enter your DCR properties here.
                                //  Consider using these variables:
                                //  "dataCollectionEndpointId": "[concat('/subscriptions/',parameters('subscription'),'/resourceGroups/',parameters('resourceGroupName'),'/providers/Microsoft.Insights/dataCollectionEndpoints/',parameters('workspace'))]",
                                //  "workspaceResourceId": "[variables('workspaceResourceId')]",
							}
                        },
                        {
                            "name": "[variables('_logAnalyticsTableId1')]",
                            "apiVersion": "2022-10-01",
                            "type": "Microsoft.OperationalInsights/workspaces/tables",
                            "location": "[parameters('workspace-location')]",
                            "kind": null,
                            "properties": 
							{
								// Enter your log analytics table schema here. 
                                //  Consider using this variable for the name property:
                                //  "name": "[variables('_logAnalyticsTableId1')]",
							}			
                        }
						// Enter more tables if needed.
                    ]
                },
                "packageKind": "Solution",
                "packageVersion": "[variables('_solutionVersion')]",
                "packageName": "[variables('_solutionName')]",
                "contentProductId": "[concat(substring(variables('_solutionId'), 0, 50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentIdConnectorDefinition'),'-', variables('dataConnectorVersionConnectorDefinition'))))]",
                "packageId": "[variables('_solutionId')]",
                "contentSchemaVersion": "3.0.0",
                "version": "[variables('_solutionVersion')]"
            }
        },
        // resource 2 section here
        // resource section 2 - dataConnectorDefinitions
        {
            "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition'))]",
            "apiVersion": "2022-09-01-preview",
            "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions",
            "location": "[parameters('workspace-location')]",
            "kind": "Customizable",
            "properties": 
			{
				//Enter your data connector definition properties here
				//"connectorUiConfig": {
				//	"graphQueriesTableName": "[variables('_logAnalyticsTableId1')]",
                //}, 
			}
        },
        // resource 3 section here
        // resource section 3 - metadata
        {
            "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnectorDefinition')))]",
            "apiVersion": "2022-01-01-preview",
            "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
            "properties": {
                "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentIdConnectorDefinition'))]",
                "contentId": "[variables('_dataConnectorContentIdConnectorDefinition')]",
                "kind": "DataConnector",
                "version": "[variables('dataConnectorVersionConnectorDefinition')]",
                "source": {
                    "sourceId": "[variables('_solutionId')]",
                    "name": "[variables('_solutionName')]",
                    "kind": "Solution"
                },
                "author": {
                    "name": "[variables('_solutionAuthor')]"
                },
                "support": {
                    "name": "[variables('_solutionAuthor')]",
                    "tier": "[variables('_solutionTier')]"
                },
                "dependencies": {
                    "criteria": [
                        {
                            "version": "[variables('dataConnectorVersionConnections')]",
                            "contentId": "[variables('_dataConnectorContentIdConnections')]",
                            "kind": "ResourcesDataConnector"
                        }
                    ]
                }
            }
        },
        // resource 4 section here
        // resource section 4 - contentTemplates
        {
            "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
            "apiVersion": "2023-04-01-preview",
            "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('dataConnectorTemplateNameConnections'), variables('dataConnectorVersionConnections'))]",
            "location": "[parameters('workspace-location')]",
            "dependsOn": [
                "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
            ],
            "properties": {
                "contentId": "[variables('_dataConnectorContentIdConnections')]",
                "displayName": "[concat(variables('_solutionName'), variables('dataConnectorTemplateNameConnections'))]",
                "contentKind": "ResourcesDataConnector",
                "mainTemplate": {
                    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                    "contentVersion": "[variables('dataConnectorVersionConnections')]",
                    "parameters":
                    // These parameters are used by the data connector primarily as properties for the administrator to enter in the UI when configuring the connector
					{
                        "connectorDefinitionName": {
                            "defaultValue": "connectorDefinitionName",
                            "type": "string",
                            "minLength": 1
                        },
                        "workspace": {
                            "defaultValue": "[parameters('workspace')]",
                            "type": "string"
                        },
                        "dcrConfig": {
                            "defaultValue": {
                                "dataCollectionEndpoint": "data collection Endpoint",
                                "dataCollectionRuleImmutableId": "data collection rule immutableId"
                            },
                            "type": "object"
                        }
						// Enter additional parameters, for example:
						//"domainname": {
                        //    "defaultValue": "domain name",
                        //    "type": "string",
                        //    "minLength": 1
                        //},
                        //"apikey": {
                        //    "defaultValue": "",
                        //    "type": "securestring",
                        //    "minLength": 1
                        //}
                    },
                    "variables": {
                        "_dataConnectorContentIdConnections": "[variables('_dataConnectorContentIdConnections')]"
                    },
                    "resources": [
                        {
                            "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnections')))]",
                            "apiVersion": "2022-01-01-preview",
                            "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
                            "properties": {
                                "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentIdConnections'))]",
                                "contentId": "[variables('_dataConnectorContentIdConnections')]",
                                "kind": "ResourcesDataConnector",
                                "version": "[variables('dataConnectorVersionConnections')]",
                                "source": {
                                    "sourceId": "[variables('_solutionId')]",
                                    "name": "[variables('_solutionName')]",
                                    "kind": "Solution"
                                },
                                "author": {
                                    "name": "[variables('_solutionAuthor')]"
                                },
                                "support": {
                                    "name": "[variables('_solutionAuthor')]",
                                    "tier": "[variables('_solutionTier')]"
                                }
                            }
                        },
                        {
                            "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', 'MyDataConnector')]", // Replace the last part of the name with your data connector name
                            //  To create several connections using this template, make the name dynamic. For example, use the 'concat' function to add the connector name with a GUID using the 'guid' function.
                            "apiVersion": "2022-12-01-preview",
                            "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
                            "location": "[parameters('workspace-location')]",
                            "kind": "RestApiPoller",
                            "properties": 
							{
								// Enter your data connector properties here. If you want to use UI parameters remember to escape the parameter like this: "[[parameters('paramName')]"
								//  Use parameters as needed. For example:	
                                // "dataType": "My product security event API",
                                // "response": {
                                //   "eventsJsonPaths": [
                                //        "$"
                                //    ],
                                //    "format": "json"
                                // },
                                // "paging": {
                                //    "pagingType": "LinkHeader"
                                // },
                                // "connectorDefinitionName": "[[parameters('connectorDefinitionName')]",
                                // "auth": {
                                //   "apiKeyName": "Authorization",
                                //    "ApiKey": "[[parameters('apikey')]",
                                //    "apiKeyIdentifier": "SSWS",
                                //    "type": "APIKey"
                                //} ,
                                // "request": {
                                //   "apiEndpoint": "[[concat('https://',parameters('domainname'),'/api/v1/logs')]",
                                //    "rateLimitQPS": 10,
                                //   "queryWindowInMin": 5,
                                //   "httpMethod": "GET",
                                //    "retryCount": 3,
                                //    "timeoutInSeconds": 60,
                                //    "headers": {
                                //        "Accept": "application/json",
                                //        "User-Agent": "My-Data-Source"
                                //    },
                                //    "startTimeAttributeName": "since",
								//    "endTimeAttributeName": "until"		     
                                // },
                                // "dcrConfig": {
                                //    "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]",
                                //    "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]",
                                //    "streamName": "Custom-ExampleConnectorAlerts_CL" //This input stream should be the same as the inputStream property configured for the DataCollectionRule 
                                // },
                                // "isActive": true
                            }
                        }
                    ]
                },
                "packageKind": "Solution",
                "packageVersion": "[variables('_solutionVersion')]",
                "packageName": "[variables('_solutionName')]",
                "contentProductId": "[concat(substring(variables('_solutionId'), 0, 50),'-','rdc','-', uniqueString(concat(variables('_solutionId'),'-','ResourcesDataConnector','-',variables('_dataConnectorContentIdConnections'),'-', variables('dataConnectorVersionConnections'))))]",
                "packageId": "[variables('_solutionId')]",
                "contentSchemaVersion": "3.0.0",
                "version": "[variables('_solutionVersion')]"
            }
        },
        // resource 5 section here
        // resource section 5 - contentPackages
        {
            "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages",
            "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]",
            "location": "[parameters('workspace-location')]",
            "apiVersion": "2023-04-01-preview",
            "properties": {
                "version": "[variables('_solutionVersion')]",
                "kind": "Solution",
                "contentSchemaVersion": "3.0.0",
                "contentId": "[variables('_solutionId')]",
                "source": {
                    "kind": "Solution",
                    "name": "[variables('_solutionName')]",
                    "sourceId": "[variables('_solutionId')]"
                },
                "author": {
                    "name": "[variables('_solutionAuthor')]"
                },
                "support": {
                    "name": "[variables('_solutionAuthor')]"
                },
                "dependencies": {
                    "operator": "AND",
                    "criteria": [
                        {
                            "kind": "DataConnector",
                            "contentId": "[variables('dataConnectorVersionConnectorDefinition')]",
                            "version": "[variables('_dataConnectorContentIdConnectorDefinition')]"
                        }
                    ]
                },
                "firstPublishDate": "2023-12-05",
                "providers": [
                    "[variables('_solutionAuthor')]"
                ],
                "contentKind": "Solution",
                "packageId": "[variables('_solutionId')]",
                "contentProductId": "[concat(substring(variables('_solutionId'), 0, 50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]",
                "displayName": "[variables('_solutionName')]",
                "publisherDisplayName": "[variables('_solutionId')]",
                "descriptionHtml": "test",
                "icon": "[variables('_packageIcon')]"
            }
        }
        
    ]
}