Microsoft Sentinel용 코드 없는 커넥터 만들기

CCP(Codeless Connector Platform)는 파트너, 고급 사용자 및 개발자에게 데이터를 Microsoft Sentinel에 수집할 수 있는 사용자 지정 커넥터를 만들 수 있는 기능을 제공합니다.

CCP를 사용하여 만든 커넥터는 서비스 설치 요구 사항 없는 완전히 SaaS입니다. 또한 상태 모니터링과 Microsoft Sentinel의 전폭적인 지원을 포함합니다.

다음 단계를 수행하여 CCP 커넥터를 만들고 데이터 원본을 Microsoft Sentinel에 연결합니다.

  • 데이터 커넥터 빌드
  • ARM 템플릿 만들기
  • 커넥터 배포
  • Microsoft Sentinel을 데이터 원본에 연결하고 데이터 수집 시작

이 문서에서는 각 단계를 완료하는 방법을 보여주고 그 과정에서 빌드할 예제 코드리스 커넥터를 제공합니다.

이 CCP는 이전 버전과 어떻게 다른가요?

CCP의 초기 버전은 2022년 1월에 발표되었습니다. 그 이후로 플랫폼이 개선되었으며 레거시 릴리스는 더 이상 권장되지 않습니다. 이 새 버전의 CCP에는 다음과 같은 주요 개선 사항이 있습니다.

  1. 다양한 인증 및 페이지 매김 유형을 보다 효율적으로 지원합니다.

  2. 표준 DCR(데이터 수집 규칙)을 지원합니다.

  3. 이제 코드리스 커넥터의 사용자 인터페이스와 연결 구성 부분이 분리되어 있습니다. 이를 통해 이전에는 불가능했던 여러 연결이 있는 커넥터를 만들 수 있습니다.

필수 조건

커넥터를 빌드하기 전에 데이터 원본과 Microsoft Sentinel을 연결하는 방법을 이해합니다.

  1. DCE(데이터 수집 엔드포인트)

    DCE는 DCR에 대한 요구 사항입니다. 로그 분석 작업 영역 DCR 배포별로 DCE 하나만 생성됩니다. Microsoft Sentinel 작업 영역에 배포된 모든 DCR은 같은 DCE를 사용합니다. DCE를 만드는 방법이나 새 DCE가 필요한지 여부에 대한 자세한 내용은 Azure Monitor의 데이터 수집 엔드포인트를 참조하세요.

  2. 출력 테이블의 스키마

    데이터 스트림의 모양과 출력 테이블에 포함할 필드를 이해하는 것이 중요합니다. 데이터 원본 문서를 참조하거나 충분한 출력 예제를 분석합니다.

다음 구성 요소를 연구하고 데이터 커넥터 API 참조에서 구성 요소에 대한 지원을 확인합니다.

  1. 데이터 원본에 대한 HTTP 요청 및 응답 구조

  2. 데이터 원본에 필요한 인증
    예를 들어 데이터 원본에 인증서로 서명된 토큰이 필요하면 데이터 커넥터 API 참조에서 인증서 인증이 지원되지 않음을 지정합니다.

  3. 데이터 원본에 대한 페이지 매김 옵션

API 테스트

다음 중 하나와 같은 API 테스트 도구를 사용하여 구성 요소를 테스트하는 것이 좋습니다.

주의

자격 증명, 비밀, 액세스 토큰, API 키 및 기타 유사한 정보와 같은 중요한 데이터가 있는 시나리오의 경우 필요한 보안 기능으로 데이터를 보호하고, 오프라인 또는 로컬로 작동하며, 데이터를 클라우드에 동기화하지 않고, 온라인 계정에 로그인할 필요가 없는 도구를 사용해야 합니다. 이렇게 하면 중요한 데이터가 대중에게 노출되는 위험을 줄일 수 있습니다.

데이터 커넥터 빌드

CCP 데이터 커넥터를 빌드하는 데 필요한 네 가지 구성 요소가 있습니다.

  1. 출력 테이블 정의
  2. DCR(데이터 수집 규칙)
  3. 데이터 커넥터 사용자 인터페이스
  4. 데이터 커넥터 연결 규칙

각 구성 요소에는 만들고 유효성을 검사하는 프로세스를 자세히 설명하는 섹션이 있습니다. ARM 템플릿의 최종 패키징을 위해 각 구성 요소에서 JSON을 가져옵니다.

출력 테이블 정의

