{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.32.4.45862",
      "templateHash": "13074892105796432857"
    }
  },
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location of the Cluster"
      }
    },
    "clusterName": {
      "type": "string",
      "metadata": {
        "description": "Name of your cluster - Between 3 and 23 characters. Letters and numbers only"
      }
    },
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Remote desktop user Id"
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Remote desktop user password. Must be a strong password"
      }
    },
    "vmImagePublisher": {
      "type": "string",
      "defaultValue": "MicrosoftWindowsServer",
      "metadata": {
        "description": "VM image Publisher"
      }
    },
    "vmImageOffer": {
      "type": "string",
      "defaultValue": "WindowsServer",
      "metadata": {
        "description": "VM image offer"
      }
    },
    "vmImageSku": {
      "type": "string",
      "defaultValue": "2019-Datacenter",
      "metadata": {
        "description": "VM image SKU"
      }
    },
    "vmImageVersion": {
      "type": "string",
      "defaultValue": "latest",
      "metadata": {
        "description": "VM image version"
      }
    },
    "loadBalancedAppPort1": {
      "type": "int",
      "defaultValue": 80,
      "metadata": {
        "description": "Input endpoint1 for the application to use. Replace it with what your application uses"
      }
    },
    "loadBalancedAppPort2": {
      "type": "int",
      "defaultValue": 8081,
      "metadata": {
        "description": "Input endpoint2 for the application to use. Replace it with what your application uses"
      }
    },
    "certificateStoreValue": {
      "type": "string",
      "defaultValue": "My",
      "allowedValues": [
        "My"
      ],
      "metadata": {
        "description": "The store name where the cert will be deployed in the virtual machine"
      }
    },
    "certificateThumbprint": {
      "type": "string",
      "metadata": {
        "description": "Certificate Thumbprint"
      }
    },
    "sourceVaultResourceId": {
      "type": "string",
      "metadata": {
        "description": "Resource Id of the key vault, is should be in the format of /subscriptions/<Sub ID>/resourceGroups/<Resource group name>/providers/Microsoft.KeyVault/vaults/<vault name>"
      }
    },
    "certificateUrlValue": {
      "type": "string",
      "metadata": {
        "description": "Refers to the location URL in your key vault where the certificate was uploaded"
      }
    },
    "clusterProtectionLevel": {
      "type": "string",
      "defaultValue": "EncryptAndSign",
      "allowedValues": [
        "None",
        "Sign",
        "EncryptAndSign"
      ],
      "metadata": {
        "description": "Protection level.Three values are allowed - EncryptAndSign, Sign, None. It is best to keep the default of EncryptAndSign, unless you have a need not to"
      }
    },
    "nt0InstanceCount": {
      "type": "int",
      "defaultValue": 5,
      "metadata": {
        "description": "Instance count for node type"
      }
    },
    "nodeDataDrive": {
      "type": "string",
      "defaultValue": "Temp",
      "allowedValues": [
        "OS",
        "Temp"
      ],
      "metadata": {
        "description": "The drive to use to store data on a cluster node."
      }
    },
    "nodeTypeSize": {
      "type": "string",
      "defaultValue": "Standard_D2_v3",
      "metadata": {
        "description": "The VM size to use for cluster nodes."
      }
    },
    "tenantId": {
      "type": "string"
    },
    "clusterApplication": {
      "type": "string"
    },
    "clientapplication": {
      "type": "string"
    }
  },
  "variables": {
    "dnsName": "[parameters('clusterName')]",
    "vmName": "vm",
    "virtualNetworkName": "VNet",
    "addressPrefix": "10.0.0.0/16",
    "nicName": "NIC",
    "lbIPName": "PublicIP-LB-FE",
    "overProvision": false,
    "nt0applicationStartPort": 20000,
    "nt0applicationEndPort": 30000,
    "nt0ephemeralStartPort": 49152,
    "nt0ephemeralEndPort": 65534,
    "nt0fabricTcpGatewayPort": 19000,
    "nt0fabricHttpGatewayPort": 19080,
    "subnet0Name": "Subnet-0",
    "subnet0Prefix": "10.0.0.0/24",
    "subnet0Ref": "[resourceId('Microsoft.Network/virtualNetworks/subnets/', variables('virtualNetworkName'), variables('subnet0Name'))]",
    "supportLogStorageAccountName": "[format('{0}2', uniqueString(resourceGroup().id))]",
    "applicationDiagnosticsStorageAccountName": "[format('{0}3', uniqueString(resourceGroup().id))]",
    "lbName": "[format('LB-{0}-{1}', parameters('clusterName'), variables('vmNodeType0Name'))]",
    "lbIPConfig0": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations/', variables('lbName'), 'LoadBalancerIPConfig')]",
    "lbPoolID0": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), 'LoadBalancerBEAddressPool')]",
    "lbProbeID0": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), 'FabricGatewayProbe')]",
    "lbHttpProbeID0": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), 'FabricHttpGatewayProbe')]",
    "lbNatPoolID0": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('lbName'), 'LoadBalancerBEAddressNatPool')]",
    "vmNodeType0Name": "[toLower(format('NT1{0}', variables('vmName')))]",
    "vmNodeType0Size": "[parameters('nodeTypeSize')]"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2023-01-01",
      "name": "[variables('supportLogStorageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "tags": {
        "resourceType": "Service Fabric",
        "clusterName": "[parameters('clusterName')]"
      },
      "properties": {}
    },
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2023-01-01",
      "name": "[variables('applicationDiagnosticsStorageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "tags": {
        "resourceType": "Service Fabric",
        "clusterName": "[parameters('clusterName')]"
      },
      "properties": {}
    },
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2023-09-01",
      "name": "[variables('virtualNetworkName')]",
      "location": "[parameters('location')]",
      "tags": {
        "resourceType": "Service Fabric",
        "clusterName": "[parameters('clusterName')]"
      },
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[variables('addressPrefix')]"
          ]
        },
        "subnets": [
          {
            "name": "[variables('subnet0Name')]",
            "properties": {
              "addressPrefix": "[variables('subnet0Prefix')]"
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2023-09-01",
      "name": "[variables('lbIPName')]",
      "location": "[parameters('location')]",
      "tags": {
        "resourceType": "Service Fabric",
        "clusterName": "[parameters('clusterName')]"
      },
      "properties": {
        "dnsSettings": {
          "domainNameLabel": "[variables('dnsName')]"
        },
        "publicIPAllocationMethod": "Dynamic"
      }
    },
    {
      "type": "Microsoft.Network/loadBalancers",
      "apiVersion": "2023-09-01",
      "name": "[variables('lbName')]",
      "location": "[parameters('location')]",
      "tags": {
        "resourceType": "Service Fabric",
        "clusterName": "[parameters('clusterName')]"
      },
      "properties": {
        "frontendIPConfigurations": [
          {
            "name": "LoadBalancerIPConfig",
            "properties": {
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('lbIPName'))]"
              }
            }
          }
        ],
        "backendAddressPools": [
          {
            "name": "LoadBalancerBEAddressPool",
            "properties": {}
          }
        ],
        "loadBalancingRules": [
          {
            "name": "LBRule",
            "properties": {
              "backendAddressPool": {
                "id": "[variables('lbPoolID0')]"
              },
              "backendPort": "[variables('nt0fabricTcpGatewayPort')]",
              "enableFloatingIP": false,
              "frontendIPConfiguration": {
                "id": "[variables('lbIPConfig0')]"
              },
              "frontendPort": "[variables('nt0fabricTcpGatewayPort')]",
              "idleTimeoutInMinutes": 5,
              "probe": {
                "id": "[variables('lbProbeID0')]"
              },
              "protocol": "Tcp"
            }
          },
          {
            "name": "LBHttpRule",
            "properties": {
              "backendAddressPool": {
                "id": "[variables('lbPoolID0')]"
              },
              "backendPort": "[variables('nt0fabricHttpGatewayPort')]",
              "enableFloatingIP": false,
              "frontendIPConfiguration": {
                "id": "[variables('lbIPConfig0')]"
              },
              "frontendPort": "[variables('nt0fabricHttpGatewayPort')]",
              "idleTimeoutInMinutes": 5,
              "probe": {
                "id": "[variables('lbHttpProbeID0')]"
              },
              "protocol": "Tcp"
            }
          },
          {
            "name": "AppPortLBRule1",
            "properties": {
              "backendAddressPool": {
                "id": "[variables('lbPoolID0')]"
              },
              "backendPort": "[parameters('loadBalancedAppPort1')]",
              "enableFloatingIP": false,
              "frontendIPConfiguration": {
                "id": "[variables('lbIPConfig0')]"
              },
              "frontendPort": "[parameters('loadBalancedAppPort1')]",
              "idleTimeoutInMinutes": 5,
              "probe": {
                "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), 'AppPortProbe1')]"
              },
              "protocol": "Tcp"
            }
          },
          {
            "name": "AppPortLBRule2",
            "properties": {
              "backendAddressPool": {
                "id": "[variables('lbPoolID0')]"
              },
              "backendPort": "[parameters('loadBalancedAppPort2')]",
              "enableFloatingIP": false,
              "frontendIPConfiguration": {
                "id": "[variables('lbIPConfig0')]"
              },
              "frontendPort": "[parameters('loadBalancedAppPort2')]",
              "idleTimeoutInMinutes": 5,
              "probe": {
                "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), 'AppPortProbe2')]"
              },
              "protocol": "Tcp"
            }
          }
        ],
        "probes": [
          {
            "name": "FabricGatewayProbe",
            "properties": {
              "intervalInSeconds": 5,
              "numberOfProbes": 2,
              "port": "[variables('nt0fabricTcpGatewayPort')]",
              "protocol": "Tcp"
            }
          },
          {
            "name": "FabricHttpGatewayProbe",
            "properties": {
              "intervalInSeconds": 5,
              "numberOfProbes": 2,
              "port": "[variables('nt0fabricHttpGatewayPort')]",
              "protocol": "Tcp"
            }
          },
          {
            "name": "AppPortProbe1",
            "properties": {
              "intervalInSeconds": 5,
              "numberOfProbes": 2,
              "port": "[parameters('loadBalancedAppPort1')]",
              "protocol": "Tcp"
            }
          },
          {
            "name": "AppPortProbe2",
            "properties": {
              "intervalInSeconds": 5,
              "numberOfProbes": 2,
              "port": "[parameters('loadBalancedAppPort2')]",
              "protocol": "Tcp"
            }
          }
        ],
        "inboundNatPools": [
          {
            "name": "LoadBalancerBEAddressNatPool",
            "properties": {
              "backendPort": 3389,
              "frontendIPConfiguration": {
                "id": "[variables('lbIPConfig0')]"
              },
              "frontendPortRangeEnd": 4500,
              "frontendPortRangeStart": 3389,
              "protocol": "Tcp"
            }
          }
        ]
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses', variables('lbIPName'))]"
      ]
    },
    {
      "type": "Microsoft.Compute/virtualMachineScaleSets",
      "apiVersion": "2023-09-01",
      "name": "[variables('vmNodeType0Name')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[variables('vmNodeType0Size')]",
        "capacity": "[parameters('nt0InstanceCount')]",
        "tier": "Standard"
      },
      "tags": {
        "resourceType": "Service Fabric",
        "clusterName": "[parameters('clusterName')]"
      },
      "properties": {
        "overprovision": "[variables('overProvision')]",
        "upgradePolicy": {
          "mode": "Automatic"
        },
        "virtualMachineProfile": {
          "extensionProfile": {
            "extensions": [
              {
                "name": "ServiceFabricNodeVmExt_vmNodeType0Name",
                "properties": {
                  "type": "ServiceFabricNode",
                  "autoUpgradeMinorVersion": true,
                  "protectedSettings": {
                    "StorageAccountKey1": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')), '2023-01-01').keys[0].value]",
                    "StorageAccountKey2": "[listkeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')), '2023-01-01').keys[1].value]"
                  },
                  "publisher": "Microsoft.Azure.ServiceFabric",
                  "settings": {
                    "clusterEndpoint": "[reference(resourceId('Microsoft.ServiceFabric/clusters', parameters('clusterName')), '2023-11-01-preview').clusterEndpoint]",
                    "nodeTypeRef": "[variables('vmNodeType0Name')]",
                    "dataPath": "[format('{0}:\\\\SvcFab', if(equals(parameters('nodeDataDrive'), 'OS'), 'C', 'D'))]",
                    "durabilityLevel": "Silver",
                    "nicPrefixOverride": "[variables('subnet0Prefix')]",
                    "certificate": {
                      "thumbprint": "[parameters('certificateThumbprint')]",
                      "x509StoreName": "[parameters('certificateStoreValue')]"
                    }
                  },
                  "typeHandlerVersion": "1.0"
                }
              },
              {
                "name": "VMDiagnosticsVmExt_vmNodeType0Name",
                "properties": {
                  "type": "IaaSDiagnostics",
                  "autoUpgradeMinorVersion": true,
                  "protectedSettings": {
                    "storageAccountName": "[variables('applicationDiagnosticsStorageAccountName')]",
                    "storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('applicationDiagnosticsStorageAccountName')), '2021-01-01').keys[0].value]",
                    "storageAccountEndPoint": "[format('https://{0}', environment().suffixes.storage)]"
                  },
                  "publisher": "Microsoft.Azure.Diagnostics",
                  "settings": {
                    "WadCfg": {
                      "DiagnosticMonitorConfiguration": {
                        "overallQuotaInMB": "50000",
                        "EtwProviders": {
                          "EtwEventSourceProviderConfiguration": [
                            {
                              "provider": "Microsoft-ServiceFabric-Actors",
                              "scheduledTransferKeywordFilter": "1",
                              "scheduledTransferPeriod": "PT5M",
                              "DefaultEvents": {
                                "eventDestination": "ServiceFabricReliableActorEventTable"
                              }
                            },
                            {
                              "provider": "Microsoft-ServiceFabric-Services",
                              "scheduledTransferPeriod": "PT5M",
                              "DefaultEvents": {
                                "eventDestination": "ServiceFabricReliableServiceEventTable"
                              }
                            }
                          ],
                          "EtwManifestProviderConfiguration": [
                            {
                              "provider": "cbd93bc2-71e5-4566-b3a7-595d8eeca6e8",
                              "scheduledTransferLogLevelFilter": "Information",
                              "scheduledTransferKeywordFilter": "4611686018427387904",
                              "scheduledTransferPeriod": "PT5M",
                              "DefaultEvents": {
                                "eventDestination": "ServiceFabricSystemEventTable"
                              }
                            }
                          ]
                        }
                      }
                    },
                    "StorageAccount": "[variables('applicationDiagnosticsStorageAccountName')]"
                  },
                  "typeHandlerVersion": "1.5"
                }
              }
            ]
          },
          "networkProfile": {
            "networkInterfaceConfigurations": [
              {
                "name": "[format('{0}-0', variables('nicName'))]",
                "properties": {
                  "ipConfigurations": [
                    {
                      "name": "[format('{0}-0', variables('nicName'))]",
                      "properties": {
                        "loadBalancerBackendAddressPools": [
                          {
                            "id": "[variables('lbPoolID0')]"
                          }
                        ],
                        "loadBalancerInboundNatPools": [
                          {
                            "id": "[variables('lbNatPoolID0')]"
                          }
                        ],
                        "subnet": {
                          "id": "[variables('subnet0Ref')]"
                        }
                      }
                    }
                  ],
                  "primary": true
                }
              }
            ]
          },
          "osProfile": {
            "adminPassword": "[parameters('adminPassword')]",
            "adminUsername": "[parameters('adminUsername')]",
            "computerNamePrefix": "[variables('vmNodeType0Name')]",
            "secrets": [
              {
                "sourceVault": {
                  "id": "[parameters('sourceVaultResourceId')]"
                },
                "vaultCertificates": [
                  {
                    "certificateStore": "[parameters('certificateStoreValue')]",
                    "certificateUrl": "[parameters('certificateUrlValue')]"
                  }
                ]
              }
            ]
          },
          "storageProfile": {
            "imageReference": {
              "publisher": "[parameters('vmImagePublisher')]",
              "offer": "[parameters('vmImageOffer')]",
              "sku": "[parameters('vmImageSku')]",
              "version": "[parameters('vmImageVersion')]"
            },
            "osDisk": {
              "managedDisk": {
                "storageAccountType": "StandardSSD_LRS"
              },
              "caching": "ReadOnly",
              "createOption": "FromImage"
            }
          }
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', variables('applicationDiagnosticsStorageAccountName'))]",
        "[resourceId('Microsoft.ServiceFabric/clusters', parameters('clusterName'))]",
        "[resourceId('Microsoft.Network/loadBalancers', variables('lbName'))]",
        "[resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName'))]",
        "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]"
      ]
    },
    {
      "type": "Microsoft.ServiceFabric/clusters",
      "apiVersion": "2023-11-01-preview",
      "name": "[parameters('clusterName')]",
      "location": "[parameters('location')]",
      "tags": {
        "resourceType": "Service Fabric",
        "clusterName": "[parameters('clusterName')]"
      },
      "properties": {
        "azureActiveDirectory": {
          "clientApplication": "[parameters('clientapplication')]",
          "clusterApplication": "[parameters('clusterApplication')]",
          "tenantId": "[parameters('tenantId')]"
        },
        "certificate": {
          "thumbprint": "[parameters('certificateThumbprint')]",
          "x509StoreName": "[parameters('certificateStoreValue')]"
        },
        "diagnosticsStorageAccountConfig": {
          "blobEndpoint": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')), '2021-01-01').primaryEndpoints.blob]",
          "protectedAccountKeyName": "StorageAccountKey1",
          "queueEndpoint": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')), '2021-01-01').primaryEndpoints.queue]",
          "storageAccountName": "[variables('supportLogStorageAccountName')]",
          "tableEndpoint": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')), '2021-01-01').primaryEndpoints.table]"
        },
        "fabricSettings": [
          {
            "parameters": [
              {
                "name": "ClusterProtectionLevel",
                "value": "[parameters('clusterProtectionLevel')]"
              }
            ],
            "name": "Security"
          }
        ],
        "managementEndpoint": "[format('https://{0}:{1}', reference(resourceId('Microsoft.Network/publicIPAddresses', variables('lbIPName')), '2023-09-01').dnsSettings.fqdn, variables('nt0fabricHttpGatewayPort'))]",
        "nodeTypes": [
          {
            "name": "[variables('vmNodeType0Name')]",
            "applicationPorts": {
              "endPort": "[variables('nt0applicationEndPort')]",
              "startPort": "[variables('nt0applicationStartPort')]"
            },
            "clientConnectionEndpointPort": "[variables('nt0fabricTcpGatewayPort')]",
            "durabilityLevel": "Silver",
            "ephemeralPorts": {
              "endPort": "[variables('nt0ephemeralEndPort')]",
              "startPort": "[variables('nt0ephemeralStartPort')]"
            },
            "httpGatewayEndpointPort": "[variables('nt0fabricHttpGatewayPort')]",
            "isPrimary": true,
            "vmInstanceCount": "[parameters('nt0InstanceCount')]"
          }
        ],
        "reliabilityLevel": "Silver",
        "upgradeMode": "Automatic",
        "vmImage": "Windows"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses', variables('lbIPName'))]",
        "[resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName'))]"
      ]
    }
  ],
  "outputs": {
    "location": {
      "type": "string",
      "value": "[parameters('location')]"
    },
    "name": {
      "type": "string",
      "value": "[parameters('clusterName')]"
    },
    "resourceGroupName": {
      "type": "string",
      "value": "[resourceGroup().name]"
    },
    "resourceId": {
      "type": "string",
      "value": "[resourceId('Microsoft.ServiceFabric/clusters', parameters('clusterName'))]"
    },
    "clusterProperties": {
      "type": "object",
      "value": "[reference(resourceId('Microsoft.ServiceFabric/clusters', parameters('clusterName')), '2023-11-01-preview')]"
    }
  }
}