From d1a5a446e2474c2b39ed3d57f4cecc50ae74ce1c Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Sun, 1 Sep 2024 14:19:45 +0200 Subject: [PATCH] feat: Enable tenant/constributor-specific parameters in test cases (#3015) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description - Example implementation to dynamically inject tenant/contributor-specific information into test cases - Tests - Using GitHub Secrets: Failed as not dynamic. All secrets would need to be declared explicitely in the templates, requiring continuous updates - Using Key Vault: Works, but requires an Azure Key Vault in the test subscription + granting the deploying principal Key Vault Secret User permissions on set Key vault - Secret values are fetched by prefix (currently `CI-`) and only if a given test template has a parameter of the same name. - Secrets are passed as secureStrings from beginning to end (i.e., also the parameter **must** be declared as `@secure()` - The test template parameter must follow the same naming as the secret to be matched as per the following rules - `CI-MySecret` would be matched wih a parameter named `mySecret` Remaining TODOs - [x] Agree on naming of variable & prefix - [x] Test whether the solution is robust enough to not fail if the Key Vault name variable is not set ([Test Run - See attempt #1](https://github.com/Azure/bicep-registry-modules/actions/runs/10559737937))
Result The lack of the variable does **not** fail the pipeline as shown in the following run. The logic goes past the point where it checks for the Key Vault ![image](https://github.com/user-attachments/assets/8756cf62-bfef-473e-929f-01611ba560ee)
@clintgrove, @rahalan & @segraef, please note that if this PR is merged it means you would need to update your forks in order to continue contributing to your modules. As the names etc. can still change I'd advice against any action at this point, but you should be the first to know :) On the plus side, no more updating of tenant-specific values 😉 ### GitHub Settings ![image](https://github.com/user-attachments/assets/2af9a297-6938-4a29-b926-16e4148d949e) ### Azure KeyVault ![image](https://github.com/user-attachments/assets/24e57585-571e-4494-9aa7-de64feeb2d15) ### Pipeline logic in action ![image](https://github.com/user-attachments/assets/4efa1919-e09d-46af-ac4d-52cbfbbeef3e) ## Pipeline Reference | Pipeline | | -------- | [![avm.res.managed-services.registration-definition](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.managed-services.registration-definition.yml/badge.svg?branch=users%2Falsehr%2FsecretPassThru&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.managed-services.registration-definition.yml) [![avm.res.compute.virtual-machine](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.compute.virtual-machine.yml/badge.svg?branch=users%2Falsehr%2FsecretPassThru&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.compute.virtual-machine.yml) [![avm.res.databricks.workspace](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.databricks.workspace.yml/badge.svg?branch=users%2Falsehr%2FsecretPassThru&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.databricks.workspace.yml) ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [ ] I'm sure there are no other open Pull Requests for the same update/change - [ ] I have run `Set-AVMModule` locally to generate the supporting module files. - [ ] My corresponding pipelines / checks run clean and green without any errors or warnings --------- Co-authored-by: Jack Tracey <41163455+jtracey93@users.noreply.github.com> --- .../avm-validateModuleDeployment/action.yml | 37 +++++++++++++++++++ .github/workflows/avm.template.module.yml | 1 + .../tests/e2e/linux.max/main.test.bicep | 6 ++- .../tests/e2e/waf-aligned/main.test.bicep | 6 ++- .../tests/e2e/windows.max/main.test.bicep | 6 ++- .../workspace/tests/e2e/max/main.test.bicep | 6 ++- .../tests/e2e/waf-aligned/main.test.bicep | 6 ++- .../registration-definition/README.md | 16 ++++---- .../tests/e2e/defaults/main.test.bicep | 6 ++- .../tests/e2e/max/main.test.bicep | 6 ++- .../tests/e2e/rg/main.test.bicep | 6 ++- .../tests/e2e/waf-aligned/main.test.bicep | 6 ++- 12 files changed, 91 insertions(+), 17 deletions(-) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index f73968f350..715a2f642b 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -208,6 +208,7 @@ runs: AdditionalParameters = @{} } + # Add custom parameters as needed if($moduleTemplatePossibleParameters -contains 'resourceLocation') { $functionInput.AdditionalParameters += @{ resourceLocation = '${{ steps.get-resource-location.outputs.resourceLocation }}' @@ -219,6 +220,24 @@ runs: } } + # Fetch & add custom secrets, if any + # ----------------------------------- + $keyVaultName = "${{ env.CI_KEY_VAULT_NAME }}" + if(-not [String]::IsNullOrEmpty($keyVaultName)) { + # Note: This action requires at least 'Key Vault Secrets User' permissions + $customKeyVaultSecrets = Get-AzKeyVaultSecret -VaultName $keyVaultName | Where-Object { $_.Name -match '^CI-.+' } + + foreach($customSecret in $customKeyVaultSecrets) { + $formattedName = $customSecret.Name -replace '^CI-' # e.g. 'CI-mySecret' -> 'mySecret' + if($moduleTemplatePossibleParameters -contains $formattedName) { + Write-Verbose ('Setting value for parameter [{0}]' -f $formattedName) -Verbose + $functionInput.AdditionalParameters += @{ + $formattedName = (Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $customSecret.Name).SecretValue + } + } + } + } + Write-Verbose 'Invoke task with' -Verbose Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose @@ -280,6 +299,24 @@ runs: } } + # Fetch & add custom secrets, if any + # ----------------------------------- + $keyVaultName = "${{ env.CI_KEY_VAULT_NAME }}" + if(-not [String]::IsNullOrEmpty($keyVaultName)) { + # Note: This action requires at least 'Key Vault Secrets User' permissions + $customKeyVaultSecrets = Get-AzKeyVaultSecret -VaultName $keyVaultName | Where-Object { $_.Name -match '^CI-.+' } + + foreach($customSecret in $customKeyVaultSecrets) { + $formattedName = $customSecret.Name -replace '^CI-' # e.g. 'CI-mySecret' -> 'mySecret' + if($moduleTemplatePossibleParameters -contains $formattedName) { + Write-Verbose ('Setting value for parameter [{0}]' -f $formattedName) -Verbose + $functionInput.AdditionalParameters += @{ + $formattedName = (Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $customSecret.Name).SecretValue + } + } + } + } + Write-Verbose 'Invoke task with' -Verbose Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose diff --git a/.github/workflows/avm.template.module.yml b/.github/workflows/avm.template.module.yml index efb117c5f6..55bbbc0abd 100644 --- a/.github/workflows/avm.template.module.yml +++ b/.github/workflows/avm.template.module.yml @@ -25,6 +25,7 @@ env: ARM_MGMTGROUP_ID: "${{ secrets.ARM_MGMTGROUP_ID }}" ARM_TENANT_ID: "${{ secrets.ARM_TENANT_ID }}" TOKEN_NAMEPREFIX: "${{ secrets.TOKEN_NAMEPREFIX }}" + CI_KEY_VAULT_NAME: "${{ vars.CI_KEY_VAULT_NAME }}" jobs: ######################### diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep index d52c494855..248bc72f56 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep @@ -20,6 +20,10 @@ param serviceShort string = 'cvmlinmax' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Required. The object id of the Backup Management Service Enterprise Application. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-BackupManagementServiceEnterpriseApplicationObjectId\'.') +@secure() +param backupManagementServiceEnterpriseApplicationObjectId string + // ============ // // Dependencies // // ============ // @@ -47,7 +51,7 @@ module nestedDependencies 'dependencies.bicep' = { sshDeploymentScriptName: 'dep-${namePrefix}-ds-${serviceShort}' sshKeyName: 'dep-${namePrefix}-ssh-${serviceShort}' dcrName: 'dep-${namePrefix}-dcr-${serviceShort}' - backupManagementServiceApplicationObjectId: 'be766fc3-eac4-4627-b8f5-298e35c8aea4' // Tenant-specific Backup Management Service Enterprise Application Object Id + backupManagementServiceApplicationObjectId: backupManagementServiceEnterpriseApplicationObjectId logAnalyticsWorkspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } } diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index e12caa5c22..c2c0f9abf4 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -24,6 +24,10 @@ param password string = newGuid() @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Required. The object id of the Backup Management Service Enterprise Application. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-BackupManagementServiceEnterpriseApplicationObjectId\'.') +@secure() +param backupManagementServiceEnterpriseApplicationObjectId string + // ============ // // Dependencies // // ============ // @@ -50,7 +54,7 @@ module nestedDependencies 'dependencies.bicep' = { storageAccountName: 'dep${namePrefix}sa${serviceShort}01' storageUploadDeploymentScriptName: 'dep-${namePrefix}-sads-${serviceShort}' proximityPlacementGroupName: 'dep-${namePrefix}-ppg-${serviceShort}' - backupManagementServiceApplicationObjectId: 'be766fc3-eac4-4627-b8f5-298e35c8aea4' // Tenant-specific Backup Management Service Enterprise Application Object Id + backupManagementServiceApplicationObjectId: backupManagementServiceEnterpriseApplicationObjectId dcrName: 'dep-${namePrefix}-dcr-${serviceShort}' logAnalyticsWorkspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep index 62a7fd077f..ef5aef28f6 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep @@ -24,6 +24,10 @@ param password string = newGuid() @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Required. The object id of the Backup Management Service Enterprise Application. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-BackupManagementServiceEnterpriseApplicationObjectId\'.') +@secure() +param backupManagementServiceEnterpriseApplicationObjectId string + // ============ // // Dependencies // // ============ // @@ -49,7 +53,7 @@ module nestedDependencies 'dependencies.bicep' = { storageAccountName: 'dep${namePrefix}sa${serviceShort}01' storageUploadDeploymentScriptName: 'dep-${namePrefix}-sads-${serviceShort}' proximityPlacementGroupName: 'dep-${namePrefix}-ppg-${serviceShort}' - backupManagementServiceApplicationObjectId: 'be766fc3-eac4-4627-b8f5-298e35c8aea4' // Tenant-specific Backup Management Service Enterprise Application Object Id + backupManagementServiceApplicationObjectId: backupManagementServiceEnterpriseApplicationObjectId dcrName: 'dep-${namePrefix}-dcr-${serviceShort}' logAnalyticsWorkspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } diff --git a/avm/res/databricks/workspace/tests/e2e/max/main.test.bicep b/avm/res/databricks/workspace/tests/e2e/max/main.test.bicep index da9e093759..7f696b9c29 100644 --- a/avm/res/databricks/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/databricks/workspace/tests/e2e/max/main.test.bicep @@ -23,6 +23,10 @@ param baseTime string = utcNow('u') @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Required. The object id of the AzureDatabricks Enterprise Application. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-AzureDatabricksEnterpriseApplicationObjectId\'.') +@secure() +param azureDatabricksEnterpriseApplicationObjectId string + // ============ // // Dependencies // // ============ // @@ -47,7 +51,7 @@ module nestedDependencies 'dependencies.bicep' = { storageAccountName: 'dep${namePrefix}sa${serviceShort}' virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' networkSecurityGroupName: 'dep-${namePrefix}-nsg-${serviceShort}' - databricksApplicationObjectId: '711330f9-cfad-4b10-a462-d82faa92027d' // Tenant-specific 'AzureDatabricks' Enterprise Application Object Id + databricksApplicationObjectId: azureDatabricksEnterpriseApplicationObjectId keyVaultDiskName: 'dep-${namePrefix}-kve-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' // Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total) keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' diff --git a/avm/res/databricks/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/databricks/workspace/tests/e2e/waf-aligned/main.test.bicep index 5211c6b795..b841659c89 100644 --- a/avm/res/databricks/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/databricks/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -23,6 +23,10 @@ param baseTime string = utcNow('u') @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Required. The object id of the AzureDatabricks Enterprise Application. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-AzureDatabricksEnterpriseApplicationObjectId\'.') +@secure() +param azureDatabricksEnterpriseApplicationObjectId string + // ============ // // Dependencies // // ============ // @@ -47,7 +51,7 @@ module nestedDependencies 'dependencies.bicep' = { storageAccountName: 'dep${namePrefix}sa${serviceShort}' virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' networkSecurityGroupName: 'dep-${namePrefix}-nsg-${serviceShort}' - databricksApplicationObjectId: '711330f9-cfad-4b10-a462-d82faa92027d' // Tenant-specific 'AzureDatabricks' Enterprise Application Object Id + databricksApplicationObjectId: azureDatabricksEnterpriseApplicationObjectId keyVaultDiskName: 'dep-${namePrefix}-kve-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' // Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total) keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' diff --git a/avm/res/managed-services/registration-definition/README.md b/avm/res/managed-services/registration-definition/README.md index 51a35a1643..8802eff657 100644 --- a/avm/res/managed-services/registration-definition/README.md +++ b/avm/res/managed-services/registration-definition/README.md @@ -62,7 +62,7 @@ module registrationDefinition 'br/public:avm/res/managed-services/registration-d roleDefinitionId: '91c1777a-f3dc-4fae-b103-61d183457e46' } ] - managedByTenantId: '449fbe1d-9c99-4509-9014-4fd5cf25b014' + managedByTenantId: '' name: 'Component Validation - msrdmin Subscription assignment' registrationDescription: 'Managed by Lighthouse' // Non-required parameters @@ -97,7 +97,7 @@ module registrationDefinition 'br/public:avm/res/managed-services/registration-d ] }, "managedByTenantId": { - "value": "449fbe1d-9c99-4509-9014-4fd5cf25b014" + "value": "" }, "name": { "value": "Component Validation - msrdmin Subscription assignment" @@ -149,7 +149,7 @@ module registrationDefinition 'br/public:avm/res/managed-services/registration-d roleDefinitionId: '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' } ] - managedByTenantId: '449fbe1d-9c99-4509-9014-4fd5cf25b014' + managedByTenantId: '' name: 'Component Validation - msrdmax Subscription assignment' registrationDescription: 'Managed by Lighthouse' // Non-required parameters @@ -194,7 +194,7 @@ module registrationDefinition 'br/public:avm/res/managed-services/registration-d ] }, "managedByTenantId": { - "value": "449fbe1d-9c99-4509-9014-4fd5cf25b014" + "value": "" }, "name": { "value": "Component Validation - msrdmax Subscription assignment" @@ -240,7 +240,7 @@ module registrationDefinition 'br/public:avm/res/managed-services/registration-d roleDefinitionId: '91c1777a-f3dc-4fae-b103-61d183457e46' } ] - managedByTenantId: '449fbe1d-9c99-4509-9014-4fd5cf25b014' + managedByTenantId: '' name: 'Component Validation - msrdrg Subscription assignment' registrationDescription: 'Managed by Lighthouse' // Non-required parameters @@ -277,7 +277,7 @@ module registrationDefinition 'br/public:avm/res/managed-services/registration-d ] }, "managedByTenantId": { - "value": "449fbe1d-9c99-4509-9014-4fd5cf25b014" + "value": "" }, "name": { "value": "Component Validation - msrdrg Subscription assignment" @@ -326,7 +326,7 @@ module registrationDefinition 'br/public:avm/res/managed-services/registration-d roleDefinitionId: '91c1777a-f3dc-4fae-b103-61d183457e46' } ] - managedByTenantId: '449fbe1d-9c99-4509-9014-4fd5cf25b014' + managedByTenantId: '' name: 'Component Validation - msrdwaf Subscription assignment' registrationDescription: 'Managed by Lighthouse' // Non-required parameters @@ -362,7 +362,7 @@ module registrationDefinition 'br/public:avm/res/managed-services/registration-d ] }, "managedByTenantId": { - "value": "449fbe1d-9c99-4509-9014-4fd5cf25b014" + "value": "" }, "name": { "value": "Component Validation - msrdwaf Subscription assignment" diff --git a/avm/res/managed-services/registration-definition/tests/e2e/defaults/main.test.bicep b/avm/res/managed-services/registration-definition/tests/e2e/defaults/main.test.bicep index 0c64dc087e..49c66084b1 100644 --- a/avm/res/managed-services/registration-definition/tests/e2e/defaults/main.test.bicep +++ b/avm/res/managed-services/registration-definition/tests/e2e/defaults/main.test.bicep @@ -16,6 +16,10 @@ param resourceLocation string = deployment().location @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Required. The tenant Id of the lighthouse tenant. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-LighthouseManagedByTenantId\'.') +@secure() +param lighthouseManagedByTenantId string + // ============== // // Test Execution // // ============== // @@ -38,7 +42,7 @@ module testDeployment '../../../main.bicep' = [ roleDefinitionId: '91c1777a-f3dc-4fae-b103-61d183457e46' } ] - managedByTenantId: '449fbe1d-9c99-4509-9014-4fd5cf25b014' + managedByTenantId: lighthouseManagedByTenantId } } ] diff --git a/avm/res/managed-services/registration-definition/tests/e2e/max/main.test.bicep b/avm/res/managed-services/registration-definition/tests/e2e/max/main.test.bicep index 17fdc6a502..774e4d5165 100644 --- a/avm/res/managed-services/registration-definition/tests/e2e/max/main.test.bicep +++ b/avm/res/managed-services/registration-definition/tests/e2e/max/main.test.bicep @@ -16,6 +16,10 @@ param resourceLocation string = deployment().location @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Required. The tenant Id of the lighthouse tenant. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-LighthouseManagedByTenantId\'.') +@secure() +param lighthouseManagedByTenantId string + // ============== // // Test Execution // // ============== // @@ -48,7 +52,7 @@ module testDeployment '../../../main.bicep' = [ roleDefinitionId: '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' // User Access Administrator } ] - managedByTenantId: '449fbe1d-9c99-4509-9014-4fd5cf25b014' + managedByTenantId: lighthouseManagedByTenantId } } ] diff --git a/avm/res/managed-services/registration-definition/tests/e2e/rg/main.test.bicep b/avm/res/managed-services/registration-definition/tests/e2e/rg/main.test.bicep index 710d6a08ce..0779dc39e3 100644 --- a/avm/res/managed-services/registration-definition/tests/e2e/rg/main.test.bicep +++ b/avm/res/managed-services/registration-definition/tests/e2e/rg/main.test.bicep @@ -20,6 +20,10 @@ param resourceLocation string = deployment().location @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Required. The tenant Id of the lighthouse tenant. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-LighthouseManagedByTenantId\'.') +@secure() +param lighthouseManagedByTenantId string + // ============ // // Dependencies // // ============ // @@ -61,7 +65,7 @@ module testDeployment '../../../main.bicep' = [ roleDefinitionId: '91c1777a-f3dc-4fae-b103-61d183457e46' } ] - managedByTenantId: '449fbe1d-9c99-4509-9014-4fd5cf25b014' + managedByTenantId: lighthouseManagedByTenantId } } ] diff --git a/avm/res/managed-services/registration-definition/tests/e2e/waf-aligned/main.test.bicep b/avm/res/managed-services/registration-definition/tests/e2e/waf-aligned/main.test.bicep index add8fba41d..b69547f748 100644 --- a/avm/res/managed-services/registration-definition/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/managed-services/registration-definition/tests/e2e/waf-aligned/main.test.bicep @@ -20,6 +20,10 @@ param resourceLocation string = deployment().location @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Required. The tenant Id of the lighthouse tenant. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-LighthouseManagedByTenantId\'.') +@secure() +param lighthouseManagedByTenantId string + // ============ // // Dependencies // // ============ // @@ -54,7 +58,7 @@ module testDeployment '../../../main.bicep' = [ roleDefinitionId: '91c1777a-f3dc-4fae-b103-61d183457e46' } ] - managedByTenantId: '449fbe1d-9c99-4509-9014-4fd5cf25b014' + managedByTenantId: lighthouseManagedByTenantId } } ]