데이터가 표준 Log Analytics 테이블에만 수집되는 경우에는 이 단계를 건너뜁니다. 표준 테이블 예로는 CommonSecurityLogASimDnsActivityLogs 등이 있습니다. 지원되는 표준 데이터 형식의 전체 목록에 대한 자세한 내용은 사용자 지정 데이터 커넥터에 대한 데이터 변환 지원을 참조하세요.

데이터 원본이 표준 테이블의 스키마를 준수하지 않는 경우 다음 두 가지 옵션이 있습니다.

  • 모든 데이터에 대한 사용자 지정 테이블 만들기
  • 일부 데이터에 대한 사용자 지정 테이블을 만들고 준수하는 테이블을 표준 테이블로 분할합니다.

직접 전달 메서드에 Log Analytics UI를 사용하여 DCR과 함께 사용자 지정 테이블을 만듭니다. Tables API 또는 다른 프로그래매틱 메서드를 사용하여 사용자 지정 테이블을 만드는 경우 수동으로 테이블 이름에 _CL 접미사를 추가합니다. 자세한 내용은 사용자 지정 테이블 만들기를 참조하세요.

데이터를 테이블 2개 이상으로 분할하는 방법에 대한 자세한 내용은 예제 데이터 및 해당 데이터에 생성된 예제 사용자 지정 테이블을 참조하세요.

데이터 수집 규칙

DCR(데이터 수집 규칙)은 Azure Monitor의 데이터 수집 프로세스를 정의합니다. DCR은 수집해야 하는 데이터, 해당 데이터를 변환하는 방법 및 해당 데이터를 보낼 위치를 지정합니다.

  • 데이터 커넥터당 배포되는 DCR은 하나뿐입니다.
  • DCR에는 같은 지역의 해당 DCE가 있어야 합니다.
  • CCP 데이터 커넥터가 배포될 때 DCR이 아직 없으면 생성됩니다.

다음 문서에서 DCR에 대한 최신 정보를 참조하세요.

샘플 데이터를 사용하여 사용자 지정 테이블과 DCR 만들기를 포함하여 DCE를 만드는 방법을 보여주는 자습서는 자습서: 로그 수집 API를 사용하여 Azure Monitor 로그에 데이터 보내기(Azure Portal)를 참조하세요. 이 자습서의 프로세스를 사용하여 데이터가 DCR을 통해 테이블에 올바르게 수집되었는지 확인합니다.

데이터 흐름이 여러 개 있는 복잡한 DCR을 만드는 방법을 이해하려면 DCR 예제 섹션을 참조하세요.

데이터 커넥터 사용자 인터페이스

이 구성 요소는 Microsoft Sentinel 데이터 커넥터 갤러리의 데이터 커넥터에 대한 UI를 렌더링합니다. 데이터 커넥터마다 UI 정의가 하나만 있을 수 있습니다.

데이터 커넥터 정의 API를 사용하여 데이터 커넥터 사용자 인터페이스를 빌드합니다. 데이터 커넥터 정의 참조를 보완으로 사용하여 API 요소를 자세히 설명합니다.

참고:

  1. API 폴링 커넥터의 kind 속성은 항상 Customizable이어야 합니다.
  2. API 폴링 커넥터 형식이므로 connectivityCriteria 형식을 hasDataConnectors로 설정합니다.
  3. instructionSteps 예제에서는 ConnectionToggleButton 형식의 단추가 포함됩니다. 이 단추를 사용하면 지정된 연결 매개 변수에 따라 데이터 커넥터 규칙을 배포할 수 있습니다.

API 테스트 도구를 사용하여 데이터 커넥터 정의 API를 호출하여 데이터 커넥터 갤러리에서 유효성을 검사하기 위해 데이터 커넥터 UI를 만듭니다.

예제에서 알아보려면 데이터 커넥터 정의 참조 예제 섹션을 참조하세요.

데이터 연결 규칙

현재 CCP 데이터 커넥터를 정의할 수 있는 두 가지 종류의 데이터 연결 규칙이 있습니다.

API 테스트 도구를 사용하여 데이터 커넥터 API를 호출하여 연결 규칙과 이전 구성 요소를 결합하는 데이터 커넥터를 만듭니다. 커넥터가 이제 UI에 연결되어 있는지 확인합니다.

기밀 입력 보호

CCP 데이터 커넥터에서 어떤 인증을 사용하든 기밀 정보를 안전하게 유지하려면 다음 단계를 수행합니다. 목표는 배포 기록에 읽을 수 있는 기밀 개체를 남겨두지 않고 ARM 템플릿에서 CCP로 자격 증명을 전달하는 것입니다.

