diff --git a/.gitignore b/.gitignore index a0b152c2e..b38b0f982 100644 --- a/.gitignore +++ b/.gitignore @@ -316,3 +316,6 @@ Temporary Items # End of https://www.toptal.com/developers/gitignore/api/macos src/AzureIoTHub.Portal/Client/assets/package-lock.json src/AzureIoTHub.Portal/Server/appsettings.Development.json + +# Folder for iotedge-lorawan-starterkit bicep templates +iotedge-lorawan-starterkit/ diff --git a/templates/azuredeploy.bicep b/templates/azuredeploy.bicep index d56cc8806..ed59f221c 100644 --- a/templates/azuredeploy.bicep +++ b/templates/azuredeploy.bicep @@ -74,26 +74,22 @@ param ideasAuthenticationHeader string = 'Ocp-Apim-Subscription-Key' @description('Authentication token to interact with Awesome-Ideas. Required when ideasEnabled is true') param ideasAuthenticationToken string = '' -var starterKitDeploymentName = 'lorawan-starter-kit' -var portalWithLoRaDeploymentName = 'iothub-portal-with-lora' -var portalWithoutLoRaDeploymentName = 'iothub-portal-without-lora' - -module starterKitDeployment '../iotedge-lorawan-starterkit/TemplateBicep/main.bicep' = if (isLoRaFeatureEnabled) { - name: starterKitDeploymentName - params: { - location: location - uniqueSolutionPrefix: uniqueSolutionPrefix - edgeGatewayName: edgeGatewayName - deployDevice: deployDevice - resetPin: resetPin - region: region - spiSpeed: spiSpeed - spiDev: spiDev - } -} - -module portalWithLoRaDeployment './portalDeployWithLoRa.bicep' = if (isLoRaFeatureEnabled) { - name: portalWithLoRaDeploymentName +var pgsqlServerName = '${uniqueSolutionPrefix}pgsql' +var iotHubName = '${uniqueSolutionPrefix}hub' +var dpsName = '${uniqueSolutionPrefix}dps' +var siteName = '${uniqueSolutionPrefix}portal' +var servicePlanName = '${uniqueSolutionPrefix}asp' +var storageAccountName = '${uniqueSolutionPrefix}storage' +var iotHubOwnerPolicyName = 'iothubowner' +var provisioningserviceownerPolicyName = 'provisioningserviceowner' +var deviceImageContainerName = 'device-images' +var iamScopeName = 'API.Access' +var storageAccountId = '${resourceGroup().id}/providers/Microsoft.Storage/storageAccounts/${storageAccountName}' +var appInsightName = '${uniqueSolutionPrefix}insight' +var functionAppName = '${uniqueSolutionPrefix}function' + +module portalWithLoRaDeployment './portal_with_lorawan_and_starter_kit.bicep' = if (isLoRaFeatureEnabled) { + name: 'iothub-portal-with-lorawan' params: { location: location uniqueSolutionPrefix: uniqueSolutionPrefix @@ -107,17 +103,32 @@ module portalWithLoRaDeployment './portalDeployWithLoRa.bicep' = if (isLoRaFeatu ideasUrl: ideasUrl ideasAuthenticationHeader: ideasAuthenticationHeader ideasAuthenticationToken: ideasAuthenticationToken + edgeGatewayName: edgeGatewayName + deployDevice: deployDevice + resetPin: resetPin + region: region + spiSpeed: spiSpeed + spiDev: spiDev + appInsightName: appInsightName + deviceImageContainerName: deviceImageContainerName + dpsName: dpsName + iamScopeName: iamScopeName + iotHubName: iotHubName + iotHubOwnerPolicyName: iotHubOwnerPolicyName + pgsqlServerName: pgsqlServerName + provisioningserviceownerPolicyName: provisioningserviceownerPolicyName + servicePlanName: servicePlanName + siteName: siteName + storageAccountId: storageAccountId + storageAccountName: storageAccountName + functionAppName: functionAppName } - dependsOn: [ - starterKitDeployment - ] } -module portalWithoutLoRaDeployment './portalDeployWithoutLoRa.bicep' = if (!isLoRaFeatureEnabled) { - name: portalWithoutLoRaDeploymentName +module portalWithoutLoRaDeployment './portal_without_lorawan.bicep' = if (!isLoRaFeatureEnabled) { + name: 'iothub-portal-without-lorawan' params: { location: location - uniqueSolutionPrefix: uniqueSolutionPrefix pgsqlAdminLogin: pgsqlAdminLogin pgsqlAdminPassword: pgsqlAdminPassword openIdAuthority: openIdAuthority @@ -128,5 +139,17 @@ module portalWithoutLoRaDeployment './portalDeployWithoutLoRa.bicep' = if (!isLo ideasUrl: ideasUrl ideasAuthenticationHeader: ideasAuthenticationHeader ideasAuthenticationToken: ideasAuthenticationToken + appInsightName: appInsightName + deviceImageContainerName: deviceImageContainerName + dpsName: dpsName + iamScopeName: iamScopeName + iotHubName: iotHubName + iotHubOwnerPolicyName: iotHubOwnerPolicyName + pgsqlServerName: pgsqlServerName + provisioningserviceownerPolicyName: provisioningserviceownerPolicyName + servicePlanName: servicePlanName + siteName: siteName + storageAccountId: storageAccountId + storageAccountName: storageAccountName } -} \ No newline at end of file +} diff --git a/templates/portalDeployWithLoRa.bicep b/templates/portal_with_lorawan.bicep similarity index 80% rename from templates/portalDeployWithLoRa.bicep rename to templates/portal_with_lorawan.bicep index e759bbcde..1f2cc5a7b 100644 --- a/templates/portalDeployWithLoRa.bicep +++ b/templates/portal_with_lorawan.bicep @@ -1,9 +1,6 @@ @description('Location for the resources.') param location string -@description('Prefix used for resource names. Should be unique as this will also be used for domain names.') -param uniqueSolutionPrefix string - @description('PostgreSQL user') param pgsqlAdminLogin string = concat(uniqueString(resourceGroup().id, newGuid())) @@ -35,19 +32,45 @@ param ideasAuthenticationHeader string = 'Ocp-Apim-Subscription-Key' @description('Authentication token to interact with Awesome-Ideas. Required when ideasEnabled is true') param ideasAuthenticationToken string = '' -var pgsqlServerName = '${uniqueSolutionPrefix}pgsql' -var iotHubName = '${uniqueSolutionPrefix}hub' -var dpsName = '${uniqueSolutionPrefix}dps' -var siteName = '${uniqueSolutionPrefix}portal' -var servicePlanName = '${uniqueSolutionPrefix}asp' -var functionAppName = '${uniqueSolutionPrefix}function' -var storageAccountName = '${uniqueSolutionPrefix}storage' -var iotHubOwnerPolicyName = 'iothubowner' -var provisioningserviceownerPolicyName = 'provisioningserviceowner' -var deviceImageContainerName = 'device-images' -var iamScopeName = 'API.Access' -var storageAccountId = '${resourceGroup().id}/providers/Microsoft.Storage/storageAccounts/${storageAccountName}' -var appInsightName = '${uniqueSolutionPrefix}insight' +@description('PostgreSQL Server Name') +param pgsqlServerName string + +@description('IotHub Name') +param iotHubName string + +@description('DPS Name') +param dpsName string + +@description('Site Name') +param siteName string + +@description('Service Plan Name') +param servicePlanName string + +@description('Storage Account Name') +param storageAccountName string + +@description('IotHub Owner Policy Name') +param iotHubOwnerPolicyName string + +@description('Provisioning Service Owner Policy Name') +param provisioningserviceownerPolicyName string + +@description('Device Image Container Name') +param deviceImageContainerName string + +@description('IAM Scope Name') +param iamScopeName string + +@description('Storage Account Id') +param storageAccountId string + +@description('App Insight Name') +param appInsightName string + +@description('Function App Name') +param functionAppName string + var functionAppDefaultHost = '${resourceId('Microsoft.Web/sites', functionAppName)}/host/default/' var ioTHubEventHubConsumerGroupName = 'iothub-portal' @@ -61,6 +84,9 @@ module ioTHubEventHubConsumerGroup './iothub_eventhub_consumer_group.bicep' = { iotHubName: iotHubName ioTHubEventHubConsumerGroupName: ioTHubEventHubConsumerGroupName } + dependsOn: [ + iotHub + ] } module storageAccountName_default_deviceImageContainer './blob_container.bicep' = { diff --git a/templates/portal_with_lorawan_and_starter_kit.bicep b/templates/portal_with_lorawan_and_starter_kit.bicep new file mode 100644 index 000000000..e9ba15575 --- /dev/null +++ b/templates/portal_with_lorawan_and_starter_kit.bicep @@ -0,0 +1,141 @@ +@description('Location for the resources.') +param location string + +@description('Prefix used for resource names. Should be unique as this will also be used for domain names.') +param uniqueSolutionPrefix string + +@description('PostgreSQL user') +param pgsqlAdminLogin string = concat(uniqueString(resourceGroup().id, newGuid())) + +@description('PostgreSQL password') +@secure() +param pgsqlAdminPassword string = '${uniqueString(resourceGroup().id, newGuid())}x!' + +@description('The Open ID Authority') +param openIdAuthority string + +@description('The Open ID metadata Url from the Identity provider') +param openIdMetadataURL string + +@description('The client ID for the B2C tenant') +param clientId string + +@description('The API client ID for the B2C tenant') +param apiClientId string + +@description('To enable Awesome-Ideas feature when set to true') +param ideasEnabled bool = false + +@description('Url of Awesome-Ideas, to publish ideas submitted by users. Required when ideasEnabled is true') +param ideasUrl string = '' + +@description('Authentication header to interact with Awesome-Ideas. Required when ideasEnabled is true') +param ideasAuthenticationHeader string = 'Ocp-Apim-Subscription-Key' + +@description('Authentication token to interact with Awesome-Ideas. Required when ideasEnabled is true') +param ideasAuthenticationToken string = '' + +@description('The name of the Edge gateway') +param edgeGatewayName string + +@description('Provision a final LoRa device in the IoT hub in addition to the gateway') +param deployDevice bool + +@description('Provide the reset pin value of your gateway. Please refer to the doc if you are unfamiliar with the value') +param resetPin int + +@description('In what region is your gateway deployed?') +@allowed(['EU863', 'US902', 'AS923-1', 'AS923-2', 'AS923-3', 'CN470RP1', 'CN470RP2', 'AU915']) +param region string = 'EU863' + +@description('[In Mbps] Custom SPI speed for your gateway, currently only supported for ARM gateways') +@allowed([8,2]) +param spiSpeed int = 8 + +@description('SPI Dev version for x86 based gateway') +@allowed([0,1,2]) +param spiDev int = 0 + +@description('PostgreSQL Server Name') +param pgsqlServerName string + +@description('IotHub Name') +param iotHubName string + +@description('DPS Name') +param dpsName string + +@description('Site Name') +param siteName string + +@description('Service Plan Name') +param servicePlanName string + +@description('Storage Account Name') +param storageAccountName string + +@description('IotHub Owner Policy Name') +param iotHubOwnerPolicyName string + +@description('Provisioning Service Owner Policy Name') +param provisioningserviceownerPolicyName string + +@description('Device Image Container Name') +param deviceImageContainerName string + +@description('IAM Scope Name') +param iamScopeName string + +@description('Storage Account Id') +param storageAccountId string + +@description('App Insight Name') +param appInsightName string + +@description('Function App Name') +param functionAppName string + +module starterKitDeployment '../iotedge-lorawan-starterkit/TemplateBicep/main.bicep' = { + name: 'lorawan-starter-kit' + params: { + location: location + uniqueSolutionPrefix: uniqueSolutionPrefix + edgeGatewayName: edgeGatewayName + deployDevice: deployDevice + resetPin: resetPin + region: region + spiSpeed: spiSpeed + spiDev: spiDev + } +} + +module portalWithLoRaWAN './portal_with_lorawan.bicep' = { + name: 'portal-with-lorawan' + params: { + location: location + pgsqlAdminLogin: pgsqlAdminLogin + pgsqlAdminPassword: pgsqlAdminPassword + openIdAuthority: openIdAuthority + openIdMetadataURL: openIdMetadataURL + apiClientId: apiClientId + clientId: clientId + ideasEnabled: ideasEnabled + ideasUrl: ideasUrl + ideasAuthenticationHeader: ideasAuthenticationHeader + ideasAuthenticationToken: ideasAuthenticationToken + appInsightName: appInsightName + deviceImageContainerName: deviceImageContainerName + dpsName: dpsName + iamScopeName: iamScopeName + iotHubName: iotHubName + iotHubOwnerPolicyName: iotHubOwnerPolicyName + pgsqlServerName: pgsqlServerName + provisioningserviceownerPolicyName: provisioningserviceownerPolicyName + servicePlanName: servicePlanName + siteName: siteName + storageAccountId: storageAccountId + storageAccountName: storageAccountName + functionAppName: functionAppName + } + dependsOn: [ starterKitDeployment ] +} diff --git a/templates/portalDeployWithoutLoRa.bicep b/templates/portal_without_lorawan.bicep similarity index 81% rename from templates/portalDeployWithoutLoRa.bicep rename to templates/portal_without_lorawan.bicep index 0049eb18b..222d6a04e 100644 --- a/templates/portalDeployWithoutLoRa.bicep +++ b/templates/portal_without_lorawan.bicep @@ -1,9 +1,6 @@ @description('Location for the resources.') param location string -@description('Prefix used for resource names. Should be unique as this will also be used for domain names.') -param uniqueSolutionPrefix string - @description('PostgreSQL user') param pgsqlAdminLogin string = concat(uniqueString(resourceGroup().id, newGuid())) @@ -35,18 +32,42 @@ param ideasAuthenticationHeader string = 'Ocp-Apim-Subscription-Key' @description('Authentication token to interact with Awesome-Ideas. Required when ideasEnabled is true') param ideasAuthenticationToken string = '' -var pgsqlServerName = '${uniqueSolutionPrefix}pgsql' -var iotHubName = '${uniqueSolutionPrefix}hub' -var dpsName = '${uniqueSolutionPrefix}dps' -var siteName = '${uniqueSolutionPrefix}portal' -var servicePlanName = '${uniqueSolutionPrefix}asp' -var storageAccountName = '${uniqueSolutionPrefix}storage' -var iotHubOwnerPolicyName = 'iothubowner' -var provisioningserviceownerPolicyName = 'provisioningserviceowner' -var deviceImageContainerName = 'device-images' -var iamScopeName = 'API.Access' -var storageAccountId = '${resourceGroup().id}/providers/Microsoft.Storage/storageAccounts/${storageAccountName}' -var appInsightName = '${uniqueSolutionPrefix}insight' +@description('PostgreSQL Server Name') +param pgsqlServerName string + +@description('IotHub Name') +param iotHubName string + +@description('DPS Name') +param dpsName string + +@description('Site Name') +param siteName string + +@description('Service Plan Name') +param servicePlanName string + +@description('Storage Account Name') +param storageAccountName string + +@description('IotHub Owner Policy Name') +param iotHubOwnerPolicyName string + +@description('Provisioning Service Owner Policy Name') +param provisioningserviceownerPolicyName string + +@description('Device Image Container Name') +param deviceImageContainerName string + +@description('IAM Scope Name') +param iamScopeName string + +@description('Storage Account Id') +param storageAccountId string + +@description('App Insight Name') +param appInsightName string + module iotHub './iothub.bicep' = { name: 'iotHub'