{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "languageVersion": "2.0",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.46.1.21595",
      "templateHash": "10262575960603298231"
    }
  },
  "parameters": {
    "namePrefix": {
      "type": "string",
      "defaultValue": "groundcover-azure-ingester",
      "minLength": 3,
      "metadata": {
        "description": "Name prefix for created resources."
      }
    },
    "GCIngestionKey": {
      "type": "securestring",
      "metadata": {
        "description": "groundcover ingestion API key. Expected format: gcik_YOUR_INGESTION_KEY."
      }
    },
    "GCEndpoint": {
      "type": "string",
      "minLength": 1,
      "metadata": {
        "description": "groundcover OTLP/gRPC hostname. Example format: telemetry.example.com. Enter the hostname only; do not include https://, a port, or a path."
      }
    },
    "GCEnvironment": {
      "type": "string",
      "defaultValue": "",
      "metadata": {
        "description": "Optional groundcover environment label attached to forwarded telemetry."
      }
    },
    "containerImageUri": {
      "type": "string",
      "defaultValue": "public.ecr.aws/groundcovercom/groundcover-azure-ingester:1.3.0",
      "minLength": 1,
      "metadata": {
        "description": "Full container image URI, including the tag. Defaults to the public ECR release image; pass a private ECR URI (<account>.dkr.ecr.<region>.amazonaws.com/<repo>:<tag>) together with ecrRegistryPassword to pull from a private registry."
      }
    },
    "ecrRegistryPassword": {
      "type": "securestring",
      "defaultValue": "",
      "metadata": {
        "description": "ECR registry password (private ECR: aws ecr get-login-password; public ECR: aws ecr-public get-login-password --region us-east-1; leave empty for anonymous public pulls)."
      }
    },
    "eventHubNamespaceName": {
      "type": "string",
      "metadata": {
        "description": "Existing Event Hubs namespace name."
      }
    },
    "eventHubName": {
      "type": "string",
      "metadata": {
        "description": "Event Hub name receiving Application Insights, subscription Activity Logs, and other Azure resource logs through diagnostic settings."
      }
    },
    "eventHubConsumerGroup": {
      "type": "string",
      "defaultValue": "azure-function",
      "metadata": {
        "description": "Consumer group used by the Function App Event Hub trigger."
      }
    },
    "createEventHubConsumerGroup": {
      "type": "bool",
      "defaultValue": true,
      "metadata": {
        "description": "Create the consumer group when it does not exist. Set false if it already exists."
      }
    },
    "useManagedIdentityForEventHub": {
      "type": "bool",
      "defaultValue": true,
      "metadata": {
        "description": "Use managed identity for Event Hub access (recommended). When false, set eventHubConnectionString."
      }
    },
    "eventHubConnectionString": {
      "type": "securestring",
      "defaultValue": "",
      "metadata": {
        "description": "Event Hub connection string. Used only when useManagedIdentityForEventHub=false."
      }
    },
    "applicationInsightsNames": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "defaultValue": [
        "app-1",
        "app-2"
      ],
      "metadata": {
        "description": "Existing Application Insights resource names. Replace the default app-1 and app-2 examples with real resource names before deployment. Use resource names only, not resource IDs. Every resource must exist in this resource group and the Event Hub region. When diagnostic-setting deployment is enabled, the template creates one setting per name targeting the shared Event Hub."
      }
    },
    "deployDiagnosticSetting": {
      "type": "bool",
      "defaultValue": true,
      "metadata": {
        "description": "Create/update an App Insights diagnostic setting that exports logs to the Event Hub."
      }
    },
    "enableAzureResourceTags": {
      "type": "bool",
      "defaultValue": true,
      "metadata": {
        "description": "Enrich forwarded logs with tags attached directly to their Azure resource. Grants Reader on listed Application Insights resources. For other resources, grant Reader separately or enable subscription-wide access with grantActivityLogTagReader."
      }
    },
    "deployActivityLogDiagnosticSetting": {
      "type": "bool",
      "defaultValue": false,
      "metadata": {
        "description": "Export all eight Activity Log categories from this subscription to the shared Event Hub. Requires subscription diagnostic-setting deployment permissions."
      }
    },
    "grantActivityLogTagReader": {
      "type": "bool",
      "defaultValue": false,
      "metadata": {
        "description": "Grant the Function identity Reader across this subscription for Activity Log and other Azure resource-log tag lookup. Requires enableAzureResourceTags and permission to assign roles at subscription scope. Can be enabled independently of template-managed diagnostic export."
      }
    }
  },
  "variables": {
    "eventHubsDataReceiverRoleId": "a638d3c7-ab3a-418d-83e6-5f17a39d4fde",
    "location": "[resourceGroup().location]",
    "containerRegistryHost": "[split(parameters('containerImageUri'), '/')[0]]",
    "dockerRegistryServerUrl": "[format('https://{0}', variables('containerRegistryHost'))]",
    "storageNamePrefix": "[toLower(take(replace(format('gc{0}', parameters('namePrefix')), '-', ''), 11))]",
    "storageAccountName": "[format('{0}{1}', variables('storageNamePrefix'), toLower(uniqueString(resourceGroup().id)))]",
    "functionAppName": "[format('{0}-{1}', take(replace(format('{0}-func', parameters('namePrefix')), '_', '-'), 46), toLower(uniqueString(resourceGroup().id)))]",
    "appServicePlanName": "[format('{0}-plan', parameters('namePrefix'))]",
    "shouldDeployDiagnosticSettings": "[and(parameters('deployDiagnosticSetting'), not(empty(parameters('applicationInsightsNames'))))]"
  },
  "resources": {
    "storageAccount": {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2023-05-01",
      "name": "[variables('storageAccountName')]",
      "location": "[variables('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "StorageV2",
      "properties": {
        "supportsHttpsTrafficOnly": true,
        "minimumTlsVersion": "TLS1_2",
        "allowBlobPublicAccess": false
      }
    },
    "appServicePlan": {
      "type": "Microsoft.Web/serverfarms",
      "apiVersion": "2023-12-01",
      "name": "[variables('appServicePlanName')]",
      "location": "[variables('location')]",
      "sku": {
        "name": "EP1",
        "tier": "ElasticPremium"
      },
      "kind": "linux",
      "properties": {
        "reserved": true
      }
    },
    "functionApp": {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2023-12-01",
      "name": "[variables('functionAppName')]",
      "location": "[variables('location')]",
      "kind": "functionapp,linux,container",
      "identity": {
        "type": "SystemAssigned"
      },
      "properties": {
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]",
        "httpsOnly": true,
        "siteConfig": {
          "linuxFxVersion": "[format('DOCKER|{0}', parameters('containerImageUri'))]",
          "appSettings": "[concat(createArray(createObject('name', 'AzureWebJobsStorage', 'value', format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2}', variables('storageAccountName'), listKeys('storageAccount', '2023-05-01').keys[0].value, environment().suffixes.storage)), createObject('name', 'FUNCTIONS_EXTENSION_VERSION', 'value', '~4'), createObject('name', 'FUNCTIONS_WORKER_RUNTIME', 'value', 'Custom'), createObject('name', 'WEBSITES_ENABLE_APP_SERVICE_STORAGE', 'value', 'false'), createObject('name', 'DOCKER_REGISTRY_SERVER_URL', 'value', variables('dockerRegistryServerUrl')), createObject('name', 'EVENTHUB_NAME', 'value', parameters('eventHubName')), createObject('name', 'EVENTHUB_CONSUMER_GROUP', 'value', parameters('eventHubConsumerGroup')), createObject('name', 'GC_API_KEY', 'value', parameters('GCIngestionKey')), createObject('name', 'GC_ENDPOINT', 'value', parameters('GCEndpoint')), createObject('name', 'GC_ENV', 'value', parameters('GCEnvironment')), createObject('name', 'AZURE_RESOURCE_TAGS_ENABLED', 'value', string(parameters('enableAzureResourceTags')))), if(empty(parameters('ecrRegistryPassword')), createArray(), createArray(createObject('name', 'DOCKER_REGISTRY_SERVER_USERNAME', 'value', 'AWS'), createObject('name', 'DOCKER_REGISTRY_SERVER_PASSWORD', 'value', parameters('ecrRegistryPassword')))), if(parameters('useManagedIdentityForEventHub'), createArray(createObject('name', 'EVENTHUB_CONNECTION__fullyQualifiedNamespace', 'value', format('{0}.servicebus.windows.net', parameters('eventHubNamespaceName'))), createObject('name', 'EVENTHUB_CONNECTION__credential', 'value', 'managedidentity')), createArray(createObject('name', 'EVENTHUB_CONNECTION', 'value', parameters('eventHubConnectionString')))))]"
        }
      },
      "dependsOn": [
        "appServicePlan",
        "storageAccount"
      ]
    },
    "eventHubNamespace": {
      "existing": true,
      "type": "Microsoft.EventHub/namespaces",
      "apiVersion": "2024-05-01-preview",
      "name": "[parameters('eventHubNamespaceName')]"
    },
    "eventHub": {
      "existing": true,
      "type": "Microsoft.EventHub/namespaces/eventhubs",
      "apiVersion": "2024-05-01-preview",
      "name": "[format('{0}/{1}', parameters('eventHubNamespaceName'), parameters('eventHubName'))]"
    },
    "consumerGroup": {
      "condition": "[parameters('createEventHubConsumerGroup')]",
      "type": "Microsoft.EventHub/namespaces/eventhubs/consumergroups",
      "apiVersion": "2024-05-01-preview",
      "name": "[format('{0}/{1}/{2}', parameters('eventHubNamespaceName'), parameters('eventHubName'), parameters('eventHubConsumerGroup'))]",
      "properties": {}
    },
    "eventHubDataReceiverRole": {
      "condition": "[parameters('useManagedIdentityForEventHub')]",
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2022-04-01",
      "scope": "[resourceId('Microsoft.EventHub/namespaces/eventhubs', parameters('eventHubNamespaceName'), parameters('eventHubName'))]",
      "name": "[guid(resourceId('Microsoft.Web/sites', variables('functionAppName')), resourceId('Microsoft.EventHub/namespaces/eventhubs', parameters('eventHubNamespaceName'), parameters('eventHubName')), variables('eventHubsDataReceiverRoleId'))]",
      "properties": {
        "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('eventHubsDataReceiverRoleId'))]",
        "principalId": "[reference('functionApp', '2023-12-01', 'full').identity.principalId]",
        "principalType": "ServicePrincipal"
      },
      "dependsOn": [
        "functionApp"
      ]
    },
    "applicationInsights": {
      "copy": {
        "name": "applicationInsights",
        "count": "[length(parameters('applicationInsightsNames'))]"
      },
      "existing": true,
      "type": "Microsoft.Insights/components",
      "apiVersion": "2020-02-02",
      "name": "[parameters('applicationInsightsNames')[copyIndex()]]"
    },
    "diagnosticSettingAuthRule": {
      "condition": "[or(variables('shouldDeployDiagnosticSettings'), parameters('deployActivityLogDiagnosticSetting'))]",
      "type": "Microsoft.EventHub/namespaces/authorizationRules",
      "apiVersion": "2024-05-01-preview",
      "name": "[format('{0}/{1}', parameters('eventHubNamespaceName'), format('{0}-appi-diagnostic-rule', parameters('namePrefix')))]",
      "properties": {
        "rights": [
          "Listen",
          "Send",
          "Manage"
        ]
      }
    },
    "appInsightsDiagnosticSetting": {
      "copy": {
        "name": "appInsightsDiagnosticSetting",
        "count": "[length(range(0, length(parameters('applicationInsightsNames'))))]"
      },
      "condition": "[variables('shouldDeployDiagnosticSettings')]",
      "type": "Microsoft.Insights/diagnosticSettings",
      "apiVersion": "2021-05-01-preview",
      "scope": "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsNames')[range(0, length(parameters('applicationInsightsNames')))[copyIndex()]])]",
      "name": "[format('{0}-appi-to-eventhub', parameters('namePrefix'))]",
      "properties": {
        "eventHubAuthorizationRuleId": "[resourceId('Microsoft.EventHub/namespaces/authorizationRules', parameters('eventHubNamespaceName'), format('{0}-appi-diagnostic-rule', parameters('namePrefix')))]",
        "eventHubName": "[parameters('eventHubName')]",
        "logs": [
          {
            "categoryGroup": "allLogs",
            "enabled": true
          }
        ]
      },
      "dependsOn": [
        "diagnosticSettingAuthRule"
      ]
    },
    "applicationInsightsReaderRole": {
      "copy": {
        "name": "applicationInsightsReaderRole",
        "count": "[length(range(0, length(parameters('applicationInsightsNames'))))]"
      },
      "condition": "[parameters('enableAzureResourceTags')]",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "[format('application-insights-reader-role-{0}', range(0, length(parameters('applicationInsightsNames')))[copyIndex()])]",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "mode": "Incremental",
        "parameters": {
          "applicationInsightsName": {
            "value": "[parameters('applicationInsightsNames')[range(0, length(parameters('applicationInsightsNames')))[copyIndex()]]]"
          },
          "principalId": {
            "value": "[reference('functionApp', '2023-12-01', 'full').identity.principalId]"
          }
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "metadata": {
            "_generator": {
              "name": "bicep",
              "version": "0.46.1.21595",
              "templateHash": "3528499899810871245"
            }
          },
          "parameters": {
            "applicationInsightsName": {
              "type": "string",
              "metadata": {
                "description": "Existing Application Insights resource name."
              }
            },
            "principalId": {
              "type": "string",
              "metadata": {
                "description": "Object ID of the Function system-assigned identity."
              }
            }
          },
          "variables": {
            "readerRoleId": "acdd72a7-3385-48ef-bd42-f606fba81ae7"
          },
          "resources": [
            {
              "type": "Microsoft.Authorization/roleAssignments",
              "apiVersion": "2022-04-01",
              "scope": "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]",
              "name": "[guid(parameters('principalId'), resourceId('Microsoft.Insights/components', parameters('applicationInsightsName')), variables('readerRoleId'))]",
              "properties": {
                "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('readerRoleId'))]",
                "principalId": "[parameters('principalId')]",
                "principalType": "ServicePrincipal"
              }
            }
          ]
        }
      },
      "dependsOn": [
        "functionApp"
      ]
    },
    "activityLogs": {
      "condition": "[or(parameters('deployActivityLogDiagnosticSetting'), and(parameters('enableAzureResourceTags'), parameters('grantActivityLogTagReader')))]",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "[format('activity-logs-{0}', uniqueString(resourceGroup().id, variables('functionAppName')))]",
      "subscriptionId": "[subscription().subscriptionId]",
      "location": "[resourceGroup().location]",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "mode": "Incremental",
        "parameters": {
          "diagnosticSettingName": {
            "value": "[format('{0}-activity-{1}', parameters('namePrefix'), uniqueString(resourceGroup().id))]"
          },
          "deployDiagnosticSetting": {
            "value": "[parameters('deployActivityLogDiagnosticSetting')]"
          },
          "eventHubAuthorizationRuleId": "[if(parameters('deployActivityLogDiagnosticSetting'), createObject('value', resourceId('Microsoft.EventHub/namespaces/authorizationRules', parameters('eventHubNamespaceName'), format('{0}-appi-diagnostic-rule', parameters('namePrefix')))), createObject('value', ''))]",
          "eventHubName": {
            "value": "[parameters('eventHubName')]"
          },
          "principalId": {
            "value": "[reference('functionApp', '2023-12-01', 'full').identity.principalId]"
          },
          "grantTagReader": {
            "value": "[and(parameters('enableAzureResourceTags'), parameters('grantActivityLogTagReader'))]"
          }
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "metadata": {
            "_generator": {
              "name": "bicep",
              "version": "0.46.1.21595",
              "templateHash": "8161270537387211195"
            }
          },
          "parameters": {
            "diagnosticSettingName": {
              "type": "string"
            },
            "deployDiagnosticSetting": {
              "type": "bool"
            },
            "eventHubAuthorizationRuleId": {
              "type": "string"
            },
            "eventHubName": {
              "type": "string"
            },
            "principalId": {
              "type": "string"
            },
            "grantTagReader": {
              "type": "bool"
            }
          },
          "variables": {
            "activityLogCategories": [
              "Administrative",
              "Security",
              "ServiceHealth",
              "ResourceHealth",
              "Alert",
              "Autoscale",
              "Recommendation",
              "Policy"
            ],
            "readerRoleId": "acdd72a7-3385-48ef-bd42-f606fba81ae7"
          },
          "resources": [
            {
              "condition": "[parameters('deployDiagnosticSetting')]",
              "type": "Microsoft.Insights/diagnosticSettings",
              "apiVersion": "2021-05-01-preview",
              "name": "[parameters('diagnosticSettingName')]",
              "properties": {
                "copy": [
                  {
                    "name": "logs",
                    "count": "[length(variables('activityLogCategories'))]",
                    "input": {
                      "category": "[variables('activityLogCategories')[copyIndex('logs')]]",
                      "enabled": true
                    }
                  }
                ],
                "eventHubAuthorizationRuleId": "[parameters('eventHubAuthorizationRuleId')]",
                "eventHubName": "[parameters('eventHubName')]"
              }
            },
            {
              "condition": "[parameters('grantTagReader')]",
              "type": "Microsoft.Authorization/roleAssignments",
              "apiVersion": "2022-04-01",
              "name": "[guid(subscription().id, parameters('principalId'), variables('readerRoleId'))]",
              "properties": {
                "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('readerRoleId'))]",
                "principalId": "[parameters('principalId')]",
                "principalType": "ServicePrincipal"
              }
            }
          ]
        }
      },
      "dependsOn": [
        "diagnosticSettingAuthRule",
        "functionApp"
      ]
    }
  },
  "outputs": {
    "functionAppName": {
      "type": "string",
      "value": "[variables('functionAppName')]"
    },
    "functionAppHostName": {
      "type": "string",
      "value": "[reference('functionApp').defaultHostName]"
    },
    "functionAppPrincipalId": {
      "type": "string",
      "value": "[reference('functionApp', '2023-12-01', 'full').identity.principalId]"
    },
    "containerImageUri": {
      "type": "string",
      "value": "[parameters('containerImageUri')]"
    },
    "containerRegistryUrl": {
      "type": "string",
      "value": "[variables('dockerRegistryServerUrl')]"
    }
  }
}