레이블 만들기

데이터 커넥터 정의는 보안 자격 증명을 요청하는 UI 요소를 만듭니다. 예를 들어 데이터 커넥터가 OAuth를 사용하여 로그 원본에 인증되는 경우 데이터 커넥터 정의 섹션의 지침에 OAuthForm 형식이 포함됩니다. 그러면 자격 증명을 묻는 메시지를 표시하도록 ARM 템플릿이 설정됩니다.

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

기밀 입력 저장

ARM 배포 템플릿의 섹션에는 데이터 커넥터를 배포하는 관리자가 암호를 입력할 수 있는 위치가 제공됩니다. securestring을 사용하여 배포 후 읽을 수 없는 개체에 기밀 정보를 보호합니다. 자세한 내용은 매개 변수에 대한 보안 권장 사항을 참조하세요.

"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."
            }
        },
    // more deployment template information
    }
}

securestring 개체 사용

마지막으로 CCP는 데이터 커넥터 섹션의 자격 증명 개체를 활용합니다.

"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"
    }
},

참고 항목

자격 증명 개체에 대한 이상한 구문인 "ClientSecret": "[[parameters('Password')]",는 오타가 아닙니다. 매개 변수도 사용하는 배포 템플릿을 만들려면 시작하는 추가적인 시작 [를 사용하여 해당 섹션의 매개 변수를 이스케이프해야 합니다. 이렇게 하면 매개 변수가 커넥터와의 사용자 상호 작용에 따라 값을 할당할 수 있습니다.

자세한 내용은 템플릿 식 이스케이프 문자를 참조하세요.

배포 템플릿 만들기

예제 템플릿 코드 샘플을 가이드로 사용하여 ARM(Azure Resource Management) 템플릿을 수동으로 패키지합니다. 이러한 코드 샘플은 함께 스플라이스해야 하는 ARM 템플릿 섹션으로 나뉩니다.

GCP(Google Cloud Platform) CCP 데이터 커넥터를 만드는 경우 예제 GCP CCP 템플릿을 사용하여 배포 템플릿패키지합니다. GCP CCP 템플릿을 채우는 방법에 대한 자세한 내용은 GCP 데이터 커넥터 연결 규칙 참조를 참조하세요.

예제 템플릿 외에도 Microsoft Sentinel 콘텐츠 허브에서 사용할 수 있는 게시된 솔루션은 해당 데이터 커넥터에 CCP를 사용합니다. 구성 요소를 ARM 템플릿에 연결하는 방법에 대한 추가 예제로 다음 솔루션을 검토합니다.

RestApiPoller CCP 데이터 커넥터 예제

GCP CCP 데이터 커넥터 예제

커넥터 배포

코드리스 커넥터를 사용자 지정 템플릿으로 배포합니다.

이전 단계에서 만든 리소스를 삭제합니다. DCR 및 사용자 지정 테이블은 배포 시에 생성됩니다. 배포하기 전에 해당 리소스를 제거하지 않으면 템플릿을 확인하기가 더 어렵습니다.

  1. ARM 배포 템플릿 콘텐츠를 복사합니다.
  2. 빠른 시작: Azure Portal을 사용하여 ARM 템플릿 만들기 및 배포 문서의 템플릿 편집 및 배포 지침을 따릅니다.

로깅 원본에 대한 네트워크 격리 유지 관리

로깅 원본에 네트워크 격리가 필요한 경우 CCP에서 사용하는 공용 IP 주소의 허용 목록을 구성합니다.

Azure 가상 네트워크는 서비스 태그를 사용하여 네트워크 액세스 제어를 정의합니다. CCP의 경우 해당 서비스 태그는 Scuba입니다.

Scuba 서비스 태그와 연결된 현재 IP 범위를 찾으려면 서비스 태그 검색 API 사용을 참조하세요.

코드리스 커넥터 확인

데이터 커넥터 갤러리에서 코드리스 커넥터를 봅니다. 데이터 커넥터를 열고 연결하는 데 필요한 인증 매개 변수를 완료합니다. 성공적으로 연결되면 DCR 및 사용자 지정 테이블이 생성됩니다. 리소스 그룹의 DCR 리소스와 로그 분석 작업 영역의 사용자 지정 테이블을 봅니다.

참고 항목

데이터가 수집 중인지 확인하는 데 최대 30분이 걸릴 수 있습니다.

예시

코드리스 커넥터를 빌드하는 각 단계는 다음 예제 섹션에 표시됩니다.

테이블 2개 이상에 수집된 복잡한 데이터 원본을 보여주기 위해 이 예제에서는 출력 테이블 스키마와 출력 스트림이 여러 개 있는 DCR을 제공합니다. DCR 예제에서는 KQL 변환과 함께 배치합니다. 데이터 커넥터 UI 정의 및 연결 규칙 예제는 이 같은 예제 데이터 원본에서 계속됩니다. 마지막으로 솔루션 템플릿은 이러한 모든 예제 구성 요소를 사용하여 예제 CCP 데이터 커넥터를 만드는 방법을 보여줍니다.

예제 데이터

데이터 원본은 엔드포인트에 연결될 때 다음 JSON을 반환합니다.

[
        {
        "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"
        }
]

이 응답에는 경고파일eventType이 포함됩니다. 파일 이벤트는 정규화된 표준 테이블 AsimFileEventLogs에 수집되어야 하며 경고 이벤트는 사용자 지정 테이블에 수집되어야 합니다.

예제 사용자 지정 테이블

이 테이블 구조에 대한 자세한 내용은 테이블 API를 참조하세요. 사용자 지정 로그 테이블 이름에는 _CL 접미사가 있어야 합니다.

{
"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"
        }
        ]
      }
    }
}

예제 데이터 수집 규칙

다음 DCR은 예제 데이터 원본을 사용하여 단일 스트림 Custom-ExampleConnectorInput을 정의하고 출력을 테이블 2개로 변환합니다.

  1. 첫 번째 데이터 흐름은 eventType = 경고를 사용자 지정 ExampleConnectorAlerts_CL 테이블로 전달합니다.
  2. 두 번째 데이터 흐름은 eventType = 파일을 정규화된 표준 테이블 ASimFileEventLogs로 전달합니다.

이 예제 구조에 대한 자세한 내용은 데이터 수집 규칙 구조를 참조하세요.

테스트 환경에서 이 DCR을 만들려면 데이터 수집 규칙 API를 따릅니다. {{double curly braces}}의 예제 요소는 API 테스트 도구를 사용하기 위해 값이 필요한 변수를 나타냅니다. ARM 템플릿에서 이 리소스를 만들면 여기에 표시된 변수가 매개 변수로 교환됩니다.

{
  "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"
      }
    ]
  }
}

예제 데이터 커넥터 UI 정의

이 예제는 데이터 커넥터 정의 참조에 있습니다.

예제 데이터 커넥터 연결 규칙

이 예제는 데이터 커넥터 참조에 있습니다.

ARM 템플릿 예제

CCP 데이터 커넥터를 빌드하는 데 필요한 JSON 구성 요소의 섹션 4개를 포함하는 다음 구조로 ARM 배포 템플릿을 빌드합니다.

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

섹션을 Visual Code와 같은 JSON 인식 편집기와 함께 연결하여 쉼표와 닫힘 대괄호 및 괄호와 같은 구문 오류를 최소화합니다.

템플릿 빌드 프로세스를 안내하기 위해 주석은 메타데이터 description 또는 // 주석 표기법으로 인라인에 표시됩니다. 자세한 내용은 ARM 템플릿 모범 사례 - 주석을 참조하세요.

ARM 템플릿 테스트 도구 키트(arm-ttk)를 사용하여 빌드한 템플릿의 유효성을 검사하는 것이 좋습니다. 자세한 내용은 amr-ttk를 참조하세요.

예제 ARM 템플릿 - 매개 변수

자세한 내용은 ARM 템플릿의 매개 변수를 참조하세요.

Warning

리소스 배포 후 읽을 수 있는 개체의 모든 암호 및 비밀에 securestring을 사용합니다. 자세한 내용은 기민 입력 보호매개 변수에 대한 보안 권장 사항을 참조하세요.

{
    "$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
}

예제 ARM 템플릿 - 변수

이러한 권장 변수는 템플릿을 간소화하는 데 도움이 됩니다. 필요에 따라 더 많이 또는 적게 사용합니다. 자세한 내용은 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

예제 ARM 템플릿 - 리소스

이 템플릿 가이드에는 CCP 데이터 커넥터 빌드 구성 요소 4개를 비롯하여 ARM 배포 리소스 5개가 있습니다.

  1. contentTemplates(부모 리소스)
  2. dataConnectorDefinitions - 자세한 내용은 데이터 커넥터 사용자 인터페이스를 참조하세요.
  3. metadata
  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')]"
            }
        }
        // that's the end!
    ]
}

자세한 내용은 참조하세요.