diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6a536fcca5..9c07668bb9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -41,9 +41,9 @@ /avm/res/db-for-my-sql/flexible-server/ @Azure/avm-res-dbformysql-flexibleserver-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/db-for-postgre-sql/flexible-server/ @Azure/avm-res-dbforpostgresql-flexibleserver-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/desktop-virtualization/application-group/ @Azure/avm-res-desktopvirtualization-applicationgroup-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/desktop-virtualization/host-pool/ @Azure/avm-res-desktopvirtualization-hostpool-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/desktop-virtualization/host-pool/ @Azure/avm-res-desktopvirtualization-hostpool-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/desktop-virtualization/scaling-plan/ @Azure/avm-res-desktopvirtualization-scalingplan-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/desktop-virtualization/workspace/ @Azure/avm-res-desktopvirtualization-workspace-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/desktop-virtualization/workspace/ @Azure/avm-res-desktopvirtualization-workspace-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/dev-center/devcenter/ @Azure/avm-res-devcenter-devcenter-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/dev-test-lab/lab/ @Azure/avm-res-devtestlab-lab-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/digital-twins/digital-twins-instance/ @Azure/avm-res-digitaltwins-digitaltwinsinstance-module-owners-bicep @Azure/avm-core-team-technical-bicep @@ -61,7 +61,7 @@ /avm/res/insights/data-collection-rule/ @Azure/avm-res-insights-datacollectionrule-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/insights/diagnostic-setting/ @Azure/avm-res-insights-diagnosticsetting-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/insights/metric-alert/ @Azure/avm-res-insights-metricalert-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/insights/private-link-scope/ @Azure/avm-res-insights-privatelinkscope-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/insights/private-link-scope/ @Azure/avm-res-insights-privatelinkscope-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/insights/scheduled-query-rule/ @Azure/avm-res-insights-scheduledqueryrule-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/insights/webtest/ @Azure/avm-res-insights-webtest-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/key-vault/vault/ @Azure/avm-res-keyvault-vault-module-owners-bicep @Azure/avm-core-team-technical-bicep @@ -73,7 +73,7 @@ /avm/res/maintenance/maintenance-configuration/ @Azure/avm-res-maintenance-maintenanceconfiguration-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/managed-identity/user-assigned-identity/ @Azure/avm-res-managedidentity-userassignedidentity-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/managed-services/registration-definition/ @Azure/avm-res-managedservices-registrationdefinition-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/management/management-group/ @Azure/avm-res-management-managementgroup-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/management/management-group/ @Azure/avm-res-management-managementgroup-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/net-app/net-app-account/ @Azure/avm-res-netapp-netappaccount-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/network/application-gateway/ @Azure/avm-res-network-applicationgateway-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/network/application-gateway-web-application-firewall-policy/ @Azure/avm-res-network-applicationgatewaywebapplicationfirewallpolicy-module-owners-bicep @Azure/avm-core-team-technical-bicep @@ -90,7 +90,7 @@ /avm/res/network/firewall-policy/ @Azure/avm-res-network-firewallpolicy-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/front-door/ @Azure/avm-res-network-frontdoor-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/front-door-web-application-firewall-policy/ @Azure/avm-res-network-frontdoorwebapplicationfirewallpolicy-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/network/ip-group/ @Azure/avm-res-network-ipgroup-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/network/ip-group/ @Azure/avm-res-network-ipgroup-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/load-balancer/ @Azure/avm-res-network-loadbalancer-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/local-network-gateway/ @Azure/avm-res-network-localnetworkgateway-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/nat-gateway/ @Azure/avm-res-network-natgateway-module-owners-bicep @Azure/avm-core-team-technical-bicep @@ -100,16 +100,16 @@ #/avm/res/network/network-watcher/ @Azure/avm-res-network-networkwatcher-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/private-dns-zone/ @Azure/avm-res-network-privatednszone-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/private-endpoint/ @Azure/avm-res-network-privateendpoint-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/network/private-link-service/ @Azure/avm-res-network-privatelinkservice-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/network/private-link-service/ @Azure/avm-res-network-privatelinkservice-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/public-ip-address/ @Azure/avm-res-network-publicipaddress-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/public-ip-prefix/ @Azure/avm-res-network-publicipprefix-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/route-table/ @Azure/avm-res-network-routetable-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/network/service-endpoint-policy/ @Azure/avm-res-network-serviceendpointpolicy-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/trafficmanagerprofile/ @Azure/avm-res-network-trafficmanagerprofile-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/network/virtual-hub/ @Azure/avm-res-network-virtualhub-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/network/virtual-hub/ @Azure/avm-res-network-virtualhub-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/virtual-network/ @Azure/avm-res-network-virtualnetwork-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/virtual-network-gateway/ @Azure/avm-res-network-virtualnetworkgateway-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/network/virtual-wan/ @Azure/avm-res-network-virtualwan-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/network/virtual-wan/ @Azure/avm-res-network-virtualwan-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/vpn-gateway/ @Azure/avm-res-network-vpngateway-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/vpn-site/ @Azure/avm-res-network-vpnsite-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/operational-insights/workspace/ @Azure/avm-res-operationalinsights-workspace-module-owners-bicep @Azure/avm-core-team-technical-bicep @@ -131,9 +131,9 @@ #/avm/res/sql/managed-instance/ @Azure/avm-res-sql-managedinstance-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/sql/server/ @Azure/avm-res-sql-server-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/storage/storage-account/ @Azure/avm-res-storage-storageaccount-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/synapse/private-link-hub/ @Azure/avm-res-synapse-privatelinkhub-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/synapse/workspace/ @Azure/avm-res-synapse-workspace-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/virtual-machine-images/image-template/ @Azure/avm-res-virtualmachineimages-imagetemplate-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/synapse/private-link-hub/ @Azure/avm-res-synapse-privatelinkhub-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/synapse/workspace/ @Azure/avm-res-synapse-workspace-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/virtual-machine-images/image-template/ @Azure/avm-res-virtualmachineimages-imagetemplate-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/web/connection/ @Azure/avm-res-web-connection-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/web/hosting-environment/ @Azure/avm-res-web-hostingenvironment-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/web/serverfarm/ @Azure/avm-res-web-serverfarm-module-owners-bicep @Azure/avm-core-team-technical-bicep diff --git a/.github/ISSUE_TEMPLATE/avm_module_issue.yml b/.github/ISSUE_TEMPLATE/avm_module_issue.yml index 9f2c9bf5d6..1b302169da 100644 --- a/.github/ISSUE_TEMPLATE/avm_module_issue.yml +++ b/.github/ISSUE_TEMPLATE/avm_module_issue.yml @@ -75,9 +75,9 @@ body: - "avm/res/db-for-my-sql/flexible-server" - "avm/res/db-for-postgre-sql/flexible-server" - "avm/res/desktop-virtualization/application-group" - # - "avm/res/desktop-virtualization/host-pool" + - "avm/res/desktop-virtualization/host-pool" - "avm/res/desktop-virtualization/scaling-plan" - # - "avm/res/desktop-virtualization/workspace" + - "avm/res/desktop-virtualization/workspace" # - "avm/res/dev-center/devcenter" # - "avm/res/dev-test-lab/lab" # - "avm/res/digital-twins/digital-twins-instance" @@ -95,7 +95,7 @@ body: - "avm/res/insights/data-collection-rule" - "avm/res/insights/diagnostic-setting" - "avm/res/insights/metric-alert" - # - "avm/res/insights/private-link-scope" + - "avm/res/insights/private-link-scope" - "avm/res/insights/scheduled-query-rule" - "avm/res/insights/webtest" - "avm/res/key-vault/vault" @@ -107,7 +107,7 @@ body: - "avm/res/maintenance/maintenance-configuration" - "avm/res/managed-identity/user-assigned-identity" # - "avm/res/managed-services/registration-definition" - # - "avm/res/management/management-group" + - "avm/res/management/management-group" - "avm/res/net-app/net-app-account" # - "avm/res/network/application-gateway" # - "avm/res/network/application-gateway-web-application-firewall-policy" @@ -124,7 +124,7 @@ body: - "avm/res/network/firewall-policy" - "avm/res/network/front-door" - "avm/res/network/front-door-web-application-firewall-policy" - # - "avm/res/network/ip-group" + - "avm/res/network/ip-group" - "avm/res/network/load-balancer" - "avm/res/network/local-network-gateway" - "avm/res/network/nat-gateway" @@ -134,16 +134,16 @@ body: # - "avm/res/network/network-watcher" - "avm/res/network/private-dns-zone" - "avm/res/network/private-endpoint" - # - "avm/res/network/private-link-service" + - "avm/res/network/private-link-service" - "avm/res/network/public-ip-address" - "avm/res/network/public-ip-prefix" - "avm/res/network/route-table" # - "avm/res/network/service-endpoint-policy" - "avm/res/network/trafficmanagerprofile" - # - "avm/res/network/virtual-hub" + - "avm/res/network/virtual-hub" - "avm/res/network/virtual-network" - "avm/res/network/virtual-network-gateway" - # - "avm/res/network/virtual-wan" + - "avm/res/network/virtual-wan" - "avm/res/network/vpn-gateway" - "avm/res/network/vpn-site" - "avm/res/operational-insights/workspace" @@ -165,9 +165,9 @@ body: # - "avm/res/sql/managed-instance" - "avm/res/sql/server" - "avm/res/storage/storage-account" - # - "avm/res/synapse/private-link-hub" - # - "avm/res/synapse/workspace" - # - "avm/res/virtual-machine-images/image-template" + - "avm/res/synapse/private-link-hub" + - "avm/res/synapse/workspace" + - "avm/res/virtual-machine-images/image-template" # - "avm/res/web/connection" # - "avm/res/web/hosting-environment" - "avm/res/web/serverfarm" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 5d7a0cb627..719d90a85f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,32 +1,42 @@ ## Description - + -Enable GitHub Workflows in your fork to enable auto-generation of assets with our [GitHub Action](/.github/workflows/push-auto-generate.yml). -To trigger GitHub Actions after auto-generation, [add a GitHub PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) as a secret in your forked repository called `PAT`. +## Pipeline Reference -## Adding a new module + - +| Pipeline | +| -------- | +| | -- [ ] A proposal has been submitted and approved. -- [ ] I have included "Closes #{module_proposal_issue_number}" in the PR description. -- [ ] I have run `brm validate` locally to verify the module files. -- [ ] I have run deployment tests locally to ensure the module is deployable. +## Type of Change -## Updating an existing module + - +- [ ] Update to CI Environment or utlities (Non-module effecting 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 -- [ ] This is a bug fix: - - [ ] 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. -- [ ] I have run `brm validate` locally to verify the module files. -- [ ] I have run deployment tests locally to ensure the module is deployable. -- [ ] I have read the [Updating an existing module](https://github.com/Azure/bicep-registry-modules/blob/main/CONTRIBUTING.md#updating-an-existing-module) section in the contributing guide and updated the `version.json` file properly: - - [ ] The PR contains backwards compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`. - - [ ] The PR contains backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - - [ ] The PR contains breaking changes, and I have bumped the MAJOR version in `version.json`. -- [ ] I have updated the examples in README with the latest module version number. +## 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 + + diff --git a/.github/workflows/avm.res.desktop-virtualization.host-pool.yml b/.github/workflows/avm.res.desktop-virtualization.host-pool.yml new file mode 100644 index 0000000000..77450dc9d6 --- /dev/null +++ b/.github/workflows/avm.res.desktop-virtualization.host-pool.yml @@ -0,0 +1,85 @@ +name: "avm.res.desktop-virtualization.host-pool" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.desktop-virtualization.host-pool.yml" + - "avm/res/desktop-virtualization/host-pool/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/desktop-virtualization/host-pool" + workflowPath: ".github/workflows/avm.res.desktop-virtualization.host-pool.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/avm.res.desktop-virtualization.workspace.yml b/.github/workflows/avm.res.desktop-virtualization.workspace.yml new file mode 100644 index 0000000000..01eee9836a --- /dev/null +++ b/.github/workflows/avm.res.desktop-virtualization.workspace.yml @@ -0,0 +1,85 @@ +name: "avm.res.desktop-virtualization.workspace" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.desktop-virtualization.workspace.yml" + - "avm/res/desktop-virtualization/workspace/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/desktop-virtualization/workspace" + workflowPath: ".github/workflows/avm.res.desktop-virtualization.workspace.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/avm.res.insights.private-link-scope.yml b/.github/workflows/avm.res.insights.private-link-scope.yml new file mode 100644 index 0000000000..7c353ac15c --- /dev/null +++ b/.github/workflows/avm.res.insights.private-link-scope.yml @@ -0,0 +1,85 @@ +name: "avm.res.insights.private-link-scope" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.insights.private-link-scope.yml" + - "avm/res/insights/private-link-scope/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/insights/private-link-scope" + workflowPath: ".github/workflows/avm.res.insights.private-link-scope.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/avm.res.management.management-group.yml b/.github/workflows/avm.res.management.management-group.yml new file mode 100644 index 0000000000..1e90874a6c --- /dev/null +++ b/.github/workflows/avm.res.management.management-group.yml @@ -0,0 +1,85 @@ +name: "avm.res.management.management-group" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.management.management-group.yml" + - "avm/res/management/management-group/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/management/management-group" + workflowPath: ".github/workflows/avm.res.management.management-group.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/avm.res.network.ip-group.yml b/.github/workflows/avm.res.network.ip-group.yml new file mode 100644 index 0000000000..4da94cdffb --- /dev/null +++ b/.github/workflows/avm.res.network.ip-group.yml @@ -0,0 +1,85 @@ +name: "avm.res.network.ip-group" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.network.ip-group.yml" + - "avm/res/network/ip-group/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/network/ip-group" + workflowPath: ".github/workflows/avm.res.network.ip-group.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/avm.res.network.private-link-service.yml b/.github/workflows/avm.res.network.private-link-service.yml new file mode 100644 index 0000000000..19784ca217 --- /dev/null +++ b/.github/workflows/avm.res.network.private-link-service.yml @@ -0,0 +1,85 @@ +name: "avm.res.network.private-link-service" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.network.private-link-service.yml" + - "avm/res/network/private-link-service/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/network/private-link-service" + workflowPath: ".github/workflows/avm.res.network.private-link-service.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/avm.res.network.virtual-hub.yml b/.github/workflows/avm.res.network.virtual-hub.yml new file mode 100644 index 0000000000..2cb6561fbe --- /dev/null +++ b/.github/workflows/avm.res.network.virtual-hub.yml @@ -0,0 +1,85 @@ +name: "avm.res.network.virtual-hub" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.network.virtual-hub.yml" + - "avm/res/network/virtual-hub/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/network/virtual-hub" + workflowPath: ".github/workflows/avm.res.network.virtual-hub.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/avm.res.network.virtual-wan.yml b/.github/workflows/avm.res.network.virtual-wan.yml new file mode 100644 index 0000000000..a0a1c6f5ce --- /dev/null +++ b/.github/workflows/avm.res.network.virtual-wan.yml @@ -0,0 +1,86 @@ +name: "avm.res.network.virtual-wan" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.network.virtual-wan.yml" + - "avm/res/network/virtual-wan/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/network/virtual-wan" + workflowPath: ".github/workflows/avm.res.network.virtual-wan.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/avm.res.synapse.private-link-hub.yml b/.github/workflows/avm.res.synapse.private-link-hub.yml new file mode 100644 index 0000000000..61536513c7 --- /dev/null +++ b/.github/workflows/avm.res.synapse.private-link-hub.yml @@ -0,0 +1,85 @@ +name: "avm.res.synapse.private-link-hub" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.synapse.private-link-hub.yml" + - "avm/res/synapse/private-link-hub/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/synapse/private-link-hub" + workflowPath: ".github/workflows/avm.res.synapse.private-link-hub.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/avm.res.synapse.workspace.yml b/.github/workflows/avm.res.synapse.workspace.yml new file mode 100644 index 0000000000..d44cd5ad6e --- /dev/null +++ b/.github/workflows/avm.res.synapse.workspace.yml @@ -0,0 +1,85 @@ +name: "avm.res.synapse.workspace" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.synapse.workspace.yml" + - "avm/res/synapse/workspace/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/synapse/workspace" + workflowPath: ".github/workflows/avm.res.synapse.workspace.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/avm.res.virtual-machine-images.image-template.yml b/.github/workflows/avm.res.virtual-machine-images.image-template.yml new file mode 100644 index 0000000000..ad5e833d1e --- /dev/null +++ b/.github/workflows/avm.res.virtual-machine-images.image-template.yml @@ -0,0 +1,85 @@ +name: "avm.res.virtual-machine-images.image-template" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.virtual-machine-images.image-template.yml" + - "avm/res/virtual-machine-images/image-template/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/virtual-machine-images/image-template" + workflowPath: ".github/workflows/avm.res.virtual-machine-images.image-template.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/.github/workflows/publish-module.yml b/.github/workflows/publish-module.yml index 2cd04c6786..fe82d54fce 100644 --- a/.github/workflows/publish-module.yml +++ b/.github/workflows/publish-module.yml @@ -70,7 +70,7 @@ jobs: bicep --version - name: Publish module - run: bicep publish "modules/${{ steps.parse-tag.outputs.module_path }}/main.json" --target "br:${{ secrets.PUBLISH_REGISTRY_SERVER }}/public/bicep/${{ steps.parse-tag.outputs.module_path }}:${{ steps.parse-tag.outputs.version }}" --documentationUri "${{ steps.parse-tag.outputs.documentation_uri }}" --force + run: bicep publish "modules/${{ steps.parse-tag.outputs.module_path }}/main.bicep" --target "br:${{ secrets.PUBLISH_REGISTRY_SERVER }}/public/bicep/${{ steps.parse-tag.outputs.module_path }}:${{ steps.parse-tag.outputs.version }}" --documentationUri "${{ steps.parse-tag.outputs.documentation_uri }}" --with-source --force - name: Validate publish run: | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 65151cb56a..46c945774b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,7 @@ Add a new directory under the `modules` folder in your local bicep-registry-modu Open a terminal and navigate to the newly created folder. From there, run the following command to generate the required files for the Bicep public registry module: -``` +```shell brm generate ``` @@ -105,7 +105,7 @@ Each template should include the following 3 parameters: `location`, `prefix` an ##### Outputs - The `name` output should link to the `name` parameter. -- THe `id` output should link to the main resource of the deployment. Additional ID parameters may be provided. +- The `id` output should link to the main resource of the deployment. Additional ID parameters may be provided. ##### Zone Redundancy @@ -172,13 +172,15 @@ Instead go with: - `./modules/storage.bicep` - `./modules/compute.bicep` -## User-Defined Types (Preview) +## User-Defined Types + +User-defined type `type` assignments should be declared to the end of the file, after the declaration of `outputs`. -The repository has been setup to leverage the preview feature, [user-defined types](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/user-defined-data-types), on a per module basis. +Types should include descriptions, which can be copied from the Azure API documentation when wrapping existing resource provider objects. Nested `type` declarations do not need a description. Types are reserved for use in complex cases and should not be used to in place of primitive types. -While the feature is in Preview, [to enable](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/user-defined-data-types#enable-the-preview-feature) include a `bicepconfig.json` in your module directory. +To utilize `type` it is required to use Bicep version of 0.24.24 or higher. -`type` assignments should be declared to the end of the file, after the declaration of `outputs`. Types should include descriptions, which can be copied from the Azure API documentation when wrapping existing RP objects. Nested `type` declarations do not need a description. `type` should be reserved for use in complex cases and should not be used to in place of primitive types. +Follow these patterns: ```bicep @description('The properties of a storage account’s Blob service.') @@ -210,7 +212,7 @@ type containerDeleteRetentionPolicy = { } ``` -Avoid these patterns. +Avoid these patterns: ```bicep type enabled = bool // Avoid setting aliases for primitive types @@ -298,7 +300,7 @@ If your change is non-breaking but does not require updating the MINOR version, You may use the Bicep registry module tool to validate the contents of the registry module files. To do so, invoke the follow command from the module folder: -``` +```shell brm validate ``` diff --git a/README.md b/README.md index 991905d4ab..9f2ff5ae29 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ +

⚠️ Upcoming changes ⚠️

+ +To provide our customers with a unified experience, Azure Verified Modules ([AVM](https://aka.ms/AVM)) will become the single Microsoft standard for Bicep modules, published to the Public Bicep Registry, via this repository. + +Going forward, new modules will be need to be developed and published in accordance with the [AVM specifications](https://azure.github.io/Azure-Verified-Modules/specs/module-specs/). Module proposals for new, non-AVM modules will no longer be accepted. To propose a new AVM module, you can file a Module Proposal, [here](https://aka.ms/AVM/ModuleProposal). + +Existing non-AVM modules will be retired or migrated to AVM. To provide continued access for existing customers, non-AVM modules formerly published in the registry will be kept there indefinitely, but their source code will be replaced with an informational notice and a pointer to their successor in AVM, when applicable. Over time, VS code intellisense support for the old, non-AVM modules will also be removed - while existing references will keep working. + +The AVM core team will orchestrate this transition, starting with developing a migration/retirement plan together with the owners of the modules impacted. + +For the list of available and planned AVM modules, please visit the [AVM Module Index](https://aka.ms/AVM/ModuleIndex) pages. + # Bicep Registry Modules This repo contains the source code of all currently available Bicep modules in the Bicep public module registry. diff --git a/avm/bicepconfig.json b/avm/bicepconfig.json index 51a199061b..24a40e0f6c 100644 --- a/avm/bicepconfig.json +++ b/avm/bicepconfig.json @@ -1,7 +1,10 @@ // This is a Bicep configuration file. It can be used to control how Bicep operates and to customize validation settings for the Bicep linter. The linter uses these settings when evaluating your Bicep files for best practices. // For further information, please refer to the official documentation at: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-config { - "analyzers": { + "experimentalFeaturesEnabled": { + "publishSource": true + }, + "analyzers": { "core": { "rules": { "no-deployments-resources": { @@ -10,4 +13,4 @@ } } } -} \ No newline at end of file +} diff --git a/avm/res/analysis-services/server/README.md b/avm/res/analysis-services/server/README.md index 9e0a19293c..8b399c205a 100644 --- a/avm/res/analysis-services/server/README.md +++ b/avm/res/analysis-services/server/README.md @@ -457,9 +457,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -494,11 +494,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -508,11 +537,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/analysis-services/server/main.bicep b/avm/res/analysis-services/server/main.bicep index a0aa9df6f9..17aca5df92 100644 --- a/avm/res/analysis-services/server/main.bicep +++ b/avm/res/analysis-services/server/main.bicep @@ -96,19 +96,16 @@ resource server_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-0 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -180,19 +177,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/analysis-services/server/main.json b/avm/res/analysis-services/server/main.json index 5b79ada3b8..f5beb4b850 100644 --- a/avm/res/analysis-services/server/main.json +++ b/avm/res/analysis-services/server/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "531940121050857025" + "version": "0.25.53.49325", + "templateHash": "15159283808347195170" }, "name": "Analysis Services Servers", "description": "This module deploys an Analysis Services Server.", @@ -134,12 +134,19 @@ "metadata": { "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -152,12 +159,19 @@ "metadata": { "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -356,12 +370,30 @@ "scope": "[format('Microsoft.AnalysisServices/servers/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, diff --git a/avm/res/api-management/service/README.md b/avm/res/api-management/service/README.md index 44cf2cd6a4..751e823427 100644 --- a/avm/res/api-management/service/README.md +++ b/avm/res/api-management/service/README.md @@ -1,10 +1,5 @@ # API Management Services `[Microsoft.ApiManagement/service]` -> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ -> -> - Only security and bug fixes are being handled by the AVM core team at present. -> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! - This module deploys an API Management Service. ## Navigation @@ -1040,9 +1035,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1077,11 +1072,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1091,11 +1115,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/api-management/service/api-version-set/main.json b/avm/res/api-management/service/api-version-set/main.json index a29bdb808d..bd4daa7b03 100644 --- a/avm/res/api-management/service/api-version-set/main.json +++ b/avm/res/api-management/service/api-version-set/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9070035824484371815" + "version": "0.25.53.49325", + "templateHash": "4002198465184356188" }, "name": "API Management Service API Version Sets", "description": "This module deploys an API Management Service API Version Set.", diff --git a/avm/res/api-management/service/api/main.json b/avm/res/api-management/service/api/main.json index 337d13cc70..09a9425d19 100644 --- a/avm/res/api-management/service/api/main.json +++ b/avm/res/api-management/service/api/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16858272831537944791" + "version": "0.25.53.49325", + "templateHash": "857470281336543408" }, "name": "API Management Service APIs", "description": "This module deploys an API Management Service API.", @@ -267,8 +267,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17055958863698771520" + "version": "0.25.53.49325", + "templateHash": "5383521143080449228" }, "name": "API Management Service APIs Policies", "description": "This module deploys an API Management Service API Policy.", diff --git a/avm/res/api-management/service/api/policy/main.json b/avm/res/api-management/service/api/policy/main.json index f00a07ab0d..4667963a3b 100644 --- a/avm/res/api-management/service/api/policy/main.json +++ b/avm/res/api-management/service/api/policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17055958863698771520" + "version": "0.25.53.49325", + "templateHash": "5383521143080449228" }, "name": "API Management Service APIs Policies", "description": "This module deploys an API Management Service API Policy.", diff --git a/avm/res/api-management/service/authorization-server/main.json b/avm/res/api-management/service/authorization-server/main.json index 6688ca8138..10e75c27e4 100644 --- a/avm/res/api-management/service/authorization-server/main.json +++ b/avm/res/api-management/service/authorization-server/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6542432156469813267" + "version": "0.25.53.49325", + "templateHash": "6703063831636643162" }, "name": "API Management Service Authorization Servers", "description": "This module deploys an API Management Service Authorization Server.", diff --git a/avm/res/api-management/service/backend/main.json b/avm/res/api-management/service/backend/main.json index a2eb69c8b6..2e1bca38c9 100644 --- a/avm/res/api-management/service/backend/main.json +++ b/avm/res/api-management/service/backend/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1760564242838625433" + "version": "0.25.53.49325", + "templateHash": "16587888030936573636" }, "name": "API Management Service Backends", "description": "This module deploys an API Management Service Backend.", diff --git a/avm/res/api-management/service/cache/main.json b/avm/res/api-management/service/cache/main.json index dd373125fd..38eb6d1873 100644 --- a/avm/res/api-management/service/cache/main.json +++ b/avm/res/api-management/service/cache/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16846150865263245054" + "version": "0.25.53.49325", + "templateHash": "1295772952565058470" }, "name": "API Management Service Caches", "description": "This module deploys an API Management Service Cache.", diff --git a/avm/res/api-management/service/identity-provider/main.json b/avm/res/api-management/service/identity-provider/main.json index e66468ba20..6d182b6014 100644 --- a/avm/res/api-management/service/identity-provider/main.json +++ b/avm/res/api-management/service/identity-provider/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10477107104795505586" + "version": "0.25.53.49325", + "templateHash": "17146377320278316178" }, "name": "API Management Service Identity Providers", "description": "This module deploys an API Management Service Identity Provider.", diff --git a/avm/res/api-management/service/main.bicep b/avm/res/api-management/service/main.bicep index 230e363a04..dcc0cd05e7 100644 --- a/avm/res/api-management/service/main.bicep +++ b/avm/res/api-management/service/main.bicep @@ -395,19 +395,16 @@ resource service_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021- workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -490,19 +487,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/api-management/service/main.json b/avm/res/api-management/service/main.json index 0657083967..170cb02392 100644 --- a/avm/res/api-management/service/main.json +++ b/avm/res/api-management/service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12440563688380406844" + "version": "0.25.53.49325", + "templateHash": "8102357484603903216" }, "name": "API Management Services", "description": "This module deploys an API Management Service.", @@ -155,14 +155,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -173,14 +180,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -587,12 +601,30 @@ "scope": "[format('Microsoft.ApiManagement/service/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -713,8 +745,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16858272831537944791" + "version": "0.25.53.49325", + "templateHash": "857470281336543408" }, "name": "API Management Service APIs", "description": "This module deploys an API Management Service API.", @@ -975,8 +1007,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17055958863698771520" + "version": "0.25.53.49325", + "templateHash": "5383521143080449228" }, "name": "API Management Service APIs Policies", "description": "This module deploys an API Management Service API Policy.", @@ -1121,8 +1153,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9070035824484371815" + "version": "0.25.53.49325", + "templateHash": "4002198465184356188" }, "name": "API Management Service API Version Sets", "description": "This module deploys an API Management Service API Version Set.", @@ -1237,8 +1269,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6542432156469813267" + "version": "0.25.53.49325", + "templateHash": "6703063831636643162" }, "name": "API Management Service Authorization Servers", "description": "This module deploys an API Management Service Authorization Server.", @@ -1480,8 +1512,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1760564242838625433" + "version": "0.25.53.49325", + "templateHash": "16587888030936573636" }, "name": "API Management Service Backends", "description": "This module deploys an API Management Service Backend.", @@ -1664,8 +1696,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16846150865263245054" + "version": "0.25.53.49325", + "templateHash": "1295772952565058470" }, "name": "API Management Service Caches", "description": "This module deploys an API Management Service Cache.", @@ -1799,8 +1831,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10477107104795505586" + "version": "0.25.53.49325", + "templateHash": "17146377320278316178" }, "name": "API Management Service Identity Providers", "description": "This module deploys an API Management Service Identity Provider.", @@ -1986,8 +2018,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14717777062043537489" + "version": "0.25.53.49325", + "templateHash": "5043439748386656207" }, "name": "API Management Service Named Values", "description": "This module deploys an API Management Service Named Value.", @@ -2127,8 +2159,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1608393236922114459" + "version": "0.25.53.49325", + "templateHash": "14726250901514511689" }, "name": "API Management Service Portal Settings", "description": "This module deploys an API Management Service Portal Setting.", @@ -2224,8 +2256,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "836906111243238614" + "version": "0.25.53.49325", + "templateHash": "3643398305472631880" }, "name": "API Management Service Policies", "description": "This module deploys an API Management Service Policy.", @@ -2340,8 +2372,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5075187296088698151" + "version": "0.25.53.49325", + "templateHash": "10657321045680066427" }, "name": "API Management Service Products", "description": "This module deploys an API Management Service Product.", @@ -2462,8 +2494,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7732422845023417889" + "version": "0.25.53.49325", + "templateHash": "2508310027677163402" }, "name": "API Management Service Products APIs", "description": "This module deploys an API Management Service Product API.", @@ -2552,8 +2584,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16924441760570909209" + "version": "0.25.53.49325", + "templateHash": "14996351450231036018" }, "name": "API Management Service Products Groups", "description": "This module deploys an API Management Service Product Group.", @@ -2709,8 +2741,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8462322691003694396" + "version": "0.25.53.49325", + "templateHash": "16952030877948084799" }, "name": "API Management Service Subscriptions", "description": "This module deploys an API Management Service Subscription.", diff --git a/avm/res/api-management/service/named-value/main.json b/avm/res/api-management/service/named-value/main.json index 37beac0de7..860c79be1c 100644 --- a/avm/res/api-management/service/named-value/main.json +++ b/avm/res/api-management/service/named-value/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14717777062043537489" + "version": "0.25.53.49325", + "templateHash": "5043439748386656207" }, "name": "API Management Service Named Values", "description": "This module deploys an API Management Service Named Value.", diff --git a/avm/res/api-management/service/policy/main.json b/avm/res/api-management/service/policy/main.json index 62a4853335..bb46dd0c56 100644 --- a/avm/res/api-management/service/policy/main.json +++ b/avm/res/api-management/service/policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "836906111243238614" + "version": "0.25.53.49325", + "templateHash": "3643398305472631880" }, "name": "API Management Service Policies", "description": "This module deploys an API Management Service Policy.", diff --git a/avm/res/api-management/service/portalsetting/main.json b/avm/res/api-management/service/portalsetting/main.json index 802eea68ba..0e3c01eaf1 100644 --- a/avm/res/api-management/service/portalsetting/main.json +++ b/avm/res/api-management/service/portalsetting/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1608393236922114459" + "version": "0.25.53.49325", + "templateHash": "14726250901514511689" }, "name": "API Management Service Portal Settings", "description": "This module deploys an API Management Service Portal Setting.", diff --git a/avm/res/api-management/service/product/api/main.json b/avm/res/api-management/service/product/api/main.json index b99e6c94cc..fce4061640 100644 --- a/avm/res/api-management/service/product/api/main.json +++ b/avm/res/api-management/service/product/api/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7732422845023417889" + "version": "0.25.53.49325", + "templateHash": "2508310027677163402" }, "name": "API Management Service Products APIs", "description": "This module deploys an API Management Service Product API.", diff --git a/avm/res/api-management/service/product/group/main.json b/avm/res/api-management/service/product/group/main.json index ee8d2ed87e..2091c80834 100644 --- a/avm/res/api-management/service/product/group/main.json +++ b/avm/res/api-management/service/product/group/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16924441760570909209" + "version": "0.25.53.49325", + "templateHash": "14996351450231036018" }, "name": "API Management Service Products Groups", "description": "This module deploys an API Management Service Product Group.", diff --git a/avm/res/api-management/service/product/main.json b/avm/res/api-management/service/product/main.json index 8acc96e7c8..d1bbdbe274 100644 --- a/avm/res/api-management/service/product/main.json +++ b/avm/res/api-management/service/product/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5075187296088698151" + "version": "0.25.53.49325", + "templateHash": "10657321045680066427" }, "name": "API Management Service Products", "description": "This module deploys an API Management Service Product.", @@ -126,8 +126,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7732422845023417889" + "version": "0.25.53.49325", + "templateHash": "2508310027677163402" }, "name": "API Management Service Products APIs", "description": "This module deploys an API Management Service Product API.", @@ -216,8 +216,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16924441760570909209" + "version": "0.25.53.49325", + "templateHash": "14996351450231036018" }, "name": "API Management Service Products Groups", "description": "This module deploys an API Management Service Product Group.", diff --git a/avm/res/api-management/service/subscription/main.json b/avm/res/api-management/service/subscription/main.json index 8ac5f53d38..70e72bc609 100644 --- a/avm/res/api-management/service/subscription/main.json +++ b/avm/res/api-management/service/subscription/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8462322691003694396" + "version": "0.25.53.49325", + "templateHash": "16952030877948084799" }, "name": "API Management Service Subscriptions", "description": "This module deploys an API Management Service Subscription.", diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index 78839862e0..3c3848ada9 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -468,7 +468,7 @@ module containerApp 'br/public:avm/res/app/container-app:' = { | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`exposedPort`](#parameter-exposedport) | int | Exposed Port in containers for TCP traffic from ingress. | | [`ingressAllowInsecure`](#parameter-ingressallowinsecure) | bool | Bool indicating if HTTP connections to is allowed. If set to false HTTP connections are automatically redirected to HTTPS connections. | -| [`ingressExternal`](#parameter-ingressexternal) | bool | Bool indicating if app exposes an external http endpoint. | +| [`ingressExternal`](#parameter-ingressexternal) | bool | Bool indicating if the App exposes an external HTTP endpoint. | | [`ingressTargetPort`](#parameter-ingresstargetport) | int | Target Port in containers for traffic from ingress. | | [`ingressTransport`](#parameter-ingresstransport) | string | Ingress transport protocol. | | [`initContainersTemplate`](#parameter-initcontainerstemplate) | array | List of specialized containers that run before app containers. | @@ -570,7 +570,7 @@ Bool indicating if HTTP connections to is allowed. If set to false HTTP connecti ### Parameter: `ingressExternal` -Bool indicating if app exposes an external http endpoint. +Bool indicating if the App exposes an external HTTP endpoint. - Required: No - Type: bool diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 5d2f35894d..381bf515f6 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -8,7 +8,7 @@ param name string @description('Optional. Location for all Resources.') param location string = resourceGroup().location -@description('Optional. Bool indicating if app exposes an external http endpoint.') +@description('Optional. Bool indicating if the App exposes an external HTTP endpoint.') param ingressExternal bool = true @allowed([ diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index cf8777fec4..65f3d6c5bb 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14421664754265859300" + "version": "0.25.53.49325", + "templateHash": "6631896891995690305" }, "name": "Container Apps", "description": "This module deploys a Container App.", @@ -146,7 +146,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Bool indicating if app exposes an external http endpoint." + "description": "Optional. Bool indicating if the App exposes an external HTTP endpoint." } }, "ingressTransport": { diff --git a/avm/res/app/managed-environment/main.json b/avm/res/app/managed-environment/main.json index 28af743a6d..5fd1fd0e1a 100644 --- a/avm/res/app/managed-environment/main.json +++ b/avm/res/app/managed-environment/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9283793843319359004" + "version": "0.25.53.49325", + "templateHash": "12287523603498112228" }, "name": "App ManagedEnvironments", "description": "This module deploys an App Managed Environment (also known as a Container App Environment).", diff --git a/avm/res/automation/automation-account/README.md b/avm/res/automation/automation-account/README.md index df7d038227..43a4f43ccf 100644 --- a/avm/res/automation/automation-account/README.md +++ b/avm/res/automation/automation-account/README.md @@ -1157,9 +1157,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1194,11 +1194,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1208,11 +1237,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -1414,6 +1469,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -1435,6 +1511,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/automation/automation-account/job-schedule/main.json b/avm/res/automation/automation-account/job-schedule/main.json index 0dabd80bb5..170fa3ee8a 100644 --- a/avm/res/automation/automation-account/job-schedule/main.json +++ b/avm/res/automation/automation-account/job-schedule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14246826935635972197" + "version": "0.25.53.49325", + "templateHash": "4183701486282199551" }, "name": "Automation Account Job Schedules", "description": "This module deploys an Azure Automation Account Job Schedule.", diff --git a/avm/res/automation/automation-account/main.bicep b/avm/res/automation/automation-account/main.bicep index 707228ec86..512aa2354a 100644 --- a/avm/res/automation/automation-account/main.bicep +++ b/avm/res/automation/automation-account/main.bicep @@ -312,19 +312,16 @@ resource automationAccount_diagnosticSettings 'Microsoft.Insights/diagnosticSett workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -506,19 +503,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/automation/automation-account/main.json b/avm/res/automation/automation-account/main.json index b2b552d244..0a24cab446 100644 --- a/avm/res/automation/automation-account/main.json +++ b/avm/res/automation/automation-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5485541427531214967" + "version": "0.25.53.49325", + "templateHash": "3223894986476226816" }, "name": "Automation Accounts", "description": "This module deploys an Azure Automation Account.", @@ -329,14 +329,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -347,14 +354,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -701,12 +715,30 @@ "scope": "[format('Microsoft.Automation/automationAccounts/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -776,8 +808,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6758949567913452110" + "version": "0.25.53.49325", + "templateHash": "4277151232699761913" }, "name": "Automation Account Modules", "description": "This module deploys an Azure Automation Account Module.", @@ -918,8 +950,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17013504570786383965" + "version": "0.25.53.49325", + "templateHash": "15445244253525012229" }, "name": "Automation Account Schedules", "description": "This module deploys an Azure Automation Account Schedule.", @@ -1097,8 +1129,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12519596207626057781" + "version": "0.25.53.49325", + "templateHash": "16141039584915226874" }, "name": "Automation Account Runbooks", "description": "This module deploys an Azure Automation Account Runbook.", @@ -1297,8 +1329,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14246826935635972197" + "version": "0.25.53.49325", + "templateHash": "4183701486282199551" }, "name": "Automation Account Job Schedules", "description": "This module deploys an Azure Automation Account Job Schedule.", @@ -1425,8 +1457,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "162568846997583805" + "version": "0.25.53.49325", + "templateHash": "15605588341437540157" }, "name": "Automation Account Variables", "description": "This module deploys an Azure Automation Account Variable.", @@ -1540,8 +1572,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6280157469343577004" + "version": "0.25.53.49325", + "templateHash": "14301767156435143002" }, "name": "Log Analytics Workspace Linked Services", "description": "This module deploys a Log Analytics Workspace Linked Service.", @@ -1859,8 +1891,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6362006893081858637" + "version": "0.25.53.49325", + "templateHash": "6467431009828483672" }, "name": "Automation Account Software Update Configurations", "description": "This module deploys an Azure Automation Account Software Update Configuration.", diff --git a/avm/res/automation/automation-account/module/main.json b/avm/res/automation/automation-account/module/main.json index 4baf87c834..c151060111 100644 --- a/avm/res/automation/automation-account/module/main.json +++ b/avm/res/automation/automation-account/module/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6758949567913452110" + "version": "0.25.53.49325", + "templateHash": "4277151232699761913" }, "name": "Automation Account Modules", "description": "This module deploys an Azure Automation Account Module.", diff --git a/avm/res/automation/automation-account/runbook/main.json b/avm/res/automation/automation-account/runbook/main.json index a3a4fe2e0b..0761a0bce4 100644 --- a/avm/res/automation/automation-account/runbook/main.json +++ b/avm/res/automation/automation-account/runbook/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12519596207626057781" + "version": "0.25.53.49325", + "templateHash": "16141039584915226874" }, "name": "Automation Account Runbooks", "description": "This module deploys an Azure Automation Account Runbook.", diff --git a/avm/res/automation/automation-account/schedule/main.json b/avm/res/automation/automation-account/schedule/main.json index 5ce4bf8737..26dfa7ca29 100644 --- a/avm/res/automation/automation-account/schedule/main.json +++ b/avm/res/automation/automation-account/schedule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17013504570786383965" + "version": "0.25.53.49325", + "templateHash": "15445244253525012229" }, "name": "Automation Account Schedules", "description": "This module deploys an Azure Automation Account Schedule.", diff --git a/avm/res/automation/automation-account/software-update-configuration/main.json b/avm/res/automation/automation-account/software-update-configuration/main.json index dbe061896d..e6d98f28da 100644 --- a/avm/res/automation/automation-account/software-update-configuration/main.json +++ b/avm/res/automation/automation-account/software-update-configuration/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6362006893081858637" + "version": "0.25.53.49325", + "templateHash": "6467431009828483672" }, "name": "Automation Account Software Update Configurations", "description": "This module deploys an Azure Automation Account Software Update Configuration.", diff --git a/avm/res/automation/automation-account/variable/main.json b/avm/res/automation/automation-account/variable/main.json index d6213254ee..ec55c87f17 100644 --- a/avm/res/automation/automation-account/variable/main.json +++ b/avm/res/automation/automation-account/variable/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "162568846997583805" + "version": "0.25.53.49325", + "templateHash": "15605588341437540157" }, "name": "Automation Account Variables", "description": "This module deploys an Azure Automation Account Variable.", diff --git a/avm/res/batch/batch-account/README.md b/avm/res/batch/batch-account/README.md index bc2a940025..b7a08c4390 100644 --- a/avm/res/batch/batch-account/README.md +++ b/avm/res/batch/batch-account/README.md @@ -700,9 +700,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -737,11 +737,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -751,11 +780,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -1009,6 +1064,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint IP address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private IP addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -1030,6 +1106,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/batch/batch-account/main.bicep b/avm/res/batch/batch-account/main.bicep index 1d5176205e..4326c505b0 100644 --- a/avm/res/batch/batch-account/main.bicep +++ b/avm/res/batch/batch-account/main.bicep @@ -185,19 +185,16 @@ resource batchAccount_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@ workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'allLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -272,19 +269,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/batch/batch-account/main.json b/avm/res/batch/batch-account/main.json index 9bb8fd3a6f..3731161e53 100644 --- a/avm/res/batch/batch-account/main.json +++ b/avm/res/batch/batch-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12017185166479854402" + "version": "0.25.53.49325", + "templateHash": "2397736043296643387" }, "name": "Batch Accounts", "description": "This module deploys a Batch Account.", @@ -43,12 +43,19 @@ "metadata": { "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -61,12 +68,19 @@ "metadata": { "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -745,12 +759,30 @@ "scope": "[format('Microsoft.Batch/batchAccounts/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -1486,4 +1518,4 @@ "value": "[coalesce(tryGet(tryGet(reference('batchAccount', '2022-06-01', 'full'), 'identity'), 'principalId'), '')]" } } -} +} \ No newline at end of file diff --git a/avm/res/cache/redis/README.md b/avm/res/cache/redis/README.md index 0991dd9ae4..1b8ef80cda 100644 --- a/avm/res/cache/redis/README.md +++ b/avm/res/cache/redis/README.md @@ -581,9 +581,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -618,11 +618,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -632,11 +661,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -815,6 +870,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint IP address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private IP addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -836,6 +912,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/cache/redis/main.bicep b/avm/res/cache/redis/main.bicep index 35aa732b6c..de47057248 100644 --- a/avm/res/cache/redis/main.bicep +++ b/avm/res/cache/redis/main.bicep @@ -183,19 +183,16 @@ resource redis_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -387,19 +384,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/cache/redis/main.json b/avm/res/cache/redis/main.json index 779bbf5198..85d840b572 100644 --- a/avm/res/cache/redis/main.json +++ b/avm/res/cache/redis/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13528802302857745616" + "version": "0.25.53.49325", + "templateHash": "16070478115038910597" }, "name": "Redis Cache", "description": "This module deploys a Redis Cache.", @@ -332,12 +332,19 @@ "metadata": { "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -350,12 +357,19 @@ "metadata": { "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -689,12 +703,30 @@ "scope": "[format('Microsoft.Cache/redis/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, diff --git a/avm/res/cognitive-services/account/README.md b/avm/res/cognitive-services/account/README.md index b729ea0521..2e5dc2db5d 100644 --- a/avm/res/cognitive-services/account/README.md +++ b/avm/res/cognitive-services/account/README.md @@ -17,7 +17,7 @@ This module deploys a Cognitive Service. | :-- | :-- | | `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | -| `Microsoft.CognitiveServices/accounts` | [2022-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.CognitiveServices/2022-12-01/accounts) | +| `Microsoft.CognitiveServices/accounts` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.CognitiveServices/2023-05-01/accounts) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | | `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | @@ -128,12 +128,6 @@ module account 'br/public:avm/res/cognitive-services/account:' = { storageAccountResourceId: '' workspaceResourceId: '' } - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - storageAccountResourceId: '' - workspaceResourceId: '' - } ] location: '' lock: { @@ -263,12 +257,6 @@ module account 'br/public:avm/res/cognitive-services/account:' = { "name": "customSetting", "storageAccountResourceId": "", "workspaceResourceId": "" - }, - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "storageAccountResourceId": "", - "workspaceResourceId": "" } ] }, @@ -847,6 +835,7 @@ Kind of the Cognitive Services. Use 'Get-AzCognitiveServicesAccountSku' to deter - Allowed: ```Bicep [ + 'AIServices' 'AnomalyDetector' 'Bing.Autosuggest.v7' 'Bing.CustomSearch' @@ -856,16 +845,22 @@ Kind of the Cognitive Services. Use 'Get-AzCognitiveServicesAccountSku' to deter 'CognitiveServices' 'ComputerVision' 'ContentModerator' + 'ContentSafety' + 'ConversationalLanguageUnderstanding' 'CustomVision.Prediction' 'CustomVision.Training' 'Face' 'FormRecognizer' + 'HealthInsights' 'ImmersiveReader' 'Internal.AllInOne' + 'LanguageAuthoring' 'LUIS' 'LUIS.Authoring' + 'MetricsAdvisor' + 'OpenAI' 'Personalizer' - 'QnAMaker' + 'QnAMaker.v2' 'SpeechServices' 'TextAnalytics' 'TextTranslation' @@ -963,9 +958,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1000,11 +995,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1014,11 +1038,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -1203,6 +1253,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint IP address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private IP addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -1224,6 +1295,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/cognitive-services/account/main.bicep b/avm/res/cognitive-services/account/main.bicep index 0f81a209c5..05149ac191 100644 --- a/avm/res/cognitive-services/account/main.bicep +++ b/avm/res/cognitive-services/account/main.bicep @@ -7,6 +7,7 @@ param name string @description('Required. Kind of the Cognitive Services. Use \'Get-AzCognitiveServicesAccountSku\' to determine a valid combinations of \'kind\' and \'SKU\' for your Azure region.') @allowed([ + 'AIServices' 'AnomalyDetector' 'Bing.Autosuggest.v7' 'Bing.CustomSearch' @@ -16,16 +17,22 @@ param name string 'CognitiveServices' 'ComputerVision' 'ContentModerator' + 'ContentSafety' + 'ConversationalLanguageUnderstanding' 'CustomVision.Prediction' 'CustomVision.Training' 'Face' 'FormRecognizer' + 'HealthInsights' 'ImmersiveReader' 'Internal.AllInOne' 'LUIS' 'LUIS.Authoring' + 'LanguageAuthoring' + 'MetricsAdvisor' + 'OpenAI' 'Personalizer' - 'QnAMaker' + 'QnAMaker.v2' 'SpeechServices' 'TextAnalytics' 'TextTranslation' @@ -189,7 +196,7 @@ resource cMKUserAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentiti scope: resourceGroup(split((customerManagedKey.?userAssignedIdentityResourceId ?? '//'), '/')[2], split((customerManagedKey.?userAssignedIdentityResourceId ?? '////'), '/')[4]) } -resource cognitiveService 'Microsoft.CognitiveServices/accounts@2022-12-01' = { +resource cognitiveService 'Microsoft.CognitiveServices/accounts@2023-05-01' = { name: name kind: kind identity: identity @@ -242,19 +249,16 @@ resource cognitiveService_diagnosticSettings 'Microsoft.Insights/diagnosticSetti workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'allLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -332,19 +336,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/cognitive-services/account/main.json b/avm/res/cognitive-services/account/main.json index 6595a1a7b1..97ad908e5b 100644 --- a/avm/res/cognitive-services/account/main.json +++ b/avm/res/cognitive-services/account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13697179912910947708" + "version": "0.25.53.49325", + "templateHash": "6619617132004799661" }, "name": "Cognitive Services", "description": "This module deploys a Cognitive Service.", @@ -43,12 +43,19 @@ "metadata": { "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -61,12 +68,19 @@ "metadata": { "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -452,6 +466,7 @@ "kind": { "type": "string", "allowedValues": [ + "AIServices", "AnomalyDetector", "Bing.Autosuggest.v7", "Bing.CustomSearch", @@ -461,16 +476,22 @@ "CognitiveServices", "ComputerVision", "ContentModerator", + "ContentSafety", + "ConversationalLanguageUnderstanding", "CustomVision.Prediction", "CustomVision.Training", "Face", "FormRecognizer", + "HealthInsights", "ImmersiveReader", "Internal.AllInOne", "LUIS", "LUIS.Authoring", + "LanguageAuthoring", + "MetricsAdvisor", + "OpenAI", "Personalizer", - "QnAMaker", + "QnAMaker.v2", "SpeechServices", "TextAnalytics", "TextTranslation" @@ -733,7 +754,7 @@ }, "cognitiveService": { "type": "Microsoft.CognitiveServices/accounts", - "apiVersion": "2022-12-01", + "apiVersion": "2023-05-01", "name": "[parameters('name')]", "kind": "[parameters('kind')]", "identity": "[variables('identity')]", @@ -785,12 +806,30 @@ "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -1523,14 +1562,14 @@ "metadata": { "description": "The principal ID of the system assigned identity." }, - "value": "[coalesce(tryGet(tryGet(reference('cognitiveService', '2022-12-01', 'full'), 'identity'), 'principalId'), '')]" + "value": "[coalesce(tryGet(tryGet(reference('cognitiveService', '2023-05-01', 'full'), 'identity'), 'principalId'), '')]" }, "location": { "type": "string", "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('cognitiveService', '2022-12-01', 'full').location]" + "value": "[reference('cognitiveService', '2023-05-01', 'full').location]" } } } \ No newline at end of file diff --git a/avm/res/cognitive-services/account/tests/e2e/max/main.test.bicep b/avm/res/cognitive-services/account/tests/e2e/max/main.test.bicep index df8752851e..e13f8afd9f 100644 --- a/avm/res/cognitive-services/account/tests/e2e/max/main.test.bicep +++ b/avm/res/cognitive-services/account/tests/e2e/max/main.test.bicep @@ -88,12 +88,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } ] lock: { kind: 'CanNotDelete' diff --git a/avm/res/compute/availability-set/main.json b/avm/res/compute/availability-set/main.json index 9378822660..038249ef1f 100644 --- a/avm/res/compute/availability-set/main.json +++ b/avm/res/compute/availability-set/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10039968628370445063" + "version": "0.25.53.49325", + "templateHash": "142072316382977028" }, "name": "Availability Sets", "description": "This module deploys an Availability Set.", diff --git a/avm/res/compute/disk-encryption-set/main.json b/avm/res/compute/disk-encryption-set/main.json index a29e0f7ce5..74797dbc2d 100644 --- a/avm/res/compute/disk-encryption-set/main.json +++ b/avm/res/compute/disk-encryption-set/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "231465906721977114" + "version": "0.25.53.49325", + "templateHash": "2337982856441594532" }, "name": "Disk Encryption Sets", "description": "This module deploys a Disk Encryption Set. The module will attempt to set permissions on the provided Key Vault for any used user-assigned identity.", @@ -374,8 +374,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "18116549045396353747" + "version": "0.25.53.49325", + "templateHash": "4340767234132084239" } }, "parameters": { @@ -462,8 +462,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11258728276348640403" + "version": "0.25.53.49325", + "templateHash": "9781242464769385318" }, "name": "Key Vault Access Policies", "description": "This module deploys a Key Vault Access Policy.", diff --git a/avm/res/compute/disk/main.json b/avm/res/compute/disk/main.json index 4744d1356b..7c41b3cc5d 100644 --- a/avm/res/compute/disk/main.json +++ b/avm/res/compute/disk/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8032560098908563077" + "version": "0.25.53.49325", + "templateHash": "6226788182357954709" }, "name": "Compute Disks", "description": "This module deploys a Compute Disk", diff --git a/avm/res/compute/gallery/README.md b/avm/res/compute/gallery/README.md index 532d815ad8..fcb389cc6e 100644 --- a/avm/res/compute/gallery/README.md +++ b/avm/res/compute/gallery/README.md @@ -132,6 +132,7 @@ module gallery 'br/public:avm/res/compute/gallery:' = { } { hyperVGeneration: 'V2' + isAcceleratedNetworkSupported: false isHibernateSupported: true maxRecommendedMemory: 16 maxRecommendedvCPUs: 8 @@ -272,6 +273,7 @@ module gallery 'br/public:avm/res/compute/gallery:' = { }, { "hyperVGeneration": "V2", + "isAcceleratedNetworkSupported": false, "isHibernateSupported": true, "maxRecommendedMemory": 16, "maxRecommendedvCPUs": 8, diff --git a/avm/res/compute/gallery/application/main.json b/avm/res/compute/gallery/application/main.json index 30e9cc1921..c6ccc00385 100644 --- a/avm/res/compute/gallery/application/main.json +++ b/avm/res/compute/gallery/application/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9951919331605340265" + "version": "0.25.53.49325", + "templateHash": "1766982665283226409" }, "name": "Compute Galleries Applications", "description": "This module deploys an Azure Compute Gallery Application.", diff --git a/avm/res/compute/gallery/image/README.md b/avm/res/compute/gallery/image/README.md index 0c99e3a326..1919e986ba 100644 --- a/avm/res/compute/gallery/image/README.md +++ b/avm/res/compute/gallery/image/README.md @@ -43,14 +43,8 @@ This module deploys an Azure Compute Gallery Image Definition. | [`endOfLife`](#parameter-endoflife) | string | The end of life date of the gallery Image Definition. This property can be used for decommissioning purposes. This property is updatable. Allowed format: 2020-01-10T23:00:00.000Z. | | [`eula`](#parameter-eula) | string | The Eula agreement for the gallery Image Definition. Has to be a valid URL. | | [`excludedDiskTypes`](#parameter-excludeddisktypes) | array | List of the excluded disk types (e.g., Standard_LRS). | -| [`hyperVGeneration`](#parameter-hypervgeneration) | string | The hypervisor generation of the Virtual Machine. -- If this value is not specified, then it is determined by the securityType parameter. -- If the securityType parameter is specified, then the value of hyperVGeneration will be V2, else V1. - | -| [`isAcceleratedNetworkSupported`](#parameter-isacceleratednetworksupported) | bool | Specify if the image supports accelerated networking. -Accelerated networking enables single root I/O virtualization (SR-IOV) to a VM, greatly improving its networking performance. -This high-performance path bypasses the host from the data path, which reduces latency, jitter, and CPU utilization for the most demanding network workloads on supported VM types. - | +| [`hyperVGeneration`](#parameter-hypervgeneration) | string | The hypervisor generation of the Virtual Machine.
  • If this value is not specified, then it is determined by the securityType parameter.
  • If the securityType parameter is specified, then the value of hyperVGeneration will be V2, else V1.

    | +| [`isAcceleratedNetworkSupported`](#parameter-isacceleratednetworksupported) | bool | Specify if the image supports accelerated networking.

    Accelerated networking enables single root I/O virtualization (SR-IOV) to a VM, greatly improving its networking performance.

    This high-performance path bypasses the host from the data path, which reduces latency, jitter, and CPU utilization for the most demanding network workloads on supported VM types.

    | | [`isHibernateSupported`](#parameter-ishibernatesupported) | bool | Specifiy if the image supports hibernation. | | [`location`](#parameter-location) | string | Location for all resources. | | [`maxRecommendedMemory`](#parameter-maxrecommendedmemory) | int | The maximum amount of RAM in GB recommended for this image. | @@ -148,10 +142,7 @@ List of the excluded disk types (e.g., Standard_LRS). ### Parameter: `hyperVGeneration` -The hypervisor generation of the Virtual Machine. -- If this value is not specified, then it is determined by the securityType parameter. -- If the securityType parameter is specified, then the value of hyperVGeneration will be V2, else V1. - +The hypervisor generation of the Virtual Machine.

  • If this value is not specified, then it is determined by the securityType parameter.
  • If the securityType parameter is specified, then the value of hyperVGeneration will be V2, else V1.

    - Required: No - Type: string @@ -165,14 +156,11 @@ The hypervisor generation of the Virtual Machine. ### Parameter: `isAcceleratedNetworkSupported` -Specify if the image supports accelerated networking. -Accelerated networking enables single root I/O virtualization (SR-IOV) to a VM, greatly improving its networking performance. -This high-performance path bypasses the host from the data path, which reduces latency, jitter, and CPU utilization for the most demanding network workloads on supported VM types. - +Specify if the image supports accelerated networking.

    Accelerated networking enables single root I/O virtualization (SR-IOV) to a VM, greatly improving its networking performance.

    This high-performance path bypasses the host from the data path, which reduces latency, jitter, and CPU utilization for the most demanding network workloads on supported VM types.

    - Required: No - Type: bool -- Default: `False` +- Default: `True` ### Parameter: `isHibernateSupported` diff --git a/avm/res/compute/gallery/image/main.bicep b/avm/res/compute/gallery/image/main.bicep index d82749672e..8c8411fdf0 100644 --- a/avm/res/compute/gallery/image/main.bicep +++ b/avm/res/compute/gallery/image/main.bicep @@ -81,7 +81,7 @@ param isHibernateSupported bool = false Accelerated networking enables single root I/O virtualization (SR-IOV) to a VM, greatly improving its networking performance. This high-performance path bypasses the host from the data path, which reduces latency, jitter, and CPU utilization for the most demanding network workloads on supported VM types. ''') -param isAcceleratedNetworkSupported bool = false +param isAcceleratedNetworkSupported bool = true @sys.description('Optional. The description of this gallery Image Definition resource. This property is updatable.') param description string? diff --git a/avm/res/compute/gallery/image/main.json b/avm/res/compute/gallery/image/main.json index b9e48db9e8..8558b28df4 100644 --- a/avm/res/compute/gallery/image/main.json +++ b/avm/res/compute/gallery/image/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11732013039305076688" + "version": "0.25.53.49325", + "templateHash": "3529471060432554863" }, "name": "Compute Galleries Image Definitions", "description": "This module deploys an Azure Compute Gallery Image Definition.", @@ -209,7 +209,7 @@ }, "isAcceleratedNetworkSupported": { "type": "bool", - "defaultValue": false, + "defaultValue": true, "metadata": { "description": "Optional. Specify if the image supports accelerated networking.\nAccelerated networking enables single root I/O virtualization (SR-IOV) to a VM, greatly improving its networking performance.\nThis high-performance path bypasses the host from the data path, which reduces latency, jitter, and CPU utilization for the most demanding network workloads on supported VM types.\n" } diff --git a/avm/res/compute/gallery/main.bicep b/avm/res/compute/gallery/main.bicep index 60f12f0655..bd2d9e7ddd 100644 --- a/avm/res/compute/gallery/main.bicep +++ b/avm/res/compute/gallery/main.bicep @@ -133,6 +133,7 @@ module galleries_images 'image/main.bicep' = [for (image, index) in (images ?? [ maxRecommendedMemory: image.?maxRecommendedMemory hyperVGeneration: image.?hyperVGeneration securityType: image.?securityType + isAcceleratedNetworkSupported: image.?isAcceleratedNetworkSupported description: image.?description eula: image.?eula privacyStatementUri: image.?privacyStatementUri diff --git a/avm/res/compute/gallery/main.json b/avm/res/compute/gallery/main.json index a499939ac6..cebcd05b97 100644 --- a/avm/res/compute/gallery/main.json +++ b/avm/res/compute/gallery/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17536269376876527435" + "version": "0.25.53.49325", + "templateHash": "7407411978239812730" }, "name": "Azure Compute Galleries", "description": "This module deploys an Azure Compute Gallery (formerly known as Shared Image Gallery).", @@ -319,8 +319,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9951919331605340265" + "version": "0.25.53.49325", + "templateHash": "1766982665283226409" }, "name": "Compute Galleries Applications", "description": "This module deploys an Azure Compute Gallery Application.", @@ -632,6 +632,9 @@ "securityType": { "value": "[tryGet(coalesce(parameters('images'), createArray())[copyIndex()], 'securityType')]" }, + "isAcceleratedNetworkSupported": { + "value": "[tryGet(coalesce(parameters('images'), createArray())[copyIndex()], 'isAcceleratedNetworkSupported')]" + }, "description": { "value": "[tryGet(coalesce(parameters('images'), createArray())[copyIndex()], 'description')]" }, @@ -673,8 +676,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11732013039305076688" + "version": "0.25.53.49325", + "templateHash": "3529471060432554863" }, "name": "Compute Galleries Image Definitions", "description": "This module deploys an Azure Compute Gallery Image Definition.", @@ -877,7 +880,7 @@ }, "isAcceleratedNetworkSupported": { "type": "bool", - "defaultValue": false, + "defaultValue": true, "metadata": { "description": "Optional. Specify if the image supports accelerated networking.\nAccelerated networking enables single root I/O virtualization (SR-IOV) to a VM, greatly improving its networking performance.\nThis high-performance path bypasses the host from the data path, which reduces latency, jitter, and CPU utilization for the most demanding network workloads on supported VM types.\n" } diff --git a/avm/res/compute/gallery/tests/e2e/max/main.test.bicep b/avm/res/compute/gallery/tests/e2e/max/main.test.bicep index c44883e5c9..d0f332bfc6 100644 --- a/avm/res/compute/gallery/tests/e2e/max/main.test.bicep +++ b/avm/res/compute/gallery/tests/e2e/max/main.test.bicep @@ -91,6 +91,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' { hyperVGeneration: 'V2' isHibernateSupported: true + isAcceleratedNetworkSupported: false maxRecommendedMemory: 16 maxRecommendedvCPUs: 8 minRecommendedMemory: 4 diff --git a/avm/res/compute/gallery/version.json b/avm/res/compute/gallery/version.json index 1c035df49f..76049e1c4a 100644 --- a/avm/res/compute/gallery/version.json +++ b/avm/res/compute/gallery/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.2", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.3", + "pathFilters": [ + "./main.json" + ] } \ No newline at end of file diff --git a/avm/res/compute/image/README.md b/avm/res/compute/image/README.md index 825b5a0608..7534e86119 100644 --- a/avm/res/compute/image/README.md +++ b/avm/res/compute/image/README.md @@ -1,10 +1,5 @@ # Images `[Microsoft.Compute/images]` -> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ -> -> - Only security and bug fixes are being handled by the AVM core team at present. -> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! - This module deploys a Compute Image. ## Navigation diff --git a/avm/res/compute/image/main.json b/avm/res/compute/image/main.json index c5d3badcc7..3ce18d1b64 100644 --- a/avm/res/compute/image/main.json +++ b/avm/res/compute/image/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5585282644630125803" + "version": "0.25.53.49325", + "templateHash": "262853591906300834" }, "name": "Images", "description": "This module deploys a Compute Image.", diff --git a/avm/res/compute/proximity-placement-group/main.json b/avm/res/compute/proximity-placement-group/main.json index 5f23a429f3..779f0be773 100644 --- a/avm/res/compute/proximity-placement-group/main.json +++ b/avm/res/compute/proximity-placement-group/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "4796175974201919576" + "version": "0.25.53.49325", + "templateHash": "2998974371512711861" }, "name": "Proximity Placement Groups", "description": "This module deploys a Proximity Placement Group.", diff --git a/avm/res/compute/ssh-public-key/main.json b/avm/res/compute/ssh-public-key/main.json index 6bc0c0b5a3..b33a3e997c 100644 --- a/avm/res/compute/ssh-public-key/main.json +++ b/avm/res/compute/ssh-public-key/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15902398819447691263" + "version": "0.25.53.49325", + "templateHash": "8813930198344883772" }, "name": "Public SSH Keys", "description": "This module deploys a Public SSH Key.\n\n> Note: The resource does not auto-generate the key for you.", diff --git a/avm/res/compute/virtual-machine/extension/main.json b/avm/res/compute/virtual-machine/extension/main.json index c10328f8ac..73e9c680a6 100644 --- a/avm/res/compute/virtual-machine/extension/main.json +++ b/avm/res/compute/virtual-machine/extension/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "version": "0.25.53.49325", + "templateHash": "5949079428725139834" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 58d04dc2d4..c42705b317 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -735,41 +735,3 @@ type roleAssignmentType = { @description('Optional. The Resource Id of the delegated managed identity resource.') delegatedManagedIdentityResourceId: string? }[]? - -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') - categoryGroup: string? - }[]? - - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') - category: string - }[]? - - @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') - workspaceResourceId: string? - - @description('Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') - storageAccountResourceId: string? - - @description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') - eventHubAuthorizationRuleResourceId: string? - - @description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index 4fc18fa227..54d6a68a4d 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4884548870640081043" + "version": "0.25.53.49325", + "templateHash": "15299094640883899955" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -126,112 +126,6 @@ } }, "nullable": true - }, - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } - }, - "logCategoriesAndGroups": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." - } - }, - "categoryGroup": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." - } - }, - "metricCategories": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." - } - }, - "logAnalyticsDestinationType": { - "type": "string", - "allowedValues": [ - "AzureDiagnostics", - "Dedicated" - ], - "nullable": true, - "metadata": { - "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." - } - }, - "workspaceResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "storageAccountResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "eventHubAuthorizationRuleResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." - } - }, - "eventHubName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "marketplacePartnerResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." - } - } - } - }, - "nullable": true } }, "parameters": { @@ -1000,8 +894,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11195047658552178426" + "version": "0.25.53.49325", + "templateHash": "4698911337326052062" } }, "definitions": { @@ -1058,14 +952,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \u0007llLogs to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -1076,14 +977,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to AllMetrics to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -1210,12 +1118,21 @@ "virtualMachineName": { "type": "string" }, + "ipConfigurations": { + "type": "array" + }, "location": { - "type": "string" + "type": "string", + "metadata": { + "description": "Optional. Location for all resources." + } }, "tags": { "type": "object", - "nullable": true + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } }, "enableIPForwarding": { "type": "bool", @@ -1242,11 +1159,11 @@ "description": "Optional. The network security group (NSG) to attach to the network interface." } }, - "ipConfigurations": { - "type": "array" - }, "lock": { - "$ref": "#/definitions/lockType" + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } }, "diagnosticSettings": { "$ref": "#/definitions/diagnosticSettingType", @@ -2447,8 +2364,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "version": "0.25.53.49325", + "templateHash": "5949079428725139834" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2653,8 +2570,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "version": "0.25.53.49325", + "templateHash": "5949079428725139834" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2854,8 +2771,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "version": "0.25.53.49325", + "templateHash": "5949079428725139834" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3067,8 +2984,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "version": "0.25.53.49325", + "templateHash": "5949079428725139834" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3264,8 +3181,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "version": "0.25.53.49325", + "templateHash": "5949079428725139834" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3460,8 +3377,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "version": "0.25.53.49325", + "templateHash": "5949079428725139834" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3660,8 +3577,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "version": "0.25.53.49325", + "templateHash": "5949079428725139834" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3868,8 +3785,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "version": "0.25.53.49325", + "templateHash": "5949079428725139834" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4069,8 +3986,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "version": "0.25.53.49325", + "templateHash": "5949079428725139834" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4269,8 +4186,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12595215410082531283" + "version": "0.25.53.49325", + "templateHash": "15677187951825533891" }, "name": "Recovery Service Vaults Protection Container Protected Item", "description": "This module deploys a Recovery Services Vault Protection Container Protected Item.", diff --git a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep index ad423b2418..8b308b2f8d 100644 --- a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep +++ b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep @@ -1,7 +1,13 @@ param networkInterfaceName string param virtualMachineName string +param ipConfigurations array + +@description('Optional. Location for all resources.') param location string + +@description('Optional. Tags of the resource.') param tags object? + param enableIPForwarding bool = false param enableAcceleratedNetworking bool = false param dnsServers array = [] @@ -12,7 +18,7 @@ param enableTelemetry bool @description('Optional. The network security group (NSG) to attach to the network interface.') param networkSecurityGroupResourceId string = '' -param ipConfigurations array +@description('Optional. The lock settings of the service.') param lock lockType @description('Optional. The diagnostic settings of the Network Interface.') @@ -95,19 +101,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to llLogs to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to AllMetrics to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/consumption/budget/README.md b/avm/res/consumption/budget/README.md index 389d30ab8a..b53ef655a5 100644 --- a/avm/res/consumption/budget/README.md +++ b/avm/res/consumption/budget/README.md @@ -110,6 +110,10 @@ module budget 'br/public:avm/res/consumption/budget:' = { 'dummy@contoso.com' ] location: '' + resourceGroupFilter: [ + 'rg-group1' + 'rg-group2' + ] thresholds: [ 50 75 @@ -149,6 +153,12 @@ module budget 'br/public:avm/res/consumption/budget:' = { "location": { "value": "" }, + "resourceGroupFilter": { + "value": [ + "rg-group1", + "rg-group2" + ] + }, "thresholds": { "value": [ 50, @@ -266,8 +276,10 @@ module budget 'br/public:avm/res/consumption/budget:' = { | [`category`](#parameter-category) | string | The category of the budget, whether the budget tracks cost or usage. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`endDate`](#parameter-enddate) | string | The end date for the budget. If not provided, it will default to 10 years from the start date. | +| [`filter`](#parameter-filter) | object | The filter to use for restricting which resources are considered within the budget. | | [`location`](#parameter-location) | string | Location deployment metadata. | | [`resetPeriod`](#parameter-resetperiod) | string | The time covered by a budget. Tracking of the amount will be reset based on the time grain. BillingMonth, BillingQuarter, and BillingAnnual are only supported by WD customers. | +| [`resourceGroupFilter`](#parameter-resourcegroupfilter) | array | The list of resource groups that contain the resources that are to be considered within the budget. | | [`startDate`](#parameter-startdate) | string | The start date for the budget. Start date should be the first day of the month and cannot be in the past (except for the current month). | | [`thresholds`](#parameter-thresholds) | array | Percent thresholds of budget for when to get a notification. Can be up to 5 thresholds, where each must be between 1 and 1000. | @@ -291,7 +303,6 @@ List of action group resource IDs that will receive the alert. Required if neith - Required: No - Type: array -- Default: `[]` ### Parameter: `contactEmails` @@ -299,7 +310,6 @@ The list of email addresses to send the budget notification to when the threshol - Required: No - Type: array -- Default: `[]` ### Parameter: `contactRoles` @@ -307,7 +317,6 @@ The list of contact roles to send the budget notification to when the thresholds - Required: No - Type: array -- Default: `[]` ### Parameter: `category` @@ -340,6 +349,13 @@ The end date for the budget. If not provided, it will default to 10 years from t - Type: string - Default: `''` +### Parameter: `filter` + +The filter to use for restricting which resources are considered within the budget. + +- Required: No +- Type: object + ### Parameter: `location` Location deployment metadata. @@ -367,6 +383,14 @@ The time covered by a budget. Tracking of the amount will be reset based on the ] ``` +### Parameter: `resourceGroupFilter` + +The list of resource groups that contain the resources that are to be considered within the budget. + +- Required: No +- Type: array +- Default: `[]` + ### Parameter: `startDate` The start date for the budget. Start date should be the first day of the month and cannot be in the past (except for the current month). diff --git a/avm/res/consumption/budget/main.bicep b/avm/res/consumption/budget/main.bicep index dc837ee5da..e9c4fc332f 100644 --- a/avm/res/consumption/budget/main.bicep +++ b/avm/res/consumption/budget/main.bicep @@ -45,18 +45,24 @@ param thresholds array = [ ] @description('Conditional. The list of email addresses to send the budget notification to when the thresholds are exceeded. Required if neither `contactRoles` nor `actionGroups` was provided.') -param contactEmails array = [] +param contactEmails array? @description('Conditional. The list of contact roles to send the budget notification to when the thresholds are exceeded. Required if neither `contactEmails` nor `actionGroups` was provided.') -param contactRoles array = [] +param contactRoles array? @description('Conditional. List of action group resource IDs that will receive the alert. Required if neither `contactEmails` nor `contactEmails` was provided.') -param actionGroups array = [] +param actionGroups array? + +@description('Optional. The filter to use for restricting which resources are considered within the budget.') +param filter object? + +@description('Optional. The list of resource groups that contain the resources that are to be considered within the budget.') +param resourceGroupFilter string[] = [] @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -@sys.description('Optional. Location deployment metadata.') +@description('Optional. Location deployment metadata.') param location string = deployment().location var notificationsArray = [for threshold in thresholds: { @@ -64,15 +70,13 @@ var notificationsArray = [for threshold in thresholds: { enabled: true operator: 'GreaterThan' threshold: threshold - contactEmails: !empty(contactEmails) ? array(contactEmails) : null - contactRoles: !empty(contactRoles) ? array(contactRoles) : null - contactGroups: !empty(actionGroups) ? array(actionGroups) : null + contactEmails: contactEmails + contactRoles: contactRoles + contactGroups: actionGroups thresholdType: 'Actual' } }] -var notifications = json(replace(replace(replace(string(notificationsArray), '[{', '{'), '}]', '}'), '}},{', '},')) - resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { name: '46d3xbcp.res.consumption-budget.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' location: location @@ -102,8 +106,14 @@ resource budget 'Microsoft.Consumption/budgets@2023-11-01' = { startDate: startDate endDate: endDate } - filter: {} - notifications: notifications + filter: filter ?? (!empty(resourceGroupFilter) ? { + dimensions: { + name: 'ResourceGroupName' + operator: 'In' + values: resourceGroupFilter + } + } : {}) + notifications: json(replace(replace(replace(string(notificationsArray), '[{', '{'), '}]', '}'), '}},{', '},')) } } diff --git a/avm/res/consumption/budget/main.json b/avm/res/consumption/budget/main.json index a6ea839586..90563586c0 100644 --- a/avm/res/consumption/budget/main.json +++ b/avm/res/consumption/budget/main.json @@ -1,11 +1,12 @@ { "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14996821705072365605" + "version": "0.25.53.49325", + "templateHash": "6388227242660946106" }, "name": "Consumption Budgets", "description": "This module deploys a Consumption Budget for Subscriptions.", @@ -80,25 +81,42 @@ }, "contactEmails": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Conditional. The list of email addresses to send the budget notification to when the thresholds are exceeded. Required if neither `contactRoles` nor `actionGroups` was provided." } }, "contactRoles": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Conditional. The list of contact roles to send the budget notification to when the thresholds are exceeded. Required if neither `contactEmails` nor `actionGroups` was provided." } }, "actionGroups": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Conditional. List of action group resource IDs that will receive the alert. Required if neither `contactEmails` nor `contactEmails` was provided." } }, + "filter": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The filter to use for restricting which resources are considered within the budget." + } + }, + "resourceGroupFilter": { + "type": "array", + "items": { + "type": "string" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. The list of resource groups that contain the resources that are to be considered within the budget." + } + }, "enableTelemetry": { "type": "bool", "defaultValue": true, @@ -124,18 +142,17 @@ "enabled": true, "operator": "GreaterThan", "threshold": "[parameters('thresholds')[copyIndex('notificationsArray')]]", - "contactEmails": "[if(not(empty(parameters('contactEmails'))), array(parameters('contactEmails')), null())]", - "contactRoles": "[if(not(empty(parameters('contactRoles'))), array(parameters('contactRoles')), null())]", - "contactGroups": "[if(not(empty(parameters('actionGroups'))), array(parameters('actionGroups')), null())]", + "contactEmails": "[parameters('contactEmails')]", + "contactRoles": "[parameters('contactRoles')]", + "contactGroups": "[parameters('actionGroups')]", "thresholdType": "Actual" } } } - ], - "notifications": "[json(replace(replace(replace(string(variables('notificationsArray')), '[{', '{'), '}]', '}'), '}},{', '},'))]" + ] }, - "resources": [ - { + "resources": { + "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2023-07-01", @@ -156,7 +173,7 @@ } } }, - { + "budget": { "type": "Microsoft.Consumption/budgets", "apiVersion": "2023-11-01", "name": "[parameters('name')]", @@ -168,11 +185,11 @@ "startDate": "[parameters('startDate')]", "endDate": "[parameters('endDate')]" }, - "filter": {}, - "notifications": "[variables('notifications')]" + "filter": "[coalesce(parameters('filter'), if(not(empty(parameters('resourceGroupFilter'))), createObject('dimensions', createObject('name', 'ResourceGroupName', 'operator', 'In', 'values', parameters('resourceGroupFilter'))), createObject()))]", + "notifications": "[json(replace(replace(replace(string(variables('notificationsArray')), '[{', '{'), '}]', '}'), '}},{', '},'))]" } } - ], + }, "outputs": { "name": { "type": "string", diff --git a/avm/res/consumption/budget/tests/e2e/max/main.test.bicep b/avm/res/consumption/budget/tests/e2e/max/main.test.bicep index 39f47f4977..e581db3199 100644 --- a/avm/res/consumption/budget/tests/e2e/max/main.test.bicep +++ b/avm/res/consumption/budget/tests/e2e/max/main.test.bicep @@ -30,6 +30,10 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' contactEmails: [ 'dummy@contoso.com' ] + resourceGroupFilter: [ + 'rg-group1' + 'rg-group2' + ] thresholds: [ 50 75 diff --git a/avm/res/consumption/budget/version.json b/avm/res/consumption/budget/version.json index 7fa401bdf7..729ac87673 100644 --- a/avm/res/consumption/budget/version.json +++ b/avm/res/consumption/budget/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.1", - "pathFilters": [ - "./main.json" - ] -} + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.2", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file diff --git a/avm/res/container-registry/registry/README.md b/avm/res/container-registry/registry/README.md index 97bb430b03..9c96fdf622 100644 --- a/avm/res/container-registry/registry/README.md +++ b/avm/res/container-registry/registry/README.md @@ -812,9 +812,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -849,11 +849,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -863,11 +892,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -1074,6 +1129,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -1095,6 +1171,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/container-registry/registry/cache-rules/main.json b/avm/res/container-registry/registry/cache-rules/main.json index b5ce7442b5..52b54dce7e 100644 --- a/avm/res/container-registry/registry/cache-rules/main.json +++ b/avm/res/container-registry/registry/cache-rules/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3326562317936673912" + "version": "0.25.53.49325", + "templateHash": "6942960102258463312" }, "name": "Container Registries Cache", "description": "Cache for Azure Container Registry (Preview) feature allows users to cache container images in a private container registry. Cache for ACR, is a preview feature available in Basic, Standard, and Premium service tiers ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache)).", diff --git a/avm/res/container-registry/registry/main.bicep b/avm/res/container-registry/registry/main.bicep index c7823e593d..8c33bc7154 100644 --- a/avm/res/container-registry/registry/main.bicep +++ b/avm/res/container-registry/registry/main.bicep @@ -304,19 +304,16 @@ resource registry_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -501,19 +498,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/container-registry/registry/main.json b/avm/res/container-registry/registry/main.json index 5e9055a939..fb6accc837 100644 --- a/avm/res/container-registry/registry/main.json +++ b/avm/res/container-registry/registry/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1333841895071022712" + "version": "0.25.53.49325", + "templateHash": "3316618601179718411" }, "name": "Azure Container Registries (ACR)", "description": "This module deploys an Azure Container Registry (ACR).", @@ -330,14 +330,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -348,14 +355,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -828,12 +842,30 @@ "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -903,8 +935,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7392920175754293043" + "version": "0.25.53.49325", + "templateHash": "10714256463183699741" }, "name": "Azure Container Registry (ACR) Replications", "description": "This module deploys an Azure Container Registry (ACR) Replication.", @@ -1051,8 +1083,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3326562317936673912" + "version": "0.25.53.49325", + "templateHash": "6942960102258463312" }, "name": "Container Registries Cache", "description": "Cache for Azure Container Registry (Preview) feature allows users to cache container images in a private container registry. Cache for ACR, is a preview feature available in Basic, Standard, and Premium service tiers ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache)).", @@ -1192,8 +1224,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13453164087600189664" + "version": "0.25.53.49325", + "templateHash": "3986666280667981658" }, "name": "Azure Container Registry (ACR) Webhooks", "description": "This module deploys an Azure Container Registry (ACR) Webhook.", diff --git a/avm/res/container-registry/registry/replication/main.json b/avm/res/container-registry/registry/replication/main.json index e22364ce66..ea887b53b1 100644 --- a/avm/res/container-registry/registry/replication/main.json +++ b/avm/res/container-registry/registry/replication/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7392920175754293043" + "version": "0.25.53.49325", + "templateHash": "10714256463183699741" }, "name": "Azure Container Registry (ACR) Replications", "description": "This module deploys an Azure Container Registry (ACR) Replication.", diff --git a/avm/res/container-registry/registry/webhook/main.json b/avm/res/container-registry/registry/webhook/main.json index 7c703c4726..c5520f2893 100644 --- a/avm/res/container-registry/registry/webhook/main.json +++ b/avm/res/container-registry/registry/webhook/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13453164087600189664" + "version": "0.25.53.49325", + "templateHash": "3986666280667981658" }, "name": "Azure Container Registry (ACR) Webhooks", "description": "This module deploys an Azure Container Registry (ACR) Webhook.", diff --git a/avm/res/container-service/managed-cluster/README.md b/avm/res/container-service/managed-cluster/README.md index 2c14eba530..e821115b32 100644 --- a/avm/res/container-service/managed-cluster/README.md +++ b/avm/res/container-service/managed-cluster/README.md @@ -2303,9 +2303,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -2340,11 +2340,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -2354,11 +2383,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/container-service/managed-cluster/agent-pool/main.json b/avm/res/container-service/managed-cluster/agent-pool/main.json index ccc5e14fe0..4238233b6a 100644 --- a/avm/res/container-service/managed-cluster/agent-pool/main.json +++ b/avm/res/container-service/managed-cluster/agent-pool/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "59537816730486645" + "version": "0.25.53.49325", + "templateHash": "11449186283530676915" }, "name": "Azure Kubernetes Service (AKS) Managed Cluster Agent Pools", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Agent Pool.", diff --git a/avm/res/container-service/managed-cluster/main.bicep b/avm/res/container-service/managed-cluster/main.bicep index 9dd7c344bd..f75498a437 100644 --- a/avm/res/container-service/managed-cluster/main.bicep +++ b/avm/res/container-service/managed-cluster/main.bicep @@ -455,7 +455,7 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2023-07-02-p ssh: { publicKeys: [ { - keyData: sshPublicKey + keyData: sshPublicKey ?? '' } ] } @@ -475,6 +475,7 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2023-07-02-p } ingressApplicationGateway: { enabled: ingressApplicationGatewayEnabled && !empty(appGatewayResourceId) + #disable-next-line BCP321 // Value will not be used if null or empty config: ingressApplicationGatewayEnabled && !empty(appGatewayResourceId) ? { applicationGatewayId: appGatewayResourceId effectiveApplicationGatewayId: appGatewayResourceId @@ -482,6 +483,7 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2023-07-02-p } omsagent: { enabled: omsAgentEnabled && !empty(monitoringWorkspaceId) + #disable-next-line BCP321 // Value will not be used if null or empty config: omsAgentEnabled && !empty(monitoringWorkspaceId) ? { logAnalyticsWorkspaceResourceID: monitoringWorkspaceId } : null @@ -706,19 +708,16 @@ resource managedCluster_diagnosticSettings 'Microsoft.Insights/diagnosticSetting workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -955,19 +954,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/container-service/managed-cluster/main.json b/avm/res/container-service/managed-cluster/main.json index 1caedb332b..c404ee96f1 100644 --- a/avm/res/container-service/managed-cluster/main.json +++ b/avm/res/container-service/managed-cluster/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4735311217553069306" + "version": "0.25.53.49325", + "templateHash": "2256713976702167408" }, "name": "Azure Kubernetes Service (AKS) Managed Clusters", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster.", @@ -463,14 +463,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -481,14 +488,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -1491,7 +1505,7 @@ "kubernetesVersion": "[parameters('kubernetesVersion')]", "dnsPrefix": "[parameters('dnsPrefix')]", "agentPoolProfiles": "[parameters('primaryAgentPoolProfile')]", - "linuxProfile": "[if(not(empty(parameters('sshPublicKey'))), createObject('adminUsername', parameters('adminUsername'), 'ssh', createObject('publicKeys', createArray(createObject('keyData', parameters('sshPublicKey'))))), null())]", + "linuxProfile": "[if(not(empty(parameters('sshPublicKey'))), createObject('adminUsername', parameters('adminUsername'), 'ssh', createObject('publicKeys', createArray(createObject('keyData', coalesce(parameters('sshPublicKey'), ''))))), null())]", "servicePrincipalProfile": "[parameters('aksServicePrincipalProfile')]", "ingressProfile": { "webAppRouting": { @@ -1640,12 +1654,30 @@ "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -1828,8 +1860,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "59537816730486645" + "version": "0.25.53.49325", + "templateHash": "11449186283530676915" }, "name": "Azure Kubernetes Service (AKS) Managed Cluster Agent Pools", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Agent Pool.", diff --git a/avm/res/container-service/managed-cluster/tests/e2e/azure/dependencies.bicep b/avm/res/container-service/managed-cluster/tests/e2e/azure/dependencies.bicep index 39364978b3..813a8a74ba 100644 --- a/avm/res/container-service/managed-cluster/tests/e2e/azure/dependencies.bicep +++ b/avm/res/container-service/managed-cluster/tests/e2e/azure/dependencies.bicep @@ -88,11 +88,24 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-11-01' = { } } +resource keyPermissionsKeyVaultCryptoUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-KeyVault-Crypto-User-RoleAssignment') + scope: keyVault + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // KeyVault-Crypto-User + principalType: 'ServicePrincipal' + } +} + resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2022-07-02' = { name: diskEncryptionSetName location: location identity: { - type: 'SystemAssigned' + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } } properties: { activeKey: { @@ -103,26 +116,9 @@ resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2022-07-02' = { } encryptionType: 'EncryptionAtRestWithCustomerKey' } -} - -resource keyPermissionsKeyVaultCryptoUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-KeyVault-Crypto-User-RoleAssignment') - scope: keyVault - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // KeyVault-Crypto-User - principalType: 'ServicePrincipal' - } -} - -resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-KeyVault-Key-Read-RoleAssignment') - scope: keyVault - properties: { - principalId: diskEncryptionSet.identity.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User - principalType: 'ServicePrincipal' - } + dependsOn: [ + keyPermissionsKeyVaultCryptoUser + ] } resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2022-03-01' = { diff --git a/avm/res/data-factory/factory/ORPHANED.md b/avm/res/data-factory/factory/ORPHANED.md deleted file mode 100644 index ef8fa911d2..0000000000 --- a/avm/res/data-factory/factory/ORPHANED.md +++ /dev/null @@ -1,4 +0,0 @@ -⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ - -- Only security and bug fixes are being handled by the AVM core team at present. -- If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! \ No newline at end of file diff --git a/avm/res/data-factory/factory/README.md b/avm/res/data-factory/factory/README.md index 14f30ba538..779fdc9c32 100644 --- a/avm/res/data-factory/factory/README.md +++ b/avm/res/data-factory/factory/README.md @@ -1,10 +1,5 @@ # Data Factories `[Microsoft.DataFactory/factories]` -> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ -> -> - Only security and bug fixes are being handled by the AVM core team at present. -> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! - This module deploys a Data Factory. ## Navigation @@ -560,9 +555,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -597,11 +592,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -611,11 +635,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -874,6 +924,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -895,6 +966,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/data-factory/factory/integration-runtime/main.json b/avm/res/data-factory/factory/integration-runtime/main.json index 8c2e0dd9e1..08a41bf9c3 100644 --- a/avm/res/data-factory/factory/integration-runtime/main.json +++ b/avm/res/data-factory/factory/integration-runtime/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14308450010595234197" + "version": "0.25.53.49325", + "templateHash": "7384162383092533956" }, "name": "Data Factory Integration RunTimes", "description": "This module deploys a Data Factory Managed or Self-Hosted Integration Runtime.", diff --git a/avm/res/data-factory/factory/main.bicep b/avm/res/data-factory/factory/main.bicep index 58156b0e83..77562721b6 100644 --- a/avm/res/data-factory/factory/main.bicep +++ b/avm/res/data-factory/factory/main.bicep @@ -196,19 +196,16 @@ resource dataFactory_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -390,19 +387,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/data-factory/factory/main.json b/avm/res/data-factory/factory/main.json index 8a6f80d545..ec293b4da5 100644 --- a/avm/res/data-factory/factory/main.json +++ b/avm/res/data-factory/factory/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1210072663750911007" + "version": "0.25.53.49325", + "templateHash": "6048154575317305583" }, "name": "Data Factories", "description": "This module deploys a Data Factory.", @@ -330,14 +330,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -348,14 +355,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -714,12 +728,30 @@ "scope": "[format('Microsoft.DataFactory/factories/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -776,8 +808,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2622993864386710404" + "version": "0.25.53.49325", + "templateHash": "13192908070354977743" }, "name": "Data Factory Managed Virtual Networks", "description": "This module deploys a Data Factory Managed Virtual Network.", @@ -850,8 +882,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15507361222321538498" + "version": "0.25.53.49325", + "templateHash": "727544206896372572" }, "name": "Data Factory Managed Virtual Network Managed PrivateEndpoints", "description": "This module deploys a Data Factory Managed Virtual Network Managed Private Endpoint.", @@ -995,8 +1027,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14308450010595234197" + "version": "0.25.53.49325", + "templateHash": "7384162383092533956" }, "name": "Data Factory Integration RunTimes", "description": "This module deploys a Data Factory Managed or Self-Hosted Integration Runtime.", diff --git a/avm/res/data-factory/factory/managed-virtual-network/main.json b/avm/res/data-factory/factory/managed-virtual-network/main.json index 4f9fd007ad..a7d485a538 100644 --- a/avm/res/data-factory/factory/managed-virtual-network/main.json +++ b/avm/res/data-factory/factory/managed-virtual-network/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2622993864386710404" + "version": "0.25.53.49325", + "templateHash": "13192908070354977743" }, "name": "Data Factory Managed Virtual Networks", "description": "This module deploys a Data Factory Managed Virtual Network.", @@ -78,8 +78,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15507361222321538498" + "version": "0.25.53.49325", + "templateHash": "727544206896372572" }, "name": "Data Factory Managed Virtual Network Managed PrivateEndpoints", "description": "This module deploys a Data Factory Managed Virtual Network Managed Private Endpoint.", diff --git a/avm/res/data-factory/factory/managed-virtual-network/managed-private-endpoint/main.json b/avm/res/data-factory/factory/managed-virtual-network/managed-private-endpoint/main.json index 151f77f9cc..ad3f95edbc 100644 --- a/avm/res/data-factory/factory/managed-virtual-network/managed-private-endpoint/main.json +++ b/avm/res/data-factory/factory/managed-virtual-network/managed-private-endpoint/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15507361222321538498" + "version": "0.25.53.49325", + "templateHash": "727544206896372572" }, "name": "Data Factory Managed Virtual Network Managed PrivateEndpoints", "description": "This module deploys a Data Factory Managed Virtual Network Managed Private Endpoint.", diff --git a/avm/res/data-protection/backup-vault/backup-policy/main.json b/avm/res/data-protection/backup-vault/backup-policy/main.json index 600327ed33..052a79bdb4 100644 --- a/avm/res/data-protection/backup-vault/backup-policy/main.json +++ b/avm/res/data-protection/backup-vault/backup-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1690165134705407383" + "version": "0.25.53.49325", + "templateHash": "3601741933922377880" }, "name": "Data Protection Backup Vault Backup Policies", "description": "This module deploys a Data Protection Backup Vault Backup Policy.", diff --git a/avm/res/data-protection/backup-vault/main.json b/avm/res/data-protection/backup-vault/main.json index 32d42d8c85..c43d9cb3c2 100644 --- a/avm/res/data-protection/backup-vault/main.json +++ b/avm/res/data-protection/backup-vault/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5324082929014837266" + "version": "0.25.53.49325", + "templateHash": "11297894401927654762" }, "name": "Data Protection Backup Vaults", "description": "This module deploys a Data Protection Backup Vault.", @@ -344,8 +344,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1690165134705407383" + "version": "0.25.53.49325", + "templateHash": "3601741933922377880" }, "name": "Data Protection Backup Vault Backup Policies", "description": "This module deploys a Data Protection Backup Vault Backup Policy.", diff --git a/avm/res/databricks/access-connector/ORPHANED.md b/avm/res/databricks/access-connector/ORPHANED.md deleted file mode 100644 index ef8fa911d2..0000000000 --- a/avm/res/databricks/access-connector/ORPHANED.md +++ /dev/null @@ -1,4 +0,0 @@ -⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ - -- Only security and bug fixes are being handled by the AVM core team at present. -- If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! \ No newline at end of file diff --git a/avm/res/databricks/access-connector/README.md b/avm/res/databricks/access-connector/README.md index b2c9e52f2c..93eef78750 100644 --- a/avm/res/databricks/access-connector/README.md +++ b/avm/res/databricks/access-connector/README.md @@ -1,10 +1,5 @@ # Azure Databricks Access Connectors `[Microsoft.Databricks/accessConnectors]` -> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ -> -> - Only security and bug fixes are being handled by the AVM core team at present. -> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! - This module deploys an Azure Databricks Access Connector. ## Navigation diff --git a/avm/res/databricks/access-connector/main.json b/avm/res/databricks/access-connector/main.json index 66e1ce3471..aff0caa11d 100644 --- a/avm/res/databricks/access-connector/main.json +++ b/avm/res/databricks/access-connector/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5801242046314845466" + "version": "0.25.53.49325", + "templateHash": "2158406963601048020" }, "name": "Azure Databricks Access Connectors", "description": "This module deploys an Azure Databricks Access Connector.", diff --git a/avm/res/databricks/workspace/ORPHANED.md b/avm/res/databricks/workspace/ORPHANED.md deleted file mode 100644 index ef8fa911d2..0000000000 --- a/avm/res/databricks/workspace/ORPHANED.md +++ /dev/null @@ -1,4 +0,0 @@ -⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ - -- Only security and bug fixes are being handled by the AVM core team at present. -- If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! \ No newline at end of file diff --git a/avm/res/databricks/workspace/README.md b/avm/res/databricks/workspace/README.md index 337845699b..1afe94cb26 100644 --- a/avm/res/databricks/workspace/README.md +++ b/avm/res/databricks/workspace/README.md @@ -1,10 +1,5 @@ # Azure Databricks Workspaces `[Microsoft.Databricks/workspaces]` -> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ -> -> - Only security and bug fixes are being handled by the AVM core team at present. -> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! - This module deploys an Azure Databricks Workspace. ## Navigation @@ -776,9 +771,8 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -813,24 +807,46 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array -### Parameter: `diagnosticSettings.marketplacePartnerResourceId` +**Optional parameters** -The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. - Required: No - Type: string -### Parameter: `diagnosticSettings.metricCategories` +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. - Required: No -- Type: array +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + +### Parameter: `diagnosticSettings.marketplacePartnerResourceId` + +The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. + +- Required: No +- Type: string ### Parameter: `diagnosticSettings.name` @@ -1006,6 +1022,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint IP address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private IP addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -1027,6 +1064,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. @@ -1389,9 +1476,14 @@ Address prefix for Managed virtual network. | Output | Type | Description | | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | +| `managedResourceGroupId` | string | The resource ID of the managed resource group. | +| `managedResourceGroupName` | string | The name of the managed resource group. | | `name` | string | The name of the deployed databricks workspace. | +| `privateEndpoints` | array | The private endpoints for the Databricks Workspace. | | `resourceGroupName` | string | The resource group of the deployed databricks workspace. | | `resourceId` | string | The resource ID of the deployed databricks workspace. | +| `storageAccountId` | string | The resource ID of the DBFS storage account. | +| `storageAccountName` | string | The name of the DBFS storage account. | ## Cross-referenced modules @@ -1399,7 +1491,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.3.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.3.3` | Remote reference | ## Notes diff --git a/avm/res/databricks/workspace/main.bicep b/avm/res/databricks/workspace/main.bicep index e9e6974426..5a9190ab0f 100644 --- a/avm/res/databricks/workspace/main.bicep +++ b/avm/res/databricks/workspace/main.bicep @@ -262,12 +262,11 @@ resource workspace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@202 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -288,8 +287,8 @@ resource workspace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022 scope: workspace }] -module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.3.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-KeyVault-PrivateEndpoint-${index}' +module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.3.3' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Databricks-PrivateEndpoint-${index}' params: { privateLinkServiceConnections: [ { @@ -331,6 +330,24 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = workspace.location +@description('The resource ID of the managed resource group.') +output managedResourceGroupId string = workspace.properties.managedResourceGroupId + +@description('The name of the managed resource group.') +output managedResourceGroupName string = last(split(workspace.properties.managedResourceGroupId, '/')) + +@description('The name of the DBFS storage account.') +output storageAccountName string = workspace.properties.parameters.storageAccountName.value + +@description('The resource ID of the DBFS storage account.') +output storageAccountId string = resourceId(last(split(workspace.properties.managedResourceGroupId, '/')), 'microsoft.storage/storageAccounts', workspace.properties.parameters.storageAccountName.value) + +@description('The private endpoints for the Databricks Workspace.') +output privateEndpoints array = [for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { + name: workspace_privateEndpoints[i].outputs.name + resourceId: workspace_privateEndpoints[i].outputs.resourceId +}] + // =============== // // Definitions // // =============== // @@ -470,19 +487,16 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? - }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') - category: string + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/databricks/workspace/main.json b/avm/res/databricks/workspace/main.json index 8757d2290c..03e8fa6cbb 100644 --- a/avm/res/databricks/workspace/main.json +++ b/avm/res/databricks/workspace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8329222435096885386" + "version": "0.25.53.49325", + "templateHash": "7710672223855991692" }, "name": "Azure Databricks Workspaces", "description": "This module deploys an Azure Databricks Workspace.", @@ -380,30 +380,19 @@ "metadata": { "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." - } - }, - "metricCategories": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", + }, + "enabled": { + "type": "bool", + "nullable": true, "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -778,11 +767,21 @@ "scope": "[format('Microsoft.Databricks/workspaces/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -819,7 +818,7 @@ }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-KeyVault-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-Databricks-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -889,8 +888,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "2821141217598568122" + "version": "0.24.24.22086", + "templateHash": "5518855230364102370" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", @@ -939,7 +938,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." } }, "conditionVersion": { @@ -1017,7 +1016,7 @@ "privateIPAddress": { "type": "string", "metadata": { - "description": "Required. A private ip address obtained from the private endpoint's subnet." + "description": "Required. A private IP address obtained from the private endpoint's subnet." } } }, @@ -1120,7 +1119,7 @@ "fqdn": { "type": "string", "metadata": { - "description": "Required. Fqdn that resolves to private endpoint ip address." + "description": "Required. Fqdn that resolves to private endpoint IP address." } }, "ipAddresses": { @@ -1129,7 +1128,7 @@ "type": "string" }, "metadata": { - "description": "Required. A list of private ip addresses of the private endpoint." + "description": "Required. A list of private IP addresses of the private endpoint." } } } @@ -1255,7 +1254,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.3.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.3.3', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1360,8 +1359,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "18168683629401652671" + "version": "0.24.24.22086", + "templateHash": "9321937464667207030" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1509,6 +1508,47 @@ "description": "The location the resource was deployed into." }, "value": "[reference('workspace', '2023-02-01', 'full').location]" + }, + "managedResourceGroupId": { + "type": "string", + "metadata": { + "description": "The resource ID of the managed resource group." + }, + "value": "[reference('workspace').managedResourceGroupId]" + }, + "managedResourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the managed resource group." + }, + "value": "[last(split(reference('workspace').managedResourceGroupId, '/'))]" + }, + "storageAccountName": { + "type": "string", + "metadata": { + "description": "The name of the DBFS storage account." + }, + "value": "[reference('workspace').parameters.storageAccountName.value]" + }, + "storageAccountId": { + "type": "string", + "metadata": { + "description": "The resource ID of the DBFS storage account." + }, + "value": "[resourceId(last(split(reference('workspace').managedResourceGroupId, '/')), 'microsoft.storage/storageAccounts', reference('workspace').parameters.storageAccountName.value)]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints for the Databricks Workspace." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/databricks/workspace/tests/e2e/max/dependencies.bicep b/avm/res/databricks/workspace/tests/e2e/max/dependencies.bicep index ecb008351c..9a8c73e3f6 100644 --- a/avm/res/databricks/workspace/tests/e2e/max/dependencies.bicep +++ b/avm/res/databricks/workspace/tests/e2e/max/dependencies.bicep @@ -25,307 +25,316 @@ param storageAccountName string @description('Required. The name of the Application Insights Instanec to create.') param applicationInsightsName string +@description('Required. The name of the log analytics workspace to create.') +param logAnalyticsWorkspaceName string + @description('Required. The name of the Virtual Network to create.') param virtualNetworkName string var addressPrefix = '10.0.0.0/16' resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { - name: keyVaultName - location: location - properties: { - sku: { - family: 'A' - name: 'standard' - } - tenantId: tenant().tenantId - enablePurgeProtection: true // Required by batch account - softDeleteRetentionInDays: 7 - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: true - accessPolicies: [] + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' } - - resource key 'keys@2022-07-01' = { - name: 'keyEncryptionKey' - properties: { - kty: 'RSA' - } + tenantId: tenant().tenantId + enablePurgeProtection: true // Required by batch account + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' } + } } resource keyVaultDisk 'Microsoft.KeyVault/vaults@2022-07-01' = { - name: keyVaultDiskName - location: location - properties: { - sku: { - family: 'A' - name: 'standard' - } - tenantId: tenant().tenantId - enablePurgeProtection: true // Required by batch account - softDeleteRetentionInDays: 7 - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: true - accessPolicies: [] + name: keyVaultDiskName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' } - - resource key 'keys@2022-07-01' = { - name: 'keyEncryptionKeyDisk' - properties: { - kty: 'RSA' - } + tenantId: tenant().tenantId + enablePurgeProtection: true // Required by batch account + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKeyDisk' + properties: { + kty: 'RSA' } + } } resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-Key-Key-Vault-Crypto-User-RoleAssignment') - scope: keyVault::key - properties: { - principalId: '711330f9-cfad-4b10-a462-d82faa92027d' // AzureDatabricks Enterprise Application Object Id (Note: this is tenant specific) - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User - principalType: 'ServicePrincipal' - } + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-Key-Key-Vault-Crypto-User-RoleAssignment') + scope: keyVault::key + properties: { + principalId: '711330f9-cfad-4b10-a462-d82faa92027d' // AzureDatabricks Enterprise Application Object Id (Note: this is tenant specific) + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + principalType: 'ServicePrincipal' + } } resource amlPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-Key-Vault-Contributor') - scope: keyVault - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor - principalType: 'ServicePrincipal' - } + name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-Key-Vault-Contributor') + scope: keyVault + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + principalType: 'ServicePrincipal' + } } resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = { - name: storageAccountName - location: location - sku: { - name: 'Standard_ZRS' - } - kind: 'StorageV2' - properties: {} + name: storageAccountName + location: location + sku: { + name: 'Standard_ZRS' + } + kind: 'StorageV2' + properties: {} +} + +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { + name: logAnalyticsWorkspaceName + location: location } resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { - name: applicationInsightsName - location: location - kind: 'web' - properties: { - Application_Type: 'web' - } + name: applicationInsightsName + location: location + kind: 'web' + properties: { + Application_Type: 'web' + WorkspaceResourceId: logAnalyticsWorkspace.id + } } resource machineLearningWorkspace 'Microsoft.MachineLearningServices/workspaces@2023-04-01' = { - name: amlWorkspaceName - location: location - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - storageAccount: storageAccount.id - keyVault: keyVault.id - applicationInsights: applicationInsights.id - primaryUserAssignedIdentity: managedIdentity.id + name: amlWorkspaceName + location: location + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} } + } + properties: { + storageAccount: storageAccount.id + keyVault: keyVault.id + applicationInsights: applicationInsights.id + primaryUserAssignedIdentity: managedIdentity.id + } } resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { - name: loadBalancerName - location: location - properties: { - backendAddressPools: [ - { - name: 'default' - } - ] - frontendIPConfigurations: [ - { - name: 'privateIPConfig1' - properties: { - subnet: { - id: virtualNetwork.properties.subnets[0].id - } - } - } - ] - } + name: loadBalancerName + location: location + properties: { + backendAddressPools: [ + { + name: 'default' + } + ] + frontendIPConfigurations: [ + { + name: 'privateIPConfig1' + properties: { + subnet: { + id: virtualNetwork.properties.subnets[0].id + } + } + } + ] + } } resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-04-01' = { - name: networkSecurityGroupName - location: location - properties: { - securityRules: [ - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-worker-inbound' - properties: { - description: 'Required for worker nodes communication within a cluster.' - protocol: '*' - sourcePortRange: '*' - destinationPortRange: '*' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'VirtualNetwork' - access: 'Allow' - priority: 100 - direction: 'Inbound' - } - } - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-databricks-webapp' - properties: { - description: 'Required for workers communication with Databricks Webapp.' - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '443' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'AzureDatabricks' - access: 'Allow' - priority: 100 - direction: 'Outbound' - } - } - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-sql' - properties: { - description: 'Required for workers communication with Azure SQL services.' - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '3306' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'Sql' - access: 'Allow' - priority: 101 - direction: 'Outbound' - } - } - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-storage' - properties: { - description: 'Required for workers communication with Azure Storage services.' - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '443' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'Storage' - access: 'Allow' - priority: 102 - direction: 'Outbound' - } - } - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-worker-outbound' - properties: { - description: 'Required for worker nodes communication within a cluster.' - protocol: '*' - sourcePortRange: '*' - destinationPortRange: '*' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'VirtualNetwork' - access: 'Allow' - priority: 103 - direction: 'Outbound' - } - } - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-eventhub' - properties: { - description: 'Required for worker communication with Azure Eventhub services.' - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '9093' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'EventHub' - access: 'Allow' - priority: 104 - direction: 'Outbound' - } - } - ] - } + name: networkSecurityGroupName + location: location + properties: { + securityRules: [ + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-worker-inbound' + properties: { + description: 'Required for worker nodes communication within a cluster.' + protocol: '*' + sourcePortRange: '*' + destinationPortRange: '*' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'VirtualNetwork' + access: 'Allow' + priority: 100 + direction: 'Inbound' + } + } + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-databricks-webapp' + properties: { + description: 'Required for workers communication with Databricks Webapp.' + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '443' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'AzureDatabricks' + access: 'Allow' + priority: 100 + direction: 'Outbound' + } + } + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-sql' + properties: { + description: 'Required for workers communication with Azure SQL services.' + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '3306' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'Sql' + access: 'Allow' + priority: 101 + direction: 'Outbound' + } + } + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-storage' + properties: { + description: 'Required for workers communication with Azure Storage services.' + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '443' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'Storage' + access: 'Allow' + priority: 102 + direction: 'Outbound' + } + } + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-worker-outbound' + properties: { + description: 'Required for worker nodes communication within a cluster.' + protocol: '*' + sourcePortRange: '*' + destinationPortRange: '*' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'VirtualNetwork' + access: 'Allow' + priority: 103 + direction: 'Outbound' + } + } + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-eventhub' + properties: { + description: 'Required for worker communication with Azure Eventhub services.' + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '9093' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'EventHub' + access: 'Allow' + priority: 104 + direction: 'Outbound' + } + } + ] + } } resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-01-01' = { - name: virtualNetworkName - location: location - properties: { - addressSpace: { - addressPrefixes: [ - addressPrefix - ] + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 20, 0) } - subnets: [ - { - name: 'defaultSubnet' - properties: { - addressPrefix: cidrSubnet(addressPrefix, 20, 0) - } - } + } + { + name: 'custom-public-subnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 20, 1) + networkSecurityGroup: { + id: networkSecurityGroup.id + } + delegations: [ { - name: 'custom-public-subnet' - properties: { - addressPrefix: cidrSubnet(addressPrefix, 20, 1) - networkSecurityGroup: { - id: networkSecurityGroup.id - } - delegations: [ - { - name: 'databricksDelegation' - properties: { - serviceName: 'Microsoft.Databricks/workspaces' - } - } - ] - } + name: 'databricksDelegation' + properties: { + serviceName: 'Microsoft.Databricks/workspaces' + } } + ] + } + } + { + name: 'custom-private-subnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 20, 2) + networkSecurityGroup: { + id: networkSecurityGroup.id + } + delegations: [ { - name: 'custom-private-subnet' - properties: { - addressPrefix: cidrSubnet(addressPrefix, 20, 2) - networkSecurityGroup: { - id: networkSecurityGroup.id - } - delegations: [ - { - name: 'databricksDelegation' - properties: { - serviceName: 'Microsoft.Databricks/workspaces' - } - } - ] - } + name: 'databricksDelegation' + properties: { + serviceName: 'Microsoft.Databricks/workspaces' + } } - ] - } + ] + } + } + ] + } } resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { - name: 'privatelink.azuredatabricks.net' - location: 'global' + name: 'privatelink.azuredatabricks.net' + location: 'global' - resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { - name: '${virtualNetwork.name}-vnetlink' - location: 'global' - properties: { - virtualNetwork: { - id: virtualNetwork.id - } - registrationEnabled: false - } + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false } + } } @description('The resource ID of the created Virtual Network Default Subnet.') 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 cb83ab94af..818deb76c8 100644 --- a/avm/res/databricks/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/databricks/workspace/tests/e2e/max/main.test.bicep @@ -42,6 +42,7 @@ module nestedDependencies 'dependencies.bicep' = { location: resourceLocation amlWorkspaceName: 'dep-${namePrefix}-aml-${serviceShort}' applicationInsightsName: 'dep-${namePrefix}-appi-${serviceShort}' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' storageAccountName: 'dep${namePrefix}sa${serviceShort}' virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' diff --git a/avm/res/databricks/workspace/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/databricks/workspace/tests/e2e/waf-aligned/dependencies.bicep index ecb008351c..9a8c73e3f6 100644 --- a/avm/res/databricks/workspace/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/databricks/workspace/tests/e2e/waf-aligned/dependencies.bicep @@ -25,307 +25,316 @@ param storageAccountName string @description('Required. The name of the Application Insights Instanec to create.') param applicationInsightsName string +@description('Required. The name of the log analytics workspace to create.') +param logAnalyticsWorkspaceName string + @description('Required. The name of the Virtual Network to create.') param virtualNetworkName string var addressPrefix = '10.0.0.0/16' resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { - name: keyVaultName - location: location - properties: { - sku: { - family: 'A' - name: 'standard' - } - tenantId: tenant().tenantId - enablePurgeProtection: true // Required by batch account - softDeleteRetentionInDays: 7 - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: true - accessPolicies: [] + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' } - - resource key 'keys@2022-07-01' = { - name: 'keyEncryptionKey' - properties: { - kty: 'RSA' - } + tenantId: tenant().tenantId + enablePurgeProtection: true // Required by batch account + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' } + } } resource keyVaultDisk 'Microsoft.KeyVault/vaults@2022-07-01' = { - name: keyVaultDiskName - location: location - properties: { - sku: { - family: 'A' - name: 'standard' - } - tenantId: tenant().tenantId - enablePurgeProtection: true // Required by batch account - softDeleteRetentionInDays: 7 - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: true - accessPolicies: [] + name: keyVaultDiskName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' } - - resource key 'keys@2022-07-01' = { - name: 'keyEncryptionKeyDisk' - properties: { - kty: 'RSA' - } + tenantId: tenant().tenantId + enablePurgeProtection: true // Required by batch account + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKeyDisk' + properties: { + kty: 'RSA' } + } } resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-Key-Key-Vault-Crypto-User-RoleAssignment') - scope: keyVault::key - properties: { - principalId: '711330f9-cfad-4b10-a462-d82faa92027d' // AzureDatabricks Enterprise Application Object Id (Note: this is tenant specific) - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User - principalType: 'ServicePrincipal' - } + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-Key-Key-Vault-Crypto-User-RoleAssignment') + scope: keyVault::key + properties: { + principalId: '711330f9-cfad-4b10-a462-d82faa92027d' // AzureDatabricks Enterprise Application Object Id (Note: this is tenant specific) + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + principalType: 'ServicePrincipal' + } } resource amlPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-Key-Vault-Contributor') - scope: keyVault - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor - principalType: 'ServicePrincipal' - } + name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-Key-Vault-Contributor') + scope: keyVault + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + principalType: 'ServicePrincipal' + } } resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = { - name: storageAccountName - location: location - sku: { - name: 'Standard_ZRS' - } - kind: 'StorageV2' - properties: {} + name: storageAccountName + location: location + sku: { + name: 'Standard_ZRS' + } + kind: 'StorageV2' + properties: {} +} + +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { + name: logAnalyticsWorkspaceName + location: location } resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { - name: applicationInsightsName - location: location - kind: 'web' - properties: { - Application_Type: 'web' - } + name: applicationInsightsName + location: location + kind: 'web' + properties: { + Application_Type: 'web' + WorkspaceResourceId: logAnalyticsWorkspace.id + } } resource machineLearningWorkspace 'Microsoft.MachineLearningServices/workspaces@2023-04-01' = { - name: amlWorkspaceName - location: location - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - storageAccount: storageAccount.id - keyVault: keyVault.id - applicationInsights: applicationInsights.id - primaryUserAssignedIdentity: managedIdentity.id + name: amlWorkspaceName + location: location + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} } + } + properties: { + storageAccount: storageAccount.id + keyVault: keyVault.id + applicationInsights: applicationInsights.id + primaryUserAssignedIdentity: managedIdentity.id + } } resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { - name: loadBalancerName - location: location - properties: { - backendAddressPools: [ - { - name: 'default' - } - ] - frontendIPConfigurations: [ - { - name: 'privateIPConfig1' - properties: { - subnet: { - id: virtualNetwork.properties.subnets[0].id - } - } - } - ] - } + name: loadBalancerName + location: location + properties: { + backendAddressPools: [ + { + name: 'default' + } + ] + frontendIPConfigurations: [ + { + name: 'privateIPConfig1' + properties: { + subnet: { + id: virtualNetwork.properties.subnets[0].id + } + } + } + ] + } } resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-04-01' = { - name: networkSecurityGroupName - location: location - properties: { - securityRules: [ - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-worker-inbound' - properties: { - description: 'Required for worker nodes communication within a cluster.' - protocol: '*' - sourcePortRange: '*' - destinationPortRange: '*' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'VirtualNetwork' - access: 'Allow' - priority: 100 - direction: 'Inbound' - } - } - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-databricks-webapp' - properties: { - description: 'Required for workers communication with Databricks Webapp.' - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '443' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'AzureDatabricks' - access: 'Allow' - priority: 100 - direction: 'Outbound' - } - } - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-sql' - properties: { - description: 'Required for workers communication with Azure SQL services.' - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '3306' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'Sql' - access: 'Allow' - priority: 101 - direction: 'Outbound' - } - } - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-storage' - properties: { - description: 'Required for workers communication with Azure Storage services.' - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '443' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'Storage' - access: 'Allow' - priority: 102 - direction: 'Outbound' - } - } - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-worker-outbound' - properties: { - description: 'Required for worker nodes communication within a cluster.' - protocol: '*' - sourcePortRange: '*' - destinationPortRange: '*' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'VirtualNetwork' - access: 'Allow' - priority: 103 - direction: 'Outbound' - } - } - { - name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-eventhub' - properties: { - description: 'Required for worker communication with Azure Eventhub services.' - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '9093' - sourceAddressPrefix: 'VirtualNetwork' - destinationAddressPrefix: 'EventHub' - access: 'Allow' - priority: 104 - direction: 'Outbound' - } - } - ] - } + name: networkSecurityGroupName + location: location + properties: { + securityRules: [ + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-worker-inbound' + properties: { + description: 'Required for worker nodes communication within a cluster.' + protocol: '*' + sourcePortRange: '*' + destinationPortRange: '*' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'VirtualNetwork' + access: 'Allow' + priority: 100 + direction: 'Inbound' + } + } + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-databricks-webapp' + properties: { + description: 'Required for workers communication with Databricks Webapp.' + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '443' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'AzureDatabricks' + access: 'Allow' + priority: 100 + direction: 'Outbound' + } + } + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-sql' + properties: { + description: 'Required for workers communication with Azure SQL services.' + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '3306' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'Sql' + access: 'Allow' + priority: 101 + direction: 'Outbound' + } + } + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-storage' + properties: { + description: 'Required for workers communication with Azure Storage services.' + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '443' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'Storage' + access: 'Allow' + priority: 102 + direction: 'Outbound' + } + } + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-worker-outbound' + properties: { + description: 'Required for worker nodes communication within a cluster.' + protocol: '*' + sourcePortRange: '*' + destinationPortRange: '*' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'VirtualNetwork' + access: 'Allow' + priority: 103 + direction: 'Outbound' + } + } + { + name: 'Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-eventhub' + properties: { + description: 'Required for worker communication with Azure Eventhub services.' + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '9093' + sourceAddressPrefix: 'VirtualNetwork' + destinationAddressPrefix: 'EventHub' + access: 'Allow' + priority: 104 + direction: 'Outbound' + } + } + ] + } } resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-01-01' = { - name: virtualNetworkName - location: location - properties: { - addressSpace: { - addressPrefixes: [ - addressPrefix - ] + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 20, 0) } - subnets: [ - { - name: 'defaultSubnet' - properties: { - addressPrefix: cidrSubnet(addressPrefix, 20, 0) - } - } + } + { + name: 'custom-public-subnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 20, 1) + networkSecurityGroup: { + id: networkSecurityGroup.id + } + delegations: [ { - name: 'custom-public-subnet' - properties: { - addressPrefix: cidrSubnet(addressPrefix, 20, 1) - networkSecurityGroup: { - id: networkSecurityGroup.id - } - delegations: [ - { - name: 'databricksDelegation' - properties: { - serviceName: 'Microsoft.Databricks/workspaces' - } - } - ] - } + name: 'databricksDelegation' + properties: { + serviceName: 'Microsoft.Databricks/workspaces' + } } + ] + } + } + { + name: 'custom-private-subnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 20, 2) + networkSecurityGroup: { + id: networkSecurityGroup.id + } + delegations: [ { - name: 'custom-private-subnet' - properties: { - addressPrefix: cidrSubnet(addressPrefix, 20, 2) - networkSecurityGroup: { - id: networkSecurityGroup.id - } - delegations: [ - { - name: 'databricksDelegation' - properties: { - serviceName: 'Microsoft.Databricks/workspaces' - } - } - ] - } + name: 'databricksDelegation' + properties: { + serviceName: 'Microsoft.Databricks/workspaces' + } } - ] - } + ] + } + } + ] + } } resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { - name: 'privatelink.azuredatabricks.net' - location: 'global' + name: 'privatelink.azuredatabricks.net' + location: 'global' - resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { - name: '${virtualNetwork.name}-vnetlink' - location: 'global' - properties: { - virtualNetwork: { - id: virtualNetwork.id - } - registrationEnabled: false - } + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false } + } } @description('The resource ID of the created Virtual Network Default Subnet.') 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 ff1b692f41..056d003a65 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 @@ -42,6 +42,7 @@ module nestedDependencies 'dependencies.bicep' = { location: resourceLocation amlWorkspaceName: 'dep-${namePrefix}-aml-${serviceShort}' applicationInsightsName: 'dep-${namePrefix}-appi-${serviceShort}' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' storageAccountName: 'dep${namePrefix}sa${serviceShort}' virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' diff --git a/avm/res/db-for-my-sql/flexible-server/README.md b/avm/res/db-for-my-sql/flexible-server/README.md index 5068275f29..cde312c15c 100644 --- a/avm/res/db-for-my-sql/flexible-server/README.md +++ b/avm/res/db-for-my-sql/flexible-server/README.md @@ -939,9 +939,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -976,11 +976,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -990,11 +1019,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/db-for-my-sql/flexible-server/administrator/main.json b/avm/res/db-for-my-sql/flexible-server/administrator/main.json index 56d0bff8b4..5480bf8dab 100644 --- a/avm/res/db-for-my-sql/flexible-server/administrator/main.json +++ b/avm/res/db-for-my-sql/flexible-server/administrator/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5949458902590917375" + "version": "0.25.53.49325", + "templateHash": "9797360516324373554" }, "name": "DBforMySQL Flexible Server Administrators", "description": "This module deploys a DBforMySQL Flexible Server Administrator.", diff --git a/avm/res/db-for-my-sql/flexible-server/database/main.json b/avm/res/db-for-my-sql/flexible-server/database/main.json index 9a7d2f7aac..96c3f0eeda 100644 --- a/avm/res/db-for-my-sql/flexible-server/database/main.json +++ b/avm/res/db-for-my-sql/flexible-server/database/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3740413409622743148" + "version": "0.25.53.49325", + "templateHash": "1786501395002693358" }, "name": "DBforMySQL Flexible Server Databases", "description": "This module deploys a DBforMySQL Flexible Server Database.", diff --git a/avm/res/db-for-my-sql/flexible-server/firewall-rule/main.json b/avm/res/db-for-my-sql/flexible-server/firewall-rule/main.json index 1e78abe670..c4ec0e06bc 100644 --- a/avm/res/db-for-my-sql/flexible-server/firewall-rule/main.json +++ b/avm/res/db-for-my-sql/flexible-server/firewall-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13884040071380358802" + "version": "0.25.53.49325", + "templateHash": "1600222376229916804" }, "name": "DBforMySQL Flexible Server Firewall Rules", "description": "This module deploys a DBforMySQL Flexible Server Firewall Rule.", diff --git a/avm/res/db-for-my-sql/flexible-server/main.bicep b/avm/res/db-for-my-sql/flexible-server/main.bicep index d03e3869af..a3aa0a019b 100644 --- a/avm/res/db-for-my-sql/flexible-server/main.bicep +++ b/avm/res/db-for-my-sql/flexible-server/main.bicep @@ -337,19 +337,16 @@ resource flexibleServer_diagnosticSettings 'Microsoft.Insights/diagnosticSetting workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -412,19 +409,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/db-for-my-sql/flexible-server/main.json b/avm/res/db-for-my-sql/flexible-server/main.json index 6364413b5d..2bb5f3d24a 100644 --- a/avm/res/db-for-my-sql/flexible-server/main.json +++ b/avm/res/db-for-my-sql/flexible-server/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16303493572113818798" + "version": "0.25.53.49325", + "templateHash": "7560423312278776039" }, "name": "DBforMySQL Flexible Servers", "description": "This module deploys a DBforMySQL Flexible Server.", @@ -149,12 +149,19 @@ "metadata": { "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -167,12 +174,19 @@ "metadata": { "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -725,12 +739,30 @@ "scope": "[format('Microsoft.DBforMySQL/flexibleServers/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -767,8 +799,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3740413409622743148" + "version": "0.25.53.49325", + "templateHash": "1786501395002693358" }, "name": "DBforMySQL Flexible Server Databases", "description": "This module deploys a DBforMySQL Flexible Server Database.", @@ -875,8 +907,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13884040071380358802" + "version": "0.25.53.49325", + "templateHash": "1600222376229916804" }, "name": "DBforMySQL Flexible Server Firewall Rules", "description": "This module deploys a DBforMySQL Flexible Server Firewall Rule.", @@ -982,8 +1014,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5949458902590917375" + "version": "0.25.53.49325", + "templateHash": "9797360516324373554" }, "name": "DBforMySQL Flexible Server Administrators", "description": "This module deploys a DBforMySQL Flexible Server Administrator.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/README.md b/avm/res/db-for-postgre-sql/flexible-server/README.md index 2a955d9f31..a396a0eebe 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/README.md +++ b/avm/res/db-for-postgre-sql/flexible-server/README.md @@ -1086,9 +1086,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1123,11 +1123,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1137,11 +1166,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json b/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json index 0a7769a2f4..4c1e49e061 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4173424246155226683" + "version": "0.25.53.49325", + "templateHash": "14998758936357296642" }, "name": "DBforPostgreSQL Flexible Server Administrators", "description": "This module deploys a DBforPostgreSQL Flexible Server Administrator.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json b/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json index ccd16805b5..c7a1671955 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11141557608599743123" + "version": "0.25.53.49325", + "templateHash": "13489282175455188314" }, "name": "DBforPostgreSQL Flexible Server Configurations", "description": "This module deploys a DBforPostgreSQL Flexible Server Configuration.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/database/main.json b/avm/res/db-for-postgre-sql/flexible-server/database/main.json index 7674c8e8bb..d671937490 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/database/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/database/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6112564509027745928" + "version": "0.25.53.49325", + "templateHash": "12415562574078248070" }, "name": "DBforPostgreSQL Flexible Server Databases", "description": "This module deploys a DBforPostgreSQL Flexible Server Database.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json b/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json index d19844e569..d92c543ae2 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14154143828607620758" + "version": "0.25.53.49325", + "templateHash": "12878552829645985725" }, "name": "DBforPostgreSQL Flexible Server Firewall Rules", "description": "This module deploys a DBforPostgreSQL Flexible Server Firewall Rule.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/main.bicep b/avm/res/db-for-postgre-sql/flexible-server/main.bicep index e620fc08de..235a431d3c 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/main.bicep +++ b/avm/res/db-for-postgre-sql/flexible-server/main.bicep @@ -331,19 +331,16 @@ resource flexibleServer_diagnosticSettings 'Microsoft.Insights/diagnosticSetting workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -406,19 +403,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/db-for-postgre-sql/flexible-server/main.json b/avm/res/db-for-postgre-sql/flexible-server/main.json index 70ecd47ba1..3282c25ad9 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12465588842869452313" + "version": "0.25.53.49325", + "templateHash": "14524458345533599390" }, "name": "DBforPostgreSQL Flexible Servers", "description": "This module deploys a DBforPostgreSQL Flexible Server.", @@ -147,14 +147,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -165,14 +172,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -682,12 +696,30 @@ "scope": "[format('Microsoft.DBforPostgreSQL/flexibleServers/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -724,8 +756,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6112564509027745928" + "version": "0.25.53.49325", + "templateHash": "12415562574078248070" }, "name": "DBforPostgreSQL Flexible Server Databases", "description": "This module deploys a DBforPostgreSQL Flexible Server Database.", @@ -832,8 +864,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14154143828607620758" + "version": "0.25.53.49325", + "templateHash": "12878552829645985725" }, "name": "DBforPostgreSQL Flexible Server Firewall Rules", "description": "This module deploys a DBforPostgreSQL Flexible Server Firewall Rule.", @@ -937,8 +969,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11141557608599743123" + "version": "0.25.53.49325", + "templateHash": "13489282175455188314" }, "name": "DBforPostgreSQL Flexible Server Configurations", "description": "This module deploys a DBforPostgreSQL Flexible Server Configuration.", @@ -1047,8 +1079,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4173424246155226683" + "version": "0.25.53.49325", + "templateHash": "14998758936357296642" }, "name": "DBforPostgreSQL Flexible Server Administrators", "description": "This module deploys a DBforPostgreSQL Flexible Server Administrator.", diff --git a/avm/res/desktop-virtualization/application-group/README.md b/avm/res/desktop-virtualization/application-group/README.md index 5ca1a8e2e6..226afffc3b 100644 --- a/avm/res/desktop-virtualization/application-group/README.md +++ b/avm/res/desktop-virtualization/application-group/README.md @@ -442,7 +442,7 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -478,11 +478,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `AllLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `AllLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. diff --git a/avm/res/desktop-virtualization/application-group/application/main.json b/avm/res/desktop-virtualization/application-group/application/main.json index 7fc424830f..c5394ba356 100644 --- a/avm/res/desktop-virtualization/application-group/application/main.json +++ b/avm/res/desktop-virtualization/application-group/application/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5256311106319509279" + "version": "0.25.53.49325", + "templateHash": "1502648604355228279" }, "name": "Azure Virtual Desktop Application Group Application", "description": "This module deploys an Azure Virtual Desktop Application Group Application.", diff --git a/avm/res/desktop-virtualization/application-group/main.bicep b/avm/res/desktop-virtualization/application-group/main.bicep index bfc6102ad1..78c890153c 100644 --- a/avm/res/desktop-virtualization/application-group/main.bicep +++ b/avm/res/desktop-virtualization/application-group/main.bicep @@ -148,12 +148,11 @@ resource appGroup_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'allLogs' - enabled: true - } - ] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -211,13 +210,16 @@ type diagnosticSettingType = { @sys.description('Optional. The name of diagnostic setting.') name: string? - @sys.description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @sys.description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @sys.description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @sys.description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @sys.description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `AllLogs` to collect all logs.') categoryGroup: string? + + @sys.description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @sys.description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/desktop-virtualization/application-group/main.json b/avm/res/desktop-virtualization/application-group/main.json index 0cf33715fa..d2eeb102b7 100644 --- a/avm/res/desktop-virtualization/application-group/main.json +++ b/avm/res/desktop-virtualization/application-group/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "764353980319959043" + "version": "0.25.53.49325", + "templateHash": "16737123607848283739" }, "name": "Azure Virtual Desktop Application Group", "description": "This module deploys an Azure Virtual Desktop Application Group.", @@ -132,14 +132,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `AllLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -393,11 +400,21 @@ "scope": "[format('Microsoft.DesktopVirtualization/applicationGroups/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -442,8 +459,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5256311106319509279" + "version": "0.25.53.49325", + "templateHash": "1502648604355228279" }, "name": "Azure Virtual Desktop Application Group Application", "description": "This module deploys an Azure Virtual Desktop Application Group Application.", diff --git a/avm/res/desktop-virtualization/host-pool/README.md b/avm/res/desktop-virtualization/host-pool/README.md new file mode 100644 index 0000000000..3c31139d59 --- /dev/null +++ b/avm/res/desktop-virtualization/host-pool/README.md @@ -0,0 +1,1359 @@ +# Azure Virtual Desktop Host Pool `[Microsoft.DesktopVirtualization/hostPools]` + +This module deploys an Azure Virtual Desktop Host Pool + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.DesktopVirtualization/hostPools` | [2023-09-05](https://learn.microsoft.com/en-us/azure/templates/Microsoft.DesktopVirtualization/2023-09-05/hostPools) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/desktop-virtualization/host-pool:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [Using Private Endpoints](#example-3-using-private-endpoints) +- [WAF-aligned](#example-4-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep +module hostPool 'br/public:avm/res/desktop-virtualization/host-pool:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-dvhpmin' + params: { + // Required parameters + name: 'dvhpmin002' + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "dvhpmin002" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module hostPool 'br/public:avm/res/desktop-virtualization/host-pool:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-dvhpmax' + params: { + // Required parameters + name: 'dvhpmax001' + // Non-required parameters + agentUpdate: { + maintenanceWindows: [ + { + dayOfWeek: 'Friday' + hour: 7 + } + { + dayOfWeek: 'Saturday' + hour: 8 + } + ] + maintenanceWindowTimeZone: 'Alaskan Standard Time' + type: 'Scheduled' + useSessionHostLocalTime: false + } + customRdpProperty: 'audiocapturemode:i:1;audiomode:i:0;drivestoredirect:s:;redirectclipboard:i:1;redirectcomports:i:1;redirectprinters:i:1;redirectsmartcards:i:1;screen mode id:i:2;' + description: 'My first AVD Host Pool' + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + logCategoriesAndGroups: [ + { + categoryGroup: 'allLogs' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + enableTelemetry: true + friendlyName: 'AVDv2' + hostPoolType: 'Pooled' + loadBalancerType: 'BreadthFirst' + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + maxSessionLimit: 99999 + personalDesktopAssignmentType: 'Automatic' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + '' + ] + subnetResourceId: '' + } + ] + publicNetworkAccess: 'Disabled' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + vmTemplate: { + customImageId: '' + domain: 'domainname.onmicrosoft.com' + galleryImageOffer: 'office-365' + galleryImagePublisher: 'microsoftwindowsdesktop' + galleryImageSKU: '20h1-evd-o365pp' + imageType: 'Gallery' + imageUri: '' + namePrefix: 'avdv2' + osDiskType: 'StandardSSD_LRS' + useManagedDisks: true + vmSize: { + cores: 2 + id: 'Standard_D2s_v3' + ram: 8 + } + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "dvhpmax001" + }, + // Non-required parameters + "agentUpdate": { + "value": { + "maintenanceWindows": [ + { + "dayOfWeek": "Friday", + "hour": 7 + }, + { + "dayOfWeek": "Saturday", + "hour": 8 + } + ], + "maintenanceWindowTimeZone": "Alaskan Standard Time", + "type": "Scheduled", + "useSessionHostLocalTime": false + } + }, + "customRdpProperty": { + "value": "audiocapturemode:i:1;audiomode:i:0;drivestoredirect:s:;redirectclipboard:i:1;redirectcomports:i:1;redirectprinters:i:1;redirectsmartcards:i:1;screen mode id:i:2;" + }, + "description": { + "value": "My first AVD Host Pool" + }, + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "logCategoriesAndGroups": [ + { + "categoryGroup": "allLogs" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, + "enableTelemetry": { + "value": true + }, + "friendlyName": { + "value": "AVDv2" + }, + "hostPoolType": { + "value": "Pooled" + }, + "loadBalancerType": { + "value": "BreadthFirst" + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "maxSessionLimit": { + "value": 99999 + }, + "personalDesktopAssignmentType": { + "value": "Automatic" + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneResourceIds": [ + "" + ], + "subnetResourceId": "" + } + ] + }, + "publicNetworkAccess": { + "value": "Disabled" + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "vmTemplate": { + "value": { + "customImageId": "", + "domain": "domainname.onmicrosoft.com", + "galleryImageOffer": "office-365", + "galleryImagePublisher": "microsoftwindowsdesktop", + "galleryImageSKU": "20h1-evd-o365pp", + "imageType": "Gallery", + "imageUri": "", + "namePrefix": "avdv2", + "osDiskType": "StandardSSD_LRS", + "useManagedDisks": true, + "vmSize": { + "cores": 2, + "id": "Standard_D2s_v3", + "ram": 8 + } + } + } + } +} +``` + +
    +

    + +### Example 3: _Using Private Endpoints_ + +This instance deploys the module with Private Endpoints. + + +

    + +via Bicep module + +```bicep +module hostPool 'br/public:avm/res/desktop-virtualization/host-pool:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-dvhppe' + params: { + // Required parameters + name: 'dvhppe001' + // Non-required parameters + location: '' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + '' + ] + subnetResourceId: '' + } + ] + publicNetworkAccess: 'Disabled' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "dvhppe001" + }, + // Non-required parameters + "location": { + "value": "" + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneResourceIds": [ + "" + ], + "subnetResourceId": "" + } + ] + }, + "publicNetworkAccess": { + "value": "Disabled" + } + } +} +``` + +
    +

    + +### Example 4: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module hostPool 'br/public:avm/res/desktop-virtualization/host-pool:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-dvhpwaf' + params: { + // Required parameters + name: 'dvhpwaf002' + // Non-required parameters + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + location: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "dvhpwaf002" + }, + // Non-required parameters + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, + "location": { + "value": "" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | Name of the scaling plan. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`agentUpdate`](#parameter-agentupdate) | object | The session host configuration for updating agent, monitoring agent, and stack component. | +| [`customRdpProperty`](#parameter-customrdpproperty) | string | Host Pool RDP properties. | +| [`description`](#parameter-description) | string | Description of the scaling plan. | +| [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`friendlyName`](#parameter-friendlyname) | string | Friendly name of the scaling plan. | +| [`hostPoolType`](#parameter-hostpooltype) | string | Set this parameter to Personal if you would like to enable Persistent Desktop experience. Defaults to Pooled. | +| [`loadBalancerType`](#parameter-loadbalancertype) | string | Type of load balancer algorithm. | +| [`location`](#parameter-location) | string | Location of the scaling plan. Defaults to resource group location. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`maxSessionLimit`](#parameter-maxsessionlimit) | int | Maximum number of sessions. | +| [`personalDesktopAssignmentType`](#parameter-personaldesktopassignmenttype) | string | Set the type of assignment for a Personal Host Pool type. | +| [`preferredAppGroupType`](#parameter-preferredappgrouptype) | string | The type of preferred application group type, default to Desktop Application Group. | +| [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. | +| [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | Set public network access. | +| [`ring`](#parameter-ring) | int | The ring number of HostPool. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`ssoadfsAuthority`](#parameter-ssoadfsauthority) | string | URL to customer ADFS server for signing WVD SSO certificates. | +| [`ssoClientId`](#parameter-ssoclientid) | string | ClientId for the registered Relying Party used to issue WVD SSO certificates. | +| [`ssoClientSecretKeyVaultPath`](#parameter-ssoclientsecretkeyvaultpath) | string | Path to Azure KeyVault storing the secret used for communication to ADFS. | +| [`ssoSecretType`](#parameter-ssosecrettype) | string | The type of single sign on Secret Type. | +| [`startVMOnConnect`](#parameter-startvmonconnect) | bool | Enable Start VM on connect to allow users to start the virtual machine from a deallocated state. Important: Custom RBAC role required to power manage VMs. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`tokenValidityLength`](#parameter-tokenvaliditylength) | string | Host Pool token validity length. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the token will be valid for 8 hours. | +| [`validationEnvironment`](#parameter-validationenvironment) | bool | Validation host pools allows you to test service changes before they are deployed to production. When set to true, the Host Pool will be deployed in a validation 'ring' (environment) that receives all the new features (might be less stable). Defaults to false that stands for the stable, production-ready environment. | +| [`vmTemplate`](#parameter-vmtemplate) | object | The necessary information for adding more VMs to this Host Pool. | + +**Generated parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`baseTime`](#parameter-basetime) | string | Do not provide a value! This date value is used to generate a registration token. | + +### Parameter: `name` + +Name of the scaling plan. + +- Required: Yes +- Type: string + +### Parameter: `agentUpdate` + +The session host configuration for updating agent, monitoring agent, and stack component. + +- Required: No +- Type: object +- Default: + ```Bicep + { + useSessionHostLocalTime: true + } + ``` + +### Parameter: `customRdpProperty` + +Host Pool RDP properties. + +- Required: No +- Type: string +- Default: `'audiocapturemode:i:1;audiomode:i:0;drivestoredirect:s:;redirectclipboard:i:1;redirectcomports:i:1;redirectprinters:i:1;redirectsmartcards:i:1;screen mode id:i:2;'` + +### Parameter: `description` + +Description of the scaling plan. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `diagnosticSettings` + +The diagnostic settings of the service. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | +| [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | + +### Parameter: `diagnosticSettings.eventHubAuthorizationRuleResourceId` + +Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.eventHubName` + +Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logAnalyticsDestinationType` + +A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AzureDiagnostics' + 'Dedicated' + ] + ``` + +### Parameter: `diagnosticSettings.logCategoriesAndGroups` + +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + +### Parameter: `diagnosticSettings.marketplacePartnerResourceId` + +The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.name` + +The name of diagnostic setting. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.storageAccountResourceId` + +Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.workspaceResourceId` + +Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `friendlyName` + +Friendly name of the scaling plan. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `hostPoolType` + +Set this parameter to Personal if you would like to enable Persistent Desktop experience. Defaults to Pooled. + +- Required: No +- Type: string +- Default: `'Pooled'` +- Allowed: + ```Bicep + [ + 'Personal' + 'Pooled' + ] + ``` + +### Parameter: `loadBalancerType` + +Type of load balancer algorithm. + +- Required: No +- Type: string +- Default: `'BreadthFirst'` +- Allowed: + ```Bicep + [ + 'BreadthFirst' + 'DepthFirst' + 'Persistent' + ] + ``` + +### Parameter: `location` + +Location of the scaling plan. Defaults to resource group location. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `maxSessionLimit` + +Maximum number of sessions. + +- Required: No +- Type: int +- Default: `99999` + +### Parameter: `personalDesktopAssignmentType` + +Set the type of assignment for a Personal Host Pool type. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + 'Automatic' + 'Direct' + ] + ``` + +### Parameter: `preferredAppGroupType` + +The type of preferred application group type, default to Desktop Application Group. + +- Required: No +- Type: string +- Default: `'Desktop'` +- Allowed: + ```Bicep + [ + 'Desktop' + 'None' + 'RailApplications' + ] + ``` + +### Parameter: `privateEndpoints` + +Configuration details for private endpoints. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`subnetResourceId`](#parameter-privateendpointssubnetresourceid) | string | Resource ID of the subnet where the endpoint needs to be created. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | +| [`manualPrivateLinkServiceConnections`](#parameter-privateendpointsmanualprivatelinkserviceconnections) | array | Manual PrivateLink Service Connections. | +| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | +| [`privateDnsZoneGroupName`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. | +| [`privateDnsZoneResourceIds`](#parameter-privateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | +| [`service`](#parameter-privateendpointsservice) | string | The service (sub-) type to deploy the private endpoint for. For example "connection". | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | + +### Parameter: `privateEndpoints.subnetResourceId` + +Resource ID of the subnet where the endpoint needs to be created. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` + +Application security groups in which the private endpoint IP configuration is included. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.customDnsConfigs` + +Custom DNS configurations. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint IP address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private IP addresses of the private endpoint. + +- Required: Yes +- Type: array + +### Parameter: `privateEndpoints.customNetworkInterfaceName` + +The custom name of the network interface attached to the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool + +### Parameter: `privateEndpoints.ipConfigurations` + +A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.location` + +The location to deploy the private endpoint to. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.lock` + +Specify the type of lock. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-privateendpointslockkind) | string | Specify the type of lock. | +| [`name`](#parameter-privateendpointslockname) | string | Specify the name of lock. | + +### Parameter: `privateEndpoints.lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `privateEndpoints.lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.manualPrivateLinkServiceConnections` + +Manual PrivateLink Service Connections. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.name` + +The name of the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroupName` + +The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneResourceIds` + +The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-privateendpointsroleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-privateendpointsroleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-privateendpointsroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-privateendpointsroleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-privateendpointsroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-privateendpointsroleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-privateendpointsroleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `privateEndpoints.roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `privateEndpoints.roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `privateEndpoints.service` + +The service (sub-) type to deploy the private endpoint for. For example "connection". + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.tags` + +Tags to be applied on all resources/resource groups in this deployment. + +- Required: No +- Type: object + +### Parameter: `publicNetworkAccess` + +Set public network access. + +- Required: No +- Type: string +- Default: `'Enabled'` +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + 'EnabledForClientsOnly' + 'EnabledForSessionHostsOnly' + ] + ``` + +### Parameter: `ring` + +The ring number of HostPool. + +- Required: No +- Type: int +- Default: `-1` + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `ssoadfsAuthority` + +URL to customer ADFS server for signing WVD SSO certificates. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `ssoClientId` + +ClientId for the registered Relying Party used to issue WVD SSO certificates. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `ssoClientSecretKeyVaultPath` + +Path to Azure KeyVault storing the secret used for communication to ADFS. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `ssoSecretType` + +The type of single sign on Secret Type. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + 'Certificate' + 'CertificateInKeyVault' + 'SharedKey' + 'SharedKeyInKeyVault' + ] + ``` + +### Parameter: `startVMOnConnect` + +Enable Start VM on connect to allow users to start the virtual machine from a deallocated state. Important: Custom RBAC role required to power manage VMs. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `tokenValidityLength` + +Host Pool token validity length. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the token will be valid for 8 hours. + +- Required: No +- Type: string +- Default: `'PT8H'` + +### Parameter: `validationEnvironment` + +Validation host pools allows you to test service changes before they are deployed to production. When set to true, the Host Pool will be deployed in a validation 'ring' (environment) that receives all the new features (might be less stable). Defaults to false that stands for the stable, production-ready environment. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `vmTemplate` + +The necessary information for adding more VMs to this Host Pool. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `baseTime` + +Do not provide a value! This date value is used to generate a registration token. + +- Required: No +- Type: string +- Default: `[utcNow('u')]` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location of the host pool. | +| `name` | string | The name of the host pool. | +| `resourceGroupName` | string | The name of the resource group the host pool was created in. | +| `resourceId` | string | The resource ID of the host pool. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other CARML modules that are referenced in this module) and all remote-referenced files (i.e., Bicep modules that are referenced from a Bicep Registry or Template Specs). + +| Reference | Type | +| :-- | :-- | +| `br/public:avm-res-network-privateendpoint:0.1.1` | Remote reference | + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/desktop-virtualization/host-pool/main.bicep b/avm/res/desktop-virtualization/host-pool/main.bicep new file mode 100644 index 0000000000..9e4cb17472 --- /dev/null +++ b/avm/res/desktop-virtualization/host-pool/main.bicep @@ -0,0 +1,412 @@ +metadata name = 'Azure Virtual Desktop Host Pool' +metadata description = 'This module deploys an Azure Virtual Desktop Host Pool' +metadata owner = 'Azure/module-maintainers' + +@sys.description('Required. Name of the scaling plan.') +param name string + +@sys.description('Optional. Location of the scaling plan. Defaults to resource group location.') +param location string = resourceGroup().location + +@sys.description('Optional. Friendly name of the scaling plan.') +param friendlyName string = '' + +@sys.description('Optional. Description of the scaling plan.') +param description string = '' + +@sys.description('Optional. Set this parameter to Personal if you would like to enable Persistent Desktop experience. Defaults to Pooled.') +@allowed([ + 'Personal' + 'Pooled' +]) +param hostPoolType string = 'Pooled' + +@sys.description('Optional. Set public network access.') +@allowed([ + 'Disabled' + 'Enabled' + 'EnabledForClientsOnly' + 'EnabledForSessionHostsOnly' +]) +param publicNetworkAccess string = 'Enabled' + +@sys.description('Optional. Configuration details for private endpoints.') +param privateEndpoints privateEndpointType + +@sys.description('Optional. Set the type of assignment for a Personal Host Pool type.') +@allowed([ + 'Automatic' + 'Direct' + '' +]) +param personalDesktopAssignmentType string = '' + +@sys.description('Optional. Type of load balancer algorithm.') +@allowed([ + 'BreadthFirst' + 'DepthFirst' + 'Persistent' +]) +param loadBalancerType string = 'BreadthFirst' + +@sys.description('Optional. Maximum number of sessions.') +param maxSessionLimit int = 99999 + +@sys.description('Optional. Host Pool RDP properties.') +param customRdpProperty string = 'audiocapturemode:i:1;audiomode:i:0;drivestoredirect:s:;redirectclipboard:i:1;redirectcomports:i:1;redirectprinters:i:1;redirectsmartcards:i:1;screen mode id:i:2;' + +@sys.description('Optional. Validation host pools allows you to test service changes before they are deployed to production. When set to true, the Host Pool will be deployed in a validation \'ring\' (environment) that receives all the new features (might be less stable). Defaults to false that stands for the stable, production-ready environment.') +param validationEnvironment bool = false + +@sys.description('Optional. The necessary information for adding more VMs to this Host Pool.') +param vmTemplate object = {} + +@sys.description('Optional. Host Pool token validity length. Usage: \'PT8H\' - valid for 8 hours; \'P5D\' - valid for 5 days; \'P1Y\' - valid for 1 year. When not provided, the token will be valid for 8 hours.') +param tokenValidityLength string = 'PT8H' + +@sys.description('Generated. Do not provide a value! This date value is used to generate a registration token.') +param baseTime string = utcNow('u') + +@sys.description('Optional. The type of preferred application group type, default to Desktop Application Group.') +@allowed([ + 'Desktop' + 'None' + 'RailApplications' +]) +param preferredAppGroupType string = 'Desktop' + +@sys.description('Optional. Enable Start VM on connect to allow users to start the virtual machine from a deallocated state. Important: Custom RBAC role required to power manage VMs.') +param startVMOnConnect bool = false + +@sys.description('Optional. The session host configuration for updating agent, monitoring agent, and stack component.') +param agentUpdate object = { + useSessionHostLocalTime: true +} + +@sys.description('Optional. The ring number of HostPool.') +param ring int = -1 + +@sys.description('Optional. URL to customer ADFS server for signing WVD SSO certificates.') +param ssoadfsAuthority string = '' + +@sys.description('Optional. ClientId for the registered Relying Party used to issue WVD SSO certificates.') +param ssoClientId string = '' + +@sys.description('Optional. Path to Azure KeyVault storing the secret used for communication to ADFS.') +#disable-next-line secure-secrets-in-params +param ssoClientSecretKeyVaultPath string = '' + +@sys.description('Optional. The type of single sign on Secret Type.') +@allowed([ + '' + 'Certificate' + 'CertificateInKeyVault' + 'SharedKey' + 'SharedKeyInKeyVault' +]) +#disable-next-line secure-secrets-in-params +param ssoSecretType string = '' + +@sys.description('Optional. Tags of the resource.') +param tags object? + +@sys.description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@sys.description('Optional. The lock settings of the service.') +param lock lockType + +@sys.description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@sys.description('Optional. The diagnostic settings of the service.') +param diagnosticSettings diagnosticSettingType + +var builtInRoleNames = { + Owner: '/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635' + Contributor: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' + Reader: '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7' + 'Role Based Access Control Administrator (Preview)': '/providers/Microsoft.Authorization/roleDefinitions/f58310d9-a9f6-439a-9e8d-f62e7b41a168' + 'User Access Administrator': '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + 'Application Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ca6382a4-1721-4bcf-a114-ff0c70227b6b' + 'Desktop Virtualization Application Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/86240b0e-9422-4c43-887b-b61143f32ba8' + 'Desktop Virtualization Application Group Reader': '/providers/Microsoft.Authorization/roleDefinitions/aebf23d0-b568-4e86-b8f9-fe83a2c6ab55' + 'Desktop Virtualization Contributor': '/providers/Microsoft.Authorization/roleDefinitions/082f0a83-3be5-4ba1-904c-961cca79b387' + 'Desktop Virtualization Host Pool Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e307426c-f9b6-4e81-87de-d99efb3c32bc' + 'Desktop Virtualization Host Pool Reader': '/providers/Microsoft.Authorization/roleDefinitions/ceadfde2-b300-400a-ab7b-6143895aa822' + 'Desktop Virtualization Power On Off Contributor': '/providers/Microsoft.Authorization/roleDefinitions/40c5ff49-9181-41f8-ae61-143b0e78555e' + 'Desktop Virtualization Reader': '/providers/Microsoft.Authorization/roleDefinitions/49a72310-ab8d-41df-bbb0-79b649203868' + 'Desktop Virtualization Session Host Operator': '/providers/Microsoft.Authorization/roleDefinitions/2ad6aaab-ead9-4eaa-8ac5-da422f562408' + 'Desktop Virtualization User': '/providers/Microsoft.Authorization/roleDefinitions/1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63' + 'Desktop Virtualization User Session Operator': '/providers/Microsoft.Authorization/roleDefinitions/ea4bfff8-7fb4-485a-aadd-d4129a0ffaa6' + 'Desktop Virtualization Virtual Machine Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a959dbd1-f747-45e3-8ba6-dd80f235f97c' + 'Desktop Virtualization Workspace Contributor': '/providers/Microsoft.Authorization/roleDefinitions/21efdde3-836f-432b-bf3d-3e8e734d4b2b' + 'Desktop Virtualization Workspace Reader': '/providers/Microsoft.Authorization/roleDefinitions/0fa44ee9-7a7d-466b-9bb2-2bf446b1204d' + 'Managed Application Contributor Role': '/providers/Microsoft.Authorization/roleDefinitions/641177b8-a67a-45b9-a033-47bc880bb21e' + 'Managed Application Operator Role': '/providers/Microsoft.Authorization/roleDefinitions/c7393b34-138c-406f-901b-d8cf2b17e6ae' + 'Managed Applications Reader': '/providers/Microsoft.Authorization/roleDefinitions/b9331d33-8a36-4f8c-b097-4f54124fdb44' +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: take('46d3xbcp.res.desktopvirtualization-hostpool.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}', 64) + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource hostPool 'Microsoft.DesktopVirtualization/hostPools@2023-09-05' = { + name: name + location: location + tags: tags + properties: { + friendlyName: friendlyName + description: description + hostPoolType: hostPoolType + publicNetworkAccess: publicNetworkAccess + customRdpProperty: customRdpProperty + personalDesktopAssignmentType: any(personalDesktopAssignmentType) + preferredAppGroupType: preferredAppGroupType + maxSessionLimit: maxSessionLimit + loadBalancerType: loadBalancerType + startVMOnConnect: startVMOnConnect + validationEnvironment: validationEnvironment + registrationInfo: { + expirationTime: dateTimeAdd(baseTime, tokenValidityLength) + token: null + registrationTokenOperation: 'Update' + } + vmTemplate: ((!empty(vmTemplate)) ? null : string(vmTemplate)) + agentUpdate: agentUpdate + ring: ring != -1 ? ring : null + ssoadfsAuthority: ssoadfsAuthority + ssoClientId: ssoClientId + ssoClientSecretKeyVaultPath: ssoClientSecretKeyVaultPath + ssoSecretType: ssoSecretType + } +} + +module hostPool_privateEndpoints 'br/public:avm-res-network-privateendpoint:0.1.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-HostPool-PrivateEndpoint-${index}' + params: { + groupIds: [ + privateEndpoint.?service ?? 'connection' + ] + name: privateEndpoint.?name ?? 'pep-${last(split(hostPool.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' + serviceResourceId: hostPool.id + subnetResourceId: privateEndpoint.subnetResourceId + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + lock: privateEndpoint.?lock ?? lock + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } +}] + +resource hostPool_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: hostPool +} + +resource hostPool_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(hostPool.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: hostPool +}] + +resource hostPool_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [for (diagnosticSetting, index) in (diagnosticSettings ?? []): { + name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' + properties: { + storageAccountId: diagnosticSetting.?storageAccountResourceId + workspaceId: diagnosticSetting.?workspaceResourceId + eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId + eventHubName: diagnosticSetting.?eventHubName + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: hostPool +}] + +@sys.description('The resource ID of the host pool.') +output resourceId string = hostPool.id + +@sys.description('The name of the resource group the host pool was created in.') +output resourceGroupName string = resourceGroup().name + +@sys.description('The name of the host pool.') +output name string = hostPool.name + +@sys.description('The location of the host pool.') +output location string = hostPool.location + +// ================ // +// Definitions // +// ================ // + +type diagnosticSettingType = { + @sys.description('Optional. The name of diagnostic setting.') + name: string? + + @sys.description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') + logCategoriesAndGroups: { + @sys.description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') + category: string? + + @sys.description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') + categoryGroup: string? + + @sys.description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? + }[]? + + @sys.description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') + logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? + + @sys.description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + workspaceResourceId: string? + + @sys.description('Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + storageAccountResourceId: string? + + @sys.description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') + eventHubAuthorizationRuleResourceId: string? + + @sys.description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + eventHubName: string? + + @sys.description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') + marketplacePartnerResourceId: string? +}[]? + +type roleAssignmentType = { + @sys.description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @sys.description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @sys.description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @sys.description('Optional. The description of the role assignment.') + description: string? + + @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @sys.description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @sys.description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? + +type privateEndpointType = { + + @sys.description('Optional. The name of the private endpoint.') + name: string? + + @sys.description('Optional. The location to deploy the private endpoint to.') + location: string? + + @sys.description('Optional. The service (sub-) type to deploy the private endpoint for. For example "connection".') + service: string? + + @sys.description('Required. Resource ID of the subnet where the endpoint needs to be created.') + subnetResourceId: string + + @sys.description('Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided.') + privateDnsZoneGroupName: string? + + @sys.description('Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneResourceIds: string[]? + + @sys.description('Optional. Custom DNS configurations.') + customDnsConfigs: { + @sys.description('Required. Fqdn that resolves to private endpoint IP address.') + fqdn: string? + + @sys.description('Required. A list of private IP addresses of the private endpoint.') + ipAddresses: string[] + }[]? + + @sys.description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') + ipConfigurations: { + @sys.description('Required. The name of the resource that is unique within a resource group.') + name: string + + @sys.description('Required. Properties of private endpoint IP configurations.') + properties: { + @sys.description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') + groupId: string + + @sys.description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') + memberName: string + + @sys.description('Required. A private IP address obtained from the private endpoint\'s subnet.') + privateIPAddress: string + } + }[]? + + @sys.description('Optional. Application security groups in which the private endpoint IP configuration is included.') + applicationSecurityGroupResourceIds: string[]? + + @sys.description('Optional. The custom name of the network interface attached to the private endpoint.') + customNetworkInterfaceName: string? + + @sys.description('Optional. Specify the type of lock.') + lock: lockType + + @sys.description('Optional. Array of role assignments to create.') + roleAssignments: roleAssignmentType + + @sys.description('Optional. Tags to be applied on all resources/resource groups in this deployment.') + tags: object? + + @sys.description('Optional. Manual PrivateLink Service Connections.') + manualPrivateLinkServiceConnections: array? + + @sys.description('Optional. Enable/Disable usage telemetry for module.') + enableTelemetry: bool? +}[]? + +type lockType = { + @sys.description('Optional. Specify the name of lock.') + name: string? + + @sys.description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? diff --git a/avm/res/desktop-virtualization/host-pool/main.json b/avm/res/desktop-virtualization/host-pool/main.json new file mode 100644 index 0000000000..6719f26b5d --- /dev/null +++ b/avm/res/desktop-virtualization/host-pool/main.json @@ -0,0 +1,1312 @@ +{ + "$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.25.53.49325", + "templateHash": "4511420670498379838" + }, + "name": "Azure Virtual Desktop Host Pool", + "description": "This module deploys an Azure Virtual Desktop Host Pool", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The service (sub-) type to deploy the private endpoint for. For example \"connection\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the scaling plan." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location of the scaling plan. Defaults to resource group location." + } + }, + "friendlyName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Friendly name of the scaling plan." + } + }, + "description": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Description of the scaling plan." + } + }, + "hostPoolType": { + "type": "string", + "defaultValue": "Pooled", + "allowedValues": [ + "Personal", + "Pooled" + ], + "metadata": { + "description": "Optional. Set this parameter to Personal if you would like to enable Persistent Desktop experience. Defaults to Pooled." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Disabled", + "Enabled", + "EnabledForClientsOnly", + "EnabledForSessionHostsOnly" + ], + "metadata": { + "description": "Optional. Set public network access." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints." + } + }, + "personalDesktopAssignmentType": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "Automatic", + "Direct", + "" + ], + "metadata": { + "description": "Optional. Set the type of assignment for a Personal Host Pool type." + } + }, + "loadBalancerType": { + "type": "string", + "defaultValue": "BreadthFirst", + "allowedValues": [ + "BreadthFirst", + "DepthFirst", + "Persistent" + ], + "metadata": { + "description": "Optional. Type of load balancer algorithm." + } + }, + "maxSessionLimit": { + "type": "int", + "defaultValue": 99999, + "metadata": { + "description": "Optional. Maximum number of sessions." + } + }, + "customRdpProperty": { + "type": "string", + "defaultValue": "audiocapturemode:i:1;audiomode:i:0;drivestoredirect:s:;redirectclipboard:i:1;redirectcomports:i:1;redirectprinters:i:1;redirectsmartcards:i:1;screen mode id:i:2;", + "metadata": { + "description": "Optional. Host Pool RDP properties." + } + }, + "validationEnvironment": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Validation host pools allows you to test service changes before they are deployed to production. When set to true, the Host Pool will be deployed in a validation 'ring' (environment) that receives all the new features (might be less stable). Defaults to false that stands for the stable, production-ready environment." + } + }, + "vmTemplate": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. The necessary information for adding more VMs to this Host Pool." + } + }, + "tokenValidityLength": { + "type": "string", + "defaultValue": "PT8H", + "metadata": { + "description": "Optional. Host Pool token validity length. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the token will be valid for 8 hours." + } + }, + "baseTime": { + "type": "string", + "defaultValue": "[utcNow('u')]", + "metadata": { + "description": "Generated. Do not provide a value! This date value is used to generate a registration token." + } + }, + "preferredAppGroupType": { + "type": "string", + "defaultValue": "Desktop", + "allowedValues": [ + "Desktop", + "None", + "RailApplications" + ], + "metadata": { + "description": "Optional. The type of preferred application group type, default to Desktop Application Group." + } + }, + "startVMOnConnect": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable Start VM on connect to allow users to start the virtual machine from a deallocated state. Important: Custom RBAC role required to power manage VMs." + } + }, + "agentUpdate": { + "type": "object", + "defaultValue": { + "useSessionHostLocalTime": true + }, + "metadata": { + "description": "Optional. The session host configuration for updating agent, monitoring agent, and stack component." + } + }, + "ring": { + "type": "int", + "defaultValue": -1, + "metadata": { + "description": "Optional. The ring number of HostPool." + } + }, + "ssoadfsAuthority": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. URL to customer ADFS server for signing WVD SSO certificates." + } + }, + "ssoClientId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. ClientId for the registered Relying Party used to issue WVD SSO certificates." + } + }, + "ssoClientSecretKeyVaultPath": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Path to Azure KeyVault storing the secret used for communication to ADFS." + } + }, + "ssoSecretType": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "Certificate", + "CertificateInKeyVault", + "SharedKey", + "SharedKeyInKeyVault" + ], + "metadata": { + "description": "Optional. The type of single sign on Secret Type." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "builtInRoleNames": { + "Owner": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635", + "Contributor": "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c", + "Reader": "/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7", + "Role Based Access Control Administrator (Preview)": "/providers/Microsoft.Authorization/roleDefinitions/f58310d9-a9f6-439a-9e8d-f62e7b41a168", + "User Access Administrator": "/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9", + "Application Group Contributor": "/providers/Microsoft.Authorization/roleDefinitions/ca6382a4-1721-4bcf-a114-ff0c70227b6b", + "Desktop Virtualization Application Group Contributor": "/providers/Microsoft.Authorization/roleDefinitions/86240b0e-9422-4c43-887b-b61143f32ba8", + "Desktop Virtualization Application Group Reader": "/providers/Microsoft.Authorization/roleDefinitions/aebf23d0-b568-4e86-b8f9-fe83a2c6ab55", + "Desktop Virtualization Contributor": "/providers/Microsoft.Authorization/roleDefinitions/082f0a83-3be5-4ba1-904c-961cca79b387", + "Desktop Virtualization Host Pool Contributor": "/providers/Microsoft.Authorization/roleDefinitions/e307426c-f9b6-4e81-87de-d99efb3c32bc", + "Desktop Virtualization Host Pool Reader": "/providers/Microsoft.Authorization/roleDefinitions/ceadfde2-b300-400a-ab7b-6143895aa822", + "Desktop Virtualization Power On Off Contributor": "/providers/Microsoft.Authorization/roleDefinitions/40c5ff49-9181-41f8-ae61-143b0e78555e", + "Desktop Virtualization Reader": "/providers/Microsoft.Authorization/roleDefinitions/49a72310-ab8d-41df-bbb0-79b649203868", + "Desktop Virtualization Session Host Operator": "/providers/Microsoft.Authorization/roleDefinitions/2ad6aaab-ead9-4eaa-8ac5-da422f562408", + "Desktop Virtualization User": "/providers/Microsoft.Authorization/roleDefinitions/1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63", + "Desktop Virtualization User Session Operator": "/providers/Microsoft.Authorization/roleDefinitions/ea4bfff8-7fb4-485a-aadd-d4129a0ffaa6", + "Desktop Virtualization Virtual Machine Contributor": "/providers/Microsoft.Authorization/roleDefinitions/a959dbd1-f747-45e3-8ba6-dd80f235f97c", + "Desktop Virtualization Workspace Contributor": "/providers/Microsoft.Authorization/roleDefinitions/21efdde3-836f-432b-bf3d-3e8e734d4b2b", + "Desktop Virtualization Workspace Reader": "/providers/Microsoft.Authorization/roleDefinitions/0fa44ee9-7a7d-466b-9bb2-2bf446b1204d", + "Managed Application Contributor Role": "/providers/Microsoft.Authorization/roleDefinitions/641177b8-a67a-45b9-a033-47bc880bb21e", + "Managed Application Operator Role": "/providers/Microsoft.Authorization/roleDefinitions/c7393b34-138c-406f-901b-d8cf2b17e6ae", + "Managed Applications Reader": "/providers/Microsoft.Authorization/roleDefinitions/b9331d33-8a36-4f8c-b097-4f54124fdb44" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[take(format('46d3xbcp.res.desktopvirtualization-hostpool.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4)), 64)]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "hostPool": { + "type": "Microsoft.DesktopVirtualization/hostPools", + "apiVersion": "2023-09-05", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "friendlyName": "[parameters('friendlyName')]", + "description": "[parameters('description')]", + "hostPoolType": "[parameters('hostPoolType')]", + "publicNetworkAccess": "[parameters('publicNetworkAccess')]", + "customRdpProperty": "[parameters('customRdpProperty')]", + "personalDesktopAssignmentType": "[parameters('personalDesktopAssignmentType')]", + "preferredAppGroupType": "[parameters('preferredAppGroupType')]", + "maxSessionLimit": "[parameters('maxSessionLimit')]", + "loadBalancerType": "[parameters('loadBalancerType')]", + "startVMOnConnect": "[parameters('startVMOnConnect')]", + "validationEnvironment": "[parameters('validationEnvironment')]", + "registrationInfo": { + "expirationTime": "[dateTimeAdd(parameters('baseTime'), parameters('tokenValidityLength'))]", + "token": null, + "registrationTokenOperation": "Update" + }, + "vmTemplate": "[if(not(empty(parameters('vmTemplate'))), null(), string(parameters('vmTemplate')))]", + "agentUpdate": "[parameters('agentUpdate')]", + "ring": "[if(not(equals(parameters('ring'), -1)), parameters('ring'), null())]", + "ssoadfsAuthority": "[parameters('ssoadfsAuthority')]", + "ssoClientId": "[parameters('ssoClientId')]", + "ssoClientSecretKeyVaultPath": "[parameters('ssoClientSecretKeyVaultPath')]", + "ssoSecretType": "[parameters('ssoSecretType')]" + } + }, + "hostPool_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.DesktopVirtualization/hostPools/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "hostPool" + ] + }, + "hostPool_roleAssignments": { + "copy": { + "name": "hostPool_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.DesktopVirtualization/hostPools/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "hostPool" + ] + }, + "hostPool_diagnosticSettings": { + "copy": { + "name": "hostPool_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.DesktopVirtualization/hostPools/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "hostPool" + ] + }, + "hostPool_privateEndpoints": { + "copy": { + "name": "hostPool_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-HostPool-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "groupIds": { + "value": [ + "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'connection')]" + ] + }, + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'connection'), copyIndex()))]" + }, + "serviceResourceId": { + "value": "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('name'))]" + }, + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "manualPrivateLinkServiceConnections": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections')]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$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.21.1.54444", + "templateHash": "13152465847704433697" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "serviceResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the resource that needs to be connected to the network." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.1.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": [ + { + "name": "[parameters('name')]", + "properties": { + "privateLinkServiceId": "[parameters('serviceResourceId')]", + "groupIds": "[parameters('groupIds')]" + } + } + ], + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.21.1.54444", + "templateHash": "1698104586574073002" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "hostPool" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the host pool." + }, + "value": "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the host pool was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the host pool." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location of the host pool." + }, + "value": "[reference('hostPool', '2023-09-05', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/desktop-virtualization/host-pool/tests/e2e/defaults/main.test.bicep b/avm/res/desktop-virtualization/host-pool/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..d7a8cf3b7d --- /dev/null +++ b/avm/res/desktop-virtualization/host-pool/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,42 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-desktopvirtualization.hostpools-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'dvhpmin' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= + +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' + params: { + name: '${namePrefix}${serviceShort}002' + location: resourceLocation + } +} diff --git a/avm/res/desktop-virtualization/host-pool/tests/e2e/max/dependencies.bicep b/avm/res/desktop-virtualization/host-pool/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..ba30623a20 --- /dev/null +++ b/avm/res/desktop-virtualization/host-pool/tests/e2e/max/dependencies.bicep @@ -0,0 +1,60 @@ +@sys.description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +var addressPrefix = '10.0.0.0/16' + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.wvd.microsoft.com' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/res/desktop-virtualization/host-pool/tests/e2e/max/main.test.bicep b/avm/res/desktop-virtualization/host-pool/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..1150a73b43 --- /dev/null +++ b/avm/res/desktop-virtualization/host-pool/tests/e2e/max/main.test.bicep @@ -0,0 +1,156 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-desktopvirtualization.hostpools-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'dvhpmax' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= + +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + location: resourceLocation + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + } +} + +// Diagnostics +// =========== + +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}03' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' + params: { + name: '${namePrefix}${serviceShort}001' + customRdpProperty: 'audiocapturemode:i:1;audiomode:i:0;drivestoredirect:s:;redirectclipboard:i:1;redirectcomports:i:1;redirectprinters:i:1;redirectsmartcards:i:1;screen mode id:i:2;' + enableTelemetry: true + diagnosticSettings: [ + { + name: 'customSetting' + logCategoriesAndGroups: [ + { + categoryGroup: 'allLogs' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + description: 'My first AVD Host Pool' + friendlyName: 'AVDv2' + hostPoolType: 'Pooled' + publicNetworkAccess: 'Disabled' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + loadBalancerType: 'BreadthFirst' + location: resourceLocation + maxSessionLimit: 99999 + personalDesktopAssignmentType: 'Automatic' + vmTemplate: { + customImageId: null + domain: 'domainname.onmicrosoft.com' + galleryImageOffer: 'office-365' + galleryImagePublisher: 'microsoftwindowsdesktop' + galleryImageSKU: '20h1-evd-o365pp' + imageType: 'Gallery' + imageUri: null + namePrefix: 'avdv2' + osDiskType: 'StandardSSD_LRS' + useManagedDisks: true + vmSize: { + cores: 2 + id: 'Standard_D2s_v3' + ram: 8 + } + } + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + agentUpdate: { + type: 'Scheduled' + useSessionHostLocalTime: false + maintenanceWindowTimeZone: 'Alaskan Standard Time' + maintenanceWindows: [ + { + hour: 7 + dayOfWeek: 'Friday' + } + { + hour: 8 + dayOfWeek: 'Saturday' + } + ] + } + } +} diff --git a/avm/res/desktop-virtualization/host-pool/tests/e2e/private-endpoint/dependencies.bicep b/avm/res/desktop-virtualization/host-pool/tests/e2e/private-endpoint/dependencies.bicep new file mode 100644 index 0000000000..f18c0628e3 --- /dev/null +++ b/avm/res/desktop-virtualization/host-pool/tests/e2e/private-endpoint/dependencies.bicep @@ -0,0 +1,49 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.wvd.microsoft.com' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/avm/res/desktop-virtualization/host-pool/tests/e2e/private-endpoint/main.test.bicep b/avm/res/desktop-virtualization/host-pool/tests/e2e/private-endpoint/main.test.bicep new file mode 100644 index 0000000000..0cf73ba6a0 --- /dev/null +++ b/avm/res/desktop-virtualization/host-pool/tests/e2e/private-endpoint/main.test.bicep @@ -0,0 +1,61 @@ +targetScope = 'subscription' + +metadata name = 'Using Private Endpoints' +metadata description = 'This instance deploys the module with Private Endpoints.' + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-desktopvirtualization.hostpools-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'dvhppe' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= + +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + publicNetworkAccess: 'Disabled' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + } +}] diff --git a/avm/res/desktop-virtualization/host-pool/tests/e2e/waf-aligned/main.test.bicep b/avm/res/desktop-virtualization/host-pool/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..d77316a896 --- /dev/null +++ b/avm/res/desktop-virtualization/host-pool/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,70 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-desktopvirtualization.hostpools-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'dvhpwaf' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= + +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// Diagnostics +// =========== + +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}03' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' + params: { + name: '${namePrefix}${serviceShort}002' + location: resourceLocation + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +} diff --git a/avm/res/desktop-virtualization/host-pool/version.json b/avm/res/desktop-virtualization/host-pool/version.json new file mode 100644 index 0000000000..7245f14872 --- /dev/null +++ b/avm/res/desktop-virtualization/host-pool/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] + } \ No newline at end of file diff --git a/avm/res/desktop-virtualization/scaling-plan/README.md b/avm/res/desktop-virtualization/scaling-plan/README.md index e0c04279d8..856c5bc093 100644 --- a/avm/res/desktop-virtualization/scaling-plan/README.md +++ b/avm/res/desktop-virtualization/scaling-plan/README.md @@ -598,7 +598,7 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -634,11 +634,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `AllLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `AllLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. diff --git a/avm/res/desktop-virtualization/scaling-plan/main.bicep b/avm/res/desktop-virtualization/scaling-plan/main.bicep index ebd5c8a544..8f822e0e06 100644 --- a/avm/res/desktop-virtualization/scaling-plan/main.bicep +++ b/avm/res/desktop-virtualization/scaling-plan/main.bicep @@ -129,12 +129,11 @@ resource scalingPlan_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'allLogs' - enabled: true - } - ] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -192,13 +191,16 @@ type diagnosticSettingType = { @sys.description('Optional. The name of diagnostic setting.') name: string? - @sys.description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @sys.description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @sys.description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @sys.description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @sys.description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `AllLogs` to collect all logs.') categoryGroup: string? + + @sys.description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @sys.description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/desktop-virtualization/scaling-plan/main.json b/avm/res/desktop-virtualization/scaling-plan/main.json index 216ee620fd..f9f1af28c7 100644 --- a/avm/res/desktop-virtualization/scaling-plan/main.json +++ b/avm/res/desktop-virtualization/scaling-plan/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12587321174502367128" + "version": "0.25.53.49325", + "templateHash": "18153655960792051130" }, "name": "Azure Virtual Desktop Scaling Plan", "description": "This module deploys an Azure Virtual Desktop Scaling Plan.", @@ -132,14 +132,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `AllLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -395,11 +402,21 @@ "scope": "[format('Microsoft.DesktopVirtualization/scalingPlans/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, diff --git a/avm/res/desktop-virtualization/workspace/README.md b/avm/res/desktop-virtualization/workspace/README.md new file mode 100644 index 0000000000..398a16117c --- /dev/null +++ b/avm/res/desktop-virtualization/workspace/README.md @@ -0,0 +1,1333 @@ +# Workspace `[Microsoft.DesktopVirtualization/workspaces]` + +This module deploys an Azure Virtual Desktop Workspace. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.DesktopVirtualization/workspaces` | [2022-10-14-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.DesktopVirtualization/2022-10-14-preview/workspaces) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/desktop-virtualization/workspace:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [Using Private Endpoints](#example-3-using-private-endpoints) +- [WAF-aligned](#example-4-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep +module workspace 'br/public:avm/res/desktop-virtualization/workspace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-dvwsmin' + params: { + // Required parameters + name: 'dvwsmin002' + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "dvwsmin002" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module workspace 'br/public:avm/res/desktop-virtualization/workspace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-dvwsmax' + params: { + // Required parameters + name: 'dvwsmax001' + // Non-required parameters + applicationGroupReferences: [] + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + logCategoriesAndGroups: [ + { + categoryGroup: 'allLogs' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + friendlyName: 'AVD Workspace' + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + privateEndpoints: [ + { + customDnsConfigs: [] + ipConfigurations: [ + { + name: 'myIPconfig-feed1' + properties: { + groupId: 'feed' + memberName: 'web-r0' + privateIPAddress: '10.0.0.10' + } + } + { + name: 'myIPconfig-feed2' + properties: { + groupId: 'feed' + memberName: 'web-r1' + privateIPAddress: '10.0.0.13' + } + } + ] + privateDnsZoneResourceIds: [ + '' + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + service: 'feed' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + { + customDnsConfigs: [] + ipConfigurations: [ + { + name: 'myIPconfig-global' + properties: { + groupId: 'global' + memberName: 'web' + privateIPAddress: '10.0.0.11' + } + } + ] + privateDnsZoneResourceIds: [ + '' + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + service: 'global' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + publicNetworkAccess: 'Disabled' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "dvwsmax001" + }, + // Non-required parameters + "applicationGroupReferences": { + "value": [] + }, + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "logCategoriesAndGroups": [ + { + "categoryGroup": "allLogs" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, + "friendlyName": { + "value": "AVD Workspace" + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "privateEndpoints": { + "value": [ + { + "customDnsConfigs": [], + "ipConfigurations": [ + { + "name": "myIPconfig-feed1", + "properties": { + "groupId": "feed", + "memberName": "web-r0", + "privateIPAddress": "10.0.0.10" + } + }, + { + "name": "myIPconfig-feed2", + "properties": { + "groupId": "feed", + "memberName": "web-r1", + "privateIPAddress": "10.0.0.13" + } + } + ], + "privateDnsZoneResourceIds": [ + "" + ], + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ], + "service": "feed", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + { + "customDnsConfigs": [], + "ipConfigurations": [ + { + "name": "myIPconfig-global", + "properties": { + "groupId": "global", + "memberName": "web", + "privateIPAddress": "10.0.0.11" + } + } + ], + "privateDnsZoneResourceIds": [ + "" + ], + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ], + "service": "global", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "publicNetworkAccess": { + "value": "Disabled" + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + +### Example 3: _Using Private Endpoints_ + +This instance deploys the module with Private Endpoints. + + +

    + +via Bicep module + +```bicep +module workspace 'br/public:avm/res/desktop-virtualization/workspace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-dvwspe' + params: { + // Required parameters + name: 'dvwspe001' + // Non-required parameters + location: '' + privateEndpoints: [ + { + customDnsConfigs: [ + { + fqdn: 'abc.workspace.com' + ipAddresses: [ + '10.0.0.10' + '10.0.0.13' + ] + } + ] + ipConfigurations: [ + { + name: 'myIPconfig-feed1' + properties: { + groupId: 'feed' + memberName: 'web-r0' + privateIPAddress: '10.0.0.10' + } + } + { + name: 'myIPconfig-feed2' + properties: { + groupId: 'feed' + memberName: 'web-r1' + privateIPAddress: '10.0.0.13' + } + } + ] + privateDnsZoneResourceIds: [ + '' + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + service: 'feed' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + { + customDnsConfigs: [ + { + fqdn: 'abc.workspace.com' + ipAddresses: [ + '10.0.0.11' + ] + } + ] + ipConfigurations: [ + { + name: 'myIPconfig-global' + properties: { + groupId: 'global' + memberName: 'web' + privateIPAddress: '10.0.0.11' + } + } + ] + privateDnsZoneResourceIds: [ + '' + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + service: 'global' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + publicNetworkAccess: 'Disabled' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "dvwspe001" + }, + // Non-required parameters + "location": { + "value": "" + }, + "privateEndpoints": { + "value": [ + { + "customDnsConfigs": [ + { + "fqdn": "abc.workspace.com", + "ipAddresses": [ + "10.0.0.10", + "10.0.0.13" + ] + } + ], + "ipConfigurations": [ + { + "name": "myIPconfig-feed1", + "properties": { + "groupId": "feed", + "memberName": "web-r0", + "privateIPAddress": "10.0.0.10" + } + }, + { + "name": "myIPconfig-feed2", + "properties": { + "groupId": "feed", + "memberName": "web-r1", + "privateIPAddress": "10.0.0.13" + } + } + ], + "privateDnsZoneResourceIds": [ + "" + ], + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ], + "service": "feed", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + { + "customDnsConfigs": [ + { + "fqdn": "abc.workspace.com", + "ipAddresses": [ + "10.0.0.11" + ] + } + ], + "ipConfigurations": [ + { + "name": "myIPconfig-global", + "properties": { + "groupId": "global", + "memberName": "web", + "privateIPAddress": "10.0.0.11" + } + } + ], + "privateDnsZoneResourceIds": [ + "" + ], + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ], + "service": "global", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "publicNetworkAccess": { + "value": "Disabled" + } + } +} +``` + +
    +

    + +### Example 4: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module workspace 'br/public:avm/res/desktop-virtualization/workspace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-dvwswaf' + params: { + // Required parameters + name: 'dvwswaf002' + // Non-required parameters + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + location: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "dvwswaf002" + }, + // Non-required parameters + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, + "location": { + "value": "" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | Name of the workspace. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`applicationGroupReferences`](#parameter-applicationgroupreferences) | array | Array of application group references. | +| [`description`](#parameter-description) | string | Description of the workspace. | +| [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`friendlyName`](#parameter-friendlyname) | string | Friendly name of the workspace. | +| [`location`](#parameter-location) | string | Location for all resources. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. | +| [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | Public network access for the workspace. Enabled by default. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | + +### Parameter: `name` + +Name of the workspace. + +- Required: Yes +- Type: string + +### Parameter: `applicationGroupReferences` + +Array of application group references. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `description` + +Description of the workspace. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `diagnosticSettings` + +The diagnostic settings of the service. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | + +### Parameter: `diagnosticSettings.eventHubAuthorizationRuleResourceId` + +Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.eventHubName` + +Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logAnalyticsDestinationType` + +A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AzureDiagnostics' + 'Dedicated' + ] + ``` + +### Parameter: `diagnosticSettings.logCategoriesAndGroups` + +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.marketplacePartnerResourceId` + +The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.name` + +The name of diagnostic setting. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.storageAccountResourceId` + +Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.workspaceResourceId` + +Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `friendlyName` + +Friendly name of the workspace. + +- Required: No +- Type: string +- Default: `[parameters('name')]` + +### Parameter: `location` + +Location for all resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints` + +Configuration details for private endpoints. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`service`](#parameter-privateendpointsservice) | string | The service (sub-) type to deploy the private endpoint for. For example "feed" or "global". | +| [`subnetResourceId`](#parameter-privateendpointssubnetresourceid) | string | Resource ID of the subnet where the endpoint needs to be created. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | +| [`manualPrivateLinkServiceConnections`](#parameter-privateendpointsmanualprivatelinkserviceconnections) | array | Manual PrivateLink Service Connections. | +| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | +| [`privateDnsZoneGroupName`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. | +| [`privateDnsZoneResourceIds`](#parameter-privateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | + +### Parameter: `privateEndpoints.service` + +The service (sub-) type to deploy the private endpoint for. For example "feed" or "global". + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.subnetResourceId` + +Resource ID of the subnet where the endpoint needs to be created. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` + +Application security groups in which the private endpoint IP configuration is included. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.customDnsConfigs` + +Custom DNS configurations. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint IP address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private IP addresses of the private endpoint. + +- Required: Yes +- Type: array + +### Parameter: `privateEndpoints.customNetworkInterfaceName` + +The custom name of the network interface attached to the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool + +### Parameter: `privateEndpoints.ipConfigurations` + +A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.location` + +The location to deploy the private endpoint to. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.lock` + +Specify the type of lock. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-privateendpointslockkind) | string | Specify the type of lock. | +| [`name`](#parameter-privateendpointslockname) | string | Specify the name of lock. | + +### Parameter: `privateEndpoints.lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `privateEndpoints.lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.manualPrivateLinkServiceConnections` + +Manual PrivateLink Service Connections. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.name` + +The name of the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroupName` + +The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneResourceIds` + +The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-privateendpointsroleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-privateendpointsroleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-privateendpointsroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-privateendpointsroleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-privateendpointsroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-privateendpointsroleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-privateendpointsroleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `privateEndpoints.roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `privateEndpoints.roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `privateEndpoints.tags` + +Tags to be applied on all resources/resource groups in this deployment. + +- Required: No +- Type: object + +### Parameter: `publicNetworkAccess` + +Public network access for the workspace. Enabled by default. + +- Required: No +- Type: string +- Default: `'Enabled'` + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location of the workspace. | +| `name` | string | The name of the workspace. | +| `resourceGroupName` | string | The name of the resource group the workspace was created in. | +| `resourceId` | string | The resource ID of the workspace. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other CARML modules that are referenced in this module) and all remote-referenced files (i.e., Bicep modules that are referenced from a Bicep Registry or Template Specs). + +| Reference | Type | +| :-- | :-- | +| `br/public:avm-res-network-privateendpoint:0.1.1` | Remote reference | + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/desktop-virtualization/workspace/main.bicep b/avm/res/desktop-virtualization/workspace/main.bicep new file mode 100644 index 0000000000..76b833e555 --- /dev/null +++ b/avm/res/desktop-virtualization/workspace/main.bicep @@ -0,0 +1,304 @@ +metadata name = 'Workspace' +metadata description = 'This module deploys an Azure Virtual Desktop Workspace.' +metadata owner = 'Azure/module-maintainers' + +@sys.description('Required. Name of the workspace.') +param name string + +@sys.description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@sys.description('Optional. Tags of the resource.') +param tags object? + +@sys.description('Optional. Array of application group references.') +param applicationGroupReferences array = [] + +@sys.description('Optional. Description of the workspace.') +param description string = '' + +@sys.description('Optional. Friendly name of the workspace.') +param friendlyName string = name + +@sys.description('Optional. Public network access for the workspace. Enabled by default.') +param publicNetworkAccess string = 'Enabled' + +@sys.description('Optional. Configuration details for private endpoints.') +param privateEndpoints privateEndpointType + +@sys.description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@sys.description('Optional. The lock settings of the service.') +param lock lockType + +@sys.description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@sys.description('Optional. The diagnostic settings of the service.') +param diagnosticSettings diagnosticSettingType + +var builtInRoleNames = { + Owner: '/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635' + Contributor: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' + Reader: '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7' + 'Role Based Access Control Administrator (Preview)': '/providers/Microsoft.Authorization/roleDefinitions/f58310d9-a9f6-439a-9e8d-f62e7b41a168' + 'User Access Administrator': '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + 'Application Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ca6382a4-1721-4bcf-a114-ff0c70227b6b' + 'Desktop Virtualization Application Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/86240b0e-9422-4c43-887b-b61143f32ba8' + 'Desktop Virtualization Application Group Reader': '/providers/Microsoft.Authorization/roleDefinitions/aebf23d0-b568-4e86-b8f9-fe83a2c6ab55' + 'Desktop Virtualization Contributor': '/providers/Microsoft.Authorization/roleDefinitions/082f0a83-3be5-4ba1-904c-961cca79b387' + 'Desktop Virtualization Host Pool Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e307426c-f9b6-4e81-87de-d99efb3c32bc' + 'Desktop Virtualization Host Pool Reader': '/providers/Microsoft.Authorization/roleDefinitions/ceadfde2-b300-400a-ab7b-6143895aa822' + 'Desktop Virtualization Power On Off Contributor': '/providers/Microsoft.Authorization/roleDefinitions/40c5ff49-9181-41f8-ae61-143b0e78555e' + 'Desktop Virtualization Reader': '/providers/Microsoft.Authorization/roleDefinitions/49a72310-ab8d-41df-bbb0-79b649203868' + 'Desktop Virtualization Session Host Operator': '/providers/Microsoft.Authorization/roleDefinitions/2ad6aaab-ead9-4eaa-8ac5-da422f562408' + 'Desktop Virtualization User': '/providers/Microsoft.Authorization/roleDefinitions/1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63' + 'Desktop Virtualization User Session Operator': '/providers/Microsoft.Authorization/roleDefinitions/ea4bfff8-7fb4-485a-aadd-d4129a0ffaa6' + 'Desktop Virtualization Virtual Machine Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a959dbd1-f747-45e3-8ba6-dd80f235f97c' + 'Desktop Virtualization Workspace Contributor': '/providers/Microsoft.Authorization/roleDefinitions/21efdde3-836f-432b-bf3d-3e8e734d4b2b' + 'Desktop Virtualization Workspace Reader': '/providers/Microsoft.Authorization/roleDefinitions/0fa44ee9-7a7d-466b-9bb2-2bf446b1204d' +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: take('46d3xbcp.res.desktopvirtualization-workspace.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}', 64) + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource workspace 'Microsoft.DesktopVirtualization/workspaces@2022-10-14-preview' = { + name: name + location: location + tags: tags + properties: { + applicationGroupReferences: applicationGroupReferences + description: description + friendlyName: friendlyName + publicNetworkAccess: publicNetworkAccess + } +} + +module workspace_privateEndpoints 'br/public:avm-res-network-privateendpoint:0.1.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Workspace-PrivateEndpoint-${index}' + params: { + groupIds: [ + privateEndpoint.service + ] + name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.?service}-${index}' + serviceResourceId: workspace.id + subnetResourceId: privateEndpoint.subnetResourceId + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + lock: privateEndpoint.?lock ?? lock + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } +}] + +resource workspace_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: workspace +} + +resource workspace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(workspace.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: workspace +}] + +resource workspace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [for (diagnosticSetting, index) in (diagnosticSettings ?? []): { + name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' + properties: { + storageAccountId: diagnosticSetting.?storageAccountResourceId + workspaceId: diagnosticSetting.?workspaceResourceId + eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId + eventHubName: diagnosticSetting.?eventHubName + logs: diagnosticSetting.?logCategoriesAndGroups ?? [ + { + categoryGroup: 'allLogs' + enabled: true + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: workspace +}] + +@sys.description('The resource ID of the workspace.') +output resourceId string = workspace.id + +@sys.description('The name of the resource group the workspace was created in.') +output resourceGroupName string = resourceGroup().name + +@sys.description('The name of the workspace.') +output name string = workspace.name + +@sys.description('The location of the workspace.') +output location string = workspace.location + +// ================ // +// Definitions // +// ================ // + +type diagnosticSettingType = { + @sys.description('Optional. The name of diagnostic setting.') + name: string? + + @sys.description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + logCategoriesAndGroups: { + @sys.description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') + category: string? + + @sys.description('Optional. Name of a Diagnostic Log group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') + categoryGroup: string? + }[]? + + @sys.description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') + logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics' | null)? + + @sys.description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + workspaceResourceId: string? + + @sys.description('Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + storageAccountResourceId: string? + + @sys.description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') + eventHubAuthorizationRuleResourceId: string? + + @sys.description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + eventHubName: string? + + @sys.description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') + marketplacePartnerResourceId: string? +}[]? + +type roleAssignmentType = { + @sys.description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @sys.description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @sys.description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @sys.description('Optional. The description of the role assignment.') + description: string? + + @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @sys.description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @sys.description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? + +type privateEndpointType = { + + @sys.description('Optional. The name of the private endpoint.') + name: string? + + @sys.description('Optional. The location to deploy the private endpoint to.') + location: string? + + @sys.description('Required. The service (sub-) type to deploy the private endpoint for. For example "feed" or "global".') + service: string + + @sys.description('Required. Resource ID of the subnet where the endpoint needs to be created.') + subnetResourceId: string + + @sys.description('Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided.') + privateDnsZoneGroupName: string? + + @sys.description('Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneResourceIds: string[]? + + @sys.description('Optional. Custom DNS configurations.') + customDnsConfigs: { + @sys.description('Required. Fqdn that resolves to private endpoint IP address.') + fqdn: string? + + @sys.description('Required. A list of private IP addresses of the private endpoint.') + ipAddresses: string[] + }[]? + + @sys.description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') + ipConfigurations: { + @sys.description('Required. The name of the resource that is unique within a resource group.') + name: string + + @sys.description('Required. Properties of private endpoint IP configurations.') + properties: { + @sys.description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') + groupId: string + + @sys.description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') + memberName: string + + @sys.description('Required. A private IP address obtained from the private endpoint\'s subnet.') + privateIPAddress: string + } + }[]? + + @sys.description('Optional. Application security groups in which the private endpoint IP configuration is included.') + applicationSecurityGroupResourceIds: string[]? + + @sys.description('Optional. The custom name of the network interface attached to the private endpoint.') + customNetworkInterfaceName: string? + + @sys.description('Optional. Specify the type of lock.') + lock: lockType + + @sys.description('Optional. Array of role assignments to create.') + roleAssignments: roleAssignmentType + + @sys.description('Optional. Tags to be applied on all resources/resource groups in this deployment.') + tags: object? + + @sys.description('Optional. Manual PrivateLink Service Connections.') + manualPrivateLinkServiceConnections: array? + + @sys.description('Optional. Enable/Disable usage telemetry for module.') + enableTelemetry: bool? +}[]? + +type lockType = { + @sys.description('Optional. Specify the name of lock.') + name: string? + + @sys.description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? diff --git a/avm/res/desktop-virtualization/workspace/main.json b/avm/res/desktop-virtualization/workspace/main.json new file mode 100644 index 0000000000..ac075c7a41 --- /dev/null +++ b/avm/res/desktop-virtualization/workspace/main.json @@ -0,0 +1,1126 @@ +{ + "$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.25.53.49325", + "templateHash": "4530090726614666900" + }, + "name": "Workspace", + "description": "This module deploys an Azure Virtual Desktop Workspace.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "service": { + "type": "string", + "metadata": { + "description": "Required. The service (sub-) type to deploy the private endpoint for. For example \"feed\" or \"global\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the workspace." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "applicationGroupReferences": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Array of application group references." + } + }, + "description": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Description of the workspace." + } + }, + "friendlyName": { + "type": "string", + "defaultValue": "[parameters('name')]", + "metadata": { + "description": "Optional. Friendly name of the workspace." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "metadata": { + "description": "Optional. Public network access for the workspace. Enabled by default." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "builtInRoleNames": { + "Owner": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635", + "Contributor": "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c", + "Reader": "/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7", + "Role Based Access Control Administrator (Preview)": "/providers/Microsoft.Authorization/roleDefinitions/f58310d9-a9f6-439a-9e8d-f62e7b41a168", + "User Access Administrator": "/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9", + "Application Group Contributor": "/providers/Microsoft.Authorization/roleDefinitions/ca6382a4-1721-4bcf-a114-ff0c70227b6b", + "Desktop Virtualization Application Group Contributor": "/providers/Microsoft.Authorization/roleDefinitions/86240b0e-9422-4c43-887b-b61143f32ba8", + "Desktop Virtualization Application Group Reader": "/providers/Microsoft.Authorization/roleDefinitions/aebf23d0-b568-4e86-b8f9-fe83a2c6ab55", + "Desktop Virtualization Contributor": "/providers/Microsoft.Authorization/roleDefinitions/082f0a83-3be5-4ba1-904c-961cca79b387", + "Desktop Virtualization Host Pool Contributor": "/providers/Microsoft.Authorization/roleDefinitions/e307426c-f9b6-4e81-87de-d99efb3c32bc", + "Desktop Virtualization Host Pool Reader": "/providers/Microsoft.Authorization/roleDefinitions/ceadfde2-b300-400a-ab7b-6143895aa822", + "Desktop Virtualization Power On Off Contributor": "/providers/Microsoft.Authorization/roleDefinitions/40c5ff49-9181-41f8-ae61-143b0e78555e", + "Desktop Virtualization Reader": "/providers/Microsoft.Authorization/roleDefinitions/49a72310-ab8d-41df-bbb0-79b649203868", + "Desktop Virtualization Session Host Operator": "/providers/Microsoft.Authorization/roleDefinitions/2ad6aaab-ead9-4eaa-8ac5-da422f562408", + "Desktop Virtualization User": "/providers/Microsoft.Authorization/roleDefinitions/1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63", + "Desktop Virtualization User Session Operator": "/providers/Microsoft.Authorization/roleDefinitions/ea4bfff8-7fb4-485a-aadd-d4129a0ffaa6", + "Desktop Virtualization Virtual Machine Contributor": "/providers/Microsoft.Authorization/roleDefinitions/a959dbd1-f747-45e3-8ba6-dd80f235f97c", + "Desktop Virtualization Workspace Contributor": "/providers/Microsoft.Authorization/roleDefinitions/21efdde3-836f-432b-bf3d-3e8e734d4b2b", + "Desktop Virtualization Workspace Reader": "/providers/Microsoft.Authorization/roleDefinitions/0fa44ee9-7a7d-466b-9bb2-2bf446b1204d" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[take(format('46d3xbcp.res.desktopvirtualization-workspace.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4)), 64)]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "workspace": { + "type": "Microsoft.DesktopVirtualization/workspaces", + "apiVersion": "2022-10-14-preview", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "applicationGroupReferences": "[parameters('applicationGroupReferences')]", + "description": "[parameters('description')]", + "friendlyName": "[parameters('friendlyName')]", + "publicNetworkAccess": "[parameters('publicNetworkAccess')]" + } + }, + "workspace_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.DesktopVirtualization/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_roleAssignments": { + "copy": { + "name": "workspace_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.DesktopVirtualization/workspaces/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.DesktopVirtualization/workspaces', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_diagnosticSettings": { + "copy": { + "name": "workspace_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.DesktopVirtualization/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())))]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_privateEndpoints": { + "copy": { + "name": "workspace_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Workspace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "groupIds": { + "value": [ + "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service]" + ] + }, + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.DesktopVirtualization/workspaces', parameters('name')), '/')), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), copyIndex()))]" + }, + "serviceResourceId": { + "value": "[resourceId('Microsoft.DesktopVirtualization/workspaces', parameters('name'))]" + }, + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "manualPrivateLinkServiceConnections": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections')]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$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.21.1.54444", + "templateHash": "13152465847704433697" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "serviceResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the resource that needs to be connected to the network." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.1.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": [ + { + "name": "[parameters('name')]", + "properties": { + "privateLinkServiceId": "[parameters('serviceResourceId')]", + "groupIds": "[parameters('groupIds')]" + } + } + ], + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.21.1.54444", + "templateHash": "1698104586574073002" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "workspace" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the workspace." + }, + "value": "[resourceId('Microsoft.DesktopVirtualization/workspaces', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the workspace was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the workspace." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location of the workspace." + }, + "value": "[reference('workspace', '2022-10-14-preview', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/desktop-virtualization/workspace/tests/e2e/defaults/main.test.bicep b/avm/res/desktop-virtualization/workspace/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..4fe2615c0e --- /dev/null +++ b/avm/res/desktop-virtualization/workspace/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,43 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-desktopvirtualization.workspace-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'dvwsmin' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= + +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}002' + location: resourceLocation + } +}] diff --git a/avm/res/desktop-virtualization/workspace/tests/e2e/max/dependencies.bicep b/avm/res/desktop-virtualization/workspace/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..41441e38a7 --- /dev/null +++ b/avm/res/desktop-virtualization/workspace/tests/e2e/max/dependencies.bicep @@ -0,0 +1,60 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.wvd.microsoft.com' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/res/desktop-virtualization/workspace/tests/e2e/max/main.test.bicep b/avm/res/desktop-virtualization/workspace/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..5cb9db486c --- /dev/null +++ b/avm/res/desktop-virtualization/workspace/tests/e2e/max/main.test.bicep @@ -0,0 +1,181 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-desktopvirtualization.workspace-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'dvwsmax' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= + +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + location: resourceLocation + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + } +} + +// Diagnostics +// =========== + +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-diagnosticDependencies' + params: { + storageAccountName: substring('dep${uniqueString(deployment().name, resourceLocation)}${serviceShort}03', 0, 24) + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + applicationGroupReferences: [] + friendlyName: 'AVD Workspace' + publicNetworkAccess: 'Disabled' + diagnosticSettings: [ + { + name: 'customSetting' + logCategoriesAndGroups: [ + { + categoryGroup: 'allLogs' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + privateEndpoints: [ + { + service: 'feed' + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + ipConfigurations: [ + { + name: 'myIPconfig-feed1' + properties: { + groupId: 'feed' + memberName: 'web-r0' + privateIPAddress: '10.0.0.10' + } + } + { + name: 'myIPconfig-feed2' + properties: { + groupId: 'feed' + memberName: 'web-r1' + privateIPAddress: '10.0.0.13' + } + } + ] + customDnsConfigs: [] + } + { + service: 'global' + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + ipConfigurations: [ + { + name: 'myIPconfig-global' + properties: { + groupId: 'global' + memberName: 'web' + privateIPAddress: '10.0.0.11' + } + } + ] + customDnsConfigs: [] + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + } +}] diff --git a/avm/res/desktop-virtualization/workspace/tests/e2e/private-endpoint/dependencies.bicep b/avm/res/desktop-virtualization/workspace/tests/e2e/private-endpoint/dependencies.bicep new file mode 100644 index 0000000000..2e1877ac5d --- /dev/null +++ b/avm/res/desktop-virtualization/workspace/tests/e2e/private-endpoint/dependencies.bicep @@ -0,0 +1,59 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +var addressPrefix = '10.0.0.0/16' + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.wvd.microsoft.com' + location: 'global' + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/res/desktop-virtualization/workspace/tests/e2e/private-endpoint/main.test.bicep b/avm/res/desktop-virtualization/workspace/tests/e2e/private-endpoint/main.test.bicep new file mode 100644 index 0000000000..2bef56353d --- /dev/null +++ b/avm/res/desktop-virtualization/workspace/tests/e2e/private-endpoint/main.test.bicep @@ -0,0 +1,139 @@ +targetScope = 'subscription' + +metadata name = 'Using Private Endpoints' +metadata description = 'This instance deploys the module with Private Endpoints.' + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-desktopvirtualization.workspace-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'dvwspe' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= + +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + location: resourceLocation + managedIdentityName: 'dvwspe-managedidentity' + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + publicNetworkAccess: 'Disabled' + privateEndpoints: [ + { + service: 'feed' + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + ipConfigurations: [ + { + name: 'myIPconfig-feed1' + properties: { + groupId: 'feed' + memberName: 'web-r0' + privateIPAddress: '10.0.0.10' + } + } + { + name: 'myIPconfig-feed2' + properties: { + groupId: 'feed' + memberName: 'web-r1' + privateIPAddress: '10.0.0.13' + } + } + ] + customDnsConfigs: [ + { + fqdn: 'abc.workspace.com' + ipAddresses: [ + '10.0.0.10' + '10.0.0.13' + ] + } + ] + } + { + service: 'global' + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + ipConfigurations: [ + { + name: 'myIPconfig-global' + properties: { + groupId: 'global' + memberName: 'web' + privateIPAddress: '10.0.0.11' + } + } + ] + customDnsConfigs: [ + { + fqdn: 'abc.workspace.com' + ipAddresses: [ + '10.0.0.11' + ] + } + ] + } + ] + } +}] diff --git a/avm/res/desktop-virtualization/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/desktop-virtualization/workspace/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..6650e01b10 --- /dev/null +++ b/avm/res/desktop-virtualization/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,71 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Well-Architected Framework.' + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-desktopvirtualization.workspace-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'dvwswaf' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= + +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// Diagnostics +// =========== + +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-diagnosticDependencies' + params: { + storageAccountName: substring('dep${uniqueString(deployment().name, resourceLocation)}${serviceShort}03', 0, 24) + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}002' + location: resourceLocation + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/desktop-virtualization/workspace/version.json b/avm/res/desktop-virtualization/workspace/version.json new file mode 100644 index 0000000000..7245f14872 --- /dev/null +++ b/avm/res/desktop-virtualization/workspace/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] + } \ No newline at end of file diff --git a/avm/res/document-db/database-account/ORPHANED.md b/avm/res/document-db/database-account/ORPHANED.md deleted file mode 100644 index ef8fa911d2..0000000000 --- a/avm/res/document-db/database-account/ORPHANED.md +++ /dev/null @@ -1,4 +0,0 @@ -⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ - -- Only security and bug fixes are being handled by the AVM core team at present. -- If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! \ No newline at end of file diff --git a/avm/res/document-db/database-account/README.md b/avm/res/document-db/database-account/README.md index 4b0477997d..beb99218f9 100644 --- a/avm/res/document-db/database-account/README.md +++ b/avm/res/document-db/database-account/README.md @@ -1,10 +1,5 @@ # DocumentDB Database Accounts `[Microsoft.DocumentDB/databaseAccounts]` -> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ -> -> - Only security and bug fixes are being handled by the AVM core team at present. -> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! - This module deploys a DocumentDB Database Account. ## Navigation @@ -1788,9 +1783,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1825,11 +1820,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1839,11 +1863,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -2045,6 +2095,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -2066,6 +2137,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/document-db/database-account/gremlin-database/graph/main.json b/avm/res/document-db/database-account/gremlin-database/graph/main.json index 1483098c2e..531189986d 100644 --- a/avm/res/document-db/database-account/gremlin-database/graph/main.json +++ b/avm/res/document-db/database-account/gremlin-database/graph/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14243370867444327055" + "version": "0.25.53.49325", + "templateHash": "4078462189838201163" }, "name": "DocumentDB Database Accounts Gremlin Databases Graphs", "description": "This module deploys a DocumentDB Database Accounts Gremlin Database Graph.", diff --git a/avm/res/document-db/database-account/gremlin-database/main.json b/avm/res/document-db/database-account/gremlin-database/main.json index e64ef29612..1ff6b48baa 100644 --- a/avm/res/document-db/database-account/gremlin-database/main.json +++ b/avm/res/document-db/database-account/gremlin-database/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2617432375264179405" + "version": "0.25.53.49325", + "templateHash": "5227237801347888732" }, "name": "DocumentDB Database Account Gremlin Databases", "description": "This module deploys a Gremlin Database within a CosmosDB Account.", @@ -109,8 +109,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14243370867444327055" + "version": "0.25.53.49325", + "templateHash": "4078462189838201163" }, "name": "DocumentDB Database Accounts Gremlin Databases Graphs", "description": "This module deploys a DocumentDB Database Accounts Gremlin Database Graph.", diff --git a/avm/res/document-db/database-account/main.bicep b/avm/res/document-db/database-account/main.bicep index a978785d22..e472d947fc 100644 --- a/avm/res/document-db/database-account/main.bicep +++ b/avm/res/document-db/database-account/main.bicep @@ -253,19 +253,16 @@ resource databaseAccount_diagnosticSettings 'Microsoft.Insights/diagnosticSettin workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -481,19 +478,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/document-db/database-account/main.json b/avm/res/document-db/database-account/main.json index 5fa57ee291..454bcda8db 100644 --- a/avm/res/document-db/database-account/main.json +++ b/avm/res/document-db/database-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1861152987880656619" + "version": "0.25.53.49325", + "templateHash": "14608365683973460476" }, "name": "DocumentDB Database Accounts", "description": "This module deploys a DocumentDB Database Account.", @@ -329,14 +329,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -347,14 +354,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -741,12 +755,30 @@ "scope": "[format('Microsoft.DocumentDB/databaseAccounts/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -809,8 +841,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6855947757310197808" + "version": "0.25.53.49325", + "templateHash": "3371007626132936503" }, "name": "DocumentDB Database Account SQL Databases", "description": "This module deploys a SQL Database in a CosmosDB Account.", @@ -924,8 +956,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6680377134811820539" + "version": "0.25.53.49325", + "templateHash": "15407611441750959399" }, "name": "DocumentDB Database Account SQL Database Containers", "description": "This module deploys a SQL Database Container in a CosmosDB Account.", @@ -1164,8 +1196,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5366984101532329712" + "version": "0.25.53.49325", + "templateHash": "5538920636867167805" }, "name": "DocumentDB Database Account MongoDB Databases", "description": "This module deploys a MongoDB Database within a CosmosDB Account.", @@ -1267,8 +1299,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10065636031063619686" + "version": "0.25.53.49325", + "templateHash": "12727124123085683569" }, "name": "DocumentDB Database Account MongoDB Database Collections", "description": "This module deploys a MongoDB Database Collection.", @@ -1423,8 +1455,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2617432375264179405" + "version": "0.25.53.49325", + "templateHash": "5227237801347888732" }, "name": "DocumentDB Database Account Gremlin Databases", "description": "This module deploys a Gremlin Database within a CosmosDB Account.", @@ -1527,8 +1559,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14243370867444327055" + "version": "0.25.53.49325", + "templateHash": "4078462189838201163" }, "name": "DocumentDB Database Accounts Gremlin Databases Graphs", "description": "This module deploys a DocumentDB Database Accounts Gremlin Database Graph.", diff --git a/avm/res/document-db/database-account/mongodb-database/collection/main.json b/avm/res/document-db/database-account/mongodb-database/collection/main.json index 10a7d6e4ca..925b996e85 100644 --- a/avm/res/document-db/database-account/mongodb-database/collection/main.json +++ b/avm/res/document-db/database-account/mongodb-database/collection/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10065636031063619686" + "version": "0.25.53.49325", + "templateHash": "12727124123085683569" }, "name": "DocumentDB Database Account MongoDB Database Collections", "description": "This module deploys a MongoDB Database Collection.", diff --git a/avm/res/document-db/database-account/mongodb-database/main.json b/avm/res/document-db/database-account/mongodb-database/main.json index 8a15ed3962..549aa6394d 100644 --- a/avm/res/document-db/database-account/mongodb-database/main.json +++ b/avm/res/document-db/database-account/mongodb-database/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5366984101532329712" + "version": "0.25.53.49325", + "templateHash": "5538920636867167805" }, "name": "DocumentDB Database Account MongoDB Databases", "description": "This module deploys a MongoDB Database within a CosmosDB Account.", @@ -108,8 +108,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10065636031063619686" + "version": "0.25.53.49325", + "templateHash": "12727124123085683569" }, "name": "DocumentDB Database Account MongoDB Database Collections", "description": "This module deploys a MongoDB Database Collection.", diff --git a/avm/res/document-db/database-account/sql-database/container/main.json b/avm/res/document-db/database-account/sql-database/container/main.json index 2714d00e36..18ea3e8513 100644 --- a/avm/res/document-db/database-account/sql-database/container/main.json +++ b/avm/res/document-db/database-account/sql-database/container/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6680377134811820539" + "version": "0.25.53.49325", + "templateHash": "15407611441750959399" }, "name": "DocumentDB Database Account SQL Database Containers", "description": "This module deploys a SQL Database Container in a CosmosDB Account.", diff --git a/avm/res/document-db/database-account/sql-database/main.json b/avm/res/document-db/database-account/sql-database/main.json index 0d5900963a..e57bc190b0 100644 --- a/avm/res/document-db/database-account/sql-database/main.json +++ b/avm/res/document-db/database-account/sql-database/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6855947757310197808" + "version": "0.25.53.49325", + "templateHash": "3371007626132936503" }, "name": "DocumentDB Database Account SQL Databases", "description": "This module deploys a SQL Database in a CosmosDB Account.", @@ -120,8 +120,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6680377134811820539" + "version": "0.25.53.49325", + "templateHash": "15407611441750959399" }, "name": "DocumentDB Database Account SQL Database Containers", "description": "This module deploys a SQL Database Container in a CosmosDB Account.", diff --git a/avm/res/event-grid/domain/README.md b/avm/res/event-grid/domain/README.md index e70962e416..10afb3de29 100644 --- a/avm/res/event-grid/domain/README.md +++ b/avm/res/event-grid/domain/README.md @@ -567,9 +567,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -604,11 +604,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -618,11 +647,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -793,6 +848,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -814,6 +890,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/event-grid/domain/main.bicep b/avm/res/event-grid/domain/main.bicep index bbf28cf7bb..7cf3d9fa9e 100644 --- a/avm/res/event-grid/domain/main.bicep +++ b/avm/res/event-grid/domain/main.bicep @@ -127,19 +127,16 @@ resource domain_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-0 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -314,19 +311,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/event-grid/domain/main.json b/avm/res/event-grid/domain/main.json index a7a735774e..6c5b06c183 100644 --- a/avm/res/event-grid/domain/main.json +++ b/avm/res/event-grid/domain/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1330606995473778125" + "version": "0.25.53.49325", + "templateHash": "13095982235255644248" }, "name": "Event Grid Domains", "description": "This module deploys an Event Grid Domain.", @@ -330,14 +330,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -348,14 +355,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -590,12 +604,30 @@ "scope": "[format('Microsoft.EventGrid/domains/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -652,8 +684,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2298883170481877104" + "version": "0.25.53.49325", + "templateHash": "3346602576302560002" }, "name": "Event Grid Domain Topics", "description": "This module deploys an Event Grid Domain Topic.", diff --git a/avm/res/event-grid/domain/topic/main.json b/avm/res/event-grid/domain/topic/main.json index ed4d0c4403..2d26a76f82 100644 --- a/avm/res/event-grid/domain/topic/main.json +++ b/avm/res/event-grid/domain/topic/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2298883170481877104" + "version": "0.25.53.49325", + "templateHash": "3346602576302560002" }, "name": "Event Grid Domain Topics", "description": "This module deploys an Event Grid Domain Topic.", diff --git a/avm/res/event-grid/system-topic/README.md b/avm/res/event-grid/system-topic/README.md index e1b5fd1989..fb69e0682d 100644 --- a/avm/res/event-grid/system-topic/README.md +++ b/avm/res/event-grid/system-topic/README.md @@ -504,9 +504,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -541,11 +541,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -555,11 +584,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/event-grid/system-topic/event-subscription/main.json b/avm/res/event-grid/system-topic/event-subscription/main.json index f234fce047..bd8f0faa07 100644 --- a/avm/res/event-grid/system-topic/event-subscription/main.json +++ b/avm/res/event-grid/system-topic/event-subscription/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17973992796962490837" + "version": "0.25.53.49325", + "templateHash": "5245070501778317327" }, "name": "Event Grid System Topic Event Subscriptions", "description": "This module deploys an Event Grid System Topic Event Subscription.", diff --git a/avm/res/event-grid/system-topic/main.bicep b/avm/res/event-grid/system-topic/main.bicep index 44d2a06045..4224e2fb28 100644 --- a/avm/res/event-grid/system-topic/main.bicep +++ b/avm/res/event-grid/system-topic/main.bicep @@ -117,19 +117,16 @@ resource systemTopic_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -212,19 +209,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/event-grid/system-topic/main.json b/avm/res/event-grid/system-topic/main.json index d553c57a1e..2844dda4b8 100644 --- a/avm/res/event-grid/system-topic/main.json +++ b/avm/res/event-grid/system-topic/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3698031087535001530" + "version": "0.25.53.49325", + "templateHash": "8773071401179464366" }, "name": "Event Grid System Topics", "description": "This module deploys an Event Grid System Topic.", @@ -155,14 +155,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -173,14 +180,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -378,12 +392,30 @@ "scope": "[format('Microsoft.EventGrid/systemTopics/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -451,8 +483,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17973992796962490837" + "version": "0.25.53.49325", + "templateHash": "5245070501778317327" }, "name": "Event Grid System Topic Event Subscriptions", "description": "This module deploys an Event Grid System Topic Event Subscription.", diff --git a/avm/res/event-grid/topic/README.md b/avm/res/event-grid/topic/README.md index 32be5d2e6a..8ec0604200 100644 --- a/avm/res/event-grid/topic/README.md +++ b/avm/res/event-grid/topic/README.md @@ -653,9 +653,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -690,11 +690,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -704,11 +733,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -887,6 +942,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -908,6 +984,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/event-grid/topic/event-subscription/main.json b/avm/res/event-grid/topic/event-subscription/main.json index f25065edfa..c73adf1ab6 100644 --- a/avm/res/event-grid/topic/event-subscription/main.json +++ b/avm/res/event-grid/topic/event-subscription/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15563150221070279509" + "version": "0.25.53.49325", + "templateHash": "12495597102731978024" }, "name": "EventGrid Topic Event Subscriptions", "description": "This module deploys an Event Grid Topic Event Subscription.", diff --git a/avm/res/event-grid/topic/main.bicep b/avm/res/event-grid/topic/main.bicep index ac92c43f27..f6ce5a84bf 100644 --- a/avm/res/event-grid/topic/main.bicep +++ b/avm/res/event-grid/topic/main.bicep @@ -129,19 +129,16 @@ resource topic_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -316,19 +313,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/event-grid/topic/main.json b/avm/res/event-grid/topic/main.json index 769a4ae56a..c3ef671cd3 100644 --- a/avm/res/event-grid/topic/main.json +++ b/avm/res/event-grid/topic/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3665951373659879423" + "version": "0.25.53.49325", + "templateHash": "11641318899572418269" }, "name": "Event Grid Topics", "description": "This module deploys an Event Grid Topic.", @@ -330,14 +330,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -348,14 +355,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -574,12 +588,30 @@ "scope": "[format('Microsoft.EventGrid/topics/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -647,8 +679,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15563150221070279509" + "version": "0.25.53.49325", + "templateHash": "12495597102731978024" }, "name": "EventGrid Topic Event Subscriptions", "description": "This module deploys an Event Grid Topic Event Subscription.", diff --git a/avm/res/health-bot/health-bot/README.md b/avm/res/health-bot/health-bot/README.md index 65a7aef659..f0bb6b306d 100644 --- a/avm/res/health-bot/health-bot/README.md +++ b/avm/res/health-bot/health-bot/README.md @@ -50,7 +50,7 @@ module healthBot 'br/public:avm/res/health-bot/health-bot:' = { name: '${uniqueString(deployment().name, resourceLocation)}-test-hbhbmin' params: { // Required parameters - name: 'hbhbmin001' + name: 'hbhbmin002' sku: 'F0' // Non-required parameters location: '' @@ -72,7 +72,7 @@ module healthBot 'br/public:avm/res/health-bot/health-bot:' = { "parameters": { // Required parameters "name": { - "value": "hbhbmin001" + "value": "hbhbmin002" }, "sku": { "value": "F0" @@ -102,7 +102,7 @@ module healthBot 'br/public:avm/res/health-bot/health-bot:' = { name: '${uniqueString(deployment().name, resourceLocation)}-test-hbhbmax' params: { // Required parameters - name: 'hbhbmax001' + name: 'hbhbmax002' sku: 'F0' // Non-required parameters location: '' @@ -155,7 +155,7 @@ module healthBot 'br/public:avm/res/health-bot/health-bot:' = { "parameters": { // Required parameters "name": { - "value": "hbhbmax001" + "value": "hbhbmax002" }, "sku": { "value": "F0" @@ -224,7 +224,7 @@ module healthBot 'br/public:avm/res/health-bot/health-bot:' = { name: '${uniqueString(deployment().name, resourceLocation)}-test-hbhbwaf' params: { // Required parameters - name: 'hbhbwaf001' + name: 'hbhbwaf002' sku: 'F0' // Non-required parameters location: '' @@ -255,7 +255,7 @@ module healthBot 'br/public:avm/res/health-bot/health-bot:' = { "parameters": { // Required parameters "name": { - "value": "hbhbwaf001" + "value": "hbhbwaf002" }, "sku": { "value": "F0" diff --git a/avm/res/health-bot/health-bot/main.json b/avm/res/health-bot/health-bot/main.json index b066f64432..6f8d59ab81 100644 --- a/avm/res/health-bot/health-bot/main.json +++ b/avm/res/health-bot/health-bot/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7639602546717326275" + "version": "0.25.53.49325", + "templateHash": "13278518763850368052" }, "name": "Azure Health Bots", "description": "This module deploys an Azure Health Bot.", diff --git a/avm/res/health-bot/health-bot/tests/e2e/defaults/main.test.bicep b/avm/res/health-bot/health-bot/tests/e2e/defaults/main.test.bicep index a68c3076ce..8b458aca57 100644 --- a/avm/res/health-bot/health-bot/tests/e2e/defaults/main.test.bicep +++ b/avm/res/health-bot/health-bot/tests/e2e/defaults/main.test.bicep @@ -40,7 +40,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' location: resourceGroup.location sku: 'F0' } diff --git a/avm/res/health-bot/health-bot/tests/e2e/max/main.test.bicep b/avm/res/health-bot/health-bot/tests/e2e/max/main.test.bicep index 96499db8d7..f063d1e4e4 100644 --- a/avm/res/health-bot/health-bot/tests/e2e/max/main.test.bicep +++ b/avm/res/health-bot/health-bot/tests/e2e/max/main.test.bicep @@ -49,7 +49,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' location: resourceGroup.location lock: { kind: 'CanNotDelete' diff --git a/avm/res/health-bot/health-bot/tests/e2e/waf-aligned/main.test.bicep b/avm/res/health-bot/health-bot/tests/e2e/waf-aligned/main.test.bicep index 7dc48ae873..ca8e64a199 100644 --- a/avm/res/health-bot/health-bot/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/health-bot/health-bot/tests/e2e/waf-aligned/main.test.bicep @@ -40,7 +40,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' location: resourceGroup.location lock: { kind: 'CanNotDelete' diff --git a/avm/res/insights/action-group/main.json b/avm/res/insights/action-group/main.json index be5f458929..db92f1556e 100644 --- a/avm/res/insights/action-group/main.json +++ b/avm/res/insights/action-group/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9236568032649497201" + "version": "0.25.53.49325", + "templateHash": "452819506402297284" }, "name": "Action Groups", "description": "This module deploys an Action Group.", diff --git a/avm/res/insights/activity-log-alert/main.json b/avm/res/insights/activity-log-alert/main.json index fb5e812da8..567c3f6c42 100644 --- a/avm/res/insights/activity-log-alert/main.json +++ b/avm/res/insights/activity-log-alert/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12712034346035097235" + "version": "0.25.53.49325", + "templateHash": "11885081769153040344" }, "name": "Activity Log Alerts", "description": "This module deploys an Activity Log Alert.", diff --git a/avm/res/insights/component/README.md b/avm/res/insights/component/README.md index d75b5b633b..a1e3ed73b6 100644 --- a/avm/res/insights/component/README.md +++ b/avm/res/insights/component/README.md @@ -17,6 +17,7 @@ This component deploys an Application Insights instance. | :-- | :-- | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | | `Microsoft.Insights/components` | [2020-02-02](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2020-02-02/components) | +| `microsoft.insights/components/linkedStorageAccounts` | [2020-03-01-preview](https://learn.microsoft.com/en-us/azure/templates/microsoft.insights/2020-03-01-preview/components/linkedStorageAccounts) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | ## Usage examples @@ -114,6 +115,10 @@ module component 'br/public:avm/res/insights/component:' = { workspaceResourceId: '' } ] + disableIpMasking: false + disableLocalAuth: true + forceCustomerStorageForProfiler: true + linkedStorageAccountResourceId: '' location: '' roleAssignments: [ { @@ -177,6 +182,18 @@ module component 'br/public:avm/res/insights/component:' = { } ] }, + "disableIpMasking": { + "value": false + }, + "disableLocalAuth": { + "value": true + }, + "forceCustomerStorageForProfiler": { + "value": true + }, + "linkedStorageAccountResourceId": { + "value": "" + }, "location": { "value": "" }, @@ -323,8 +340,12 @@ module component 'br/public:avm/res/insights/component:' = { | :-- | :-- | :-- | | [`applicationType`](#parameter-applicationtype) | string | Application type. | | [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | +| [`disableIpMasking`](#parameter-disableipmasking) | bool | Disable IP masking. Default value is set to true. | +| [`disableLocalAuth`](#parameter-disablelocalauth) | bool | Disable Non-AAD based Auth. Default value is set to false. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`forceCustomerStorageForProfiler`](#parameter-forcecustomerstorageforprofiler) | bool | Force users to create their own storage account for profiler and debugger. | | [`kind`](#parameter-kind) | string | The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of the following: web, ios, other, store, java, phone. | +| [`linkedStorageAccountResourceId`](#parameter-linkedstorageaccountresourceid) | string | Linked storage account resource ID. | | [`location`](#parameter-location) | string | Location for all Resources. | | [`publicNetworkAccessForIngestion`](#parameter-publicnetworkaccessforingestion) | string | The network access type for accessing Application Insights ingestion. - Enabled or Disabled. | | [`publicNetworkAccessForQuery`](#parameter-publicnetworkaccessforquery) | string | The network access type for accessing Application Insights query. - Enabled or Disabled. | @@ -376,9 +397,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -413,11 +434,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -427,11 +477,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -453,6 +529,22 @@ Resource ID of the diagnostic log analytics workspace. For security reasons, it - Required: No - Type: string +### Parameter: `disableIpMasking` + +Disable IP masking. Default value is set to true. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `disableLocalAuth` + +Disable Non-AAD based Auth. Default value is set to false. + +- Required: No +- Type: bool +- Default: `False` + ### Parameter: `enableTelemetry` Enable/Disable usage telemetry for module. @@ -461,6 +553,14 @@ Enable/Disable usage telemetry for module. - Type: bool - Default: `True` +### Parameter: `forceCustomerStorageForProfiler` + +Force users to create their own storage account for profiler and debugger. + +- Required: No +- Type: bool +- Default: `False` + ### Parameter: `kind` The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of the following: web, ios, other, store, java, phone. @@ -469,6 +569,14 @@ The kind of application that this component refers to, used to customize UI. Thi - Type: string - Default: `''` +### Parameter: `linkedStorageAccountResourceId` + +Linked storage account resource ID. + +- Required: No +- Type: string +- Default: `''` + ### Parameter: `location` Location for all Resources. diff --git a/avm/res/insights/component/linkedStorageAccounts/README.md b/avm/res/insights/component/linkedStorageAccounts/README.md new file mode 100644 index 0000000000..83106ae2fd --- /dev/null +++ b/avm/res/insights/component/linkedStorageAccounts/README.md @@ -0,0 +1,62 @@ +# Application Insights Linked Storage Account `[microsoft.insights/components/linkedStorageAccounts]` + +This component deploys an Application Insights Linked Storage Account. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `microsoft.insights/components/linkedStorageAccounts` | [2020-03-01-preview](https://learn.microsoft.com/en-us/azure/templates/microsoft.insights/2020-03-01-preview/components/linkedStorageAccounts) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`storageAccountResourceId`](#parameter-storageaccountresourceid) | string | Linked storage account resource ID. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`appInsightsName`](#parameter-appinsightsname) | string | The name of the parent Application Insights instance. Required if the template is used in a standalone deployment. | + +### Parameter: `storageAccountResourceId` + +Linked storage account resource ID. + +- Required: Yes +- Type: string + +### Parameter: `appInsightsName` + +The name of the parent Application Insights instance. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the Linked Storage Account. | +| `resourceGroupName` | string | The resource group the agent pool was deployed into. | +| `resourceId` | string | The resource ID of the Linked Storage Account. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/insights/component/linkedStorageAccounts/main.bicep b/avm/res/insights/component/linkedStorageAccounts/main.bicep new file mode 100644 index 0000000000..065b289da1 --- /dev/null +++ b/avm/res/insights/component/linkedStorageAccounts/main.bicep @@ -0,0 +1,30 @@ +metadata name = 'Application Insights Linked Storage Account' +metadata description = 'This component deploys an Application Insights Linked Storage Account.' +metadata owner = 'Azure/module-maintainers' + +@description('Conditional. The name of the parent Application Insights instance. Required if the template is used in a standalone deployment.') +param appInsightsName string + +@description('Required. Linked storage account resource ID.') +param storageAccountResourceId string + +resource appInsights 'Microsoft.Insights/components@2020-02-02' existing = { + name: appInsightsName +} + +resource linkedStorageAccount 'Microsoft.Insights/components/linkedStorageAccounts@2020-03-01-preview' = { + name: 'ServiceProfiler' + parent: appInsights + properties: { + linkedStorageAccount: storageAccountResourceId + } +} + +@description('The name of the Linked Storage Account.') +output name string = linkedStorageAccount.name + +@description('The resource ID of the Linked Storage Account.') +output resourceId string = linkedStorageAccount.id + +@description('The resource group the agent pool was deployed into.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/insights/component/linkedStorageAccounts/main.json b/avm/res/insights/component/linkedStorageAccounts/main.json new file mode 100644 index 0000000000..853cdbcf3a --- /dev/null +++ b/avm/res/insights/component/linkedStorageAccounts/main.json @@ -0,0 +1,61 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "15515506165880058222" + }, + "name": "Application Insights Linked Storage Account", + "description": "This component deploys an Application Insights Linked Storage Account.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "appInsightsName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Application Insights instance. Required if the template is used in a standalone deployment." + } + }, + "storageAccountResourceId": { + "type": "string", + "metadata": { + "description": "Required. Linked storage account resource ID." + } + } + }, + "resources": [ + { + "type": "microsoft.insights/components/linkedStorageAccounts", + "apiVersion": "2020-03-01-preview", + "name": "[format('{0}/{1}', parameters('appInsightsName'), 'ServiceProfiler')]", + "properties": { + "linkedStorageAccount": "[parameters('storageAccountResourceId')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the Linked Storage Account." + }, + "value": "ServiceProfiler" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Linked Storage Account." + }, + "value": "[resourceId('microsoft.insights/components/linkedStorageAccounts', parameters('appInsightsName'), 'ServiceProfiler')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the agent pool was deployed into." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/insights/component/linkedStorageAccounts/version.json b/avm/res/insights/component/linkedStorageAccounts/version.json new file mode 100644 index 0000000000..729ac87673 --- /dev/null +++ b/avm/res/insights/component/linkedStorageAccounts/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.2", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file diff --git a/avm/res/insights/component/main.bicep b/avm/res/insights/component/main.bicep index 078e1404da..e469deb503 100644 --- a/avm/res/insights/component/main.bicep +++ b/avm/res/insights/component/main.bicep @@ -15,6 +15,18 @@ param applicationType string = 'web' @description('Required. Resource ID of the log analytics workspace which the data will be ingested to. This property is required to create an application with this API version. Applications from older versions will not have this property.') param workspaceResourceId string +@description('Optional. Disable IP masking. Default value is set to true.') +param disableIpMasking bool = true + +@description('Optional. Disable Non-AAD based Auth. Default value is set to false.') +param disableLocalAuth bool = false + +@description('Optional. Force users to create their own storage account for profiler and debugger.') +param forceCustomerStorageForProfiler bool = false + +@description('Optional. Linked storage account resource ID.') +param linkedStorageAccountResourceId string = '' + @description('Optional. The network access type for accessing Application Insights ingestion. - Enabled or Disabled.') @allowed([ 'Enabled' @@ -99,6 +111,9 @@ resource appInsights 'Microsoft.Insights/components@2020-02-02' = { kind: kind properties: { Application_Type: applicationType + DisableIpMasking: disableIpMasking + DisableLocalAuth: disableLocalAuth + ForceCustomerStorageForProfiler: forceCustomerStorageForProfiler WorkspaceResourceId: workspaceResourceId publicNetworkAccessForIngestion: publicNetworkAccessForIngestion publicNetworkAccessForQuery: publicNetworkAccessForQuery @@ -107,6 +122,14 @@ resource appInsights 'Microsoft.Insights/components@2020-02-02' = { } } +module linkedStorageAccount 'linkedStorageAccounts/main.bicep' = if (!empty(linkedStorageAccountResourceId)) { + name: '${uniqueString(deployment().name, location)}-appInsights-linkedStorageAccount' + params: { + appInsightsName: appInsights.name + storageAccountResourceId: linkedStorageAccountResourceId + } +} + resource appInsights_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { name: guid(appInsights.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) properties: { @@ -128,19 +151,16 @@ resource appInsights_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -196,19 +216,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/insights/component/main.json b/avm/res/insights/component/main.json index 019623c96f..a81cf052b7 100644 --- a/avm/res/insights/component/main.json +++ b/avm/res/insights/component/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14533830287443568216" + "version": "0.25.53.49325", + "templateHash": "9561238160025481382" }, "name": "Application Insights", "description": "This component deploys an Application Insights instance.", @@ -107,14 +107,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -125,14 +132,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -210,6 +224,34 @@ "description": "Required. Resource ID of the log analytics workspace which the data will be ingested to. This property is required to create an application with this API version. Applications from older versions will not have this property." } }, + "disableIpMasking": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Disable IP masking. Default value is set to true." + } + }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Disable Non-AAD based Auth. Default value is set to false." + } + }, + "forceCustomerStorageForProfiler": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Force users to create their own storage account for profiler and debugger." + } + }, + "linkedStorageAccountResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Linked storage account resource ID." + } + }, "publicNetworkAccessForIngestion": { "type": "string", "defaultValue": "Enabled", @@ -339,6 +381,9 @@ "kind": "[parameters('kind')]", "properties": { "Application_Type": "[parameters('applicationType')]", + "DisableIpMasking": "[parameters('disableIpMasking')]", + "DisableLocalAuth": "[parameters('disableLocalAuth')]", + "ForceCustomerStorageForProfiler": "[parameters('forceCustomerStorageForProfiler')]", "WorkspaceResourceId": "[parameters('workspaceResourceId')]", "publicNetworkAccessForIngestion": "[parameters('publicNetworkAccessForIngestion')]", "publicNetworkAccessForQuery": "[parameters('publicNetworkAccessForQuery')]", @@ -378,18 +423,120 @@ "scope": "[format('Microsoft.Insights/components/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, "dependsOn": [ "appInsights" ] + }, + "linkedStorageAccount": { + "condition": "[not(empty(parameters('linkedStorageAccountResourceId')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-appInsights-linkedStorageAccount', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "appInsightsName": { + "value": "[parameters('name')]" + }, + "storageAccountResourceId": { + "value": "[parameters('linkedStorageAccountResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "15515506165880058222" + }, + "name": "Application Insights Linked Storage Account", + "description": "This component deploys an Application Insights Linked Storage Account.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "appInsightsName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Application Insights instance. Required if the template is used in a standalone deployment." + } + }, + "storageAccountResourceId": { + "type": "string", + "metadata": { + "description": "Required. Linked storage account resource ID." + } + } + }, + "resources": [ + { + "type": "microsoft.insights/components/linkedStorageAccounts", + "apiVersion": "2020-03-01-preview", + "name": "[format('{0}/{1}', parameters('appInsightsName'), 'ServiceProfiler')]", + "properties": { + "linkedStorageAccount": "[parameters('storageAccountResourceId')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the Linked Storage Account." + }, + "value": "ServiceProfiler" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Linked Storage Account." + }, + "value": "[resourceId('microsoft.insights/components/linkedStorageAccounts', parameters('appInsightsName'), 'ServiceProfiler')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the agent pool was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "appInsights" + ] } }, "outputs": { diff --git a/avm/res/insights/component/tests/e2e/max/dependencies.bicep b/avm/res/insights/component/tests/e2e/max/dependencies.bicep index a7f42aee7b..dfc9e8a89c 100644 --- a/avm/res/insights/component/tests/e2e/max/dependencies.bicep +++ b/avm/res/insights/component/tests/e2e/max/dependencies.bicep @@ -4,10 +4,32 @@ param location string = resourceGroup().location @description('Required. The name of the Managed Identity to create.') param managedIdentityName string +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + allowBlobPublicAccess: false + networkAcls: { + defaultAction: 'Deny' + bypass: 'AzureServices' + } + } } +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + @description('The principal ID of the created Managed Identity.') output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/res/insights/component/tests/e2e/max/main.test.bicep b/avm/res/insights/component/tests/e2e/max/main.test.bicep index fe5aa82226..1f587dd740 100644 --- a/avm/res/insights/component/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/component/tests/e2e/max/main.test.bicep @@ -36,6 +36,7 @@ module nestedDependencies 'dependencies.bicep' = { name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' params: { managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}' location: resourceLocation } } @@ -64,6 +65,10 @@ module testDeployment '../../../main.bicep' = { params: { name: '${namePrefix}${serviceShort}001' location: resourceLocation + disableIpMasking: false + disableLocalAuth: true + forceCustomerStorageForProfiler: true + linkedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId diagnosticSettings: [ { diff --git a/avm/res/insights/component/version.json b/avm/res/insights/component/version.json index 83083db694..729ac87673 100644 --- a/avm/res/insights/component/version.json +++ b/avm/res/insights/component/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.1", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.2", + "pathFilters": [ + "./main.json" + ] } \ No newline at end of file diff --git a/avm/res/insights/data-collection-endpoint/main.json b/avm/res/insights/data-collection-endpoint/main.json index 4ca30572ed..01c4550922 100644 --- a/avm/res/insights/data-collection-endpoint/main.json +++ b/avm/res/insights/data-collection-endpoint/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9682892471414965708" + "version": "0.25.53.49325", + "templateHash": "2640603462631612916" }, "name": "Data Collection Endpoints", "description": "This module deploys a Data Collection Endpoint.", diff --git a/avm/res/insights/data-collection-rule/main.json b/avm/res/insights/data-collection-rule/main.json index e4426e5f5f..b076b6e1de 100644 --- a/avm/res/insights/data-collection-rule/main.json +++ b/avm/res/insights/data-collection-rule/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1284995352756523865" + "version": "0.25.53.49325", + "templateHash": "11839102114188195603" }, "name": "Data Collection Rules", "description": "This module deploys a Data Collection Rule.", diff --git a/avm/res/insights/diagnostic-setting/README.md b/avm/res/insights/diagnostic-setting/README.md index bb077b2bc2..2b1b23c78b 100644 --- a/avm/res/insights/diagnostic-setting/README.md +++ b/avm/res/insights/diagnostic-setting/README.md @@ -233,9 +233,9 @@ module diagnosticSetting 'br/public:avm/res/insights/diagnostic-setting:**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/insights/private-link-scope:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep + name: '${uniqueString(deployment().name, resourceLocation)}-test-iplsmin' + params: { + // Required parameters + name: 'iplsmin001' + // Non-required parameters + location: 'global' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "iplsmin001" + }, + // Non-required parameters + "location": { + "value": "global" + } + } +} +``` + +
    +

    + +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep + name: '${uniqueString(deployment().name, resourceLocation)}-test-iplsmax' + params: { + // Required parameters + name: 'iplsmax001' + // Non-required parameters + accessModeSettings: { + exclusions: [ + { + ingestionAccessMode: 'PrivateOnly' + privateEndpointConnectionName: 'thisisatest' + queryAccessMode: 'PrivateOnly' + } + ] + ingestionAccessMode: 'Open' + queryAccessMode: 'Open' + } + location: 'global' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + privateEndpoints: [ + { + customNetworkInterfaceName: 'nic-pe-' + ipConfigurations: [ + { + name: 'api' + properties: { + groupId: 'azuremonitor' + memberName: 'api' + privateIPAddress: '10.0.0.11' + } + } + { + name: 'globalinai' + properties: { + groupId: 'azuremonitor' + memberName: 'global.in.ai' + privateIPAddress: '10.0.0.12' + } + } + { + name: 'profiler' + properties: { + groupId: 'azuremonitor' + memberName: 'profiler' + privateIPAddress: '10.0.0.13' + } + } + { + name: 'live' + properties: { + groupId: 'azuremonitor' + memberName: 'live' + privateIPAddress: '10.0.0.14' + } + } + { + name: 'diagservicesquery' + properties: { + groupId: 'azuremonitor' + memberName: 'diagservicesquery' + privateIPAddress: '10.0.0.15' + } + } + { + name: 'snapshot' + properties: { + groupId: 'azuremonitor' + memberName: 'snapshot' + privateIPAddress: '10.0.0.16' + } + } + { + name: 'agentsolutionpackstore' + properties: { + groupId: 'azuremonitor' + memberName: 'agentsolutionpackstore' + privateIPAddress: '10.0.0.17' + } + } + { + name: 'dce-global' + properties: { + groupId: 'azuremonitor' + memberName: 'dce-global' + privateIPAddress: '10.0.0.18' + } + } + { + name: '' + properties: { + groupId: 'azuremonitor' + memberName: '' + privateIPAddress: '10.0.0.19' + } + } + { + name: '' + properties: { + groupId: 'azuremonitor' + memberName: '' + privateIPAddress: '10.0.0.20' + } + } + { + name: '' + properties: { + groupId: 'azuremonitor' + memberName: '' + privateIPAddress: '10.0.0.21' + } + } + ] + name: 'pe-' + privateDnsZoneResourceIds: [ + '' + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + scopedResources: [ + { + linkedResourceId: '' + name: 'scoped1' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "iplsmax001" + }, + // Non-required parameters + "accessModeSettings": { + "value": { + "exclusions": [ + { + "ingestionAccessMode": "PrivateOnly", + "privateEndpointConnectionName": "thisisatest", + "queryAccessMode": "PrivateOnly" + } + ], + "ingestionAccessMode": "Open", + "queryAccessMode": "Open" + } + }, + "location": { + "value": "global" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "privateEndpoints": { + "value": [ + { + "customNetworkInterfaceName": "nic-pe-", + "ipConfigurations": [ + { + "name": "api", + "properties": { + "groupId": "azuremonitor", + "memberName": "api", + "privateIPAddress": "10.0.0.11" + } + }, + { + "name": "globalinai", + "properties": { + "groupId": "azuremonitor", + "memberName": "global.in.ai", + "privateIPAddress": "10.0.0.12" + } + }, + { + "name": "profiler", + "properties": { + "groupId": "azuremonitor", + "memberName": "profiler", + "privateIPAddress": "10.0.0.13" + } + }, + { + "name": "live", + "properties": { + "groupId": "azuremonitor", + "memberName": "live", + "privateIPAddress": "10.0.0.14" + } + }, + { + "name": "diagservicesquery", + "properties": { + "groupId": "azuremonitor", + "memberName": "diagservicesquery", + "privateIPAddress": "10.0.0.15" + } + }, + { + "name": "snapshot", + "properties": { + "groupId": "azuremonitor", + "memberName": "snapshot", + "privateIPAddress": "10.0.0.16" + } + }, + { + "name": "agentsolutionpackstore", + "properties": { + "groupId": "azuremonitor", + "memberName": "agentsolutionpackstore", + "privateIPAddress": "10.0.0.17" + } + }, + { + "name": "dce-global", + "properties": { + "groupId": "azuremonitor", + "memberName": "dce-global", + "privateIPAddress": "10.0.0.18" + } + }, + { + "name": "", + "properties": { + "groupId": "azuremonitor", + "memberName": "", + "privateIPAddress": "10.0.0.19" + } + }, + { + "name": "", + "properties": { + "groupId": "azuremonitor", + "memberName": "", + "privateIPAddress": "10.0.0.20" + } + }, + { + "name": "", + "properties": { + "groupId": "azuremonitor", + "memberName": "", + "privateIPAddress": "10.0.0.21" + } + } + ], + "name": "pe-", + "privateDnsZoneResourceIds": [ + "" + ], + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ], + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "scopedResources": { + "value": [ + { + "linkedResourceId": "", + "name": "scoped1" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + +### Example 3: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep + name: '${uniqueString(deployment().name, resourceLocation)}-test-iplswaf' + params: { + // Required parameters + name: 'iplswaf001' + // Non-required parameters + location: 'global' + privateEndpoints: [ + { + customNetworkInterfaceName: 'nic-pe-' + ipConfigurations: [ + { + name: 'api' + properties: { + groupId: 'azuremonitor' + memberName: 'api' + privateIPAddress: '10.0.0.11' + } + } + { + name: 'globalinai' + properties: { + groupId: 'azuremonitor' + memberName: 'global.in.ai' + privateIPAddress: '10.0.0.12' + } + } + { + name: 'profiler' + properties: { + groupId: 'azuremonitor' + memberName: 'profiler' + privateIPAddress: '10.0.0.13' + } + } + { + name: 'live' + properties: { + groupId: 'azuremonitor' + memberName: 'live' + privateIPAddress: '10.0.0.14' + } + } + { + name: 'diagservicesquery' + properties: { + groupId: 'azuremonitor' + memberName: 'diagservicesquery' + privateIPAddress: '10.0.0.15' + } + } + { + name: 'snapshot' + properties: { + groupId: 'azuremonitor' + memberName: 'snapshot' + privateIPAddress: '10.0.0.16' + } + } + { + name: 'agentsolutionpackstore' + properties: { + groupId: 'azuremonitor' + memberName: 'agentsolutionpackstore' + privateIPAddress: '10.0.0.17' + } + } + { + name: 'dce-global' + properties: { + groupId: 'azuremonitor' + memberName: 'dce-global' + privateIPAddress: '10.0.0.18' + } + } + { + name: '' + properties: { + groupId: 'azuremonitor' + memberName: '' + privateIPAddress: '10.0.0.19' + } + } + { + name: '' + properties: { + groupId: 'azuremonitor' + memberName: '' + privateIPAddress: '10.0.0.20' + } + } + { + name: '' + properties: { + groupId: 'azuremonitor' + memberName: '' + privateIPAddress: '10.0.0.21' + } + } + ] + name: 'pe-' + privateDnsZoneResourceIds: [ + '' + ] + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + scopedResources: [ + { + linkedResourceId: '' + name: 'scoped1' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "iplswaf001" + }, + // Non-required parameters + "location": { + "value": "global" + }, + "privateEndpoints": { + "value": [ + { + "customNetworkInterfaceName": "nic-pe-", + "ipConfigurations": [ + { + "name": "api", + "properties": { + "groupId": "azuremonitor", + "memberName": "api", + "privateIPAddress": "10.0.0.11" + } + }, + { + "name": "globalinai", + "properties": { + "groupId": "azuremonitor", + "memberName": "global.in.ai", + "privateIPAddress": "10.0.0.12" + } + }, + { + "name": "profiler", + "properties": { + "groupId": "azuremonitor", + "memberName": "profiler", + "privateIPAddress": "10.0.0.13" + } + }, + { + "name": "live", + "properties": { + "groupId": "azuremonitor", + "memberName": "live", + "privateIPAddress": "10.0.0.14" + } + }, + { + "name": "diagservicesquery", + "properties": { + "groupId": "azuremonitor", + "memberName": "diagservicesquery", + "privateIPAddress": "10.0.0.15" + } + }, + { + "name": "snapshot", + "properties": { + "groupId": "azuremonitor", + "memberName": "snapshot", + "privateIPAddress": "10.0.0.16" + } + }, + { + "name": "agentsolutionpackstore", + "properties": { + "groupId": "azuremonitor", + "memberName": "agentsolutionpackstore", + "privateIPAddress": "10.0.0.17" + } + }, + { + "name": "dce-global", + "properties": { + "groupId": "azuremonitor", + "memberName": "dce-global", + "privateIPAddress": "10.0.0.18" + } + }, + { + "name": "", + "properties": { + "groupId": "azuremonitor", + "memberName": "", + "privateIPAddress": "10.0.0.19" + } + }, + { + "name": "", + "properties": { + "groupId": "azuremonitor", + "memberName": "", + "privateIPAddress": "10.0.0.20" + } + }, + { + "name": "", + "properties": { + "groupId": "azuremonitor", + "memberName": "", + "privateIPAddress": "10.0.0.21" + } + } + ], + "name": "pe-", + "privateDnsZoneResourceIds": [ + "" + ], + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "scopedResources": { + "value": [ + { + "linkedResourceId": "", + "name": "scoped1" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | Name of the private link scope. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`accessModeSettings`](#parameter-accessmodesettings) | object | Specifies the access mode of ingestion or queries through associated private endpoints in scope. For security reasons, it is recommended to use PrivateOnly whenever possible to avoid data exfiltration.

    * Private Only - This mode allows the connected virtual network to reach only Private Link resources. It is the most secure mode and is set as the default when the `privateEndpoints` parameter is configured.

    * Open - Allows the connected virtual network to reach both Private Link resources and the resources not in the AMPLS resource. Data exfiltration cannot be prevented in this mode. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`location`](#parameter-location) | string | The location of the private link scope. Should be global. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`scopedResources`](#parameter-scopedresources) | array | Configuration details for Azure Monitor Resources. | +| [`tags`](#parameter-tags) | object | Resource tags. | + +### Parameter: `name` + +Name of the private link scope. + +- Required: Yes +- Type: string + +### Parameter: `accessModeSettings` + +Specifies the access mode of ingestion or queries through associated private endpoints in scope. For security reasons, it is recommended to use PrivateOnly whenever possible to avoid data exfiltration.

    * Private Only - This mode allows the connected virtual network to reach only Private Link resources. It is the most secure mode and is set as the default when the `privateEndpoints` parameter is configured.

    * Open - Allows the connected virtual network to reach both Private Link resources and the resources not in the AMPLS resource. Data exfiltration cannot be prevented in this mode. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`exclusions`](#parameter-accessmodesettingsexclusions) | array | List of exclusions that override the default access mode settings for specific private endpoint connections. Exclusions for the current created Private endpoints can only be applied post initial provisioning. | +| [`ingestionAccessMode`](#parameter-accessmodesettingsingestionaccessmode) | string | Specifies the default access mode of ingestion through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value. | +| [`queryAccessMode`](#parameter-accessmodesettingsqueryaccessmode) | string | Specifies the default access mode of queries through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value. | + +### Parameter: `accessModeSettings.exclusions` + +List of exclusions that override the default access mode settings for specific private endpoint connections. Exclusions for the current created Private endpoints can only be applied post initial provisioning. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`ingestionAccessMode`](#parameter-accessmodesettingsexclusionsingestionaccessmode) | string | Specifies the access mode of ingestion through the specified private endpoint connection in the exclusion. | +| [`privateEndpointConnectionName`](#parameter-accessmodesettingsexclusionsprivateendpointconnectionname) | string | The private endpoint connection name associated to the private endpoint on which we want to apply the specific access mode settings. | +| [`queryAccessMode`](#parameter-accessmodesettingsexclusionsqueryaccessmode) | string | Specifies the access mode of queries through the specified private endpoint connection in the exclusion. | + +### Parameter: `accessModeSettings.exclusions.ingestionAccessMode` + +Specifies the access mode of ingestion through the specified private endpoint connection in the exclusion. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Open' + 'PrivateOnly' + ] + ``` + +### Parameter: `accessModeSettings.exclusions.privateEndpointConnectionName` + +The private endpoint connection name associated to the private endpoint on which we want to apply the specific access mode settings. + +- Required: Yes +- Type: string + +### Parameter: `accessModeSettings.exclusions.queryAccessMode` + +Specifies the access mode of queries through the specified private endpoint connection in the exclusion. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Open' + 'PrivateOnly' + ] + ``` + +### Parameter: `accessModeSettings.ingestionAccessMode` + +Specifies the default access mode of ingestion through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Open' + 'PrivateOnly' + ] + ``` + +### Parameter: `accessModeSettings.queryAccessMode` + +Specifies the default access mode of queries through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Open' + 'PrivateOnly' + ] + ``` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `location` + +The location of the private link scope. Should be global. + +- Required: No +- Type: string +- Default: `'global'` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints` + +Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`subnetResourceId`](#parameter-privateendpointssubnetresourceid) | string | Resource ID of the subnet where the endpoint needs to be created. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | +| [`manualPrivateLinkServiceConnections`](#parameter-privateendpointsmanualprivatelinkserviceconnections) | array | Manual PrivateLink Service Connections. | +| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | +| [`privateDnsZoneGroupName`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided. | +| [`privateDnsZoneResourceIds`](#parameter-privateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | +| [`service`](#parameter-privateendpointsservice) | string | The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | + +### Parameter: `privateEndpoints.subnetResourceId` + +Resource ID of the subnet where the endpoint needs to be created. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` + +Application security groups in which the private endpoint IP configuration is included. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.customDnsConfigs` + +Custom DNS configurations. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + +### Parameter: `privateEndpoints.customNetworkInterfaceName` + +The custom name of the network interface attached to the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool + +### Parameter: `privateEndpoints.ipConfigurations` + +A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.location` + +The location to deploy the private endpoint to. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.lock` + +Specify the type of lock. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-privateendpointslockkind) | string | Specify the type of lock. | +| [`name`](#parameter-privateendpointslockname) | string | Specify the name of lock. | + +### Parameter: `privateEndpoints.lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `privateEndpoints.lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.manualPrivateLinkServiceConnections` + +Manual PrivateLink Service Connections. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.name` + +The name of the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroupName` + +The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneResourceIds` + +The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-privateendpointsroleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-privateendpointsroleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-privateendpointsroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-privateendpointsroleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-privateendpointsroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-privateendpointsroleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-privateendpointsroleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `privateEndpoints.roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `privateEndpoints.roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `privateEndpoints.service` + +The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.tags` + +Tags to be applied on all resources/resource groups in this deployment. + +- Required: No +- Type: object + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `scopedResources` + +Configuration details for Azure Monitor Resources. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`linkedResourceId`](#parameter-scopedresourceslinkedresourceid) | string | The resource ID of the scoped Azure monitor resource. | +| [`name`](#parameter-scopedresourcesname) | string | Name of the private link scoped resource. | + +### Parameter: `scopedResources.linkedResourceId` + +The resource ID of the scoped Azure monitor resource. + +- Required: Yes +- Type: string + +### Parameter: `scopedResources.name` + +Name of the private link scoped resource. + +- Required: Yes +- Type: string + +### Parameter: `tags` + +Resource tags. + +- Required: No +- Type: object + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the private link scope. | +| `resourceGroupName` | string | The resource group the private link scope was deployed into. | +| `resourceId` | string | The resource ID of the private link scope. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other CARML modules that are referenced in this module) and all remote-referenced files (i.e., Bicep modules that are referenced from a Bicep Registry or Template Specs). + +| Reference | Type | +| :-- | :-- | +| `br/public:avm/res/network/private-endpoint:0.3.1` | Remote reference | + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/insights/private-link-scope/main.bicep b/avm/res/insights/private-link-scope/main.bicep new file mode 100644 index 0000000000..bd1a98c4be --- /dev/null +++ b/avm/res/insights/private-link-scope/main.bicep @@ -0,0 +1,292 @@ +metadata name = 'Azure Monitor Private Link Scopes' +metadata description = 'This module deploys an Azure Monitor Private Link Scope.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Name of the private link scope.') +@minLength(1) +param name string + +@description('''Optional. Specifies the access mode of ingestion or queries through associated private endpoints in scope. For security reasons, it is recommended to use PrivateOnly whenever possible to avoid data exfiltration. + + * Private Only - This mode allows the connected virtual network to reach only Private Link resources. It is the most secure mode and is set as the default when the `privateEndpoints` parameter is configured. + * Open - Allows the connected virtual network to reach both Private Link resources and the resources not in the AMPLS resource. Data exfiltration cannot be prevented in this mode.''') +param accessModeSettings accessModeType + +@description('Optional. The location of the private link scope. Should be global.') +param location string = 'global' + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Optional. Configuration details for Azure Monitor Resources.') +param scopedResources scopedResourceType + +@description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') +param privateEndpoints privateEndpointType + +@description('Optional. Resource tags.') +param tags object? + +@sys.description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') + 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') + 'Logic App Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '87a39d53-fc1b-424a-814c-f7e04687dc9e') + 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') + 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb') + 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'Tag Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4a9ae827-6dc8-4573-8ac7-8239d42aa03f') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.insights-privatelinkscope.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource privateLinkScope 'microsoft.insights/privateLinkScopes@2021-07-01-preview' = { + name: name + location: location + tags: tags + properties: { + accessModeSettings: !empty(privateEndpoints) ? { + ingestionAccessMode: accessModeSettings.?ingestionAccessMode ?? 'PrivateOnly' + queryAccessMode: accessModeSettings.?queryAccessMode ?? 'PrivateOnly' + exclusions: accessModeSettings.?exclusions ?? [] + } : accessModeSettings ?? { + ingestionAccessMode: accessModeSettings.?ingestionAccessMode ?? 'Open' + queryAccessMode: accessModeSettings.?queryAccessMode ?? 'Open' + exclusions: accessModeSettings.?exclusions ?? [] + } + } +} + +module privateLinkScope_scopedResource 'scoped-resource/main.bicep' = [for (scopedResource, index) in (scopedResources ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateLinkScope-ScopedResource-${index}' + params: { + name: scopedResource.name + privateLinkScopeName: privateLinkScope.name + linkedResourceId: scopedResource.linkedResourceId + } +}] + +resource privateLinkScope_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: privateLinkScope +} + +module privateLinkScope_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.3.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateLinkScope-PrivateEndpoint-${index}' + params: { + privateLinkServiceConnections: [ + { + name: name + properties: { + privateLinkServiceId: privateLinkScope.id + groupIds: [ + privateEndpoint.?service ?? 'azuremonitor' + ] + } + } + ] + name: privateEndpoint.?name ?? 'pep-${last(split(privateLinkScope.id, '/'))}-${privateEndpoint.?service ?? 'azuremonitor'}-${index}' + subnetResourceId: privateEndpoint.subnetResourceId + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location + lock: privateEndpoint.?lock ?? lock + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } +}] + +resource privateLinkScope_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(privateLinkScope.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: privateLinkScope +}] + +@description('The name of the private link scope.') +output name string = privateLinkScope.name + +@description('The resource ID of the private link scope.') +output resourceId string = privateLinkScope.id + +@description('The resource group the private link scope was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The location the resource was deployed into.') +output location string = privateLinkScope.location + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? + +type privateEndpointType = { + @description('Optional. The name of the private endpoint.') + name: string? + + @description('Optional. The location to deploy the private endpoint to.') + location: string? + + @description('Optional. The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob".') + service: string? + + @description('Required. Resource ID of the subnet where the endpoint needs to be created.') + subnetResourceId: string + + @description('Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided.') + privateDnsZoneGroupName: string? + + @description('Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneResourceIds: string[]? + + @description('Optional. Custom DNS configurations.') + customDnsConfigs: { + @description('Required. Fqdn that resolves to private endpoint ip address.') + fqdn: string? + + @description('Required. A list of private ip addresses of the private endpoint.') + ipAddresses: string[] + }[]? + + @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') + ipConfigurations: { + @description('Required. The name of the resource that is unique within a resource group.') + name: string + + @description('Required. Properties of private endpoint IP configurations.') + properties: { + @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') + groupId: string + + @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') + memberName: string + + @description('Required. A private ip address obtained from the private endpoint\'s subnet.') + privateIPAddress: string + } + }[]? + + @description('Optional. Application security groups in which the private endpoint IP configuration is included.') + applicationSecurityGroupResourceIds: string[]? + + @description('Optional. The custom name of the network interface attached to the private endpoint.') + customNetworkInterfaceName: string? + + @description('Optional. Specify the type of lock.') + lock: lockType + + @description('Optional. Array of role assignments to create.') + roleAssignments: roleAssignmentType + + @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') + tags: object? + + @description('Optional. Manual PrivateLink Service Connections.') + manualPrivateLinkServiceConnections: array? + + @description('Optional. Enable/Disable usage telemetry for module.') + enableTelemetry: bool? +}[]? + +type scopedResourceType = { + @description('Required. Name of the private link scoped resource.') + name: string + + @description('Required. The resource ID of the scoped Azure monitor resource.') + linkedResourceId: string +}[]? + +type accessModeType = { + @description('Optional. List of exclusions that override the default access mode settings for specific private endpoint connections. Exclusions for the current created Private endpoints can only be applied post initial provisioning.') + exclusions: { + @description('Required. The private endpoint connection name associated to the private endpoint on which we want to apply the specific access mode settings.') + privateEndpointConnectionName: string + + @description('Required. Specifies the access mode of ingestion through the specified private endpoint connection in the exclusion.') + ingestionAccessMode: 'Open' | 'PrivateOnly' + + @description('Required. Specifies the access mode of queries through the specified private endpoint connection in the exclusion.') + queryAccessMode: 'Open' | 'PrivateOnly' + }[]? + + @description('Optional. Specifies the default access mode of ingestion through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value.') + ingestionAccessMode: 'Open' | 'PrivateOnly'? + + @description('Optional. Specifies the default access mode of queries through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value.') + queryAccessMode: 'Open' | 'PrivateOnly'? +}? diff --git a/avm/res/insights/private-link-scope/main.json b/avm/res/insights/private-link-scope/main.json new file mode 100644 index 0000000000..bb0d88d038 --- /dev/null +++ b/avm/res/insights/private-link-scope/main.json @@ -0,0 +1,1312 @@ +{ + "$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.25.53.49325", + "templateHash": "12578290654061226677" + }, + "name": "Azure Monitor Private Link Scopes", + "description": "This module deploys an Azure Monitor Private Link Scope.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The service (sub-) type to deploy the private endpoint for. For example \"vault\" or \"blob\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint ip address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private ip addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private ip address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + } + }, + "nullable": true + }, + "scopedResourceType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private link scoped resource." + } + }, + "linkedResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the scoped Azure monitor resource." + } + } + } + }, + "nullable": true + }, + "accessModeType": { + "type": "object", + "properties": { + "exclusions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "privateEndpointConnectionName": { + "type": "string", + "metadata": { + "description": "Required. The private endpoint connection name associated to the private endpoint on which we want to apply the specific access mode settings." + } + }, + "ingestionAccessMode": { + "type": "string", + "allowedValues": [ + "Open", + "PrivateOnly" + ], + "metadata": { + "description": "Required. Specifies the access mode of ingestion through the specified private endpoint connection in the exclusion." + } + }, + "queryAccessMode": { + "type": "string", + "allowedValues": [ + "Open", + "PrivateOnly" + ], + "metadata": { + "description": "Required. Specifies the access mode of queries through the specified private endpoint connection in the exclusion." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. List of exclusions that override the default access mode settings for specific private endpoint connections. Exclusions for the current created Private endpoints can only be applied post initial provisioning." + } + }, + "ingestionAccessMode": { + "type": "string", + "allowedValues": [ + "Open", + "PrivateOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specifies the default access mode of ingestion through associated private endpoints in scope. Default is \"Open\" if no private endpoints are configured and will be set to \"PrivateOnly\" if private endpoints are configured. Override default behaviour by explicitly providing a value." + } + }, + "queryAccessMode": { + "type": "string", + "allowedValues": [ + "Open", + "PrivateOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specifies the default access mode of queries through associated private endpoints in scope. Default is \"Open\" if no private endpoints are configured and will be set to \"PrivateOnly\" if private endpoints are configured. Override default behaviour by explicitly providing a value." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Required. Name of the private link scope." + } + }, + "accessModeSettings": { + "$ref": "#/definitions/accessModeType", + "metadata": { + "description": "Optional. Specifies the access mode of ingestion or queries through associated private endpoints in scope. For security reasons, it is recommended to use PrivateOnly whenever possible to avoid data exfiltration.\n\n * Private Only - This mode allows the connected virtual network to reach only Private Link resources. It is the most secure mode and is set as the default when the `privateEndpoints` parameter is configured.\n * Open - Allows the connected virtual network to reach both Private Link resources and the resources not in the AMPLS resource. Data exfiltration cannot be prevented in this mode." + } + }, + "location": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "Optional. The location of the private link scope. Should be global." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "scopedResources": { + "$ref": "#/definitions/scopedResourceType", + "metadata": { + "description": "Optional. Configuration details for Azure Monitor Resources." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Logic App Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '87a39d53-fc1b-424a-814c-f7e04687dc9e')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Tag Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4a9ae827-6dc8-4573-8ac7-8239d42aa03f')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.insights-privatelinkscope.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateLinkScope": { + "type": "microsoft.insights/privateLinkScopes", + "apiVersion": "2021-07-01-preview", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "accessModeSettings": "[if(not(empty(parameters('privateEndpoints'))), createObject('ingestionAccessMode', coalesce(tryGet(parameters('accessModeSettings'), 'ingestionAccessMode'), 'PrivateOnly'), 'queryAccessMode', coalesce(tryGet(parameters('accessModeSettings'), 'queryAccessMode'), 'PrivateOnly'), 'exclusions', coalesce(tryGet(parameters('accessModeSettings'), 'exclusions'), createArray())), coalesce(parameters('accessModeSettings'), createObject('ingestionAccessMode', coalesce(tryGet(parameters('accessModeSettings'), 'ingestionAccessMode'), 'Open'), 'queryAccessMode', coalesce(tryGet(parameters('accessModeSettings'), 'queryAccessMode'), 'Open'), 'exclusions', coalesce(tryGet(parameters('accessModeSettings'), 'exclusions'), createArray()))))]" + } + }, + "privateLinkScope_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('microsoft.insights/privateLinkScopes/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateLinkScope" + ] + }, + "privateLinkScope_roleAssignments": { + "copy": { + "name": "privateLinkScope_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('microsoft.insights/privateLinkScopes/{0}', parameters('name'))]", + "name": "[guid(resourceId('microsoft.insights/privateLinkScopes', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateLinkScope" + ] + }, + "privateLinkScope_scopedResource": { + "copy": { + "name": "privateLinkScope_scopedResource", + "count": "[length(coalesce(parameters('scopedResources'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateLinkScope-ScopedResource-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('scopedResources'), createArray())[copyIndex()].name]" + }, + "privateLinkScopeName": { + "value": "[parameters('name')]" + }, + "linkedResourceId": { + "value": "[coalesce(parameters('scopedResources'), createArray())[copyIndex()].linkedResourceId]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "14997816805234479909" + }, + "name": "Private Link Scope Scoped Resources", + "description": "This module deploys a Private Link Scope Scoped Resource.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Required. Name of the private link scoped resource." + } + }, + "privateLinkScopeName": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Conditional. The name of the parent private link scope. Required if the template is used in a standalone deployment." + } + }, + "linkedResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the scoped Azure monitor resource." + } + } + }, + "resources": [ + { + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-07-01-preview", + "name": "[format('{0}/{1}', parameters('privateLinkScopeName'), parameters('name'))]", + "properties": { + "linkedResourceId": "[parameters('linkedResourceId')]" + } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group where the resource has been deployed." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed scopedResource." + }, + "value": "[resourceId('Microsoft.Insights/privateLinkScopes/scopedResources', parameters('privateLinkScopeName'), parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The full name of the deployed Scoped Resource." + }, + "value": "[parameters('name')]" + } + } + } + }, + "dependsOn": [ + "privateLinkScope" + ] + }, + "privateLinkScope_privateEndpoints": { + "copy": { + "name": "privateLinkScope_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateLinkScope-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateLinkServiceConnections": { + "value": [ + { + "name": "[parameters('name')]", + "properties": { + "privateLinkServiceId": "[resourceId('microsoft.insights/privateLinkScopes', parameters('name'))]", + "groupIds": [ + "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'azuremonitor')]" + ] + } + } + ] + }, + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('microsoft.insights/privateLinkScopes', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'azuremonitor'), copyIndex()))]" + }, + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "manualPrivateLinkServiceConnections": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections')]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$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.23.1.45101", + "templateHash": "2821141217598568122" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private ip address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint ip address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private ip addresses of the private endpoint." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.3.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "18168683629401652671" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "privateLinkScope" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private link scope." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private link scope." + }, + "value": "[resourceId('microsoft.insights/privateLinkScopes', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private link scope was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateLinkScope', '2021-07-01-preview', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/insights/private-link-scope/scoped-resource/README.md b/avm/res/insights/private-link-scope/scoped-resource/README.md new file mode 100644 index 0000000000..28a9842521 --- /dev/null +++ b/avm/res/insights/private-link-scope/scoped-resource/README.md @@ -0,0 +1,70 @@ +# Private Link Scope Scoped Resources `[Microsoft.Insights/privateLinkScopes/scopedResources]` + +This module deploys a Private Link Scope Scoped Resource. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Insights/privateLinkScopes/scopedResources` | [2021-07-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-07-01-preview/privateLinkScopes/scopedResources) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`linkedResourceId`](#parameter-linkedresourceid) | string | The resource ID of the scoped Azure monitor resource. | +| [`name`](#parameter-name) | string | Name of the private link scoped resource. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateLinkScopeName`](#parameter-privatelinkscopename) | string | The name of the parent private link scope. Required if the template is used in a standalone deployment. | + +### Parameter: `linkedResourceId` + +The resource ID of the scoped Azure monitor resource. + +- Required: Yes +- Type: string + +### Parameter: `name` + +Name of the private link scoped resource. + +- Required: Yes +- Type: string + +### Parameter: `privateLinkScopeName` + +The name of the parent private link scope. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The full name of the deployed Scoped Resource. | +| `resourceGroupName` | string | The name of the resource group where the resource has been deployed. | +| `resourceId` | string | The resource ID of the deployed scopedResource. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/insights/private-link-scope/scoped-resource/main.bicep b/avm/res/insights/private-link-scope/scoped-resource/main.bicep new file mode 100644 index 0000000000..94241f25fc --- /dev/null +++ b/avm/res/insights/private-link-scope/scoped-resource/main.bicep @@ -0,0 +1,35 @@ +metadata name = 'Private Link Scope Scoped Resources' +metadata description = 'This module deploys a Private Link Scope Scoped Resource.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Name of the private link scoped resource.') +@minLength(1) +param name string + +@description('Conditional. The name of the parent private link scope. Required if the template is used in a standalone deployment.') +@minLength(1) +param privateLinkScopeName string + +@description('Required. The resource ID of the scoped Azure monitor resource.') +param linkedResourceId string + +resource privateLinkScope 'Microsoft.Insights/privateLinkScopes@2021-07-01-preview' existing = { + name: privateLinkScopeName +} + +resource scopedResource 'Microsoft.Insights/privateLinkScopes/scopedResources@2021-07-01-preview' = { + name: name + parent: privateLinkScope + properties: { + linkedResourceId: linkedResourceId + } +} + +@description('The name of the resource group where the resource has been deployed.') +output resourceGroupName string = resourceGroup().name + +@description('The resource ID of the deployed scopedResource.') +output resourceId string = scopedResource.id + +@description('The full name of the deployed Scoped Resource.') +output name string = scopedResource.name diff --git a/avm/res/insights/private-link-scope/scoped-resource/main.json b/avm/res/insights/private-link-scope/scoped-resource/main.json new file mode 100644 index 0000000000..1c0c1180af --- /dev/null +++ b/avm/res/insights/private-link-scope/scoped-resource/main.json @@ -0,0 +1,69 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "14997816805234479909" + }, + "name": "Private Link Scope Scoped Resources", + "description": "This module deploys a Private Link Scope Scoped Resource.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Required. Name of the private link scoped resource." + } + }, + "privateLinkScopeName": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Conditional. The name of the parent private link scope. Required if the template is used in a standalone deployment." + } + }, + "linkedResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the scoped Azure monitor resource." + } + } + }, + "resources": [ + { + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-07-01-preview", + "name": "[format('{0}/{1}', parameters('privateLinkScopeName'), parameters('name'))]", + "properties": { + "linkedResourceId": "[parameters('linkedResourceId')]" + } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group where the resource has been deployed." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed scopedResource." + }, + "value": "[resourceId('Microsoft.Insights/privateLinkScopes/scopedResources', parameters('privateLinkScopeName'), parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The full name of the deployed Scoped Resource." + }, + "value": "[parameters('name')]" + } + } +} \ No newline at end of file diff --git a/avm/res/insights/private-link-scope/tests/e2e/defaults/main.test.bicep b/avm/res/insights/private-link-scope/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..7b221cf51c --- /dev/null +++ b/avm/res/insights/private-link-scope/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,46 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-insights.privatelinkscopes-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'iplsmin' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: 'global' + } +}] diff --git a/avm/res/insights/private-link-scope/tests/e2e/max/dependencies.bicep b/avm/res/insights/private-link-scope/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..e09c9b5a0c --- /dev/null +++ b/avm/res/insights/private-link-scope/tests/e2e/max/dependencies.bicep @@ -0,0 +1,71 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Log Analytics Workspace to create.') +param logAnalyticsWorkspaceName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.monitor.azure.com' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { + name: logAnalyticsWorkspaceName + location: location +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The resource ID of the created Log Analytics Workspace.') +output logAnalyticsWorkspaceResourceId string = logAnalyticsWorkspace.id diff --git a/avm/res/insights/private-link-scope/tests/e2e/max/main.test.bicep b/avm/res/insights/private-link-scope/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..1d3b534580 --- /dev/null +++ b/avm/res/insights/private-link-scope/tests/e2e/max/main.test.bicep @@ -0,0 +1,214 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-insights.privatelinkscopes-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'iplsmax' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-la-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +var locationUpdated = toLower(replace(resourceLocation, ' ', '')) + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: 'global' + accessModeSettings: { + exclusions: [ + { + ingestionAccessMode: 'PrivateOnly' + queryAccessMode: 'PrivateOnly' + privateEndpointConnectionName: 'thisisatest' + } + ] + ingestionAccessMode: 'Open' + queryAccessMode: 'Open' + } + scopedResources: [ + { + name: 'scoped1' + linkedResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + privateEndpoints: [ + { + name: 'pe-${namePrefix}' + customNetworkInterfaceName: 'nic-pe-${namePrefix}' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + ipConfigurations: [ + { + name: 'api' + properties: { + groupId: 'azuremonitor' + memberName: 'api' + privateIPAddress: '10.0.0.11' + } + } + { + name: 'globalinai' + properties: { + groupId: 'azuremonitor' + memberName: 'global.in.ai' + privateIPAddress: '10.0.0.12' + } + } + { + name: 'profiler' + properties: { + groupId: 'azuremonitor' + memberName: 'profiler' + privateIPAddress: '10.0.0.13' + } + } + { + name: 'live' + properties: { + groupId: 'azuremonitor' + memberName: 'live' + privateIPAddress: '10.0.0.14' + } + } + { + name: 'diagservicesquery' + properties: { + groupId: 'azuremonitor' + memberName: 'diagservicesquery' + privateIPAddress: '10.0.0.15' + } + } + { + name: 'snapshot' + properties: { + groupId: 'azuremonitor' + memberName: 'snapshot' + privateIPAddress: '10.0.0.16' + } + } + { + name: 'agentsolutionpackstore' + properties: { + groupId: 'azuremonitor' + memberName: 'agentsolutionpackstore' + privateIPAddress: '10.0.0.17' + } + } + { + name: 'dce-global' + properties: { + groupId: 'azuremonitor' + memberName: 'dce-global' + privateIPAddress: '10.0.0.18' + } + } + { + name: 'oms-${locationUpdated}' + properties: { + groupId: 'azuremonitor' + memberName: 'oms-${locationUpdated}' + privateIPAddress: '10.0.0.19' + } + } + { + name: 'ods-${locationUpdated}' + properties: { + groupId: 'azuremonitor' + memberName: 'ods-${locationUpdated}' + privateIPAddress: '10.0.0.20' + } + } + { + name: 'agent-${locationUpdated}' + properties: { + groupId: 'azuremonitor' + memberName: 'agent-${locationUpdated}' + privateIPAddress: '10.0.0.21' + } + } + ] + } + ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + } +}] diff --git a/avm/res/insights/private-link-scope/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/insights/private-link-scope/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..83e5706e42 --- /dev/null +++ b/avm/res/insights/private-link-scope/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,60 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Log Analytics Workspace to create.') +param logAnalyticsWorkspaceName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.monitor.azure.com' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { + name: logAnalyticsWorkspaceName + location: location +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The resource ID of the created Log Analytics Workspace.') +output logAnalyticsWorkspaceResourceId string = logAnalyticsWorkspace.id diff --git a/avm/res/insights/private-link-scope/tests/e2e/waf-aligned/main.test.bicep b/avm/res/insights/private-link-scope/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..f298c29766 --- /dev/null +++ b/avm/res/insights/private-link-scope/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,173 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-insights.privatelinkscopes-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'iplswaf' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-la-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // +var locationUpdated = toLower(replace(resourceLocation, ' ', '')) + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: 'global' + scopedResources: [ + { + name: 'scoped1' + linkedResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + privateEndpoints: [ + { + name: 'pe-${namePrefix}' + customNetworkInterfaceName: 'nic-pe-${namePrefix}' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + ipConfigurations: [ + { + name: 'api' + properties: { + groupId: 'azuremonitor' + memberName: 'api' + privateIPAddress: '10.0.0.11' + } + } + { + name: 'globalinai' + properties: { + groupId: 'azuremonitor' + memberName: 'global.in.ai' + privateIPAddress: '10.0.0.12' + } + } + { + name: 'profiler' + properties: { + groupId: 'azuremonitor' + memberName: 'profiler' + privateIPAddress: '10.0.0.13' + } + } + { + name: 'live' + properties: { + groupId: 'azuremonitor' + memberName: 'live' + privateIPAddress: '10.0.0.14' + } + } + { + name: 'diagservicesquery' + properties: { + groupId: 'azuremonitor' + memberName: 'diagservicesquery' + privateIPAddress: '10.0.0.15' + } + } + { + name: 'snapshot' + properties: { + groupId: 'azuremonitor' + memberName: 'snapshot' + privateIPAddress: '10.0.0.16' + } + } + { + name: 'agentsolutionpackstore' + properties: { + groupId: 'azuremonitor' + memberName: 'agentsolutionpackstore' + privateIPAddress: '10.0.0.17' + } + } + { + name: 'dce-global' + properties: { + groupId: 'azuremonitor' + memberName: 'dce-global' + privateIPAddress: '10.0.0.18' + } + } + { + name: 'oms-${locationUpdated}' + properties: { + groupId: 'azuremonitor' + memberName: 'oms-${locationUpdated}' + privateIPAddress: '10.0.0.19' + } + } + { + name: 'ods-${locationUpdated}' + properties: { + groupId: 'azuremonitor' + memberName: 'ods-${locationUpdated}' + privateIPAddress: '10.0.0.20' + } + } + { + name: 'agent-${locationUpdated}' + properties: { + groupId: 'azuremonitor' + memberName: 'agent-${locationUpdated}' + privateIPAddress: '10.0.0.21' + } + } + ] + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/insights/private-link-scope/version.json b/avm/res/insights/private-link-scope/version.json new file mode 100644 index 0000000000..83083db694 --- /dev/null +++ b/avm/res/insights/private-link-scope/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file diff --git a/avm/res/insights/scheduled-query-rule/main.json b/avm/res/insights/scheduled-query-rule/main.json index 83b0a549ae..0e84461043 100644 --- a/avm/res/insights/scheduled-query-rule/main.json +++ b/avm/res/insights/scheduled-query-rule/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12813023388359037004" + "version": "0.25.53.49325", + "templateHash": "17106717169874117365" }, "name": "Scheduled Query Rules", "description": "This module deploys a Scheduled Query Rule.", diff --git a/avm/res/insights/webtest/main.json b/avm/res/insights/webtest/main.json index 418306451b..246ccae4f5 100644 --- a/avm/res/insights/webtest/main.json +++ b/avm/res/insights/webtest/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16879601696713003830" + "version": "0.25.53.49325", + "templateHash": "16473822871746404569" }, "name": "Web Tests", "description": "This module deploys a Web Test.", diff --git a/avm/res/key-vault/vault/README.md b/avm/res/key-vault/vault/README.md index a72cb10245..5dba112ffb 100644 --- a/avm/res/key-vault/vault/README.md +++ b/avm/res/key-vault/vault/README.md @@ -156,12 +156,6 @@ module vault 'br/public:avm/res/key-vault/vault:' = { storageAccountResourceId: '' workspaceResourceId: '' } - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - storageAccountResourceId: '' - workspaceResourceId: '' - } ] enablePurgeProtection: false enableRbacAuthorization: false @@ -398,12 +392,6 @@ module vault 'br/public:avm/res/key-vault/vault:' = { "name": "customSetting", "storageAccountResourceId": "", "workspaceResourceId": "" - }, - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "storageAccountResourceId": "", - "workspaceResourceId": "" } ] }, @@ -984,7 +972,7 @@ module vault 'br/public:avm/res/key-vault/vault:' = { | [`keys`](#parameter-keys) | array | All keys to create. | | [`location`](#parameter-location) | string | Location for all resources. | | [`lock`](#parameter-lock) | object | The lock settings of the service. | -| [`networkAcls`](#parameter-networkacls) | object | Rules governing the accessibility of the resouce from specific network locations. | +| [`networkAcls`](#parameter-networkacls) | object | Rules governing the accessibility of the resource from specific network locations. | | [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | | [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | @@ -1035,6 +1023,125 @@ Permissions the identity has for keys, secrets and certificates. - Required: Yes - Type: object +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`certificates`](#parameter-accesspoliciespermissionscertificates) | array | Permissions to certificates. | +| [`keys`](#parameter-accesspoliciespermissionskeys) | array | Permissions to keys. | +| [`secrets`](#parameter-accesspoliciespermissionssecrets) | array | Permissions to secrets. | +| [`storage`](#parameter-accesspoliciespermissionsstorage) | array | Permissions to storage accounts. | + +### Parameter: `accessPolicies.permissions.certificates` + +Permissions to certificates. + +- Required: No +- Type: array +- Allowed: + ```Bicep + [ + 'all' + 'backup' + 'create' + 'delete' + 'deleteissuers' + 'get' + 'getissuers' + 'import' + 'list' + 'listissuers' + 'managecontacts' + 'manageissuers' + 'purge' + 'recover' + 'restore' + 'setissuers' + 'update' + ] + ``` + +### Parameter: `accessPolicies.permissions.keys` + +Permissions to keys. + +- Required: No +- Type: array +- Allowed: + ```Bicep + [ + 'all' + 'backup' + 'create' + 'decrypt' + 'delete' + 'encrypt' + 'get' + 'getrotationpolicy' + 'import' + 'list' + 'purge' + 'recover' + 'release' + 'restore' + 'rotate' + 'setrotationpolicy' + 'sign' + 'unwrapKey' + 'update' + 'verify' + 'wrapKey' + ] + ``` + +### Parameter: `accessPolicies.permissions.secrets` + +Permissions to secrets. + +- Required: No +- Type: array +- Allowed: + ```Bicep + [ + 'all' + 'backup' + 'delete' + 'get' + 'list' + 'purge' + 'recover' + 'restore' + 'set' + ] + ``` + +### Parameter: `accessPolicies.permissions.storage` + +Permissions to storage accounts. + +- Required: No +- Type: array +- Allowed: + ```Bicep + [ + 'all' + 'backup' + 'delete' + 'deletesas' + 'get' + 'getsas' + 'list' + 'listsas' + 'purge' + 'recover' + 'regeneratekey' + 'restore' + 'set' + 'setsas' + 'update' + ] + ``` + ### Parameter: `accessPolicies.applicationId` Application ID of the client making request on behalf of a principal. @@ -1071,9 +1178,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1108,11 +1215,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1122,11 +1258,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -1257,7 +1419,7 @@ Specify the name of lock. ### Parameter: `networkAcls` -Rules governing the accessibility of the resouce from specific network locations. +Rules governing the accessibility of the resource from specific network locations. - Required: No - Type: object @@ -1315,6 +1477,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint IP address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private IP addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -1336,6 +1519,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/key-vault/vault/access-policy/README.md b/avm/res/key-vault/vault/access-policy/README.md index 492f06067d..8c2c3ff336 100644 --- a/avm/res/key-vault/vault/access-policy/README.md +++ b/avm/res/key-vault/vault/access-policy/README.md @@ -72,6 +72,125 @@ Permissions the identity has for keys, secrets and certificates. - Required: Yes - Type: object +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`certificates`](#parameter-accesspoliciespermissionscertificates) | array | Permissions to certificates. | +| [`keys`](#parameter-accesspoliciespermissionskeys) | array | Permissions to keys. | +| [`secrets`](#parameter-accesspoliciespermissionssecrets) | array | Permissions to secrets. | +| [`storage`](#parameter-accesspoliciespermissionsstorage) | array | Permissions to storage accounts. | + +### Parameter: `accessPolicies.permissions.certificates` + +Permissions to certificates. + +- Required: No +- Type: array +- Allowed: + ```Bicep + [ + 'all' + 'backup' + 'create' + 'delete' + 'deleteissuers' + 'get' + 'getissuers' + 'import' + 'list' + 'listissuers' + 'managecontacts' + 'manageissuers' + 'purge' + 'recover' + 'restore' + 'setissuers' + 'update' + ] + ``` + +### Parameter: `accessPolicies.permissions.keys` + +Permissions to keys. + +- Required: No +- Type: array +- Allowed: + ```Bicep + [ + 'all' + 'backup' + 'create' + 'decrypt' + 'delete' + 'encrypt' + 'get' + 'getrotationpolicy' + 'import' + 'list' + 'purge' + 'recover' + 'release' + 'restore' + 'rotate' + 'setrotationpolicy' + 'sign' + 'unwrapKey' + 'update' + 'verify' + 'wrapKey' + ] + ``` + +### Parameter: `accessPolicies.permissions.secrets` + +Permissions to secrets. + +- Required: No +- Type: array +- Allowed: + ```Bicep + [ + 'all' + 'backup' + 'delete' + 'get' + 'list' + 'purge' + 'recover' + 'restore' + 'set' + ] + ``` + +### Parameter: `accessPolicies.permissions.storage` + +Permissions to storage accounts. + +- Required: No +- Type: array +- Allowed: + ```Bicep + [ + 'all' + 'backup' + 'delete' + 'deletesas' + 'get' + 'getsas' + 'list' + 'listsas' + 'purge' + 'recover' + 'regeneratekey' + 'restore' + 'set' + 'setsas' + 'update' + ] + ``` + ### Parameter: `accessPolicies.applicationId` Application ID of the client making request on behalf of a principal. diff --git a/avm/res/key-vault/vault/access-policy/main.json b/avm/res/key-vault/vault/access-policy/main.json index 91aca04548..567c4dc3c3 100644 --- a/avm/res/key-vault/vault/access-policy/main.json +++ b/avm/res/key-vault/vault/access-policy/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5144103047835198105" + "version": "0.25.53.49325", + "templateHash": "11791058225500616396" }, "name": "Key Vault Access Policies", "description": "This module deploys a Key Vault Access Policy.", diff --git a/avm/res/key-vault/vault/key/main.json b/avm/res/key-vault/vault/key/main.json index 57e27157d3..c24db6ea16 100644 --- a/avm/res/key-vault/vault/key/main.json +++ b/avm/res/key-vault/vault/key/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17466785154213688764" + "version": "0.25.53.49325", + "templateHash": "9470802651294896537" }, "name": "Key Vault Keys", "description": "This module deploys a Key Vault Key.", diff --git a/avm/res/key-vault/vault/main.bicep b/avm/res/key-vault/vault/main.bicep index 83c413e9ac..55a5bc90f2 100644 --- a/avm/res/key-vault/vault/main.bicep +++ b/avm/res/key-vault/vault/main.bicep @@ -53,7 +53,7 @@ param enablePurgeProtection bool = true ]) param sku string = 'premium' -@description('Optional. Rules governing the accessibility of the resouce from specific network locations.') +@description('Optional. Rules governing the accessibility of the resource from specific network locations.') param networkAcls object? @description('Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set.') @@ -179,19 +179,16 @@ resource keyVault_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'allLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -310,19 +307,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/key-vault/vault/main.json b/avm/res/key-vault/vault/main.json index d2d99facc5..2dc432b2e9 100644 --- a/avm/res/key-vault/vault/main.json +++ b/avm/res/key-vault/vault/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15629192251973726626" + "version": "0.25.53.49325", + "templateHash": "5160127432215154568" }, "name": "Key Vaults", "description": "This module deploys a Key Vault.", @@ -43,12 +43,19 @@ "metadata": { "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -61,12 +68,19 @@ "metadata": { "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -627,7 +641,7 @@ "type": "object", "nullable": true, "metadata": { - "description": "Optional. Rules governing the accessibility of the resouce from specific network locations." + "description": "Optional. Rules governing the accessibility of the resource from specific network locations." } }, "publicNetworkAccess": { @@ -782,12 +796,30 @@ "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -842,8 +874,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5144103047835198105" + "version": "0.25.53.49325", + "templateHash": "11791058225500616396" }, "name": "Key Vault Access Policies", "description": "This module deploys a Key Vault Access Policy.", @@ -1111,8 +1143,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14698549572049105523" + "version": "0.25.53.49325", + "templateHash": "13431676635055953332" }, "name": "Key Vault Secrets", "description": "This module deploys a Key Vault Secret.", @@ -1400,8 +1432,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17466785154213688764" + "version": "0.25.53.49325", + "templateHash": "9470802651294896537" }, "name": "Key Vault Keys", "description": "This module deploys a Key Vault Key.", diff --git a/avm/res/key-vault/vault/secret/main.json b/avm/res/key-vault/vault/secret/main.json index 30a6140cd4..8f1a79c52a 100644 --- a/avm/res/key-vault/vault/secret/main.json +++ b/avm/res/key-vault/vault/secret/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14698549572049105523" + "version": "0.25.53.49325", + "templateHash": "13431676635055953332" }, "name": "Key Vault Secrets", "description": "This module deploys a Key Vault Secret.", diff --git a/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep b/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep index b7fe8ae213..9a629f5218 100644 --- a/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep +++ b/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep @@ -116,12 +116,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } ] // Only for testing purposes enablePurgeProtection: false diff --git a/avm/res/kubernetes-configuration/extension/main.json b/avm/res/kubernetes-configuration/extension/main.json index 4032440fcd..a79e84ead3 100644 --- a/avm/res/kubernetes-configuration/extension/main.json +++ b/avm/res/kubernetes-configuration/extension/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "513848117762125355" + "version": "0.25.53.49325", + "templateHash": "7131693872347776073" }, "name": "Kubernetes Configuration Extensions", "description": "This module deploys a Kubernetes Configuration Extension.", diff --git a/avm/res/kubernetes-configuration/flux-configuration/main.json b/avm/res/kubernetes-configuration/flux-configuration/main.json index 762aa01298..6cd90c53c6 100644 --- a/avm/res/kubernetes-configuration/flux-configuration/main.json +++ b/avm/res/kubernetes-configuration/flux-configuration/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10887892542475311821" + "version": "0.25.53.49325", + "templateHash": "17949418893063624330" }, "name": "Kubernetes Configuration Flux Configurations", "description": "This module deploys a Kubernetes Configuration Flux Configuration.", diff --git a/avm/res/logic/workflow/README.md b/avm/res/logic/workflow/README.md index 545f0b5704..e9c5c824ef 100644 --- a/avm/res/logic/workflow/README.md +++ b/avm/res/logic/workflow/README.md @@ -558,9 +558,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -595,11 +595,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -609,11 +638,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/logic/workflow/main.bicep b/avm/res/logic/workflow/main.bicep index 86d345e173..709b83da75 100644 --- a/avm/res/logic/workflow/main.bicep +++ b/avm/res/logic/workflow/main.bicep @@ -162,19 +162,16 @@ resource logicApp_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -218,19 +215,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/logic/workflow/main.json b/avm/res/logic/workflow/main.json index 6375e3ae57..54957dd91a 100644 --- a/avm/res/logic/workflow/main.json +++ b/avm/res/logic/workflow/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4887030268335586960" + "version": "0.25.53.49325", + "templateHash": "2286082865500450205" }, "name": "Logic Apps (Workflows)", "description": "This module deploys a Logic App (Workflow).", @@ -41,14 +41,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -59,14 +66,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -504,12 +518,30 @@ "scope": "[format('Microsoft.Logic/workflows/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, diff --git a/avm/res/maintenance/maintenance-configuration/main.json b/avm/res/maintenance/maintenance-configuration/main.json index 4af13a2816..f06917ab55 100644 --- a/avm/res/maintenance/maintenance-configuration/main.json +++ b/avm/res/maintenance/maintenance-configuration/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "88181717284104014" + "version": "0.25.53.49325", + "templateHash": "16015110608585715401" }, "name": "Maintenance Configurations", "description": "This module deploys a Maintenance Configuration.", diff --git a/avm/res/managed-identity/user-assigned-identity/federated-identity-credential/main.json b/avm/res/managed-identity/user-assigned-identity/federated-identity-credential/main.json index 80b81d1673..41b27ff161 100644 --- a/avm/res/managed-identity/user-assigned-identity/federated-identity-credential/main.json +++ b/avm/res/managed-identity/user-assigned-identity/federated-identity-credential/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13076033972616288645" + "version": "0.25.53.49325", + "templateHash": "15826270550299120709" }, "name": "User Assigned Identity Federated Identity Credential", "description": "This module deploys a User Assigned Identity Federated Identity Credential.", diff --git a/avm/res/managed-identity/user-assigned-identity/main.json b/avm/res/managed-identity/user-assigned-identity/main.json index 6e8d8756da..6688e6518c 100644 --- a/avm/res/managed-identity/user-assigned-identity/main.json +++ b/avm/res/managed-identity/user-assigned-identity/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10668131901602645193" + "version": "0.25.53.49325", + "templateHash": "14161959215427804200" }, "name": "User Assigned Identities", "description": "This module deploys a User Assigned Identity.", @@ -264,8 +264,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13076033972616288645" + "version": "0.25.53.49325", + "templateHash": "15826270550299120709" }, "name": "User Assigned Identity Federated Identity Credential", "description": "This module deploys a User Assigned Identity Federated Identity Credential.", diff --git a/avm/res/management/management-group/README.md b/avm/res/management/management-group/README.md new file mode 100644 index 0000000000..7a1b340df3 --- /dev/null +++ b/avm/res/management/management-group/README.md @@ -0,0 +1,288 @@ +# Management Groups `[Microsoft.Management/managementGroups]` + +This template will prepare the management group structure based on the provided parameter. + +This module has some known **limitations**: +- It's not possible to change the display name of the root management group (the one that has the tenant GUID as ID) +- It can't manage the Root (/) management group + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Notes](#Notes) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Management/managementGroups` | [2021-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Management/2021-04-01/managementGroups) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/management/management-group:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep +module managementGroup 'br/public:avm/res/management/management-group:' = { + name: '${uniqueString(deployment().name)}-test-mmgmin' + params: { + // Required parameters + name: 'mmgmin001' + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "mmgmin001" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module managementGroup 'br/public:avm/res/management/management-group:' = { + name: '${uniqueString(deployment().name)}-test-mmgmax' + params: { + // Required parameters + name: 'mmgmax001' + // Non-required parameters + displayName: 'Test MG' + location: '' + parentId: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "mmgmax001" + }, + // Non-required parameters + "displayName": { + "value": "Test MG" + }, + "location": { + "value": "" + }, + "parentId": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 3: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module managementGroup 'br/public:avm/res/management/management-group:' = { + name: '${uniqueString(deployment().name)}-test-mmgwaf' + params: { + // Required parameters + name: 'mmgwaf001' + // Non-required parameters + displayName: 'Test MG' + location: '' + parentId: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "mmgwaf001" + }, + // Non-required parameters + "displayName": { + "value": "Test MG" + }, + "location": { + "value": "" + }, + "parentId": { + "value": "" + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The group ID of the Management group. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`displayName`](#parameter-displayname) | string | The friendly name of the management group. If no value is passed then this field will be set to the group ID. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`location`](#parameter-location) | string | Location deployment metadata. | +| [`parentId`](#parameter-parentid) | string | The management group parent ID. Defaults to current scope. | + +### Parameter: `name` + +The group ID of the Management group. + +- Required: Yes +- Type: string + +### Parameter: `displayName` + +The friendly name of the management group. If no value is passed then this field will be set to the group ID. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `location` + +Location deployment metadata. + +- Required: No +- Type: string +- Default: `[deployment().location]` + +### Parameter: `parentId` + +The management group parent ID. Defaults to current scope. + +- Required: No +- Type: string +- Default: `[last(split(managementGroup().id, '/'))]` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the management group. | +| `resourceId` | string | The resource ID of the management group. | + +## Cross-referenced modules + +_None_ + +## Notes + +### Considerations + +This template is using a **Tenant level deployment**, meaning the user/principal deploying it needs to have the [proper access](https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/deploy-to-tenant#required-access) + +If owner access is excessive, the following rights roles will grant enough rights: + +- **Automation Job Operator** at **tenant** level (scope '/') +- **Management Group Contributor** at the top management group that needs to be managed + +Consider using the following script: + +```powershell +$PrincipalID = "" +$TopMGID = "" +New-AzRoleAssignment -ObjectId $PrincipalID -Scope "/" -RoleDefinitionName "Automation Job Operator" +New-AzRoleAssignment -ObjectId $PrincipalID -Scope "/providers/Microsoft.Management/managementGroups/$TopMGID" -RoleDefinitionName "Management Group Contributor" +``` + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/management/management-group/main.bicep b/avm/res/management/management-group/main.bicep new file mode 100644 index 0000000000..589fe375fa --- /dev/null +++ b/avm/res/management/management-group/main.bicep @@ -0,0 +1,67 @@ +metadata name = 'Management Groups' +metadata description = '''This template will prepare the management group structure based on the provided parameter. + +This module has some known **limitations**: +- It's not possible to change the display name of the root management group (the one that has the tenant GUID as ID) +- It can't manage the Root (/) management group''' +metadata owner = 'Azure/module-maintainers' + +targetScope = 'managementGroup' + +@description('Required. The group ID of the Management group.') +param name string + +@description('Optional. The friendly name of the management group. If no value is passed then this field will be set to the group ID.') +param displayName string = '' + +@description('Optional. The management group parent ID. Defaults to current scope.') +param parentId string = last(split(az.managementGroup().id, '/'))! + +@description('Optional. Location deployment metadata.') +param location string = deployment().location + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.management-managementgroup.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + location: location + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource parentManagementGroup 'Microsoft.Management/managementGroups@2021-04-01' existing = { + name: parentId + scope: tenant() +} + +resource managementGroup 'Microsoft.Management/managementGroups@2021-04-01' = { + name: name + scope: tenant() + properties: { + displayName: displayName + details: !empty(parentId) ? { + parent: { + id: parentManagementGroup.id + } + } : null + } +} + +@description('The name of the management group.') +output name string = managementGroup.name + +@description('The resource ID of the management group.') +output resourceId string = managementGroup.id diff --git a/avm/res/management/management-group/main.json b/avm/res/management/management-group/main.json new file mode 100644 index 0000000000..7fe3ed1d62 --- /dev/null +++ b/avm/res/management/management-group/main.json @@ -0,0 +1,99 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "14104914545746658709" + }, + "name": "Management Groups", + "description": "This template will prepare the management group structure based on the provided parameter.\n\nThis module has some known **limitations**:\n- It's not possible to change the display name of the root management group (the one that has the tenant GUID as ID)\n- It can't manage the Root (/) management group", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The group ID of the Management group." + } + }, + "displayName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The friendly name of the management group. If no value is passed then this field will be set to the group ID." + } + }, + "parentId": { + "type": "string", + "defaultValue": "[last(split(managementGroup().id, '/'))]", + "metadata": { + "description": "Optional. The management group parent ID. Defaults to current scope." + } + }, + "location": { + "type": "string", + "defaultValue": "[deployment().location]", + "metadata": { + "description": "Optional. Location deployment metadata." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.management-managementgroup.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "location": "[parameters('location')]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + { + "type": "Microsoft.Management/managementGroups", + "apiVersion": "2021-04-01", + "scope": "/", + "name": "[parameters('name')]", + "properties": { + "displayName": "[parameters('displayName')]", + "details": "[if(not(empty(parameters('parentId'))), createObject('parent', createObject('id', tenantResourceId('Microsoft.Management/managementGroups', parameters('parentId')))), null())]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the management group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the management group." + }, + "value": "[tenantResourceId('Microsoft.Management/managementGroups', parameters('name'))]" + } + } +} \ No newline at end of file diff --git a/avm/res/management/management-group/tests/e2e/defaults/main.test.bicep b/avm/res/management/management-group/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..cd24a798ff --- /dev/null +++ b/avm/res/management/management-group/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,30 @@ +targetScope = 'managementGroup' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'mmgmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + name: '${uniqueString(deployment().name)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + } +}] diff --git a/avm/res/management/management-group/tests/e2e/max/main.test.bicep b/avm/res/management/management-group/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..38ef9faf72 --- /dev/null +++ b/avm/res/management/management-group/tests/e2e/max/main.test.bicep @@ -0,0 +1,32 @@ +targetScope = 'managementGroup' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'mmgmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + name: '${uniqueString(deployment().name)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + displayName: 'Test MG' + parentId: last(split(managementGroup().id, '/')) + } +}] diff --git a/avm/res/management/management-group/tests/e2e/waf-aligned/main.test.bicep b/avm/res/management/management-group/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..a27ae728fa --- /dev/null +++ b/avm/res/management/management-group/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,32 @@ +targetScope = 'managementGroup' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'mmgwaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + name: '${uniqueString(deployment().name)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + displayName: 'Test MG' + parentId: last(split(managementGroup().id, '/')) + } +}] diff --git a/avm/res/management/management-group/version.json b/avm/res/management/management-group/version.json new file mode 100644 index 0000000000..83083db694 --- /dev/null +++ b/avm/res/management/management-group/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file diff --git a/avm/res/net-app/net-app-account/capacity-pool/main.json b/avm/res/net-app/net-app-account/capacity-pool/main.json index e4bd310cfb..0d146bf069 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/main.json +++ b/avm/res/net-app/net-app-account/capacity-pool/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "126791606947586118" + "version": "0.25.53.49325", + "templateHash": "9701673230796867736" }, "name": "Azure NetApp Files Capacity Pools", "description": "This module deploys an Azure NetApp Files Capacity Pool.", @@ -273,8 +273,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "587216728391543886" + "version": "0.25.53.49325", + "templateHash": "8808262417279983135" }, "name": "Azure NetApp Files Capacity Pool Volumes", "description": "This module deploys an Azure NetApp Files Capacity Pool Volume.", diff --git a/avm/res/net-app/net-app-account/capacity-pool/volume/main.json b/avm/res/net-app/net-app-account/capacity-pool/volume/main.json index 1a8275a515..358a2f7d6e 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/volume/main.json +++ b/avm/res/net-app/net-app-account/capacity-pool/volume/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "587216728391543886" + "version": "0.25.53.49325", + "templateHash": "8808262417279983135" }, "name": "Azure NetApp Files Capacity Pool Volumes", "description": "This module deploys an Azure NetApp Files Capacity Pool Volume.", diff --git a/avm/res/net-app/net-app-account/main.json b/avm/res/net-app/net-app-account/main.json index 9cff3848e2..4cc3dd1b91 100644 --- a/avm/res/net-app/net-app-account/main.json +++ b/avm/res/net-app/net-app-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7695895341008630388" + "version": "0.25.53.49325", + "templateHash": "18391773655889763585" }, "name": "Azure NetApp Files", "description": "This module deploys an Azure NetApp File.", @@ -348,8 +348,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "126791606947586118" + "version": "0.25.53.49325", + "templateHash": "9701673230796867736" }, "name": "Azure NetApp Files Capacity Pools", "description": "This module deploys an Azure NetApp Files Capacity Pool.", @@ -616,8 +616,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "587216728391543886" + "version": "0.25.53.49325", + "templateHash": "8808262417279983135" }, "name": "Azure NetApp Files Capacity Pool Volumes", "description": "This module deploys an Azure NetApp Files Capacity Pool Volume.", diff --git a/avm/res/network/application-security-group/main.json b/avm/res/network/application-security-group/main.json index bbe3bc4be7..02317ce977 100644 --- a/avm/res/network/application-security-group/main.json +++ b/avm/res/network/application-security-group/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8371839368094432897" + "version": "0.25.53.49325", + "templateHash": "18328102101906578940" }, "name": "Application Security Groups (ASG)", "description": "This module deploys an Application Security Group (ASG).", diff --git a/avm/res/network/bastion-host/README.md b/avm/res/network/bastion-host/README.md index dd623e6f75..70bf4d00ce 100644 --- a/avm/res/network/bastion-host/README.md +++ b/avm/res/network/bastion-host/README.md @@ -552,7 +552,7 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -588,11 +588,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. diff --git a/avm/res/network/bastion-host/main.bicep b/avm/res/network/bastion-host/main.bicep index d971617aeb..61acff82d1 100644 --- a/avm/res/network/bastion-host/main.bicep +++ b/avm/res/network/bastion-host/main.bicep @@ -165,12 +165,11 @@ resource azureBastion_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@ workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -245,13 +244,16 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/network/bastion-host/main.json b/avm/res/network/bastion-host/main.json index 911abd0c01..3902a1b7fd 100644 --- a/avm/res/network/bastion-host/main.json +++ b/avm/res/network/bastion-host/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "18087298610689039063" + "version": "0.25.53.49325", + "templateHash": "17052449880021967417" }, "name": "Bastion Hosts", "description": "This module deploys a Bastion Host.", @@ -132,14 +132,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -383,11 +390,21 @@ "scope": "[format('Microsoft.Network/bastionHosts/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, diff --git a/avm/res/network/connection/main.json b/avm/res/network/connection/main.json index fd7cfc58f9..5747c1044f 100644 --- a/avm/res/network/connection/main.json +++ b/avm/res/network/connection/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14326202302024370679" + "version": "0.25.53.49325", + "templateHash": "16775998299537501869" }, "name": "Virtual Network Gateway Connections", "description": "This module deploys a Virtual Network Gateway Connection.", diff --git a/avm/res/network/ddos-protection-plan/main.json b/avm/res/network/ddos-protection-plan/main.json index 6e7bd6b4d7..a65b5d480d 100644 --- a/avm/res/network/ddos-protection-plan/main.json +++ b/avm/res/network/ddos-protection-plan/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1373305072087298852" + "version": "0.25.53.49325", + "templateHash": "1916218161096059486" }, "name": "DDoS Protection Plans", "description": "This module deploys a DDoS Protection Plan.", diff --git a/avm/res/network/dns-forwarding-ruleset/forwarding-rule/main.json b/avm/res/network/dns-forwarding-ruleset/forwarding-rule/main.json index baffefe17e..3050c7c9b5 100644 --- a/avm/res/network/dns-forwarding-ruleset/forwarding-rule/main.json +++ b/avm/res/network/dns-forwarding-ruleset/forwarding-rule/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15650802450898687792" + "version": "0.25.53.49325", + "templateHash": "16468651666444588102" }, "name": "Dns Forwarding Rulesets Forwarding Rules", "description": "This template deploys Forwarding Rule in a Dns Forwarding Ruleset.", diff --git a/avm/res/network/dns-forwarding-ruleset/main.json b/avm/res/network/dns-forwarding-ruleset/main.json index 8748446cae..c591d647ed 100644 --- a/avm/res/network/dns-forwarding-ruleset/main.json +++ b/avm/res/network/dns-forwarding-ruleset/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "108251292480329346" + "version": "0.25.53.49325", + "templateHash": "4310630541865622256" }, "name": "Dns Forwarding Rulesets", "description": "This template deploys an dns forwarding ruleset.", @@ -359,8 +359,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15650802450898687792" + "version": "0.25.53.49325", + "templateHash": "16468651666444588102" }, "name": "Dns Forwarding Rulesets Forwarding Rules", "description": "This template deploys Forwarding Rule in a Dns Forwarding Ruleset.", @@ -484,8 +484,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12597298600496339402" + "version": "0.25.53.49325", + "templateHash": "2776981605709910245" }, "name": "Dns Forwarding Rulesets Virtual Network Links", "description": "This template deploys Virtual Network Link in a Dns Forwarding Ruleset.", diff --git a/avm/res/network/dns-forwarding-ruleset/virtual-network-link/main.json b/avm/res/network/dns-forwarding-ruleset/virtual-network-link/main.json index 722cc5123e..1416d30645 100644 --- a/avm/res/network/dns-forwarding-ruleset/virtual-network-link/main.json +++ b/avm/res/network/dns-forwarding-ruleset/virtual-network-link/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12597298600496339402" + "version": "0.25.53.49325", + "templateHash": "2776981605709910245" }, "name": "Dns Forwarding Rulesets Virtual Network Links", "description": "This template deploys Virtual Network Link in a Dns Forwarding Ruleset.", diff --git a/avm/res/network/dns-resolver/inbound-endpoint/main.json b/avm/res/network/dns-resolver/inbound-endpoint/main.json index 48dfd0426f..baa29e7843 100644 --- a/avm/res/network/dns-resolver/inbound-endpoint/main.json +++ b/avm/res/network/dns-resolver/inbound-endpoint/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12086001893141712398" + "version": "0.25.53.49325", + "templateHash": "4122702757444237290" }, "name": "DNS Resolver Inbound Endpoint", "description": "This module deploys a DNS Resolver Inbound Endpoint.", diff --git a/avm/res/network/dns-resolver/main.json b/avm/res/network/dns-resolver/main.json index 7c6662a841..57c822f7e3 100644 --- a/avm/res/network/dns-resolver/main.json +++ b/avm/res/network/dns-resolver/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9938371933399319052" + "version": "0.25.53.49325", + "templateHash": "8011975579597033437" }, "name": "DNS Resolvers", "description": "This module deploys a DNS Resolver.", @@ -293,8 +293,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12086001893141712398" + "version": "0.25.53.49325", + "templateHash": "4122702757444237290" }, "name": "DNS Resolver Inbound Endpoint", "description": "This module deploys a DNS Resolver Inbound Endpoint.", @@ -444,8 +444,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10188821198018164568" + "version": "0.25.53.49325", + "templateHash": "1054861255449270275" }, "name": "DNS Resolver Outbound Endpoint", "description": "This module deploys a DNS Resolver Outbound Endpoint.", diff --git a/avm/res/network/dns-resolver/outbound-endpoint/main.json b/avm/res/network/dns-resolver/outbound-endpoint/main.json index d9c58af176..06a5c3c8b0 100644 --- a/avm/res/network/dns-resolver/outbound-endpoint/main.json +++ b/avm/res/network/dns-resolver/outbound-endpoint/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10188821198018164568" + "version": "0.25.53.49325", + "templateHash": "1054861255449270275" }, "name": "DNS Resolver Outbound Endpoint", "description": "This module deploys a DNS Resolver Outbound Endpoint.", diff --git a/avm/res/network/dns-zone/a/main.json b/avm/res/network/dns-zone/a/main.json index 981fa75486..f95aa9a994 100644 --- a/avm/res/network/dns-zone/a/main.json +++ b/avm/res/network/dns-zone/a/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11066227371005155115" + "version": "0.25.53.49325", + "templateHash": "1014861232584705848" }, "name": "Public DNS Zone A record", "description": "This module deploys a Public DNS Zone A record.", diff --git a/avm/res/network/dns-zone/aaaa/main.json b/avm/res/network/dns-zone/aaaa/main.json index 103059d07c..d0fbec5f0e 100644 --- a/avm/res/network/dns-zone/aaaa/main.json +++ b/avm/res/network/dns-zone/aaaa/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6543343844712416320" + "version": "0.25.53.49325", + "templateHash": "17816545426283561774" }, "name": "Public DNS Zone AAAA record", "description": "This module deploys a Public DNS Zone AAAA record.", diff --git a/avm/res/network/dns-zone/caa/main.json b/avm/res/network/dns-zone/caa/main.json index 300e11ae9f..c3008da102 100644 --- a/avm/res/network/dns-zone/caa/main.json +++ b/avm/res/network/dns-zone/caa/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11278264316803375711" + "version": "0.25.53.49325", + "templateHash": "2222693701620961150" }, "name": "Public DNS Zone CAA record", "description": "This module deploys a Public DNS Zone CAA record.", diff --git a/avm/res/network/dns-zone/cname/main.json b/avm/res/network/dns-zone/cname/main.json index 4e9a2a012a..ce4232f426 100644 --- a/avm/res/network/dns-zone/cname/main.json +++ b/avm/res/network/dns-zone/cname/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3103347158305617686" + "version": "0.25.53.49325", + "templateHash": "11680687850109857660" }, "name": "Public DNS Zone CNAME record", "description": "This module deploys a Public DNS Zone CNAME record.", diff --git a/avm/res/network/dns-zone/main.json b/avm/res/network/dns-zone/main.json index 33e2275916..e13f76988d 100644 --- a/avm/res/network/dns-zone/main.json +++ b/avm/res/network/dns-zone/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4876589289221431730" + "version": "0.25.53.49325", + "templateHash": "17409480183805156141" }, "name": "Public DNS Zones", "description": "This module deploys a Public DNS zone.", @@ -343,8 +343,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11066227371005155115" + "version": "0.25.53.49325", + "templateHash": "1014861232584705848" }, "name": "Public DNS Zone A record", "description": "This module deploys a Public DNS Zone A record.", @@ -597,8 +597,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6543343844712416320" + "version": "0.25.53.49325", + "templateHash": "17816545426283561774" }, "name": "Public DNS Zone AAAA record", "description": "This module deploys a Public DNS Zone AAAA record.", @@ -851,8 +851,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3103347158305617686" + "version": "0.25.53.49325", + "templateHash": "11680687850109857660" }, "name": "Public DNS Zone CNAME record", "description": "This module deploys a Public DNS Zone CNAME record.", @@ -1102,8 +1102,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11278264316803375711" + "version": "0.25.53.49325", + "templateHash": "2222693701620961150" }, "name": "Public DNS Zone CAA record", "description": "This module deploys a Public DNS Zone CAA record.", @@ -1345,8 +1345,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5857061543613276848" + "version": "0.25.53.49325", + "templateHash": "11629556138650955144" }, "name": "Public DNS Zone MX record", "description": "This module deploys a Public DNS Zone MX record.", @@ -1588,8 +1588,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7968800835197338495" + "version": "0.25.53.49325", + "templateHash": "16161487720425898744" }, "name": "Public DNS Zone NS record", "description": "This module deploys a Public DNS Zone NS record.", @@ -1831,8 +1831,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14317071564761537716" + "version": "0.25.53.49325", + "templateHash": "7707819456897162158" }, "name": "Public DNS Zone PTR record", "description": "This module deploys a Public DNS Zone PTR record.", @@ -2074,8 +2074,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17342822259090417988" + "version": "0.25.53.49325", + "templateHash": "4795044712963544053" }, "name": "Public DNS Zone SOA record", "description": "This module deploys a Public DNS Zone SOA record.", @@ -2317,8 +2317,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17909997479406761822" + "version": "0.25.53.49325", + "templateHash": "14428108443514495816" }, "name": "Public DNS Zone SRV record", "description": "This module deploys a Public DNS Zone SRV record.", @@ -2560,8 +2560,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6097421092837151165" + "version": "0.25.53.49325", + "templateHash": "789212919897780335" }, "name": "Public DNS Zone TXT record", "description": "This module deploys a Public DNS Zone TXT record.", diff --git a/avm/res/network/dns-zone/mx/main.json b/avm/res/network/dns-zone/mx/main.json index 625737ae3a..fcf04baf23 100644 --- a/avm/res/network/dns-zone/mx/main.json +++ b/avm/res/network/dns-zone/mx/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5857061543613276848" + "version": "0.25.53.49325", + "templateHash": "11629556138650955144" }, "name": "Public DNS Zone MX record", "description": "This module deploys a Public DNS Zone MX record.", diff --git a/avm/res/network/dns-zone/ns/main.json b/avm/res/network/dns-zone/ns/main.json index 7e9347b45a..46226a0939 100644 --- a/avm/res/network/dns-zone/ns/main.json +++ b/avm/res/network/dns-zone/ns/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7968800835197338495" + "version": "0.25.53.49325", + "templateHash": "16161487720425898744" }, "name": "Public DNS Zone NS record", "description": "This module deploys a Public DNS Zone NS record.", diff --git a/avm/res/network/dns-zone/ptr/main.json b/avm/res/network/dns-zone/ptr/main.json index 7547116984..cdb6b7f82d 100644 --- a/avm/res/network/dns-zone/ptr/main.json +++ b/avm/res/network/dns-zone/ptr/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14317071564761537716" + "version": "0.25.53.49325", + "templateHash": "7707819456897162158" }, "name": "Public DNS Zone PTR record", "description": "This module deploys a Public DNS Zone PTR record.", diff --git a/avm/res/network/dns-zone/soa/main.json b/avm/res/network/dns-zone/soa/main.json index 79c83b1c28..8b0dd53fa1 100644 --- a/avm/res/network/dns-zone/soa/main.json +++ b/avm/res/network/dns-zone/soa/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17342822259090417988" + "version": "0.25.53.49325", + "templateHash": "4795044712963544053" }, "name": "Public DNS Zone SOA record", "description": "This module deploys a Public DNS Zone SOA record.", diff --git a/avm/res/network/dns-zone/srv/main.json b/avm/res/network/dns-zone/srv/main.json index dc73a069b3..56e32bec1e 100644 --- a/avm/res/network/dns-zone/srv/main.json +++ b/avm/res/network/dns-zone/srv/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17909997479406761822" + "version": "0.25.53.49325", + "templateHash": "14428108443514495816" }, "name": "Public DNS Zone SRV record", "description": "This module deploys a Public DNS Zone SRV record.", diff --git a/avm/res/network/dns-zone/txt/main.json b/avm/res/network/dns-zone/txt/main.json index 80284db617..0d275f47ee 100644 --- a/avm/res/network/dns-zone/txt/main.json +++ b/avm/res/network/dns-zone/txt/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6097421092837151165" + "version": "0.25.53.49325", + "templateHash": "789212919897780335" }, "name": "Public DNS Zone TXT record", "description": "This module deploys a Public DNS Zone TXT record.", diff --git a/avm/res/network/express-route-circuit/README.md b/avm/res/network/express-route-circuit/README.md index 03dadf9daa..137836134f 100644 --- a/avm/res/network/express-route-circuit/README.md +++ b/avm/res/network/express-route-circuit/README.md @@ -471,9 +471,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -508,11 +508,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -522,11 +551,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/network/express-route-circuit/main.bicep b/avm/res/network/express-route-circuit/main.bicep index d94cbaaf80..1394cacf99 100644 --- a/avm/res/network/express-route-circuit/main.bicep +++ b/avm/res/network/express-route-circuit/main.bicep @@ -165,19 +165,16 @@ resource expressRouteCircuits_diagnosticSettings 'Microsoft.Insights/diagnosticS workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -252,19 +249,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/network/express-route-circuit/main.json b/avm/res/network/express-route-circuit/main.json index cd5d83153f..d1deecbc00 100644 --- a/avm/res/network/express-route-circuit/main.json +++ b/avm/res/network/express-route-circuit/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1104554959079995668" + "version": "0.25.53.49325", + "templateHash": "1951233357364145060" }, "name": "ExpressRoute Circuits", "description": "This module deploys an Express Route Circuit.", @@ -132,14 +132,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -150,14 +157,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -459,12 +473,30 @@ "scope": "[format('Microsoft.Network/expressRouteCircuits/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, diff --git a/avm/res/network/express-route-gateway/main.json b/avm/res/network/express-route-gateway/main.json index d939eaf4a7..2c4afb55c3 100644 --- a/avm/res/network/express-route-gateway/main.json +++ b/avm/res/network/express-route-gateway/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14141757213544356427" + "version": "0.25.53.49325", + "templateHash": "5520177504222517638" }, "name": "Express Route Gateways", "description": "This module deploys an Express Route Gateway.", diff --git a/avm/res/network/firewall-policy/main.json b/avm/res/network/firewall-policy/main.json index cc430c6b10..6c73551236 100644 --- a/avm/res/network/firewall-policy/main.json +++ b/avm/res/network/firewall-policy/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "576890491523219712" + "version": "0.25.53.49325", + "templateHash": "18010679319561930400" }, "name": "Firewall Policies", "description": "This module deploys a Firewall Policy.", @@ -310,8 +310,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "7306629689940419640" + "version": "0.25.53.49325", + "templateHash": "17945865046689186214" }, "name": "Firewall Policy Rule Collection Groups", "description": "This module deploys a Firewall Policy Rule Collection Group.", diff --git a/avm/res/network/firewall-policy/rule-collection-group/main.json b/avm/res/network/firewall-policy/rule-collection-group/main.json index fa05688bd6..b6ec7d3e49 100644 --- a/avm/res/network/firewall-policy/rule-collection-group/main.json +++ b/avm/res/network/firewall-policy/rule-collection-group/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "7306629689940419640" + "version": "0.25.53.49325", + "templateHash": "17945865046689186214" }, "name": "Firewall Policy Rule Collection Groups", "description": "This module deploys a Firewall Policy Rule Collection Group.", diff --git a/avm/res/network/front-door-web-application-firewall-policy/main.json b/avm/res/network/front-door-web-application-firewall-policy/main.json index 4ff87e228d..4df136f697 100644 --- a/avm/res/network/front-door-web-application-firewall-policy/main.json +++ b/avm/res/network/front-door-web-application-firewall-policy/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "15621879470526271545" + "version": "0.25.53.49325", + "templateHash": "1373577986476180700" }, "name": "Front Door Web Application Firewall (WAF) Policies", "description": "This module deploys a Front Door Web Application Firewall (WAF) Policy.", diff --git a/avm/res/network/front-door/README.md b/avm/res/network/front-door/README.md index 41c269566a..a6410897b1 100644 --- a/avm/res/network/front-door/README.md +++ b/avm/res/network/front-door/README.md @@ -277,7 +277,6 @@ module frontDoor 'br/public:avm/res/network/front-door:' = { privateLinkAlias: '' privateLinkApprovalMessage: '' privateLinkLocation: '' - privateLinkResourceId: '' weight: 50 } ] @@ -369,12 +368,6 @@ module frontDoor 'br/public:avm/res/network/front-door:' = { storageAccountResourceId: '' workspaceResourceId: '' } - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - storageAccountResourceId: '' - workspaceResourceId: '' - } ] enforceCertificateNameCheck: 'Disabled' location: '' @@ -438,7 +431,6 @@ module frontDoor 'br/public:avm/res/network/front-door:' = { "privateLinkAlias": "", "privateLinkApprovalMessage": "", "privateLinkLocation": "", - "privateLinkResourceId": "", "weight": 50 } ], @@ -541,12 +533,6 @@ module frontDoor 'br/public:avm/res/network/front-door:' = { "name": "customSetting", "storageAccountResourceId": "", "workspaceResourceId": "" - }, - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "storageAccountResourceId": "", - "workspaceResourceId": "" } ] }, @@ -627,7 +613,6 @@ module frontDoor 'br/public:avm/res/network/front-door:' = { privateLinkAlias: '' privateLinkApprovalMessage: '' privateLinkLocation: '' - privateLinkResourceId: '' weight: 50 } ] @@ -750,7 +735,6 @@ module frontDoor 'br/public:avm/res/network/front-door:' = { "privateLinkAlias": "", "privateLinkApprovalMessage": "", "privateLinkLocation": "", - "privateLinkResourceId": "", "weight": 50 } ], @@ -953,9 +937,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -990,11 +974,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1004,11 +1017,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/network/front-door/main.bicep b/avm/res/network/front-door/main.bicep index 09f30b2c8c..d121c34cb1 100644 --- a/avm/res/network/front-door/main.bicep +++ b/avm/res/network/front-door/main.bicep @@ -115,19 +115,16 @@ resource frontDoor_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@202 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -196,19 +193,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/network/front-door/main.json b/avm/res/network/front-door/main.json index 8a3a5a9ed0..140a73c6ad 100644 --- a/avm/res/network/front-door/main.json +++ b/avm/res/network/front-door/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "13569850532097768114" + "version": "0.25.53.49325", + "templateHash": "5209569003361494357" }, "name": "Azure Front Doors", "description": "This module deploys an Azure Front Door.", @@ -132,14 +132,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -150,14 +157,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -394,12 +408,30 @@ "scope": "[format('Microsoft.Network/frontDoors/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, diff --git a/avm/res/network/front-door/tests/e2e/max/main.test.bicep b/avm/res/network/front-door/tests/e2e/max/main.test.bicep index 2af64d2d37..aa6d4a9abe 100644 --- a/avm/res/network/front-door/tests/e2e/max/main.test.bicep +++ b/avm/res/network/front-door/tests/e2e/max/main.test.bicep @@ -80,7 +80,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' privateLinkAlias: '' privateLinkApprovalMessage: '' privateLinkLocation: '' - privateLinkResourceId: '' weight: 50 } ] @@ -193,12 +192,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } ] tags: { 'hidden-title': 'This is visible in the resource name' diff --git a/avm/res/network/front-door/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/front-door/tests/e2e/waf-aligned/main.test.bicep index ccefa82e3f..99c37e7c9b 100644 --- a/avm/res/network/front-door/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/front-door/tests/e2e/waf-aligned/main.test.bicep @@ -71,7 +71,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' privateLinkAlias: '' privateLinkApprovalMessage: '' privateLinkLocation: '' - privateLinkResourceId: '' weight: 50 } ] diff --git a/avm/res/network/ip-group/README.md b/avm/res/network/ip-group/README.md new file mode 100644 index 0000000000..0a5fc6ec51 --- /dev/null +++ b/avm/res/network/ip-group/README.md @@ -0,0 +1,467 @@ +# IP Groups `[Microsoft.Network/ipGroups]` + +This module deploys an IP Group. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Network/ipGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/ipGroups) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/network/ip-group:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep +module ipGroup 'br/public:avm/res/network/ip-group:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nigmin' + params: { + // Required parameters + name: 'nigmin001' + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "nigmin001" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module ipGroup 'br/public:avm/res/network/ip-group:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nigmax' + params: { + // Required parameters + name: 'nigmax001' + // Non-required parameters + ipAddresses: [ + '10.0.0.1' + '10.0.0.2' + ] + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "nigmax001" + }, + // Non-required parameters + "ipAddresses": { + "value": [ + "10.0.0.1", + "10.0.0.2" + ] + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + +### Example 3: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module ipGroup 'br/public:avm/res/network/ip-group:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nigwaf' + params: { + // Required parameters + name: 'nigwaf001' + // Non-required parameters + ipAddresses: [ + '10.0.0.1' + '10.0.0.2' + ] + location: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "nigwaf001" + }, + // Non-required parameters + "ipAddresses": { + "value": [ + "10.0.0.1", + "10.0.0.2" + ] + }, + "location": { + "value": "" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the ipGroups. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`ipAddresses`](#parameter-ipaddresses) | array | IpAddresses/IpAddressPrefixes in the IpGroups resource. | +| [`location`](#parameter-location) | string | Location for all resources. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`tags`](#parameter-tags) | object | Resource tags. | + +### Parameter: `name` + +The name of the ipGroups. + +- Required: Yes +- Type: string + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `ipAddresses` + +IpAddresses/IpAddressPrefixes in the IpGroups resource. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `location` + +Location for all resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `tags` + +Resource tags. + +- Required: No +- Type: object + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the IP group. | +| `resourceGroupName` | string | The resource group of the IP group was deployed into. | +| `resourceId` | string | The resource ID of the IP group. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/network/ip-group/main.bicep b/avm/res/network/ip-group/main.bicep new file mode 100644 index 0000000000..a0ac6abed3 --- /dev/null +++ b/avm/res/network/ip-group/main.bicep @@ -0,0 +1,131 @@ +metadata name = 'IP Groups' +metadata description = 'This module deploys an IP Group.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The name of the ipGroups.') +@minLength(1) +param name string + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@description('Optional. IpAddresses/IpAddressPrefixes in the IpGroups resource.') +param ipAddresses array = [] + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Optional. Resource tags.') +param tags object? + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'IPAM Pool Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b3e853f-ad5d-4fb5-a7b8-56a3581c7037') + 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.network-ipgroup.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource ipGroup 'Microsoft.Network/ipGroups@2023-04-01' = { + name: name + location: location + tags: tags + properties: { + ipAddresses: ipAddresses + } +} + +resource ipGroup_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: ipGroup +} + +resource ipGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(ipGroup.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: ipGroup +}] + +@description('The resource ID of the IP group.') +output resourceId string = ipGroup.id + +@description('The resource group of the IP group was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The name of the IP group.') +output name string = ipGroup.name + +@description('The location the resource was deployed into.') +output location string = ipGroup.location + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? diff --git a/avm/res/network/ip-group/main.json b/avm/res/network/ip-group/main.json new file mode 100644 index 0000000000..0d02c1d3c2 --- /dev/null +++ b/avm/res/network/ip-group/main.json @@ -0,0 +1,265 @@ +{ + "$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.25.53.49325", + "templateHash": "6351514954757717512" + }, + "name": "IP Groups", + "description": "This module deploys an IP Group.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Required. The name of the ipGroups." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "ipAddresses": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. IpAddresses/IpAddressPrefixes in the IpGroups resource." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "IPAM Pool Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b3e853f-ad5d-4fb5-a7b8-56a3581c7037')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-ipgroup.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "ipGroup": { + "type": "Microsoft.Network/ipGroups", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "ipAddresses": "[parameters('ipAddresses')]" + } + }, + "ipGroup_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/ipGroups/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "ipGroup" + ] + }, + "ipGroup_roleAssignments": { + "copy": { + "name": "ipGroup_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/ipGroups/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/ipGroups', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "ipGroup" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the IP group." + }, + "value": "[resourceId('Microsoft.Network/ipGroups', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the IP group was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the IP group." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('ipGroup', '2023-04-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/network/ip-group/tests/e2e/defaults/main.test.bicep b/avm/res/network/ip-group/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..6341b22f1e --- /dev/null +++ b/avm/res/network/ip-group/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,46 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.ipgroups-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nigmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + } +}] diff --git a/avm/res/network/ip-group/tests/e2e/max/dependencies.bicep b/avm/res/network/ip-group/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..a7f42aee7b --- /dev/null +++ b/avm/res/network/ip-group/tests/e2e/max/dependencies.bicep @@ -0,0 +1,13 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/res/network/ip-group/tests/e2e/max/main.test.bicep b/avm/res/network/ip-group/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..7e5f42408f --- /dev/null +++ b/avm/res/network/ip-group/tests/e2e/max/main.test.bicep @@ -0,0 +1,85 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.ipgroups-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nigmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + ipAddresses: [ + '10.0.0.1' + '10.0.0.2' + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/network/ip-group/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/ip-group/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..9c0a4a3e10 --- /dev/null +++ b/avm/res/network/ip-group/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,55 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.ipgroups-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nigwaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + ipAddresses: [ + '10.0.0.1' + '10.0.0.2' + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/network/ip-group/version.json b/avm/res/network/ip-group/version.json new file mode 100644 index 0000000000..83083db694 --- /dev/null +++ b/avm/res/network/ip-group/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file diff --git a/avm/res/network/load-balancer/README.md b/avm/res/network/load-balancer/README.md index 15334b8bb0..aee4173851 100644 --- a/avm/res/network/load-balancer/README.md +++ b/avm/res/network/load-balancer/README.md @@ -1005,7 +1005,7 @@ The diagnostic settings of the service. | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1047,11 +1047,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/network/load-balancer/backend-address-pool/main.json b/avm/res/network/load-balancer/backend-address-pool/main.json index ddba6d1c11..ab6d005e2d 100644 --- a/avm/res/network/load-balancer/backend-address-pool/main.json +++ b/avm/res/network/load-balancer/backend-address-pool/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5936342766594392284" + "version": "0.25.53.49325", + "templateHash": "16244632442901566911" }, "name": "Load Balancer Backend Address Pools", "description": "This module deploys a Load Balancer Backend Address Pools.", diff --git a/avm/res/network/load-balancer/inbound-nat-rule/main.json b/avm/res/network/load-balancer/inbound-nat-rule/main.json index a388f62a57..08de35dd26 100644 --- a/avm/res/network/load-balancer/inbound-nat-rule/main.json +++ b/avm/res/network/load-balancer/inbound-nat-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14202081637779720013" + "version": "0.25.53.49325", + "templateHash": "17788406033422026149" }, "name": "Load Balancer Inbound NAT Rules", "description": "This module deploys a Load Balancer Inbound NAT Rules.", diff --git a/avm/res/network/load-balancer/main.bicep b/avm/res/network/load-balancer/main.bicep index ca93a97443..081b5c1b8a 100644 --- a/avm/res/network/load-balancer/main.bicep +++ b/avm/res/network/load-balancer/main.bicep @@ -229,13 +229,11 @@ resource loadBalancer_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@ workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -283,10 +281,13 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/network/load-balancer/main.json b/avm/res/network/load-balancer/main.json index cda1cef236..0596ec342f 100644 --- a/avm/res/network/load-balancer/main.json +++ b/avm/res/network/load-balancer/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11386852556160593443" + "version": "0.25.53.49325", + "templateHash": "5849926741790594100" }, "name": "Load Balancers", "description": "This module deploys a Load Balancer.", @@ -33,14 +33,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -443,11 +450,21 @@ "scope": "[format('Microsoft.Network/loadBalancers/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -507,8 +524,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5936342766594392284" + "version": "0.25.53.49325", + "templateHash": "16244632442901566911" }, "name": "Load Balancer Backend Address Pools", "description": "This module deploys a Load Balancer Backend Address Pools.", @@ -644,8 +661,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14202081637779720013" + "version": "0.25.53.49325", + "templateHash": "17788406033422026149" }, "name": "Load Balancer Inbound NAT Rules", "description": "This module deploys a Load Balancer Inbound NAT Rules.", diff --git a/avm/res/network/local-network-gateway/main.json b/avm/res/network/local-network-gateway/main.json index 34fc7f19e2..2399fd278e 100644 --- a/avm/res/network/local-network-gateway/main.json +++ b/avm/res/network/local-network-gateway/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11224765230513420011" + "version": "0.25.53.49325", + "templateHash": "11943218028925171301" }, "name": "Local Network Gateways", "description": "This module deploys a Local Network Gateway.", diff --git a/avm/res/network/nat-gateway/main.bicep b/avm/res/network/nat-gateway/main.bicep index a7e93a6b3f..0790009605 100644 --- a/avm/res/network/nat-gateway/main.bicep +++ b/avm/res/network/nat-gateway/main.bicep @@ -203,41 +203,3 @@ type roleAssignmentType = { @description('Optional. The Resource Id of the delegated managed identity resource.') delegatedManagedIdentityResourceId: string? }[]? - -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') - categoryGroup: string? - }[]? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') - category: string - }[]? - - @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') - workspaceResourceId: string? - - @description('Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') - storageAccountResourceId: string? - - @description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') - eventHubAuthorizationRuleResourceId: string? - - @description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? diff --git a/avm/res/network/nat-gateway/main.json b/avm/res/network/nat-gateway/main.json index beffa56246..73b0856160 100644 --- a/avm/res/network/nat-gateway/main.json +++ b/avm/res/network/nat-gateway/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6395864833059360250" + "version": "0.25.53.49325", + "templateHash": "6217805544789578668" }, "name": "NAT Gateways", "description": "This module deploys a NAT Gateway.", @@ -103,112 +103,6 @@ } }, "nullable": true - }, - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } - }, - "logCategoriesAndGroups": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." - } - }, - "categoryGroup": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." - } - }, - "metricCategories": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." - } - }, - "logAnalyticsDestinationType": { - "type": "string", - "allowedValues": [ - "AzureDiagnostics", - "Dedicated" - ], - "nullable": true, - "metadata": { - "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." - } - }, - "workspaceResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "storageAccountResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "eventHubAuthorizationRuleResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." - } - }, - "eventHubName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "marketplacePartnerResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." - } - } - } - }, - "nullable": true } }, "parameters": { @@ -1029,8 +923,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16611084599101521713" + "version": "0.25.53.49325", + "templateHash": "7172917838055782951" } }, "parameters": { @@ -1407,8 +1301,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16611084599101521713" + "version": "0.25.53.49325", + "templateHash": "7172917838055782951" } }, "parameters": { diff --git a/avm/res/network/network-interface/README.md b/avm/res/network/network-interface/README.md index 71662f900b..c16ceff283 100644 --- a/avm/res/network/network-interface/README.md +++ b/avm/res/network/network-interface/README.md @@ -490,9 +490,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -527,11 +527,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -541,11 +570,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/network/network-interface/main.bicep b/avm/res/network/network-interface/main.bicep index 28f09418d7..9a7e7cd809 100644 --- a/avm/res/network/network-interface/main.bicep +++ b/avm/res/network/network-interface/main.bicep @@ -148,13 +148,11 @@ resource networkInterface_diagnosticSettings 'Microsoft.Insights/diagnosticSetti workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -198,19 +196,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/network/network-interface/main.json b/avm/res/network/network-interface/main.json index 49a1b1400b..75c70024f7 100644 --- a/avm/res/network/network-interface/main.json +++ b/avm/res/network/network-interface/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2855257830311225954" + "version": "0.25.53.49325", + "templateHash": "6823101790014877132" }, "name": "Network Interface", "description": "This module deploys a Network Interface.", @@ -43,12 +43,19 @@ "metadata": { "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -61,12 +68,19 @@ "metadata": { "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -423,11 +437,21 @@ "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, diff --git a/avm/res/network/network-security-group/README.md b/avm/res/network/network-security-group/README.md index d452941b7d..6a71380e4e 100644 --- a/avm/res/network/network-security-group/README.md +++ b/avm/res/network/network-security-group/README.md @@ -600,7 +600,7 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -636,11 +636,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. diff --git a/avm/res/network/network-security-group/main.bicep b/avm/res/network/network-security-group/main.bicep index 3b73fc8d4c..b91fa4c876 100644 --- a/avm/res/network/network-security-group/main.bicep +++ b/avm/res/network/network-security-group/main.bicep @@ -124,12 +124,11 @@ resource networkSecurityGroup_diagnosticSettings 'Microsoft.Insights/diagnosticS workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -201,13 +200,16 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/network/network-security-group/main.json b/avm/res/network/network-security-group/main.json index 7aeed9b40b..5c6096e566 100644 --- a/avm/res/network/network-security-group/main.json +++ b/avm/res/network/network-security-group/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14500468411287403856" + "version": "0.25.53.49325", + "templateHash": "4216984327038707510" }, "name": "Network Security Groups", "description": "This module deploys a Network security Group (NSG).", @@ -132,14 +132,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -345,11 +352,21 @@ "scope": "[format('Microsoft.Network/networkSecurityGroups/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -429,8 +446,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14729804066478009881" + "version": "0.25.53.49325", + "templateHash": "7870858269129613686" }, "name": "Network Security Group (NSG) Security Rules", "description": "This module deploys a Network Security Group (NSG) Security Rule.", diff --git a/avm/res/network/network-security-group/security-rule/main.json b/avm/res/network/network-security-group/security-rule/main.json index df50e15497..f2e48de864 100644 --- a/avm/res/network/network-security-group/security-rule/main.json +++ b/avm/res/network/network-security-group/security-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14729804066478009881" + "version": "0.25.53.49325", + "templateHash": "7870858269129613686" }, "name": "Network Security Group (NSG) Security Rules", "description": "This module deploys a Network Security Group (NSG) Security Rule.", diff --git a/avm/res/network/private-dns-zone/a/main.json b/avm/res/network/private-dns-zone/a/main.json index fb22f58404..81f4e9fa80 100644 --- a/avm/res/network/private-dns-zone/a/main.json +++ b/avm/res/network/private-dns-zone/a/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10579234366752030319" + "version": "0.25.53.49325", + "templateHash": "17565463524922013743" }, "name": "Private DNS Zone A record", "description": "This module deploys a Private DNS Zone A record.", diff --git a/avm/res/network/private-dns-zone/aaaa/main.json b/avm/res/network/private-dns-zone/aaaa/main.json index 5c94ff1357..00732682f0 100644 --- a/avm/res/network/private-dns-zone/aaaa/main.json +++ b/avm/res/network/private-dns-zone/aaaa/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9575159215218900502" + "version": "0.25.53.49325", + "templateHash": "14360797759459973436" }, "name": "Private DNS Zone AAAA record", "description": "This module deploys a Private DNS Zone AAAA record.", diff --git a/avm/res/network/private-dns-zone/cname/main.json b/avm/res/network/private-dns-zone/cname/main.json index 9a89ad2b3d..f590f488aa 100644 --- a/avm/res/network/private-dns-zone/cname/main.json +++ b/avm/res/network/private-dns-zone/cname/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2490762978448517029" + "version": "0.25.53.49325", + "templateHash": "8360937786294538789" }, "name": "Private DNS Zone CNAME record", "description": "This module deploys a Private DNS Zone CNAME record.", diff --git a/avm/res/network/private-dns-zone/main.json b/avm/res/network/private-dns-zone/main.json index 648def7b40..73b572a650 100644 --- a/avm/res/network/private-dns-zone/main.json +++ b/avm/res/network/private-dns-zone/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13412685182351792582" + "version": "0.25.53.49325", + "templateHash": "5015696597887719627" }, "name": "Private DNS Zones", "description": "This module deploys a Private DNS zone.", @@ -323,8 +323,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10579234366752030319" + "version": "0.25.53.49325", + "templateHash": "17565463524922013743" }, "name": "Private DNS Zone A record", "description": "This module deploys a Private DNS Zone A record.", @@ -562,8 +562,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9575159215218900502" + "version": "0.25.53.49325", + "templateHash": "14360797759459973436" }, "name": "Private DNS Zone AAAA record", "description": "This module deploys a Private DNS Zone AAAA record.", @@ -801,8 +801,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2490762978448517029" + "version": "0.25.53.49325", + "templateHash": "8360937786294538789" }, "name": "Private DNS Zone CNAME record", "description": "This module deploys a Private DNS Zone CNAME record.", @@ -1040,8 +1040,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8295396730182286420" + "version": "0.25.53.49325", + "templateHash": "17929107555284027881" }, "name": "Private DNS Zone MX record", "description": "This module deploys a Private DNS Zone MX record.", @@ -1279,8 +1279,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17209554570397660746" + "version": "0.25.53.49325", + "templateHash": "5937391315050932617" }, "name": "Private DNS Zone PTR record", "description": "This module deploys a Private DNS Zone PTR record.", @@ -1518,8 +1518,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15609741789639498893" + "version": "0.25.53.49325", + "templateHash": "15774595998971084317" }, "name": "Private DNS Zone SOA record", "description": "This module deploys a Private DNS Zone SOA record.", @@ -1757,8 +1757,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13106564668871801771" + "version": "0.25.53.49325", + "templateHash": "6637703638195225114" }, "name": "Private DNS Zone SRV record", "description": "This module deploys a Private DNS Zone SRV record.", @@ -1996,8 +1996,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4674546077798934805" + "version": "0.25.53.49325", + "templateHash": "4386552419329587852" }, "name": "Private DNS Zone TXT record", "description": "This module deploys a Private DNS Zone TXT record.", @@ -2235,8 +2235,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3218066471254957706" + "version": "0.25.53.49325", + "templateHash": "2508137843266136274" }, "name": "Private DNS Zone Virtual Network Link", "description": "This module deploys a Private DNS Zone Virtual Network Link.", diff --git a/avm/res/network/private-dns-zone/mx/main.json b/avm/res/network/private-dns-zone/mx/main.json index 91fa18bb0d..651880a641 100644 --- a/avm/res/network/private-dns-zone/mx/main.json +++ b/avm/res/network/private-dns-zone/mx/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8295396730182286420" + "version": "0.25.53.49325", + "templateHash": "17929107555284027881" }, "name": "Private DNS Zone MX record", "description": "This module deploys a Private DNS Zone MX record.", diff --git a/avm/res/network/private-dns-zone/ptr/main.json b/avm/res/network/private-dns-zone/ptr/main.json index 207e2d4d02..1f2c165b04 100644 --- a/avm/res/network/private-dns-zone/ptr/main.json +++ b/avm/res/network/private-dns-zone/ptr/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17209554570397660746" + "version": "0.25.53.49325", + "templateHash": "5937391315050932617" }, "name": "Private DNS Zone PTR record", "description": "This module deploys a Private DNS Zone PTR record.", diff --git a/avm/res/network/private-dns-zone/soa/main.json b/avm/res/network/private-dns-zone/soa/main.json index a1fe6a9fc7..700024ee9b 100644 --- a/avm/res/network/private-dns-zone/soa/main.json +++ b/avm/res/network/private-dns-zone/soa/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15609741789639498893" + "version": "0.25.53.49325", + "templateHash": "15774595998971084317" }, "name": "Private DNS Zone SOA record", "description": "This module deploys a Private DNS Zone SOA record.", diff --git a/avm/res/network/private-dns-zone/srv/main.json b/avm/res/network/private-dns-zone/srv/main.json index 5fe1396663..3d34cfa3fe 100644 --- a/avm/res/network/private-dns-zone/srv/main.json +++ b/avm/res/network/private-dns-zone/srv/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "13106564668871801771" + "version": "0.25.53.49325", + "templateHash": "6637703638195225114" }, "name": "Private DNS Zone SRV record", "description": "This module deploys a Private DNS Zone SRV record.", diff --git a/avm/res/network/private-dns-zone/txt/main.json b/avm/res/network/private-dns-zone/txt/main.json index d98932afb0..f5f483986d 100644 --- a/avm/res/network/private-dns-zone/txt/main.json +++ b/avm/res/network/private-dns-zone/txt/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4674546077798934805" + "version": "0.25.53.49325", + "templateHash": "4386552419329587852" }, "name": "Private DNS Zone TXT record", "description": "This module deploys a Private DNS Zone TXT record.", diff --git a/avm/res/network/private-dns-zone/virtual-network-link/main.json b/avm/res/network/private-dns-zone/virtual-network-link/main.json index 82476f6abe..0591440aad 100644 --- a/avm/res/network/private-dns-zone/virtual-network-link/main.json +++ b/avm/res/network/private-dns-zone/virtual-network-link/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3218066471254957706" + "version": "0.25.53.49325", + "templateHash": "2508137843266136274" }, "name": "Private DNS Zone Virtual Network Link", "description": "This module deploys a Private DNS Zone Virtual Network Link.", diff --git a/avm/res/network/private-endpoint/README.md b/avm/res/network/private-endpoint/README.md index 33999d57d1..37dc720a89 100644 --- a/avm/res/network/private-endpoint/README.md +++ b/avm/res/network/private-endpoint/README.md @@ -624,6 +624,35 @@ Properties of private endpoint IP configurations. - Required: Yes - Type: object +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-ipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-ipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-ipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `location` Location for all Resources. @@ -696,6 +725,40 @@ Properties of private link service connection. - Required: Yes - Type: object +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupIds`](#parameter-manualprivatelinkserviceconnectionspropertiesgroupids) | array | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateLinkServiceId`](#parameter-manualprivatelinkserviceconnectionspropertiesprivatelinkserviceid) | string | The resource id of private link service. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`requestMessage`](#parameter-manualprivatelinkserviceconnectionspropertiesrequestmessage) | string | A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars. | + +### Parameter: `manualPrivateLinkServiceConnections.properties.groupIds` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: array + +### Parameter: `manualPrivateLinkServiceConnections.properties.privateLinkServiceId` + +The resource id of private link service. + +- Required: Yes +- Type: string + +### Parameter: `manualPrivateLinkServiceConnections.properties.requestMessage` + +A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars. + +- Required: Yes +- Type: string + ### Parameter: `privateDnsZoneGroupName` The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. @@ -738,6 +801,40 @@ Properties of private link service connection. - Required: Yes - Type: object +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupIds`](#parameter-privatelinkserviceconnectionspropertiesgroupids) | array | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateLinkServiceId`](#parameter-privatelinkserviceconnectionspropertiesprivatelinkserviceid) | string | The resource id of private link service. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`requestMessage`](#parameter-privatelinkserviceconnectionspropertiesrequestmessage) | string | A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars. | + +### Parameter: `privateLinkServiceConnections.properties.groupIds` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: array + +### Parameter: `privateLinkServiceConnections.properties.privateLinkServiceId` + +The resource id of private link service. + +- Required: Yes +- Type: string + +### Parameter: `privateLinkServiceConnections.properties.requestMessage` + +A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars. + +- Required: No +- Type: string + ### Parameter: `roleAssignments` Array of role assignments to create. @@ -839,6 +936,7 @@ Tags to be applied on all resources/resource groups in this deployment. | Output | Type | Description | | :-- | :-- | :-- | +| `groupId` | string | The group Id for the private endpoint Group. | | `location` | string | The location the resource was deployed into. | | `name` | string | The name of the private endpoint. | | `resourceGroupName` | string | The resource group the private endpoint was deployed into. | diff --git a/avm/res/network/private-endpoint/main.bicep b/avm/res/network/private-endpoint/main.bicep index 79eba38a3f..2a3fc9de61 100644 --- a/avm/res/network/private-endpoint/main.bicep +++ b/avm/res/network/private-endpoint/main.bicep @@ -141,6 +141,9 @@ output name string = privateEndpoint.name @description('The location the resource was deployed into.') output location string = privateEndpoint.location +@description('The group Id for the private endpoint Group.') +output groupId string = !empty(privateEndpoint.properties.manualPrivateLinkServiceConnections) ? privateEndpoint.properties.manualPrivateLinkServiceConnections[0].properties.groupIds[0] : privateEndpoint.properties.privateLinkServiceConnections[0].properties.groupIds[0] + // ================ // // Definitions // // ================ // diff --git a/avm/res/network/private-endpoint/main.json b/avm/res/network/private-endpoint/main.json index ae410ec636..b17d43e13f 100644 --- a/avm/res/network/private-endpoint/main.json +++ b/avm/res/network/private-endpoint/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5518855230364102370" + "version": "0.25.53.49325", + "templateHash": "8700281441025836130" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", @@ -476,8 +476,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9321937464667207030" + "version": "0.25.53.49325", + "templateHash": "11244630631275470040" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -588,6 +588,13 @@ "description": "The location the resource was deployed into." }, "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + }, + "groupId": { + "type": "string", + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[if(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties.groupIds[0], reference('privateEndpoint').privateLinkServiceConnections[0].properties.groupIds[0])]" } } } \ No newline at end of file diff --git a/avm/res/network/private-endpoint/private-dns-zone-group/main.json b/avm/res/network/private-endpoint/private-dns-zone-group/main.json index 7233bc8c0f..4428758907 100644 --- a/avm/res/network/private-endpoint/private-dns-zone-group/main.json +++ b/avm/res/network/private-endpoint/private-dns-zone-group/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9321937464667207030" + "version": "0.25.53.49325", + "templateHash": "11244630631275470040" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", diff --git a/avm/res/network/private-endpoint/tests/e2e/defaults/main.test.bicep b/avm/res/network/private-endpoint/tests/e2e/defaults/main.test.bicep index 5bc9499b1c..c133a0f4af 100644 --- a/avm/res/network/private-endpoint/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/private-endpoint/tests/e2e/defaults/main.test.bicep @@ -17,6 +17,9 @@ param resourceLocation string = deployment().location @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') param serviceShort string = 'npemin' +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + @description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') param namePrefix string = '#_namePrefix_#' @@ -36,7 +39,7 @@ module nestedDependencies 'dependencies.bicep' = { name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' params: { virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' - keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' location: resourceLocation } } diff --git a/avm/res/network/private-endpoint/tests/e2e/max/main.test.bicep b/avm/res/network/private-endpoint/tests/e2e/max/main.test.bicep index c33302af69..50cb5f95c7 100644 --- a/avm/res/network/private-endpoint/tests/e2e/max/main.test.bicep +++ b/avm/res/network/private-endpoint/tests/e2e/max/main.test.bicep @@ -17,6 +17,9 @@ param resourceLocation string = deployment().location @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') param serviceShort string = 'npemax' +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + @description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') param namePrefix string = '#_namePrefix_#' @@ -36,7 +39,7 @@ module nestedDependencies 'dependencies.bicep' = { name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' params: { virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' - keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' applicationSecurityGroupName: 'dep-${namePrefix}-asg-${serviceShort}' location: resourceLocation diff --git a/avm/res/network/private-endpoint/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/private-endpoint/tests/e2e/waf-aligned/main.test.bicep index 1a7534fdc4..961dfd7d64 100644 --- a/avm/res/network/private-endpoint/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/private-endpoint/tests/e2e/waf-aligned/main.test.bicep @@ -17,6 +17,9 @@ param resourceLocation string = deployment().location @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') param serviceShort string = 'npewaf' +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + @description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') param namePrefix string = '#_namePrefix_#' @@ -36,7 +39,7 @@ module nestedDependencies 'dependencies.bicep' = { name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' params: { virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' - keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' applicationSecurityGroupName: 'dep-${namePrefix}-asg-${serviceShort}' location: resourceLocation diff --git a/avm/res/network/private-endpoint/version.json b/avm/res/network/private-endpoint/version.json index b3d560b1ad..96236a61ba 100644 --- a/avm/res/network/private-endpoint/version.json +++ b/avm/res/network/private-endpoint/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.3", + "version": "0.4", "pathFilters": [ "./main.json" ] diff --git a/avm/res/network/private-link-service/README.md b/avm/res/network/private-link-service/README.md new file mode 100644 index 0000000000..a37ec6ce9d --- /dev/null +++ b/avm/res/network/private-link-service/README.md @@ -0,0 +1,685 @@ +# Private Link Services `[Microsoft.Network/privateLinkServices]` + +This module deploys a Private Link Service. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Network/privateLinkServices` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateLinkServices) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/network/private-link-service:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep +module privateLinkService 'br/public:avm/res/network/private-link-service:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nplsmin' + params: { + // Required parameters + ipConfigurations: [ + { + name: 'nplsmin01' + properties: { + subnet: { + id: '' + } + } + } + ] + loadBalancerFrontendIpConfigurations: [ + { + id: '' + } + ] + name: 'nplsmin001' + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "ipConfigurations": { + "value": [ + { + "name": "nplsmin01", + "properties": { + "subnet": { + "id": "" + } + } + } + ] + }, + "loadBalancerFrontendIpConfigurations": { + "value": [ + { + "id": "" + } + ] + }, + "name": { + "value": "nplsmin001" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module privateLinkService 'br/public:avm/res/network/private-link-service:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nplsmax' + params: { + // Required parameters + ipConfigurations: [ + { + name: 'nplsmax01' + properties: { + primary: true + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: '' + } + } + } + ] + loadBalancerFrontendIpConfigurations: [ + { + id: '' + } + ] + name: 'nplsmax001' + // Non-required parameters + autoApproval: { + subscriptions: [ + '*' + ] + } + enableProxyProtocol: true + fqdns: [ + 'nplsmax.plsfqdn01.azure.privatelinkservice' + 'nplsmax.plsfqdn02.azure.privatelinkservice' + ] + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + visibility: { + subscriptions: [ + '' + ] + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "ipConfigurations": { + "value": [ + { + "name": "nplsmax01", + "properties": { + "primary": true, + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "" + } + } + } + ] + }, + "loadBalancerFrontendIpConfigurations": { + "value": [ + { + "id": "" + } + ] + }, + "name": { + "value": "nplsmax001" + }, + // Non-required parameters + "autoApproval": { + "value": { + "subscriptions": [ + "*" + ] + } + }, + "enableProxyProtocol": { + "value": true + }, + "fqdns": { + "value": [ + "nplsmax.plsfqdn01.azure.privatelinkservice", + "nplsmax.plsfqdn02.azure.privatelinkservice" + ] + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "visibility": { + "value": { + "subscriptions": [ + "" + ] + } + } + } +} +``` + +
    +

    + +### Example 3: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module privateLinkService 'br/public:avm/res/network/private-link-service:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nplswaf' + params: { + // Required parameters + ipConfigurations: [ + { + name: 'nplswaf01' + properties: { + primary: true + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: '' + } + } + } + ] + loadBalancerFrontendIpConfigurations: [ + { + id: '' + } + ] + name: 'nplswaf001' + // Non-required parameters + autoApproval: { + subscriptions: [ + '*' + ] + } + enableProxyProtocol: true + fqdns: [ + 'nplswaf.plsfqdn01.azure.privatelinkservice' + 'nplswaf.plsfqdn02.azure.privatelinkservice' + ] + location: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + visibility: { + subscriptions: [ + '' + ] + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "ipConfigurations": { + "value": [ + { + "name": "nplswaf01", + "properties": { + "primary": true, + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "" + } + } + } + ] + }, + "loadBalancerFrontendIpConfigurations": { + "value": [ + { + "id": "" + } + ] + }, + "name": { + "value": "nplswaf001" + }, + // Non-required parameters + "autoApproval": { + "value": { + "subscriptions": [ + "*" + ] + } + }, + "enableProxyProtocol": { + "value": true + }, + "fqdns": { + "value": [ + "nplswaf.plsfqdn01.azure.privatelinkservice", + "nplswaf.plsfqdn02.azure.privatelinkservice" + ] + }, + "location": { + "value": "" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "visibility": { + "value": { + "subscriptions": [ + "" + ] + } + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`ipConfigurations`](#parameter-ipconfigurations) | array | An array of private link service IP configurations. At least one IP configuration is required on the private link service. | +| [`loadBalancerFrontendIpConfigurations`](#parameter-loadbalancerfrontendipconfigurations) | array | An array of references to the load balancer IP configurations. The Private Link service is tied to the frontend IP address of a Standard Load Balancer. All traffic destined for the service will reach the frontend of the SLB. You can configure SLB rules to direct this traffic to appropriate backend pools where your applications are running. Load balancer frontend IP configurations are different than NAT IP configurations. At least one load balancer frontend IP configuration is required on the private link service. | +| [`name`](#parameter-name) | string | Name of the private link service to create. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`autoApproval`](#parameter-autoapproval) | object | The auto-approval list of the private link service. | +| [`enableProxyProtocol`](#parameter-enableproxyprotocol) | bool | Lets the service provider use tcp proxy v2 to retrieve connection information about the service consumer. Service Provider is responsible for setting up receiver configs to be able to parse the proxy protocol v2 header. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`extendedLocation`](#parameter-extendedlocation) | object | The extended location of the load balancer. | +| [`fqdns`](#parameter-fqdns) | array | The list of Fqdn. | +| [`location`](#parameter-location) | string | Location for all Resources. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`tags`](#parameter-tags) | object | Tags to be applied on all resources/resource groups in this deployment. | +| [`visibility`](#parameter-visibility) | object | Controls the exposure settings for your Private Link service. Service providers can choose to limit the exposure to their service to subscriptions with Azure role-based access control (Azure RBAC) permissions, a restricted set of subscriptions, or all Azure subscriptions. | + +### Parameter: `ipConfigurations` + +An array of private link service IP configurations. At least one IP configuration is required on the private link service. + +- Required: Yes +- Type: array + +### Parameter: `loadBalancerFrontendIpConfigurations` + +An array of references to the load balancer IP configurations. The Private Link service is tied to the frontend IP address of a Standard Load Balancer. All traffic destined for the service will reach the frontend of the SLB. You can configure SLB rules to direct this traffic to appropriate backend pools where your applications are running. Load balancer frontend IP configurations are different than NAT IP configurations. At least one load balancer frontend IP configuration is required on the private link service. + +- Required: Yes +- Type: array + +### Parameter: `name` + +Name of the private link service to create. + +- Required: Yes +- Type: string + +### Parameter: `autoApproval` + +The auto-approval list of the private link service. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `enableProxyProtocol` + +Lets the service provider use tcp proxy v2 to retrieve connection information about the service consumer. Service Provider is responsible for setting up receiver configs to be able to parse the proxy protocol v2 header. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `extendedLocation` + +The extended location of the load balancer. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `fqdns` + +The list of Fqdn. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `location` + +Location for all Resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `tags` + +Tags to be applied on all resources/resource groups in this deployment. + +- Required: No +- Type: object + +### Parameter: `visibility` + +Controls the exposure settings for your Private Link service. Service providers can choose to limit the exposure to their service to subscriptions with Azure role-based access control (Azure RBAC) permissions, a restricted set of subscriptions, or all Azure subscriptions. + +- Required: No +- Type: object +- Default: `{}` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the private link service. | +| `resourceGroupName` | string | The resource group the private link service was deployed into. | +| `resourceId` | string | The resource ID of the private link service. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/network/private-link-service/main.bicep b/avm/res/network/private-link-service/main.bicep new file mode 100644 index 0000000000..dd325bdc3f --- /dev/null +++ b/avm/res/network/private-link-service/main.bicep @@ -0,0 +1,155 @@ +metadata name = 'Private Link Services' +metadata description = 'This module deploys a Private Link Service.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Name of the private link service to create.') +param name string + +@description('Optional. Location for all Resources.') +param location string = resourceGroup().location + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Tags to be applied on all resources/resource groups in this deployment.') +param tags object? + +@description('Required. An array of private link service IP configurations. At least one IP configuration is required on the private link service.') +param ipConfigurations array + +@description('Required. An array of references to the load balancer IP configurations. The Private Link service is tied to the frontend IP address of a Standard Load Balancer. All traffic destined for the service will reach the frontend of the SLB. You can configure SLB rules to direct this traffic to appropriate backend pools where your applications are running. Load balancer frontend IP configurations are different than NAT IP configurations. At least one load balancer frontend IP configuration is required on the private link service.') +param loadBalancerFrontendIpConfigurations array + +@description('Optional. The extended location of the load balancer.') +param extendedLocation object = {} + +@description('Optional. The auto-approval list of the private link service.') +param autoApproval object = {} + +@description('Optional. Lets the service provider use tcp proxy v2 to retrieve connection information about the service consumer. Service Provider is responsible for setting up receiver configs to be able to parse the proxy protocol v2 header.') +param enableProxyProtocol bool = false + +@description('Optional. The list of Fqdn.') +param fqdns array = [] + +@description('Optional. Controls the exposure settings for your Private Link service. Service providers can choose to limit the exposure to their service to subscriptions with Azure role-based access control (Azure RBAC) permissions, a restricted set of subscriptions, or all Azure subscriptions.') +param visibility object = {} + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.network-privatelinkservice.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource privateLinkService 'Microsoft.Network/privateLinkServices@2023-04-01' = { + name: name + location: location + tags: tags + extendedLocation: !empty(extendedLocation) ? extendedLocation : null + properties: { + autoApproval: autoApproval + enableProxyProtocol: enableProxyProtocol + fqdns: fqdns + ipConfigurations: ipConfigurations + loadBalancerFrontendIpConfigurations: loadBalancerFrontendIpConfigurations + visibility: visibility + } +} + +resource privateLinkService_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: privateLinkService +} + +resource privateLinkService_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(privateLinkService.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: privateLinkService +}] + +@description('The resource group the private link service was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The resource ID of the private link service.') +output resourceId string = privateLinkService.id + +@description('The name of the private link service.') +output name string = privateLinkService.name + +@description('The location the resource was deployed into.') +output location string = privateLinkService.location + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? diff --git a/avm/res/network/private-link-service/main.json b/avm/res/network/private-link-service/main.json new file mode 100644 index 0000000000..65ed51e7c9 --- /dev/null +++ b/avm/res/network/private-link-service/main.json @@ -0,0 +1,311 @@ +{ + "$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.25.53.49325", + "templateHash": "9286417696593390528" + }, + "name": "Private Link Services", + "description": "This module deploys a Private Link Service.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private link service to create." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "ipConfigurations": { + "type": "array", + "metadata": { + "description": "Required. An array of private link service IP configurations. At least one IP configuration is required on the private link service." + } + }, + "loadBalancerFrontendIpConfigurations": { + "type": "array", + "metadata": { + "description": "Required. An array of references to the load balancer IP configurations. The Private Link service is tied to the frontend IP address of a Standard Load Balancer. All traffic destined for the service will reach the frontend of the SLB. You can configure SLB rules to direct this traffic to appropriate backend pools where your applications are running. Load balancer frontend IP configurations are different than NAT IP configurations. At least one load balancer frontend IP configuration is required on the private link service." + } + }, + "extendedLocation": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. The extended location of the load balancer." + } + }, + "autoApproval": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. The auto-approval list of the private link service." + } + }, + "enableProxyProtocol": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Lets the service provider use tcp proxy v2 to retrieve connection information about the service consumer. Service Provider is responsible for setting up receiver configs to be able to parse the proxy protocol v2 header." + } + }, + "fqdns": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The list of Fqdn." + } + }, + "visibility": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Controls the exposure settings for your Private Link service. Service providers can choose to limit the exposure to their service to subscriptions with Azure role-based access control (Azure RBAC) permissions, a restricted set of subscriptions, or all Azure subscriptions." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privatelinkservice.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateLinkService": { + "type": "Microsoft.Network/privateLinkServices", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "extendedLocation": "[if(not(empty(parameters('extendedLocation'))), parameters('extendedLocation'), null())]", + "properties": { + "autoApproval": "[parameters('autoApproval')]", + "enableProxyProtocol": "[parameters('enableProxyProtocol')]", + "fqdns": "[parameters('fqdns')]", + "ipConfigurations": "[parameters('ipConfigurations')]", + "loadBalancerFrontendIpConfigurations": "[parameters('loadBalancerFrontendIpConfigurations')]", + "visibility": "[parameters('visibility')]" + } + }, + "privateLinkService_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateLinkServices/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateLinkService" + ] + }, + "privateLinkService_roleAssignments": { + "copy": { + "name": "privateLinkService_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateLinkServices/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateLinkServices', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateLinkService" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private link service was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private link service." + }, + "value": "[resourceId('Microsoft.Network/privateLinkServices', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private link service." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateLinkService', '2023-04-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/network/private-link-service/tests/e2e/defaults/dependencies.bicep b/avm/res/network/private-link-service/tests/e2e/defaults/dependencies.bicep new file mode 100644 index 0000000000..cecd1df763 --- /dev/null +++ b/avm/res/network/private-link-service/tests/e2e/defaults/dependencies.bicep @@ -0,0 +1,57 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Load Balancer to create.') +param loadBalancerName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + privateLinkServiceNetworkPolicies: 'Disabled' + } + } + ] + } +} + +resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { + name: loadBalancerName + location: location + sku: { + name: 'Standard' + } + properties: { + frontendIPConfigurations: [ + { + name: 'frontendIPConfiguration' + properties: { + subnet: { + id: virtualNetwork.properties.subnets[0].id + } + } + } + ] + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Load Balancer Frontend IP Configuration.') +output loadBalancerFrontendIpConfigurationResourceId string = loadBalancer.properties.frontendIPConfigurations[0].id diff --git a/avm/res/network/private-link-service/tests/e2e/defaults/main.test.bicep b/avm/res/network/private-link-service/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..225912bdc2 --- /dev/null +++ b/avm/res/network/private-link-service/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,71 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.privatelinkservices-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nplsmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + ipConfigurations: [ + { + name: '${serviceShort}01' + properties: { + subnet: { + id: nestedDependencies.outputs.subnetResourceId + } + } + } + ] + loadBalancerFrontendIpConfigurations: [ + { + id: nestedDependencies.outputs.loadBalancerFrontendIpConfigurationResourceId + } + ] + } +}] diff --git a/avm/res/network/private-link-service/tests/e2e/max/dependencies.bicep b/avm/res/network/private-link-service/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..1031dd4830 --- /dev/null +++ b/avm/res/network/private-link-service/tests/e2e/max/dependencies.bicep @@ -0,0 +1,68 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Load Balancer to create.') +param loadBalancerName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + privateLinkServiceNetworkPolicies: 'Disabled' + } + } + ] + } +} + +resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { + name: loadBalancerName + location: location + sku: { + name: 'Standard' + } + properties: { + frontendIPConfigurations: [ + { + name: 'frontendIPConfiguration' + properties: { + subnet: { + id: virtualNetwork.properties.subnets[0].id + } + } + } + ] + } +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: managedIdentityName + location: location +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Load Balancer Frontend IP Configuration.') +output loadBalancerFrontendIpConfigurationResourceId string = loadBalancer.properties.frontendIPConfigurations[0].id diff --git a/avm/res/network/private-link-service/tests/e2e/max/main.test.bicep b/avm/res/network/private-link-service/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..8fd89f8691 --- /dev/null +++ b/avm/res/network/private-link-service/tests/e2e/max/main.test.bicep @@ -0,0 +1,115 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.privatelinkservices-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nplsmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + ipConfigurations: [ + { + name: '${serviceShort}01' + properties: { + primary: true + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: nestedDependencies.outputs.subnetResourceId + } + } + } + ] + loadBalancerFrontendIpConfigurations: [ + { + id: nestedDependencies.outputs.loadBalancerFrontendIpConfigurationResourceId + } + ] + autoApproval: { + subscriptions: [ + '*' + ] + } + visibility: { + subscriptions: [ + subscription().subscriptionId + ] + } + enableProxyProtocol: true + fqdns: [ + '${serviceShort}.plsfqdn01.azure.privatelinkservice' + '${serviceShort}.plsfqdn02.azure.privatelinkservice' + ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/network/private-link-service/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/private-link-service/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..cecd1df763 --- /dev/null +++ b/avm/res/network/private-link-service/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,57 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Load Balancer to create.') +param loadBalancerName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + privateLinkServiceNetworkPolicies: 'Disabled' + } + } + ] + } +} + +resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { + name: loadBalancerName + location: location + sku: { + name: 'Standard' + } + properties: { + frontendIPConfigurations: [ + { + name: 'frontendIPConfiguration' + properties: { + subnet: { + id: virtualNetwork.properties.subnets[0].id + } + } + } + ] + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Load Balancer Frontend IP Configuration.') +output loadBalancerFrontendIpConfigurationResourceId string = loadBalancer.properties.frontendIPConfigurations[0].id diff --git a/avm/res/network/private-link-service/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/private-link-service/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..1c3944a326 --- /dev/null +++ b/avm/res/network/private-link-service/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,93 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.privatelinkservices-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nplswaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + ipConfigurations: [ + { + name: '${serviceShort}01' + properties: { + primary: true + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: nestedDependencies.outputs.subnetResourceId + } + } + } + ] + loadBalancerFrontendIpConfigurations: [ + { + id: nestedDependencies.outputs.loadBalancerFrontendIpConfigurationResourceId + } + ] + autoApproval: { + subscriptions: [ + '*' + ] + } + visibility: { + subscriptions: [ + subscription().subscriptionId + ] + } + enableProxyProtocol: true + fqdns: [ + '${serviceShort}.plsfqdn01.azure.privatelinkservice' + '${serviceShort}.plsfqdn02.azure.privatelinkservice' + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/network/private-link-service/version.json b/avm/res/network/private-link-service/version.json new file mode 100644 index 0000000000..83083db694 --- /dev/null +++ b/avm/res/network/private-link-service/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file diff --git a/avm/res/network/public-ip-address/README.md b/avm/res/network/public-ip-address/README.md index 99b58af047..f8f4322785 100644 --- a/avm/res/network/public-ip-address/README.md +++ b/avm/res/network/public-ip-address/README.md @@ -18,7 +18,7 @@ This module deploys a Public IP Address. | `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | -| `Microsoft.Network/publicIPAddresses` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/publicIPAddresses) | +| `Microsoft.Network/publicIPAddresses` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/publicIPAddresses) | ## Usage examples @@ -459,16 +459,29 @@ The DDoS protection plan configuration associated with the public IP address. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`ddosProtectionPlan`](#parameter-ddossettingsddosprotectionplan) | object | The DDoS protection plan ID associated with the public IP address. | +| [`ddosProtectionPlan`](#parameter-ddossettingsddosprotectionplan) | object | The DDoS protection plan associated with the public IP address. | | [`protectionMode`](#parameter-ddossettingsprotectionmode) | string | The DDoS protection policy customizations. | ### Parameter: `ddosSettings.ddosProtectionPlan` -The DDoS protection plan ID associated with the public IP address. +The DDoS protection plan associated with the public IP address. - Required: Yes - Type: object +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`id`](#parameter-ddossettingsddosprotectionplanid) | string | The resource ID of the DDOS protection plan associated with the public IP address. | + +### Parameter: `ddosSettings.ddosProtectionPlan.id` + +The resource ID of the DDOS protection plan associated with the public IP address. + +- Required: Yes +- Type: string + ### Parameter: `ddosSettings.protectionMode` The DDoS protection policy customizations. @@ -496,9 +509,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -533,11 +546,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -547,11 +589,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/network/public-ip-address/main.bicep b/avm/res/network/public-ip-address/main.bicep index 8865afd5d4..d8463cb9a7 100644 --- a/avm/res/network/public-ip-address/main.bicep +++ b/avm/res/network/public-ip-address/main.bicep @@ -97,7 +97,7 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableT } } -resource publicIpAddress 'Microsoft.Network/publicIPAddresses@2023-04-01' = { +resource publicIpAddress 'Microsoft.Network/publicIPAddresses@2023-09-01' = { name: name location: location tags: tags @@ -149,19 +149,16 @@ resource publicIpAddress_diagnosticSettings 'Microsoft.Insights/diagnosticSettin workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'allLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -233,8 +230,9 @@ type dnsSettingsType = { } type ddosSettingsType = { - @description('Required. The DDoS protection plan ID associated with the public IP address.') + @description('Required. The DDoS protection plan associated with the public IP address.') ddosProtectionPlan: { + @description('Required. The resource ID of the DDOS protection plan associated with the public IP address.') id: string } @description('Required. The DDoS protection policy customizations.') @@ -245,19 +243,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/network/public-ip-address/main.json b/avm/res/network/public-ip-address/main.json index d0a1cb1b1b..77c39a8774 100644 --- a/avm/res/network/public-ip-address/main.json +++ b/avm/res/network/public-ip-address/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2070450222731835934" + "version": "0.25.53.49325", + "templateHash": "1322777943943789546" }, "name": "Public IP Addresses", "description": "This module deploys a Public IP Address.", @@ -149,11 +149,14 @@ "type": "object", "properties": { "id": { - "type": "string" + "type": "string", + "metadata": { + "description": "Required. The resource ID of the DDOS protection plan associated with the public IP address." + } } }, "metadata": { - "description": "Required. The DDoS protection plan ID associated with the public IP address." + "description": "Required. The DDoS protection plan associated with the public IP address." } }, "protectionMode": { @@ -197,12 +200,19 @@ "metadata": { "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -215,12 +225,19 @@ "metadata": { "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -437,7 +454,7 @@ }, "publicIpAddress": { "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2023-04-01", + "apiVersion": "2023-09-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -502,12 +519,30 @@ "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -550,7 +585,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('publicIpAddress', '2023-04-01', 'full').location]" + "value": "[reference('publicIpAddress', '2023-09-01', 'full').location]" } } } \ No newline at end of file diff --git a/avm/res/network/public-ip-address/tests/e2e/max/dependencies.bicep b/avm/res/network/public-ip-address/tests/e2e/max/dependencies.bicep index 7be39e253a..7b3d4e8fb0 100644 --- a/avm/res/network/public-ip-address/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/public-ip-address/tests/e2e/max/dependencies.bicep @@ -4,7 +4,7 @@ param location string = resourceGroup().location @description('Required. The name of the Managed Identity to create.') param managedIdentityName string -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: managedIdentityName location: location } diff --git a/avm/res/network/public-ip-address/tests/e2e/max/main.test.bicep b/avm/res/network/public-ip-address/tests/e2e/max/main.test.bicep index a0a37e644f..11e3670a5e 100644 --- a/avm/res/network/public-ip-address/tests/e2e/max/main.test.bicep +++ b/avm/res/network/public-ip-address/tests/e2e/max/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/network/public-ip-address/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/public-ip-address/tests/e2e/waf-aligned/dependencies.bicep index 7be39e253a..7b3d4e8fb0 100644 --- a/avm/res/network/public-ip-address/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/network/public-ip-address/tests/e2e/waf-aligned/dependencies.bicep @@ -4,7 +4,7 @@ param location string = resourceGroup().location @description('Required. The name of the Managed Identity to create.') param managedIdentityName string -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: managedIdentityName location: location } diff --git a/avm/res/network/public-ip-address/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/public-ip-address/tests/e2e/waf-aligned/main.test.bicep index 81c76101ea..ebf0000da7 100644 --- a/avm/res/network/public-ip-address/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/public-ip-address/tests/e2e/waf-aligned/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/network/public-ip-address/version.json b/avm/res/network/public-ip-address/version.json index 1c035df49f..c177b1bb58 100644 --- a/avm/res/network/public-ip-address/version.json +++ b/avm/res/network/public-ip-address/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.2", + "version": "0.3", "pathFilters": [ "./main.json" ] diff --git a/avm/res/network/public-ip-prefix/README.md b/avm/res/network/public-ip-prefix/README.md index 0b9a7496ae..09207d8853 100644 --- a/avm/res/network/public-ip-prefix/README.md +++ b/avm/res/network/public-ip-prefix/README.md @@ -17,7 +17,7 @@ This module deploys a Public IP Prefix. | :-- | :-- | | `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | -| `Microsoft.Network/publicIPPrefixes` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/publicIPPrefixes) | +| `Microsoft.Network/publicIPPrefixes` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/publicIPPrefixes) | ## Usage examples @@ -264,14 +264,14 @@ module publicIpPrefix 'br/public:avm/res/network/public-ip-prefix:' = { | Parameter | Type | Description | | :-- | :-- | :-- | -| [`name`](#parameter-name) | string | Name of the Public IP Prefix. | +| [`name`](#parameter-name) | string | The name of the Public IP Prefix. | | [`prefixLength`](#parameter-prefixlength) | int | Length of the Public IP Prefix. | **Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`customIPPrefix`](#parameter-customipprefix) | object | The customIpPrefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range. | +| [`customIPPrefix`](#parameter-customipprefix) | object | The custom IP address prefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`location`](#parameter-location) | string | Location for all resources. | | [`lock`](#parameter-lock) | object | The lock settings of the service. | @@ -280,7 +280,7 @@ module publicIpPrefix 'br/public:avm/res/network/public-ip-prefix:' = { ### Parameter: `name` -Name of the Public IP Prefix. +The name of the Public IP Prefix. - Required: Yes - Type: string @@ -294,7 +294,7 @@ Length of the Public IP Prefix. ### Parameter: `customIPPrefix` -The customIpPrefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range. +The custom IP address prefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range. - Required: No - Type: object diff --git a/avm/res/network/public-ip-prefix/main.bicep b/avm/res/network/public-ip-prefix/main.bicep index c748d1942c..d9fed7fb9d 100644 --- a/avm/res/network/public-ip-prefix/main.bicep +++ b/avm/res/network/public-ip-prefix/main.bicep @@ -2,7 +2,7 @@ metadata name = 'Public IP Prefixes' metadata description = 'This module deploys a Public IP Prefix.' metadata owner = 'Azure/module-maintainers' -@description('Required. Name of the Public IP Prefix.') +@description('Required. The name of the Public IP Prefix.') @minLength(1) param name string @@ -23,7 +23,7 @@ param roleAssignments roleAssignmentType @description('Optional. Tags of the resource.') param tags object? -@description('Optional. The customIpPrefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range.') +@description('Optional. The custom IP address prefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range.') param customIPPrefix object = {} @description('Optional. Enable/Disable usage telemetry for module.') @@ -56,7 +56,7 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableT } } -resource publicIpPrefix 'Microsoft.Network/publicIPPrefixes@2023-04-01' = { +resource publicIpPrefix 'Microsoft.Network/publicIPPrefixes@2023-09-01' = { name: name location: location tags: tags diff --git a/avm/res/network/public-ip-prefix/main.json b/avm/res/network/public-ip-prefix/main.json index 4cde7bb96b..bf928ff5b7 100644 --- a/avm/res/network/public-ip-prefix/main.json +++ b/avm/res/network/public-ip-prefix/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10236251134052848815" + "version": "0.25.53.49325", + "templateHash": "16912543771400413342" }, "name": "Public IP Prefixes", "description": "This module deploys a Public IP Prefix.", @@ -110,7 +110,7 @@ "type": "string", "minLength": 1, "metadata": { - "description": "Required. Name of the Public IP Prefix." + "description": "Required. The name of the Public IP Prefix." } }, "location": { @@ -151,7 +151,7 @@ "type": "object", "defaultValue": {}, "metadata": { - "description": "Optional. The customIpPrefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range." + "description": "Optional. The custom IP address prefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range." } }, "enableTelemetry": { @@ -195,7 +195,7 @@ }, "publicIpPrefix": { "type": "Microsoft.Network/publicIPPrefixes", - "apiVersion": "2023-04-01", + "apiVersion": "2023-09-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -272,7 +272,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('publicIpPrefix', '2023-04-01', 'full').location]" + "value": "[reference('publicIpPrefix', '2023-09-01', 'full').location]" } } } \ No newline at end of file diff --git a/avm/res/network/public-ip-prefix/tests/e2e/defaults/main.test.bicep b/avm/res/network/public-ip-prefix/tests/e2e/defaults/main.test.bicep index 44e088af33..70effcbbc5 100644 --- a/avm/res/network/public-ip-prefix/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/public-ip-prefix/tests/e2e/defaults/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/network/public-ip-prefix/tests/e2e/max/dependencies.bicep b/avm/res/network/public-ip-prefix/tests/e2e/max/dependencies.bicep index a7f42aee7b..43b2b39c33 100644 --- a/avm/res/network/public-ip-prefix/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/public-ip-prefix/tests/e2e/max/dependencies.bicep @@ -4,7 +4,7 @@ param location string = resourceGroup().location @description('Required. The name of the Managed Identity to create.') param managedIdentityName string -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: managedIdentityName location: location } diff --git a/avm/res/network/public-ip-prefix/tests/e2e/max/main.test.bicep b/avm/res/network/public-ip-prefix/tests/e2e/max/main.test.bicep index 0ea9597cf7..6504f4b21b 100644 --- a/avm/res/network/public-ip-prefix/tests/e2e/max/main.test.bicep +++ b/avm/res/network/public-ip-prefix/tests/e2e/max/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/dependencies.bicep index a7f42aee7b..43b2b39c33 100644 --- a/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/dependencies.bicep @@ -4,7 +4,7 @@ param location string = resourceGroup().location @description('Required. The name of the Managed Identity to create.') param managedIdentityName string -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: managedIdentityName location: location } diff --git a/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/main.test.bicep index 88352c6605..6e2ba0e646 100644 --- a/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/network/public-ip-prefix/version.json b/avm/res/network/public-ip-prefix/version.json index 83083db694..1c035df49f 100644 --- a/avm/res/network/public-ip-prefix/version.json +++ b/avm/res/network/public-ip-prefix/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.1", + "version": "0.2", "pathFilters": [ "./main.json" ] diff --git a/avm/res/network/route-table/README.md b/avm/res/network/route-table/README.md index fd5dcee0ad..546e717454 100644 --- a/avm/res/network/route-table/README.md +++ b/avm/res/network/route-table/README.md @@ -504,6 +504,58 @@ Properties of the route. - Required: Yes - Type: object +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`nextHopType`](#parameter-routespropertiesnexthoptype) | string | The type of Azure hop the packet should be sent to. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`addressPrefix`](#parameter-routespropertiesaddressprefix) | string | The destination CIDR to which the route applies. | +| [`hasBgpOverride`](#parameter-routespropertieshasbgpoverride) | bool | A value indicating whether this route overrides overlapping BGP routes regardless of LPM. | +| [`nextHopIpAddress`](#parameter-routespropertiesnexthopipaddress) | string | The IP address packets should be forwarded to. Next hop values are only allowed in routes where the next hop type is VirtualAppliance. | + +### Parameter: `routes.properties.nextHopType` + +The type of Azure hop the packet should be sent to. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Internet' + 'None' + 'VirtualAppliance' + 'VirtualNetworkGateway' + 'VnetLocal' + ] + ``` + +### Parameter: `routes.properties.addressPrefix` + +The destination CIDR to which the route applies. + +- Required: No +- Type: string + +### Parameter: `routes.properties.hasBgpOverride` + +A value indicating whether this route overrides overlapping BGP routes regardless of LPM. + +- Required: No +- Type: bool + +### Parameter: `routes.properties.nextHopIpAddress` + +The IP address packets should be forwarded to. Next hop values are only allowed in routes where the next hop type is VirtualAppliance. + +- Required: No +- Type: string + ### Parameter: `tags` Tags of the resource. diff --git a/avm/res/network/route-table/main.json b/avm/res/network/route-table/main.json index c926009328..3f54614e78 100644 --- a/avm/res/network/route-table/main.json +++ b/avm/res/network/route-table/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8006305196689303257" + "version": "0.25.53.49325", + "templateHash": "1632746009017446160" }, "name": "Route Tables", "description": "This module deploys a User Defined Route Table (UDR).", diff --git a/avm/res/network/trafficmanagerprofile/README.md b/avm/res/network/trafficmanagerprofile/README.md index caf0e25aed..3a294c7455 100644 --- a/avm/res/network/trafficmanagerprofile/README.md +++ b/avm/res/network/trafficmanagerprofile/README.md @@ -431,9 +431,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -468,11 +468,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -482,11 +511,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/network/trafficmanagerprofile/main.bicep b/avm/res/network/trafficmanagerprofile/main.bicep index 01157bad75..fadcb2ff94 100644 --- a/avm/res/network/trafficmanagerprofile/main.bicep +++ b/avm/res/network/trafficmanagerprofile/main.bicep @@ -130,19 +130,16 @@ resource trafficManagerProfile_diagnosticSettings 'Microsoft.Insights/diagnostic workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -211,19 +208,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/network/trafficmanagerprofile/main.json b/avm/res/network/trafficmanagerprofile/main.json index b171e4f256..5eb1678de9 100644 --- a/avm/res/network/trafficmanagerprofile/main.json +++ b/avm/res/network/trafficmanagerprofile/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3089313207378943936" + "version": "0.25.53.49325", + "templateHash": "1216778685608382825" }, "name": "Traffic Manager Profiles", "description": "This module deploys a Traffic Manager Profile.", @@ -132,14 +132,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -150,14 +157,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -410,12 +424,30 @@ "scope": "[format('Microsoft.Network/trafficmanagerprofiles/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, diff --git a/avm/res/network/virtual-hub/README.md b/avm/res/network/virtual-hub/README.md new file mode 100644 index 0000000000..9fa4017ba6 --- /dev/null +++ b/avm/res/network/virtual-hub/README.md @@ -0,0 +1,626 @@ +# Virtual Hubs `[Microsoft.Network/virtualHubs]` + +This module deploys a Virtual Hub. +If you are planning to deploy a Secure Virtual Hub (with an Azure Firewall integrated), please refer to the Azure Firewall module. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Network/virtualHubs` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-11-01/virtualHubs) | +| `Microsoft.Network/virtualHubs/hubRouteTables` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-11-01/virtualHubs/hubRouteTables) | +| `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-11-01/virtualHubs/hubVirtualNetworkConnections) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/network/virtual-hub:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep +module virtualHub 'br/public:avm/res/network/virtual-hub:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nvhmin' + params: { + // Required parameters + addressPrefix: '10.0.0.0/16' + name: 'nvhmin' + virtualWanId: '' + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "addressPrefix": { + "value": "10.0.0.0/16" + }, + "name": { + "value": "nvhmin" + }, + "virtualWanId": { + "value": "" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module virtualHub 'br/public:avm/res/network/virtual-hub:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nvhmax' + params: { + // Required parameters + addressPrefix: '10.1.0.0/16' + name: 'nvhmax' + virtualWanId: '' + // Non-required parameters + hubRouteTables: [ + { + name: 'routeTable1' + } + ] + hubVirtualNetworkConnections: [ + { + name: 'connection1' + remoteVirtualNetworkId: '' + routingConfiguration: { + associatedRouteTable: { + id: '' + } + propagatedRouteTables: { + ids: [ + { + id: '' + } + ] + labels: [ + 'none' + ] + } + } + } + ] + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "addressPrefix": { + "value": "10.1.0.0/16" + }, + "name": { + "value": "nvhmax" + }, + "virtualWanId": { + "value": "" + }, + // Non-required parameters + "hubRouteTables": { + "value": [ + { + "name": "routeTable1" + } + ] + }, + "hubVirtualNetworkConnections": { + "value": [ + { + "name": "connection1", + "remoteVirtualNetworkId": "", + "routingConfiguration": { + "associatedRouteTable": { + "id": "" + }, + "propagatedRouteTables": { + "ids": [ + { + "id": "" + } + ], + "labels": [ + "none" + ] + } + } + } + ] + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + +### Example 3: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module virtualHub 'br/public:avm/res/network/virtual-hub:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nvhwaf' + params: { + // Required parameters + addressPrefix: '10.1.0.0/16' + name: 'nvhwaf' + virtualWanId: '' + // Non-required parameters + hubRouteTables: [ + { + name: 'routeTable1' + } + ] + hubVirtualNetworkConnections: [ + { + name: 'connection1' + remoteVirtualNetworkId: '' + routingConfiguration: { + associatedRouteTable: { + id: '' + } + propagatedRouteTables: { + ids: [ + { + id: '' + } + ] + labels: [ + 'none' + ] + } + } + } + ] + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "addressPrefix": { + "value": "10.1.0.0/16" + }, + "name": { + "value": "nvhwaf" + }, + "virtualWanId": { + "value": "" + }, + // Non-required parameters + "hubRouteTables": { + "value": [ + { + "name": "routeTable1" + } + ] + }, + "hubVirtualNetworkConnections": { + "value": [ + { + "name": "connection1", + "remoteVirtualNetworkId": "", + "routingConfiguration": { + "associatedRouteTable": { + "id": "" + }, + "propagatedRouteTables": { + "ids": [ + { + "id": "" + } + ], + "labels": [ + "none" + ] + } + } + } + ] + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`addressPrefix`](#parameter-addressprefix) | string | Address-prefix for this VirtualHub. | +| [`name`](#parameter-name) | string | The virtual hub name. | +| [`virtualWanId`](#parameter-virtualwanid) | string | Resource ID of the virtual WAN to link to. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`allowBranchToBranchTraffic`](#parameter-allowbranchtobranchtraffic) | bool | Flag to control transit for VirtualRouter hub. | +| [`azureFirewallResourceId`](#parameter-azurefirewallresourceid) | string | Resource ID of the Azure Firewall to link to. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`expressRouteGatewayId`](#parameter-expressroutegatewayid) | string | Resource ID of the Express Route Gateway to link to. | +| [`hubRouteTables`](#parameter-hubroutetables) | array | Route tables to create for the virtual hub. | +| [`hubVirtualNetworkConnections`](#parameter-hubvirtualnetworkconnections) | array | Virtual network connections to create for the virtual hub. | +| [`location`](#parameter-location) | string | Location for all resources. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`p2SVpnGatewayId`](#parameter-p2svpngatewayid) | string | Resource ID of the Point-to-Site VPN Gateway to link to. | +| [`preferredRoutingGateway`](#parameter-preferredroutinggateway) | string | The preferred routing gateway types. | +| [`routeTableRoutes`](#parameter-routetableroutes) | array | VirtualHub route tables. | +| [`securityPartnerProviderId`](#parameter-securitypartnerproviderid) | string | ID of the Security Partner Provider to link to. | +| [`securityProviderName`](#parameter-securityprovidername) | string | The Security Provider name. | +| [`sku`](#parameter-sku) | string | The sku of this VirtualHub. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`virtualHubRouteTableV2s`](#parameter-virtualhubroutetablev2s) | array | List of all virtual hub route table v2s associated with this VirtualHub. | +| [`virtualRouterAsn`](#parameter-virtualrouterasn) | int | VirtualRouter ASN. | +| [`virtualRouterIps`](#parameter-virtualrouterips) | array | VirtualRouter IPs. | +| [`vpnGatewayId`](#parameter-vpngatewayid) | string | Resource ID of the VPN Gateway to link to. | + +### Parameter: `addressPrefix` + +Address-prefix for this VirtualHub. + +- Required: Yes +- Type: string + +### Parameter: `name` + +The virtual hub name. + +- Required: Yes +- Type: string + +### Parameter: `virtualWanId` + +Resource ID of the virtual WAN to link to. + +- Required: Yes +- Type: string + +### Parameter: `allowBranchToBranchTraffic` + +Flag to control transit for VirtualRouter hub. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `azureFirewallResourceId` + +Resource ID of the Azure Firewall to link to. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `expressRouteGatewayId` + +Resource ID of the Express Route Gateway to link to. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `hubRouteTables` + +Route tables to create for the virtual hub. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `hubVirtualNetworkConnections` + +Virtual network connections to create for the virtual hub. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `location` + +Location for all resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `p2SVpnGatewayId` + +Resource ID of the Point-to-Site VPN Gateway to link to. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `preferredRoutingGateway` + +The preferred routing gateway types. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + 'ExpressRoute' + 'None' + 'VpnGateway' + ] + ``` + +### Parameter: `routeTableRoutes` + +VirtualHub route tables. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `securityPartnerProviderId` + +ID of the Security Partner Provider to link to. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `securityProviderName` + +The Security Provider name. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `sku` + +The sku of this VirtualHub. + +- Required: No +- Type: string +- Default: `'Standard'` +- Allowed: + ```Bicep + [ + 'Basic' + 'Standard' + ] + ``` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `virtualHubRouteTableV2s` + +List of all virtual hub route table v2s associated with this VirtualHub. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `virtualRouterAsn` + +VirtualRouter ASN. + +- Required: No +- Type: int + +### Parameter: `virtualRouterIps` + +VirtualRouter IPs. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `vpnGatewayId` + +Resource ID of the VPN Gateway to link to. + +- Required: No +- Type: string +- Default: `''` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the virtual hub. | +| `resourceGroupName` | string | The resource group the virtual hub was deployed into. | +| `resourceId` | string | The resource ID of the virtual hub. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/network/virtual-hub/hub-route-table/README.md b/avm/res/network/virtual-hub/hub-route-table/README.md new file mode 100644 index 0000000000..a7214ef715 --- /dev/null +++ b/avm/res/network/virtual-hub/hub-route-table/README.md @@ -0,0 +1,94 @@ +# Virtual Hub Route Tables `[Microsoft.Network/virtualHubs/hubRouteTables]` + +This module deploys a Virtual Hub Route Table. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Network/virtualHubs/hubRouteTables` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-11-01/virtualHubs/hubRouteTables) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The route table name. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`virtualHubName`](#parameter-virtualhubname) | string | The name of the parent virtual hub. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`labels`](#parameter-labels) | array | List of labels associated with this route table. | +| [`routes`](#parameter-routes) | array | List of all routes. | + +### Parameter: `name` + +The route table name. + +- Required: Yes +- Type: string + +### Parameter: `virtualHubName` + +The name of the parent virtual hub. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `labels` + +List of labels associated with this route table. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `routes` + +List of all routes. + +- Required: No +- Type: array +- Default: `[]` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the deployed virtual hub route table. | +| `resourceGroupName` | string | The resource group the virtual hub route table was deployed into. | +| `resourceId` | string | The resource ID of the deployed virtual hub route table. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/network/virtual-hub/hub-route-table/main.bicep b/avm/res/network/virtual-hub/hub-route-table/main.bicep new file mode 100644 index 0000000000..46d6d2d895 --- /dev/null +++ b/avm/res/network/virtual-hub/hub-route-table/main.bicep @@ -0,0 +1,58 @@ +metadata name = 'Virtual Hub Route Tables' +metadata description = 'This module deploys a Virtual Hub Route Table.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The route table name.') +param name string + +@description('Conditional. The name of the parent virtual hub. Required if the template is used in a standalone deployment.') +param virtualHubName string + +@description('Optional. List of labels associated with this route table.') +param labels array = [] + +@description('Optional. List of all routes.') +param routes array = [] + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableTelemetry) { + name: '46d3xbcp.res.network-virtualhub.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource virtualHub 'Microsoft.Network/virtualHubs@2022-11-01' existing = { + name: virtualHubName +} + +resource hubRouteTable 'Microsoft.Network/virtualHubs/hubRouteTables@2022-11-01' = { + name: name + parent: virtualHub + properties: { + labels: !empty(labels) ? labels : null + routes: !empty(routes) ? routes : null + } +} + +@description('The name of the deployed virtual hub route table.') +output name string = hubRouteTable.name + +@description('The resource ID of the deployed virtual hub route table.') +output resourceId string = hubRouteTable.id + +@description('The resource group the virtual hub route table was deployed into.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/virtual-hub/hub-route-table/main.json b/avm/res/network/virtual-hub/hub-route-table/main.json new file mode 100644 index 0000000000..200e6c44d7 --- /dev/null +++ b/avm/res/network/virtual-hub/hub-route-table/main.json @@ -0,0 +1,103 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "10525202939204553685" + }, + "name": "Virtual Hub Route Tables", + "description": "This module deploys a Virtual Hub Route Table.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The route table name." + } + }, + "virtualHubName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual hub. Required if the template is used in a standalone deployment." + } + }, + "labels": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of labels associated with this route table." + } + }, + "routes": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of all routes." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('46d3xbcp.res.network-virtualhub.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + { + "type": "Microsoft.Network/virtualHubs/hubRouteTables", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualHubName'), parameters('name'))]", + "properties": { + "labels": "[if(not(empty(parameters('labels'))), parameters('labels'), null())]", + "routes": "[if(not(empty(parameters('routes'))), parameters('routes'), null())]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed virtual hub route table." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed virtual hub route table." + }, + "value": "[resourceId('Microsoft.Network/virtualHubs/hubRouteTables', parameters('virtualHubName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the virtual hub route table was deployed into." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md b/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md new file mode 100644 index 0000000000..da9f0e1388 --- /dev/null +++ b/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md @@ -0,0 +1,102 @@ +# Virtual Hub Virtual Network Connections `[Microsoft.Network/virtualHubs/hubVirtualNetworkConnections]` + +This module deploys a Virtual Hub Virtual Network Connection. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-11-01/virtualHubs/hubVirtualNetworkConnections) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The connection name. | +| [`remoteVirtualNetworkId`](#parameter-remotevirtualnetworkid) | string | Resource ID of the virtual network to link to. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`virtualHubName`](#parameter-virtualhubname) | string | The name of the parent virtual hub. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enableInternetSecurity`](#parameter-enableinternetsecurity) | bool | Enable internet security. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`routingConfiguration`](#parameter-routingconfiguration) | object | Routing Configuration indicating the associated and propagated route tables for this connection. | + +### Parameter: `name` + +The connection name. + +- Required: Yes +- Type: string + +### Parameter: `remoteVirtualNetworkId` + +Resource ID of the virtual network to link to. + +- Required: Yes +- Type: string + +### Parameter: `virtualHubName` + +The name of the parent virtual hub. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `enableInternetSecurity` + +Enable internet security. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `routingConfiguration` + +Routing Configuration indicating the associated and propagated route tables for this connection. + +- Required: No +- Type: object +- Default: `{}` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the virtual hub connection. | +| `resourceGroupName` | string | The resource group the virtual hub connection was deployed into. | +| `resourceId` | string | The resource ID of the virtual hub connection. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/network/virtual-hub/hub-virtual-network-connection/main.bicep b/avm/res/network/virtual-hub/hub-virtual-network-connection/main.bicep new file mode 100644 index 0000000000..6e0c0c3119 --- /dev/null +++ b/avm/res/network/virtual-hub/hub-virtual-network-connection/main.bicep @@ -0,0 +1,64 @@ +metadata name = 'Virtual Hub Virtual Network Connections' +metadata description = 'This module deploys a Virtual Hub Virtual Network Connection.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The connection name.') +param name string + +@description('Conditional. The name of the parent virtual hub. Required if the template is used in a standalone deployment.') +param virtualHubName string + +@description('Optional. Enable internet security.') +param enableInternetSecurity bool = true + +@description('Required. Resource ID of the virtual network to link to.') +param remoteVirtualNetworkId string + +@description('Optional. Routing Configuration indicating the associated and propagated route tables for this connection.') +param routingConfiguration object = {} + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableTelemetry) { + name: '46d3xbcp.res.network-virtualhub.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource virtualHub 'Microsoft.Network/virtualHubs@2022-11-01' existing = { + name: virtualHubName +} + +resource hubVirtualNetworkConnection 'Microsoft.Network/virtualHubs/hubVirtualNetworkConnections@2022-11-01' = { + name: name + parent: virtualHub + properties: { + enableInternetSecurity: enableInternetSecurity + remoteVirtualNetwork: { + id: remoteVirtualNetworkId + } + routingConfiguration: !empty(routingConfiguration) ? routingConfiguration : null + } +} + +@description('The resource group the virtual hub connection was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The resource ID of the virtual hub connection.') +output resourceId string = hubVirtualNetworkConnection.id + +@description('The name of the virtual hub connection.') +output name string = hubVirtualNetworkConnection.name diff --git a/avm/res/network/virtual-hub/hub-virtual-network-connection/main.json b/avm/res/network/virtual-hub/hub-virtual-network-connection/main.json new file mode 100644 index 0000000000..ea8e5a326f --- /dev/null +++ b/avm/res/network/virtual-hub/hub-virtual-network-connection/main.json @@ -0,0 +1,112 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "2449431200083704591" + }, + "name": "Virtual Hub Virtual Network Connections", + "description": "This module deploys a Virtual Hub Virtual Network Connection.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The connection name." + } + }, + "virtualHubName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual hub. Required if the template is used in a standalone deployment." + } + }, + "enableInternetSecurity": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable internet security." + } + }, + "remoteVirtualNetworkId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the virtual network to link to." + } + }, + "routingConfiguration": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Routing Configuration indicating the associated and propagated route tables for this connection." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('46d3xbcp.res.network-virtualhub.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + { + "type": "Microsoft.Network/virtualHubs/hubVirtualNetworkConnections", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualHubName'), parameters('name'))]", + "properties": { + "enableInternetSecurity": "[parameters('enableInternetSecurity')]", + "remoteVirtualNetwork": { + "id": "[parameters('remoteVirtualNetworkId')]" + }, + "routingConfiguration": "[if(not(empty(parameters('routingConfiguration'))), parameters('routingConfiguration'), null())]" + } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the virtual hub connection was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the virtual hub connection." + }, + "value": "[resourceId('Microsoft.Network/virtualHubs/hubVirtualNetworkConnections', parameters('virtualHubName'), parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the virtual hub connection." + }, + "value": "[parameters('name')]" + } + } +} \ No newline at end of file diff --git a/avm/res/network/virtual-hub/main.bicep b/avm/res/network/virtual-hub/main.bicep new file mode 100644 index 0000000000..e6326c72bf --- /dev/null +++ b/avm/res/network/virtual-hub/main.bicep @@ -0,0 +1,196 @@ +metadata name = 'Virtual Hubs' +metadata description = '''This module deploys a Virtual Hub. +If you are planning to deploy a Secure Virtual Hub (with an Azure Firewall integrated), please refer to the Azure Firewall module.''' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The virtual hub name.') +param name string + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Required. Address-prefix for this VirtualHub.') +param addressPrefix string + +@description('Optional. Flag to control transit for VirtualRouter hub.') +param allowBranchToBranchTraffic bool = true + +@description('Optional. Resource ID of the Azure Firewall to link to.') +param azureFirewallResourceId string = '' + +@description('Optional. Resource ID of the Express Route Gateway to link to.') +param expressRouteGatewayId string = '' + +@description('Optional. Resource ID of the Point-to-Site VPN Gateway to link to.') +param p2SVpnGatewayId string = '' + +@description('Optional. The preferred routing gateway types.') +@allowed([ + 'ExpressRoute' + 'None' + 'VpnGateway' + '' +]) +param preferredRoutingGateway string = '' + +@description('Optional. VirtualHub route tables.') +param routeTableRoutes array = [] + +@description('Optional. ID of the Security Partner Provider to link to.') +param securityPartnerProviderId string = '' + +@description('Optional. The Security Provider name.') +param securityProviderName string = '' + +@allowed([ + 'Basic' + 'Standard' +]) +@description('Optional. The sku of this VirtualHub.') +param sku string = 'Standard' + +@description('Optional. List of all virtual hub route table v2s associated with this VirtualHub.') +param virtualHubRouteTableV2s array = [] + +@description('Optional. VirtualRouter ASN.') +param virtualRouterAsn int? + +@description('Optional. VirtualRouter IPs.') +param virtualRouterIps array = [] + +@description('Required. Resource ID of the virtual WAN to link to.') +param virtualWanId string + +@description('Optional. Resource ID of the VPN Gateway to link to.') +param vpnGatewayId string = '' + +@description('Optional. Route tables to create for the virtual hub.') +param hubRouteTables array = [] + +@description('Optional. Virtual network connections to create for the virtual hub.') +param hubVirtualNetworkConnections array = [] + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +var enableReferencedModulesTelemetry = false + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: take('46d3xbcp.res.network-virtualhub.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}', 64) + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource virtualHub 'Microsoft.Network/virtualHubs@2022-11-01' = { + name: name + location: location + tags: tags + properties: { + addressPrefix: addressPrefix + allowBranchToBranchTraffic: allowBranchToBranchTraffic + azureFirewall: !empty(azureFirewallResourceId) ? { + id: azureFirewallResourceId + } : null + expressRouteGateway: !empty(expressRouteGatewayId) ? { + id: expressRouteGatewayId + } : null + p2SVpnGateway: !empty(p2SVpnGatewayId) ? { + id: p2SVpnGatewayId + } : null + preferredRoutingGateway: !empty(preferredRoutingGateway) ? any(preferredRoutingGateway) : null + routeTable: !empty(routeTableRoutes) ? { + routes: routeTableRoutes + } : null + securityPartnerProvider: !empty(securityPartnerProviderId) ? { + id: securityPartnerProviderId + } : null + securityProviderName: securityProviderName + sku: sku + virtualHubRouteTableV2s: virtualHubRouteTableV2s + virtualRouterAsn: virtualRouterAsn + virtualRouterIps: !empty(virtualRouterIps) ? virtualRouterIps : null + virtualWan: { + id: virtualWanId + } + vpnGateway: !empty(vpnGatewayId) ? { + id: vpnGatewayId + } : null + } +} + +resource virtualHub_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: virtualHub +} + +module virtualHub_routeTables 'hub-route-table/main.bicep' = [for (routeTable, index) in hubRouteTables: { + name: '${uniqueString(deployment().name, location)}-routeTable-${index}' + params: { + virtualHubName: virtualHub.name + name: routeTable.name + labels: contains(routeTable, 'labels') ? routeTable.labels : [] + routes: contains(routeTable, 'routes') ? routeTable.routes : [] + enableTelemetry: enableReferencedModulesTelemetry + } +}] + +module virtualHub_hubVirtualNetworkConnections 'hub-virtual-network-connection/main.bicep' = [for (virtualNetworkConnection, index) in hubVirtualNetworkConnections: { + name: '${uniqueString(deployment().name, location)}-connection-${index}' + params: { + virtualHubName: virtualHub.name + name: virtualNetworkConnection.name + enableInternetSecurity: contains(virtualNetworkConnection, 'enableInternetSecurity') ? virtualNetworkConnection.enableInternetSecurity : true + remoteVirtualNetworkId: virtualNetworkConnection.remoteVirtualNetworkId + routingConfiguration: contains(virtualNetworkConnection, 'routingConfiguration') ? virtualNetworkConnection.routingConfiguration : {} + enableTelemetry: enableReferencedModulesTelemetry + } + dependsOn: [ + virtualHub_routeTables + ] +}] + +@description('The resource group the virtual hub was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The resource ID of the virtual hub.') +output resourceId string = virtualHub.id + +@description('The name of the virtual hub.') +output name string = virtualHub.name + +@description('The location the resource was deployed into.') +output location string = virtualHub.location + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? diff --git a/avm/res/network/virtual-hub/main.json b/avm/res/network/virtual-hub/main.json new file mode 100644 index 0000000000..b230823993 --- /dev/null +++ b/avm/res/network/virtual-hub/main.json @@ -0,0 +1,580 @@ +{ + "$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.25.53.49325", + "templateHash": "14890345402999745367" + }, + "name": "Virtual Hubs", + "description": "This module deploys a Virtual Hub.\nIf you are planning to deploy a Secure Virtual Hub (with an Azure Firewall integrated), please refer to the Azure Firewall module.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The virtual hub name." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "addressPrefix": { + "type": "string", + "metadata": { + "description": "Required. Address-prefix for this VirtualHub." + } + }, + "allowBranchToBranchTraffic": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Flag to control transit for VirtualRouter hub." + } + }, + "azureFirewallResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the Azure Firewall to link to." + } + }, + "expressRouteGatewayId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the Express Route Gateway to link to." + } + }, + "p2SVpnGatewayId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the Point-to-Site VPN Gateway to link to." + } + }, + "preferredRoutingGateway": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "ExpressRoute", + "None", + "VpnGateway", + "" + ], + "metadata": { + "description": "Optional. The preferred routing gateway types." + } + }, + "routeTableRoutes": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. VirtualHub route tables." + } + }, + "securityPartnerProviderId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. ID of the Security Partner Provider to link to." + } + }, + "securityProviderName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The Security Provider name." + } + }, + "sku": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Basic", + "Standard" + ], + "metadata": { + "description": "Optional. The sku of this VirtualHub." + } + }, + "virtualHubRouteTableV2s": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of all virtual hub route table v2s associated with this VirtualHub." + } + }, + "virtualRouterAsn": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. VirtualRouter ASN." + } + }, + "virtualRouterIps": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. VirtualRouter IPs." + } + }, + "virtualWanId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the virtual WAN to link to." + } + }, + "vpnGatewayId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the VPN Gateway to link to." + } + }, + "hubRouteTables": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Route tables to create for the virtual hub." + } + }, + "hubVirtualNetworkConnections": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Virtual network connections to create for the virtual hub." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "enableReferencedModulesTelemetry": false + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[take(format('46d3xbcp.res.network-virtualhub.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4)), 64)]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "virtualHub": { + "type": "Microsoft.Network/virtualHubs", + "apiVersion": "2022-11-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "addressPrefix": "[parameters('addressPrefix')]", + "allowBranchToBranchTraffic": "[parameters('allowBranchToBranchTraffic')]", + "azureFirewall": "[if(not(empty(parameters('azureFirewallResourceId'))), createObject('id', parameters('azureFirewallResourceId')), null())]", + "expressRouteGateway": "[if(not(empty(parameters('expressRouteGatewayId'))), createObject('id', parameters('expressRouteGatewayId')), null())]", + "p2SVpnGateway": "[if(not(empty(parameters('p2SVpnGatewayId'))), createObject('id', parameters('p2SVpnGatewayId')), null())]", + "preferredRoutingGateway": "[if(not(empty(parameters('preferredRoutingGateway'))), parameters('preferredRoutingGateway'), null())]", + "routeTable": "[if(not(empty(parameters('routeTableRoutes'))), createObject('routes', parameters('routeTableRoutes')), null())]", + "securityPartnerProvider": "[if(not(empty(parameters('securityPartnerProviderId'))), createObject('id', parameters('securityPartnerProviderId')), null())]", + "securityProviderName": "[parameters('securityProviderName')]", + "sku": "[parameters('sku')]", + "virtualHubRouteTableV2s": "[parameters('virtualHubRouteTableV2s')]", + "virtualRouterAsn": "[parameters('virtualRouterAsn')]", + "virtualRouterIps": "[if(not(empty(parameters('virtualRouterIps'))), parameters('virtualRouterIps'), null())]", + "virtualWan": { + "id": "[parameters('virtualWanId')]" + }, + "vpnGateway": "[if(not(empty(parameters('vpnGatewayId'))), createObject('id', parameters('vpnGatewayId')), null())]" + } + }, + "virtualHub_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/virtualHubs/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "virtualHub" + ] + }, + "virtualHub_routeTables": { + "copy": { + "name": "virtualHub_routeTables", + "count": "[length(parameters('hubRouteTables'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-routeTable-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualHubName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('hubRouteTables')[copyIndex()].name]" + }, + "labels": "[if(contains(parameters('hubRouteTables')[copyIndex()], 'labels'), createObject('value', parameters('hubRouteTables')[copyIndex()].labels), createObject('value', createArray()))]", + "routes": "[if(contains(parameters('hubRouteTables')[copyIndex()], 'routes'), createObject('value', parameters('hubRouteTables')[copyIndex()].routes), createObject('value', createArray()))]", + "enableTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "10525202939204553685" + }, + "name": "Virtual Hub Route Tables", + "description": "This module deploys a Virtual Hub Route Table.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The route table name." + } + }, + "virtualHubName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual hub. Required if the template is used in a standalone deployment." + } + }, + "labels": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of labels associated with this route table." + } + }, + "routes": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of all routes." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('46d3xbcp.res.network-virtualhub.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + { + "type": "Microsoft.Network/virtualHubs/hubRouteTables", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualHubName'), parameters('name'))]", + "properties": { + "labels": "[if(not(empty(parameters('labels'))), parameters('labels'), null())]", + "routes": "[if(not(empty(parameters('routes'))), parameters('routes'), null())]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed virtual hub route table." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed virtual hub route table." + }, + "value": "[resourceId('Microsoft.Network/virtualHubs/hubRouteTables', parameters('virtualHubName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the virtual hub route table was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "virtualHub" + ] + }, + "virtualHub_hubVirtualNetworkConnections": { + "copy": { + "name": "virtualHub_hubVirtualNetworkConnections", + "count": "[length(parameters('hubVirtualNetworkConnections'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-connection-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualHubName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('hubVirtualNetworkConnections')[copyIndex()].name]" + }, + "enableInternetSecurity": "[if(contains(parameters('hubVirtualNetworkConnections')[copyIndex()], 'enableInternetSecurity'), createObject('value', parameters('hubVirtualNetworkConnections')[copyIndex()].enableInternetSecurity), createObject('value', true()))]", + "remoteVirtualNetworkId": { + "value": "[parameters('hubVirtualNetworkConnections')[copyIndex()].remoteVirtualNetworkId]" + }, + "routingConfiguration": "[if(contains(parameters('hubVirtualNetworkConnections')[copyIndex()], 'routingConfiguration'), createObject('value', parameters('hubVirtualNetworkConnections')[copyIndex()].routingConfiguration), createObject('value', createObject()))]", + "enableTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "2449431200083704591" + }, + "name": "Virtual Hub Virtual Network Connections", + "description": "This module deploys a Virtual Hub Virtual Network Connection.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The connection name." + } + }, + "virtualHubName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual hub. Required if the template is used in a standalone deployment." + } + }, + "enableInternetSecurity": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable internet security." + } + }, + "remoteVirtualNetworkId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the virtual network to link to." + } + }, + "routingConfiguration": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Routing Configuration indicating the associated and propagated route tables for this connection." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('46d3xbcp.res.network-virtualhub.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + { + "type": "Microsoft.Network/virtualHubs/hubVirtualNetworkConnections", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualHubName'), parameters('name'))]", + "properties": { + "enableInternetSecurity": "[parameters('enableInternetSecurity')]", + "remoteVirtualNetwork": { + "id": "[parameters('remoteVirtualNetworkId')]" + }, + "routingConfiguration": "[if(not(empty(parameters('routingConfiguration'))), parameters('routingConfiguration'), null())]" + } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the virtual hub connection was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the virtual hub connection." + }, + "value": "[resourceId('Microsoft.Network/virtualHubs/hubVirtualNetworkConnections', parameters('virtualHubName'), parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the virtual hub connection." + }, + "value": "[parameters('name')]" + } + } + } + }, + "dependsOn": [ + "virtualHub", + "virtualHub_routeTables" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the virtual hub was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the virtual hub." + }, + "value": "[resourceId('Microsoft.Network/virtualHubs', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the virtual hub." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('virtualHub', '2022-11-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/network/virtual-hub/tests/e2e/defaults/dependencies.bicep b/avm/res/network/virtual-hub/tests/e2e/defaults/dependencies.bicep new file mode 100644 index 0000000000..bb151ad9d8 --- /dev/null +++ b/avm/res/network/virtual-hub/tests/e2e/defaults/dependencies.bicep @@ -0,0 +1,13 @@ +@description('Required. The name of the virtual WAN to create.') +param virtualWANName string + +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +resource virtualWan 'Microsoft.Network/virtualWans@2023-04-01' = { + name: virtualWANName + location: location +} + +@description('The resource ID of the created Virtual WAN.') +output virtualWWANResourceId string = virtualWan.id diff --git a/avm/res/network/virtual-hub/tests/e2e/defaults/main.test.bicep b/avm/res/network/virtual-hub/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..5f6bfff780 --- /dev/null +++ b/avm/res/network/virtual-hub/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,58 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.virtualHub-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nvhmin' + + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualWANName: 'dep-${namePrefix}-vw-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}-${serviceShort}' + addressPrefix: '10.0.0.0/16' + virtualWanId: nestedDependencies.outputs.virtualWWANResourceId + location: resourceLocation + } +}] diff --git a/avm/res/network/virtual-hub/tests/e2e/max/dependencies.bicep b/avm/res/network/virtual-hub/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..9c4af5313d --- /dev/null +++ b/avm/res/network/virtual-hub/tests/e2e/max/dependencies.bicep @@ -0,0 +1,42 @@ +@description('Required. The name of the Virtual WAN to create.') +param virtualWANName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +var addressPrefix = '10.0.0.0/16' + +resource virtualWan 'Microsoft.Network/virtualWans@2023-04-01' = { + name: virtualWANName + location: location +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +@description('The resource ID of the created Virtual WAN.') +output virtualWWANResourceId string = virtualWan.id + +@description('The resource ID of the created Virtual Network.') +output virtualNetworkResourceId string = virtualNetwork.id diff --git a/avm/res/network/virtual-hub/tests/e2e/max/main.test.bicep b/avm/res/network/virtual-hub/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..0e72b20ad4 --- /dev/null +++ b/avm/res/network/virtual-hub/tests/e2e/max/main.test.bicep @@ -0,0 +1,93 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.virtualHub-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nvhmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualWANName: 'dep-${namePrefix}-vw-${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + location: resourceLocation + name: '${namePrefix}-${serviceShort}' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + addressPrefix: '10.1.0.0/16' + virtualWanId: nestedDependencies.outputs.virtualWWANResourceId + hubRouteTables: [ + { + name: 'routeTable1' + } + ] + hubVirtualNetworkConnections: [ + { + name: 'connection1' + remoteVirtualNetworkId: nestedDependencies.outputs.virtualNetworkResourceId + routingConfiguration: { + associatedRouteTable: { + id: '${resourceGroup.id}/providers/Microsoft.Network/virtualHubs/${namePrefix}-${serviceShort}/hubRouteTables/routeTable1' + } + propagatedRouteTables: { + ids: [ + { + id: '${resourceGroup.id}/providers/Microsoft.Network/virtualHubs/${namePrefix}-${serviceShort}/hubRouteTables/routeTable1' + } + ] + labels: [ + 'none' + ] + } + } + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/network/virtual-hub/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/virtual-hub/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..9c4af5313d --- /dev/null +++ b/avm/res/network/virtual-hub/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,42 @@ +@description('Required. The name of the Virtual WAN to create.') +param virtualWANName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +var addressPrefix = '10.0.0.0/16' + +resource virtualWan 'Microsoft.Network/virtualWans@2023-04-01' = { + name: virtualWANName + location: location +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +@description('The resource ID of the created Virtual WAN.') +output virtualWWANResourceId string = virtualWan.id + +@description('The resource ID of the created Virtual Network.') +output virtualNetworkResourceId string = virtualNetwork.id diff --git a/avm/res/network/virtual-hub/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/virtual-hub/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..ee601164eb --- /dev/null +++ b/avm/res/network/virtual-hub/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,93 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.virtualHub-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nvhwaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualWANName: 'dep-${namePrefix}-vw-${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}-${serviceShort}' + location: resourceLocation + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + addressPrefix: '10.1.0.0/16' + virtualWanId: nestedDependencies.outputs.virtualWWANResourceId + hubRouteTables: [ + { + name: 'routeTable1' + } + ] + hubVirtualNetworkConnections: [ + { + name: 'connection1' + remoteVirtualNetworkId: nestedDependencies.outputs.virtualNetworkResourceId + routingConfiguration: { + associatedRouteTable: { + id: '${resourceGroup.id}/providers/Microsoft.Network/virtualHubs/${namePrefix}-${serviceShort}/hubRouteTables/routeTable1' + } + propagatedRouteTables: { + ids: [ + { + id: '${resourceGroup.id}/providers/Microsoft.Network/virtualHubs/${namePrefix}-${serviceShort}/hubRouteTables/routeTable1' + } + ] + labels: [ + 'none' + ] + } + } + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/network/virtual-hub/version.json b/avm/res/network/virtual-hub/version.json new file mode 100644 index 0000000000..7fa401bdf7 --- /dev/null +++ b/avm/res/network/virtual-hub/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} diff --git a/avm/res/network/virtual-network-gateway/README.md b/avm/res/network/virtual-network-gateway/README.md index 0becb94816..12f7cc68d9 100644 --- a/avm/res/network/virtual-network-gateway/README.md +++ b/avm/res/network/virtual-network-gateway/README.md @@ -383,7 +383,7 @@ module virtualNetworkGateway 'br/public:avm/res/network/virtual-network-gateway: ] mode: 'EgressSnat' name: 'nat-rule-2-dynamic-EgressSnat' - type: 'Dynamic' + type: 'Static' } ] publicIpZones: [ @@ -525,7 +525,7 @@ module virtualNetworkGateway 'br/public:avm/res/network/virtual-network-gateway: ], "mode": "EgressSnat", "name": "nat-rule-2-dynamic-EgressSnat", - "type": "Dynamic" + "type": "Static" } ] }, @@ -765,7 +765,7 @@ module virtualNetworkGateway 'br/public:avm/res/network/virtual-network-gateway: ] mode: 'EgressSnat' name: 'nat-rule-2-dynamic-EgressSnat' - type: 'Dynamic' + type: 'Static' } ] publicIpZones: [ @@ -890,7 +890,7 @@ module virtualNetworkGateway 'br/public:avm/res/network/virtual-network-gateway: ], "mode": "EgressSnat", "name": "nat-rule-2-dynamic-EgressSnat", - "type": "Dynamic" + "type": "Static" } ] }, @@ -1094,9 +1094,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1131,11 +1131,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1145,11 +1174,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -1309,9 +1364,9 @@ The diagnostic settings of the Public IP. | [`eventHubAuthorizationRuleResourceId`](#parameter-publicipdiagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-publicipdiagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-publicipdiagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-publicipdiagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-publicipdiagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-publicipdiagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-publicipdiagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-publicipdiagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-publicipdiagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-publicipdiagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-publicipdiagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1346,11 +1401,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `publicIpDiagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-publicipdiagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-publicipdiagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-publicipdiagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `publicIpDiagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `publicIpDiagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `publicIpDiagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `publicIpDiagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1360,11 +1444,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `publicIpDiagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-publicipdiagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-publicipdiagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `publicIpDiagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `publicIpDiagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `publicIpDiagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/network/virtual-network-gateway/main.bicep b/avm/res/network/virtual-network-gateway/main.bicep index f05fb532d2..1057d03afd 100644 --- a/avm/res/network/virtual-network-gateway/main.bicep +++ b/avm/res/network/virtual-network-gateway/main.bicep @@ -273,7 +273,6 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableT } } - // Public IPs @batchSize(1) module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.2.0' = [for (virtualGatewayPublicIpName, index) in virtualGatewayPipNameVar: { @@ -290,12 +289,11 @@ module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.2.0' = [fo zones: contains(zoneRedundantSkus, skuName) ? publicIpZones : [] dnsSettings: { domainNameLabel: length(virtualGatewayPipNameVar) == length(domainNameLabel) ? domainNameLabel[index] : virtualGatewayPublicIpName - domainNameLabelScope:'' + domainNameLabelScope: '' } } }] - // VNET Gateway // ============ resource virtualNetworkGateway 'Microsoft.Network/virtualNetworkGateways@2023-04-01' = { @@ -359,19 +357,16 @@ resource virtualNetworkGateway_diagnosticSettings 'Microsoft.Insights/diagnostic workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -449,19 +444,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/network/virtual-network-gateway/main.json b/avm/res/network/virtual-network-gateway/main.json index 2ebecd9d73..19057806a9 100644 --- a/avm/res/network/virtual-network-gateway/main.json +++ b/avm/res/network/virtual-network-gateway/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1429972984344386718" + "version": "0.25.53.49325", + "templateHash": "17858008949530514784" }, "name": "Virtual Network Gateways", "description": "This module deploys a Virtual Network Gateway.", @@ -132,14 +132,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -150,14 +157,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -575,12 +589,30 @@ "scope": "[format('Microsoft.Network/virtualNetworkGateways/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -1246,8 +1278,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16896615660479182847" + "version": "0.25.53.49325", + "templateHash": "3205216051078222233" }, "name": "VPN Gateway NAT Rules", "description": "This module deploys a Virtual Network Gateway NAT Rule.", diff --git a/avm/res/network/virtual-network-gateway/nat-rule/main.json b/avm/res/network/virtual-network-gateway/nat-rule/main.json index f24ea82f1c..97aea584a5 100644 --- a/avm/res/network/virtual-network-gateway/nat-rule/main.json +++ b/avm/res/network/virtual-network-gateway/nat-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16896615660479182847" + "version": "0.25.53.49325", + "templateHash": "3205216051078222233" }, "name": "VPN Gateway NAT Rules", "description": "This module deploys a Virtual Network Gateway NAT Rule.", diff --git a/avm/res/network/virtual-network-gateway/tests/e2e/max/main.test.bicep b/avm/res/network/virtual-network-gateway/tests/e2e/max/main.test.bicep index 404109780e..c19158b27d 100644 --- a/avm/res/network/virtual-network-gateway/tests/e2e/max/main.test.bicep +++ b/avm/res/network/virtual-network-gateway/tests/e2e/max/main.test.bicep @@ -145,7 +145,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } { name: 'nat-rule-2-dynamic-EgressSnat' - type: 'Dynamic' + type: 'Static' mode: 'EgressSnat' internalMappings: [ { diff --git a/avm/res/network/virtual-network-gateway/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/virtual-network-gateway/tests/e2e/waf-aligned/main.test.bicep index 70fd6b61a8..bb3834d377 100644 --- a/avm/res/network/virtual-network-gateway/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/virtual-network-gateway/tests/e2e/waf-aligned/main.test.bicep @@ -126,7 +126,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } { name: 'nat-rule-2-dynamic-EgressSnat' - type: 'Dynamic' + type: 'Static' mode: 'EgressSnat' internalMappings: [ { diff --git a/avm/res/network/virtual-network/README.md b/avm/res/network/virtual-network/README.md index c780d88960..3af121ac52 100644 --- a/avm/res/network/virtual-network/README.md +++ b/avm/res/network/virtual-network/README.md @@ -772,9 +772,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -809,11 +809,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -823,11 +852,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/network/virtual-network/main.bicep b/avm/res/network/virtual-network/main.bicep index 82f4a8cc4c..65ab3baa75 100644 --- a/avm/res/network/virtual-network/main.bicep +++ b/avm/res/network/virtual-network/main.bicep @@ -209,19 +209,16 @@ resource virtualNetwork_diagnosticSettings 'Microsoft.Insights/diagnosticSetting workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -299,19 +296,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/network/virtual-network/main.json b/avm/res/network/virtual-network/main.json index 7dd860090f..a47fedbced 100644 --- a/avm/res/network/virtual-network/main.json +++ b/avm/res/network/virtual-network/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16201617947579685823" + "version": "0.25.53.49325", + "templateHash": "10816792797635578407" }, "name": "Virtual Networks", "description": "This module deploys a Virtual Network (vNet).", @@ -132,14 +132,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -150,14 +157,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -419,12 +433,30 @@ "scope": "[format('Microsoft.Network/virtualNetworks/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -497,8 +529,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "279998742971122360" + "version": "0.25.53.49325", + "templateHash": "17033578581013380517" }, "name": "Virtual Network Subnets", "description": "This module deploys a Virtual Network Subnet.", @@ -823,8 +855,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "853734530125813320" + "version": "0.25.53.49325", + "templateHash": "12334551415753639891" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", @@ -968,8 +1000,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "853734530125813320" + "version": "0.25.53.49325", + "templateHash": "12334551415753639891" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", diff --git a/avm/res/network/virtual-network/subnet/main.json b/avm/res/network/virtual-network/subnet/main.json index 3342baab09..55f868f9fd 100644 --- a/avm/res/network/virtual-network/subnet/main.json +++ b/avm/res/network/virtual-network/subnet/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "279998742971122360" + "version": "0.25.53.49325", + "templateHash": "17033578581013380517" }, "name": "Virtual Network Subnets", "description": "This module deploys a Virtual Network Subnet.", diff --git a/avm/res/network/virtual-network/virtual-network-peering/main.json b/avm/res/network/virtual-network/virtual-network-peering/main.json index 2932e94bdd..2c6b4fadea 100644 --- a/avm/res/network/virtual-network/virtual-network-peering/main.json +++ b/avm/res/network/virtual-network/virtual-network-peering/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "853734530125813320" + "version": "0.25.53.49325", + "templateHash": "12334551415753639891" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", diff --git a/avm/res/network/virtual-wan/README.md b/avm/res/network/virtual-wan/README.md new file mode 100644 index 0000000000..044630e644 --- /dev/null +++ b/avm/res/network/virtual-wan/README.md @@ -0,0 +1,513 @@ +# Virtual WANs `[Microsoft.Network/virtualWans]` + +This module deploys a Virtual WAN. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Network/virtualWans` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/virtualWans) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/network/virtual-wan:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep +module virtualWan 'br/public:avm/res/network/virtual-wan:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nvwmin' + params: { + // Required parameters + name: 'nvwmin001' + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "nvwmin001" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module virtualWan 'br/public:avm/res/network/virtual-wan:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nvwmax' + params: { + // Required parameters + name: 'nvwmax001' + // Non-required parameters + allowBranchToBranchTraffic: true + allowVnetToVnetTraffic: true + disableVpnEncryption: true + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + type: 'Basic' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "nvwmax001" + }, + // Non-required parameters + "allowBranchToBranchTraffic": { + "value": true + }, + "allowVnetToVnetTraffic": { + "value": true + }, + "disableVpnEncryption": { + "value": true + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "type": { + "value": "Basic" + } + } +} +``` + +
    +

    + +### Example 3: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module virtualWan 'br/public:avm/res/network/virtual-wan:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-nvwwaf' + params: { + // Required parameters + name: 'nvwwaf001' + // Non-required parameters + allowBranchToBranchTraffic: true + allowVnetToVnetTraffic: true + disableVpnEncryption: true + location: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + type: 'Basic' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "nvwwaf001" + }, + // Non-required parameters + "allowBranchToBranchTraffic": { + "value": true + }, + "allowVnetToVnetTraffic": { + "value": true + }, + "disableVpnEncryption": { + "value": true + }, + "location": { + "value": "" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "type": { + "value": "Basic" + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | Name of the Virtual WAN. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`allowBranchToBranchTraffic`](#parameter-allowbranchtobranchtraffic) | bool | True if branch to branch traffic is allowed. | +| [`allowVnetToVnetTraffic`](#parameter-allowvnettovnettraffic) | bool | True if VNET to VNET traffic is allowed. | +| [`disableVpnEncryption`](#parameter-disablevpnencryption) | bool | VPN encryption to be disabled or not. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`location`](#parameter-location) | string | Location where all resources will be created. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`type`](#parameter-type) | string | The type of the Virtual WAN. | + +### Parameter: `name` + +Name of the Virtual WAN. + +- Required: Yes +- Type: string + +### Parameter: `allowBranchToBranchTraffic` + +True if branch to branch traffic is allowed. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `allowVnetToVnetTraffic` + +True if VNET to VNET traffic is allowed. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `disableVpnEncryption` + +VPN encryption to be disabled or not. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `location` + +Location where all resources will be created. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `type` + +The type of the Virtual WAN. + +- Required: No +- Type: string +- Default: `'Standard'` +- Allowed: + ```Bicep + [ + 'Basic' + 'Standard' + ] + ``` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the virtual WAN. | +| `resourceGroupName` | string | The resource group the virtual WAN was deployed into. | +| `resourceId` | string | The resource ID of the virtual WAN. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/network/virtual-wan/main.bicep b/avm/res/network/virtual-wan/main.bicep new file mode 100644 index 0000000000..c130a7eae3 --- /dev/null +++ b/avm/res/network/virtual-wan/main.bicep @@ -0,0 +1,146 @@ +metadata name = 'Virtual WANs' +metadata description = 'This module deploys a Virtual WAN.' +metadata owner = 'Azure/module-maintainers' + +@description('Optional. Location where all resources will be created.') +param location string = resourceGroup().location + +@description('Required. Name of the Virtual WAN.') +param name string + +@description('Optional. The type of the Virtual WAN.') +@allowed([ + 'Standard' + 'Basic' +]) +param type string = 'Standard' + +@description('Optional. True if branch to branch traffic is allowed.') +param allowBranchToBranchTraffic bool = false + +@description('Optional. True if VNET to VNET traffic is allowed.') +param allowVnetToVnetTraffic bool = false + +@description('Optional. VPN encryption to be disabled or not.') +param disableVpnEncryption bool = false + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@description('Optional. The lock settings of the service.') +param lock lockType + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.network-virtualwan.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource virtualWan 'Microsoft.Network/virtualWans@2023-04-01' = { + name: name + location: location + tags: tags + properties: { + allowBranchToBranchTraffic: allowBranchToBranchTraffic + allowVnetToVnetTraffic: allowVnetToVnetTraffic ? allowVnetToVnetTraffic : null + disableVpnEncryption: disableVpnEncryption + type: type + } +} + +resource virtualWan_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: virtualWan +} + +resource networkInterface_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(virtualWan.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: virtualWan +}] + +@description('The name of the virtual WAN.') +output name string = virtualWan.name + +@description('The resource ID of the virtual WAN.') +output resourceId string = virtualWan.id + +@description('The resource group the virtual WAN was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The location the resource was deployed into.') +output location string = virtualWan.location + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? diff --git a/avm/res/network/virtual-wan/main.json b/avm/res/network/virtual-wan/main.json new file mode 100644 index 0000000000..4bdfcb62dc --- /dev/null +++ b/avm/res/network/virtual-wan/main.json @@ -0,0 +1,292 @@ +{ + "$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.25.53.49325", + "templateHash": "5785178353049312317" + }, + "name": "Virtual WANs", + "description": "This module deploys a Virtual WAN.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location where all resources will be created." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the Virtual WAN." + } + }, + "type": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Standard", + "Basic" + ], + "metadata": { + "description": "Optional. The type of the Virtual WAN." + } + }, + "allowBranchToBranchTraffic": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. True if branch to branch traffic is allowed." + } + }, + "allowVnetToVnetTraffic": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. True if VNET to VNET traffic is allowed." + } + }, + "disableVpnEncryption": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. VPN encryption to be disabled or not." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-virtualwan.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "virtualWan": { + "type": "Microsoft.Network/virtualWans", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "allowBranchToBranchTraffic": "[parameters('allowBranchToBranchTraffic')]", + "allowVnetToVnetTraffic": "[if(parameters('allowVnetToVnetTraffic'), parameters('allowVnetToVnetTraffic'), null())]", + "disableVpnEncryption": "[parameters('disableVpnEncryption')]", + "type": "[parameters('type')]" + } + }, + "virtualWan_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/virtualWans/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "virtualWan" + ] + }, + "networkInterface_roleAssignments": { + "copy": { + "name": "networkInterface_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/virtualWans/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/virtualWans', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "virtualWan" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the virtual WAN." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the virtual WAN." + }, + "value": "[resourceId('Microsoft.Network/virtualWans', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the virtual WAN was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('virtualWan', '2023-04-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/network/virtual-wan/tests/e2e/defaults/main.test.bicep b/avm/res/network/virtual-wan/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..02d9cb1c28 --- /dev/null +++ b/avm/res/network/virtual-wan/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,46 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.virtualwans-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nvwmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + } +}] diff --git a/avm/res/network/virtual-wan/tests/e2e/max/dependencies.bicep b/avm/res/network/virtual-wan/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..2ab8334b56 --- /dev/null +++ b/avm/res/network/virtual-wan/tests/e2e/max/dependencies.bicep @@ -0,0 +1,13 @@ +@description('Optional. The location to deploy to.') +param resourceLocation string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: resourceLocation +} + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/res/network/virtual-wan/tests/e2e/max/main.test.bicep b/avm/res/network/virtual-wan/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..1801cec4af --- /dev/null +++ b/avm/res/network/virtual-wan/tests/e2e/max/main.test.bicep @@ -0,0 +1,85 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.virtualwans-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nvwmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + resourceLocation: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + allowBranchToBranchTraffic: true + allowVnetToVnetTraffic: true + disableVpnEncryption: true + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + type: 'Basic' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/network/virtual-wan/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/virtual-wan/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..a7f42aee7b --- /dev/null +++ b/avm/res/network/virtual-wan/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,13 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/res/network/virtual-wan/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/virtual-wan/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..e9e2986686 --- /dev/null +++ b/avm/res/network/virtual-wan/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,64 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.virtualwans-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nvwwaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + location: resourceLocation + name: '${namePrefix}${serviceShort}001' + allowBranchToBranchTraffic: true + allowVnetToVnetTraffic: true + disableVpnEncryption: true + type: 'Basic' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/network/virtual-wan/version.json b/avm/res/network/virtual-wan/version.json new file mode 100644 index 0000000000..7fa401bdf7 --- /dev/null +++ b/avm/res/network/virtual-wan/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} diff --git a/avm/res/network/vpn-gateway/main.json b/avm/res/network/vpn-gateway/main.json index 7d3fef3be1..515119c148 100644 --- a/avm/res/network/vpn-gateway/main.json +++ b/avm/res/network/vpn-gateway/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1364825711477214481" + "version": "0.25.53.49325", + "templateHash": "18311728331837293497" }, "name": "VPN Gateways", "description": "This module deploys a VPN Gateway.", @@ -235,8 +235,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6272508492261221909" + "version": "0.25.53.49325", + "templateHash": "10009969919084019961" }, "name": "VPN Gateway NAT Rules", "description": "This module deploys a VPN Gateway NAT Rule.", @@ -417,8 +417,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1538972740652771448" + "version": "0.25.53.49325", + "templateHash": "2523279657002252302" }, "name": "VPN Gateway VPN Connections", "description": "This module deploys a VPN Gateway VPN Connection.", diff --git a/avm/res/network/vpn-gateway/nat-rule/main.json b/avm/res/network/vpn-gateway/nat-rule/main.json index 4aebb76e20..8cb6ebdcd5 100644 --- a/avm/res/network/vpn-gateway/nat-rule/main.json +++ b/avm/res/network/vpn-gateway/nat-rule/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6272508492261221909" + "version": "0.25.53.49325", + "templateHash": "10009969919084019961" }, "name": "VPN Gateway NAT Rules", "description": "This module deploys a VPN Gateway NAT Rule.", diff --git a/avm/res/network/vpn-gateway/vpn-connection/main.json b/avm/res/network/vpn-gateway/vpn-connection/main.json index 15b81dce41..7ec547d29d 100644 --- a/avm/res/network/vpn-gateway/vpn-connection/main.json +++ b/avm/res/network/vpn-gateway/vpn-connection/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1538972740652771448" + "version": "0.25.53.49325", + "templateHash": "2523279657002252302" }, "name": "VPN Gateway VPN Connections", "description": "This module deploys a VPN Gateway VPN Connection.", diff --git a/avm/res/network/vpn-site/main.json b/avm/res/network/vpn-site/main.json index 7be751e4a9..158bb5fe53 100644 --- a/avm/res/network/vpn-site/main.json +++ b/avm/res/network/vpn-site/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2045795544331702359" + "version": "0.25.53.49325", + "templateHash": "15929978987009174743" }, "name": "VPN Sites", "description": "This module deploys a VPN Site.", diff --git a/avm/res/operational-insights/workspace/README.md b/avm/res/operational-insights/workspace/README.md index 8b2247c2ac..d4ab956f18 100644 --- a/avm/res/operational-insights/workspace/README.md +++ b/avm/res/operational-insights/workspace/README.md @@ -1790,9 +1790,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1827,11 +1827,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1841,11 +1870,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/operational-insights/workspace/data-export/main.json b/avm/res/operational-insights/workspace/data-export/main.json index 03cf4aafb7..950108de7f 100644 --- a/avm/res/operational-insights/workspace/data-export/main.json +++ b/avm/res/operational-insights/workspace/data-export/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7413462048618089111" + "version": "0.25.53.49325", + "templateHash": "12543023571728523937" }, "name": "Log Analytics Workspace Data Exports", "description": "This module deploys a Log Analytics Workspace Data Export.", diff --git a/avm/res/operational-insights/workspace/data-source/main.json b/avm/res/operational-insights/workspace/data-source/main.json index 678bae4faf..d77dd6f3af 100644 --- a/avm/res/operational-insights/workspace/data-source/main.json +++ b/avm/res/operational-insights/workspace/data-source/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12960146774033634359" + "version": "0.25.53.49325", + "templateHash": "14032975851567807564" }, "name": "Log Analytics Workspace Datasources", "description": "This module deploys a Log Analytics Workspace Data Source.", diff --git a/avm/res/operational-insights/workspace/linked-service/main.json b/avm/res/operational-insights/workspace/linked-service/main.json index 11cc095630..816832ad7c 100644 --- a/avm/res/operational-insights/workspace/linked-service/main.json +++ b/avm/res/operational-insights/workspace/linked-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6280157469343577004" + "version": "0.25.53.49325", + "templateHash": "14301767156435143002" }, "name": "Log Analytics Workspace Linked Services", "description": "This module deploys a Log Analytics Workspace Linked Service.", diff --git a/avm/res/operational-insights/workspace/linked-storage-account/main.json b/avm/res/operational-insights/workspace/linked-storage-account/main.json index 76deab7dc8..701593c238 100644 --- a/avm/res/operational-insights/workspace/linked-storage-account/main.json +++ b/avm/res/operational-insights/workspace/linked-storage-account/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6638579504467134066" + "version": "0.25.53.49325", + "templateHash": "6713282874166856483" }, "name": "Log Analytics Workspace Linked Storage Accounts", "description": "This module deploys a Log Analytics Workspace Linked Storage Account.", diff --git a/avm/res/operational-insights/workspace/main.bicep b/avm/res/operational-insights/workspace/main.bicep index b0c4c62125..01b7730ac3 100644 --- a/avm/res/operational-insights/workspace/main.bicep +++ b/avm/res/operational-insights/workspace/main.bicep @@ -167,19 +167,16 @@ resource logAnalyticsWorkspace_diagnosticSettings 'Microsoft.Insights/diagnostic workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -379,19 +376,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/operational-insights/workspace/main.json b/avm/res/operational-insights/workspace/main.json index 66e4f01e6e..ea15eff51a 100644 --- a/avm/res/operational-insights/workspace/main.json +++ b/avm/res/operational-insights/workspace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7251796385032619850" + "version": "0.25.53.49325", + "templateHash": "12917492270750322539" }, "name": "Log Analytics Workspaces", "description": "This module deploys a Log Analytics Workspace.", @@ -155,14 +155,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -173,14 +180,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -495,12 +509,30 @@ "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -574,8 +606,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15478499623960222974" + "version": "0.25.53.49325", + "templateHash": "4862843187650272248" }, "name": "Log Analytics Workspace Storage Insight Configs", "description": "This module deploys a Log Analytics Workspace Storage Insight Config.", @@ -714,8 +746,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6280157469343577004" + "version": "0.25.53.49325", + "templateHash": "14301767156435143002" }, "name": "Log Analytics Workspace Linked Services", "description": "This module deploys a Log Analytics Workspace Linked Service.", @@ -836,8 +868,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6638579504467134066" + "version": "0.25.53.49325", + "templateHash": "6713282874166856483" }, "name": "Log Analytics Workspace Linked Storage Accounts", "description": "This module deploys a Log Analytics Workspace Linked Storage Account.", @@ -951,8 +983,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16157882734705318113" + "version": "0.25.53.49325", + "templateHash": "16347089515886811904" }, "name": "Log Analytics Workspace Saved Searches", "description": "This module deploys a Log Analytics Workspace Saved Search.", @@ -1111,8 +1143,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7413462048618089111" + "version": "0.25.53.49325", + "templateHash": "12543023571728523937" }, "name": "Log Analytics Workspace Data Exports", "description": "This module deploys a Log Analytics Workspace Data Export.", @@ -1238,8 +1270,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12960146774033634359" + "version": "0.25.53.49325", + "templateHash": "14032975851567807564" }, "name": "Log Analytics Workspace Datasources", "description": "This module deploys a Log Analytics Workspace Data Source.", @@ -1469,8 +1501,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14992933806074900242" + "version": "0.25.53.49325", + "templateHash": "4932423807790181892" }, "name": "Log Analytics Workspace Tables", "description": "This module deploys a Log Analytics Workspace Table.", diff --git a/avm/res/operational-insights/workspace/saved-search/main.json b/avm/res/operational-insights/workspace/saved-search/main.json index 1e2ae1ba46..4de5fb62b3 100644 --- a/avm/res/operational-insights/workspace/saved-search/main.json +++ b/avm/res/operational-insights/workspace/saved-search/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16157882734705318113" + "version": "0.25.53.49325", + "templateHash": "16347089515886811904" }, "name": "Log Analytics Workspace Saved Searches", "description": "This module deploys a Log Analytics Workspace Saved Search.", diff --git a/avm/res/operational-insights/workspace/storage-insight-config/main.json b/avm/res/operational-insights/workspace/storage-insight-config/main.json index 65c6106ad2..fa8367fe5c 100644 --- a/avm/res/operational-insights/workspace/storage-insight-config/main.json +++ b/avm/res/operational-insights/workspace/storage-insight-config/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15478499623960222974" + "version": "0.25.53.49325", + "templateHash": "4862843187650272248" }, "name": "Log Analytics Workspace Storage Insight Configs", "description": "This module deploys a Log Analytics Workspace Storage Insight Config.", diff --git a/avm/res/operational-insights/workspace/table/main.json b/avm/res/operational-insights/workspace/table/main.json index 62f0c0f086..94607473ef 100644 --- a/avm/res/operational-insights/workspace/table/main.json +++ b/avm/res/operational-insights/workspace/table/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14992933806074900242" + "version": "0.25.53.49325", + "templateHash": "4932423807790181892" }, "name": "Log Analytics Workspace Tables", "description": "This module deploys a Log Analytics Workspace Table.", diff --git a/avm/res/operations-management/solution/main.json b/avm/res/operations-management/solution/main.json index 245b2b34b0..3edc6a4986 100644 --- a/avm/res/operations-management/solution/main.json +++ b/avm/res/operations-management/solution/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8133055319056249118" + "version": "0.25.53.49325", + "templateHash": "2322213504829983181" }, "name": "Operations Management Solutions", "description": "This module deploys an Operations Management Solution.", diff --git a/avm/res/power-bi-dedicated/capacity/main.json b/avm/res/power-bi-dedicated/capacity/main.json index 62bbfd8d9a..d50d7153e0 100644 --- a/avm/res/power-bi-dedicated/capacity/main.json +++ b/avm/res/power-bi-dedicated/capacity/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3414879311419661380" + "version": "0.25.53.49325", + "templateHash": "401112188619972880" }, "name": "Power BI Dedicated Capacities", "description": "This module deploys a Power BI Dedicated Capacity.", diff --git a/avm/res/resource-graph/query/main.json b/avm/res/resource-graph/query/main.json index f71e8b1223..64d9052655 100644 --- a/avm/res/resource-graph/query/main.json +++ b/avm/res/resource-graph/query/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2030878924566742322" + "version": "0.25.53.49325", + "templateHash": "8072514070285903960" }, "name": "Resource Graph Queries", "description": "This module deploys a Resource Graph Query.", diff --git a/avm/res/resources/deployment-script/main.json b/avm/res/resources/deployment-script/main.json index 52febeae55..037e2c257c 100644 --- a/avm/res/resources/deployment-script/main.json +++ b/avm/res/resources/deployment-script/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "8734511554398837213" + "version": "0.25.53.49325", + "templateHash": "6812401706170828518" }, "name": "Deployment Scripts", "description": "This module deploys Deployment Scripts.", diff --git a/avm/res/resources/resource-group/main.json b/avm/res/resources/resource-group/main.json index 8b847304d2..0a38a86917 100644 --- a/avm/res/resources/resource-group/main.json +++ b/avm/res/resources/resource-group/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3228920552840640599" + "version": "0.25.53.49325", + "templateHash": "4726997439042123327" }, "name": "Resource Groups", "description": "This module deploys a Resource Group.", @@ -202,8 +202,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14547405128047917704" + "version": "0.25.53.49325", + "templateHash": "7668050384482764751" } }, "definitions": { @@ -288,8 +288,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17663600101893839261" + "version": "0.25.53.49325", + "templateHash": "3156241559834375483" } }, "definitions": { diff --git a/avm/res/search/search-service/README.md b/avm/res/search/search-service/README.md index b6afe54b40..31c7aed1bf 100644 --- a/avm/res/search/search-service/README.md +++ b/avm/res/search/search-service/README.md @@ -653,9 +653,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -690,11 +690,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -704,11 +733,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -894,6 +949,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -915,6 +991,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/search/search-service/main.bicep b/avm/res/search/search-service/main.bicep index c7692a4f77..41841fe704 100644 --- a/avm/res/search/search-service/main.bicep +++ b/avm/res/search/search-service/main.bicep @@ -159,19 +159,16 @@ resource searchService_diagnosticSettings 'Microsoft.Insights/diagnosticSettings workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -379,19 +376,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/search/search-service/main.json b/avm/res/search/search-service/main.json index 373b4d1094..126db0c411 100644 --- a/avm/res/search/search-service/main.json +++ b/avm/res/search/search-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11985965072265356380" + "version": "0.25.53.49325", + "templateHash": "1009124214102909652" }, "name": "Search Services", "description": "This module deploys a Search Service.", @@ -320,14 +320,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -338,14 +345,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -621,12 +635,30 @@ "scope": "[format('Microsoft.Search/searchServices/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -1371,8 +1403,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4217961090117926416" + "version": "0.25.53.49325", + "templateHash": "9469125394066728883" }, "name": "Search Services Private Link Resources", "description": "This module deploys a Search Service Private Link Resource.", diff --git a/avm/res/search/search-service/shared-private-link-resource/main.json b/avm/res/search/search-service/shared-private-link-resource/main.json index df5c551d26..5440329182 100644 --- a/avm/res/search/search-service/shared-private-link-resource/main.json +++ b/avm/res/search/search-service/shared-private-link-resource/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4217961090117926416" + "version": "0.25.53.49325", + "templateHash": "9469125394066728883" }, "name": "Search Services Private Link Resources", "description": "This module deploys a Search Service Private Link Resource.", diff --git a/avm/res/service-bus/namespace/README.md b/avm/res/service-bus/namespace/README.md index 8c43fe9fe7..1075d92df0 100644 --- a/avm/res/service-bus/namespace/README.md +++ b/avm/res/service-bus/namespace/README.md @@ -1324,9 +1324,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1361,11 +1361,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1375,11 +1404,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -1607,6 +1662,34 @@ List of IpRules. It will not be set if publicNetworkAccess is "Disabled". Otherw - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`action`](#parameter-networkrulesetsiprulesaction) | string | The IP filter action. | +| [`ipMask`](#parameter-networkrulesetsiprulesipmask) | string | The IP mask. | + +### Parameter: `networkRuleSets.ipRules.action` + +The IP filter action. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Allow' + 'Deny' + ] + ``` + +### Parameter: `networkRuleSets.ipRules.ipMask` + +The IP mask. + +- Required: Yes +- Type: string + ### Parameter: `networkRuleSets.publicNetworkAccess` This determines if traffic is allowed over public network. Default is "Enabled". If set to "Disabled", traffic to this namespace will be restricted over Private Endpoints only and network rules will not be applied. @@ -1635,6 +1718,27 @@ List virtual network rules. It will not be set if publicNetworkAccess is "Disabl - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`ignoreMissingVnetServiceEndpoint`](#parameter-networkrulesetsvirtualnetworkrulesignoremissingvnetserviceendpoint) | bool | The virtual network rule name. | +| [`subnetResourceId`](#parameter-networkrulesetsvirtualnetworkrulessubnetresourceid) | string | The ID of the subnet. | + +### Parameter: `networkRuleSets.virtualNetworkRules.ignoreMissingVnetServiceEndpoint` + +The virtual network rule name. + +- Required: Yes +- Type: bool + +### Parameter: `networkRuleSets.virtualNetworkRules.subnetResourceId` + +The ID of the subnet. + +- Required: Yes +- Type: string + ### Parameter: `premiumMessagingPartitions` The number of partitions of a Service Bus namespace. This property is only applicable to Premium SKU namespaces. The default value is 1 and possible values are 1, 2 and 4. @@ -1696,6 +1800,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint IP address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private IP addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -1717,6 +1842,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. @@ -2645,6 +2820,184 @@ The subscriptions of the topic. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-topicssubscriptionsname) | string | The name of the service bus namespace topic subscription. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`autoDeleteOnIdle`](#parameter-topicssubscriptionsautodeleteonidle) | string | ISO 8601 timespan idle interval after which the syubscription is automatically deleted. The minimum duration is 5 minutes. | +| [`clientAffineProperties`](#parameter-topicssubscriptionsclientaffineproperties) | object | The properties that are associated with a subscription that is client-affine. | +| [`deadLetteringOnFilterEvaluationExceptions`](#parameter-topicssubscriptionsdeadletteringonfilterevaluationexceptions) | bool | A value that indicates whether a subscription has dead letter support when a message expires. | +| [`deadLetteringOnMessageExpiration`](#parameter-topicssubscriptionsdeadletteringonmessageexpiration) | bool | A value that indicates whether a subscription has dead letter support when a message expires. | +| [`defaultMessageTimeToLive`](#parameter-topicssubscriptionsdefaultmessagetimetolive) | string | ISO 8601 timespan idle interval after which the message expires. The minimum duration is 5 minutes. | +| [`duplicateDetectionHistoryTimeWindow`](#parameter-topicssubscriptionsduplicatedetectionhistorytimewindow) | string | ISO 8601 timespan that defines the duration of the duplicate detection history. The default value is 10 minutes. | +| [`enableBatchedOperations`](#parameter-topicssubscriptionsenablebatchedoperations) | bool | A value that indicates whether server-side batched operations are enabled. | +| [`forwardDeadLetteredMessagesTo`](#parameter-topicssubscriptionsforwarddeadletteredmessagesto) | string | The name of the recipient entity to which all the messages sent to the subscription are forwarded to. | +| [`forwardTo`](#parameter-topicssubscriptionsforwardto) | string | The name of the recipient entity to which all the messages sent to the subscription are forwarded to. | +| [`isClientAffine`](#parameter-topicssubscriptionsisclientaffine) | bool | A value that indicates whether the subscription supports the concept of session. | +| [`lockDuration`](#parameter-topicssubscriptionslockduration) | string | ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute. | +| [`maxDeliveryCount`](#parameter-topicssubscriptionsmaxdeliverycount) | int | Number of maximum deliveries. A message is automatically deadlettered after this number of deliveries. Default value is 10. | +| [`requiresSession`](#parameter-topicssubscriptionsrequiressession) | bool | A value that indicates whether the subscription supports the concept of session. | +| [`status`](#parameter-topicssubscriptionsstatus) | string | Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown. | + +### Parameter: `topics.subscriptions.name` + +The name of the service bus namespace topic subscription. + +- Required: Yes +- Type: string + +### Parameter: `topics.subscriptions.autoDeleteOnIdle` + +ISO 8601 timespan idle interval after which the syubscription is automatically deleted. The minimum duration is 5 minutes. + +- Required: No +- Type: string + +### Parameter: `topics.subscriptions.clientAffineProperties` + +The properties that are associated with a subscription that is client-affine. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`clientId`](#parameter-topicssubscriptionsclientaffinepropertiesclientid) | string | Indicates the Client ID of the application that created the client-affine subscription. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`isDurable`](#parameter-topicssubscriptionsclientaffinepropertiesisdurable) | bool | For client-affine subscriptions, this value indicates whether the subscription is durable or not. | +| [`isShared`](#parameter-topicssubscriptionsclientaffinepropertiesisshared) | bool | For client-affine subscriptions, this value indicates whether the subscription is shared or not. | + +### Parameter: `topics.subscriptions.clientAffineProperties.clientId` + +Indicates the Client ID of the application that created the client-affine subscription. + +- Required: Yes +- Type: string + +### Parameter: `topics.subscriptions.clientAffineProperties.isDurable` + +For client-affine subscriptions, this value indicates whether the subscription is durable or not. + +- Required: No +- Type: bool + +### Parameter: `topics.subscriptions.clientAffineProperties.isShared` + +For client-affine subscriptions, this value indicates whether the subscription is shared or not. + +- Required: No +- Type: bool + +### Parameter: `topics.subscriptions.deadLetteringOnFilterEvaluationExceptions` + +A value that indicates whether a subscription has dead letter support when a message expires. + +- Required: No +- Type: bool + +### Parameter: `topics.subscriptions.deadLetteringOnMessageExpiration` + +A value that indicates whether a subscription has dead letter support when a message expires. + +- Required: No +- Type: bool + +### Parameter: `topics.subscriptions.defaultMessageTimeToLive` + +ISO 8601 timespan idle interval after which the message expires. The minimum duration is 5 minutes. + +- Required: No +- Type: string + +### Parameter: `topics.subscriptions.duplicateDetectionHistoryTimeWindow` + +ISO 8601 timespan that defines the duration of the duplicate detection history. The default value is 10 minutes. + +- Required: No +- Type: string + +### Parameter: `topics.subscriptions.enableBatchedOperations` + +A value that indicates whether server-side batched operations are enabled. + +- Required: No +- Type: bool + +### Parameter: `topics.subscriptions.forwardDeadLetteredMessagesTo` + +The name of the recipient entity to which all the messages sent to the subscription are forwarded to. + +- Required: No +- Type: string + +### Parameter: `topics.subscriptions.forwardTo` + +The name of the recipient entity to which all the messages sent to the subscription are forwarded to. + +- Required: No +- Type: string + +### Parameter: `topics.subscriptions.isClientAffine` + +A value that indicates whether the subscription supports the concept of session. + +- Required: No +- Type: bool + +### Parameter: `topics.subscriptions.lockDuration` + +ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute. + +- Required: No +- Type: string + +### Parameter: `topics.subscriptions.maxDeliveryCount` + +Number of maximum deliveries. A message is automatically deadlettered after this number of deliveries. Default value is 10. + +- Required: No +- Type: int + +### Parameter: `topics.subscriptions.requiresSession` + +A value that indicates whether the subscription supports the concept of session. + +- Required: No +- Type: bool + +### Parameter: `topics.subscriptions.status` + +Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Active' + 'Creating' + 'Deleting' + 'Disabled' + 'ReceiveDisabled' + 'Renaming' + 'Restoring' + 'SendDisabled' + 'Unknown' + ] + ``` + ### Parameter: `topics.supportOrdering` Value that indicates whether the topic supports ordering. diff --git a/avm/res/service-bus/namespace/authorization-rule/main.json b/avm/res/service-bus/namespace/authorization-rule/main.json index 752d7fbbf6..e7f310864e 100644 --- a/avm/res/service-bus/namespace/authorization-rule/main.json +++ b/avm/res/service-bus/namespace/authorization-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17855800292568144576" + "version": "0.25.53.49325", + "templateHash": "2305438159110957656" }, "name": "Service Bus Namespace Authorization Rules", "description": "This module deploys a Service Bus Namespace Authorization Rule.", diff --git a/avm/res/service-bus/namespace/disaster-recovery-config/main.json b/avm/res/service-bus/namespace/disaster-recovery-config/main.json index bb45a8ca6b..b3c6887e73 100644 --- a/avm/res/service-bus/namespace/disaster-recovery-config/main.json +++ b/avm/res/service-bus/namespace/disaster-recovery-config/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4224024094198092435" + "version": "0.25.53.49325", + "templateHash": "4852834945333619424" }, "name": "Service Bus Namespace Disaster Recovery Configs", "description": "This module deploys a Service Bus Namespace Disaster Recovery Config", diff --git a/avm/res/service-bus/namespace/main.bicep b/avm/res/service-bus/namespace/main.bicep index 413498aaf7..e519393cc1 100644 --- a/avm/res/service-bus/namespace/main.bicep +++ b/avm/res/service-bus/namespace/main.bicep @@ -284,19 +284,16 @@ resource serviceBusNamespace_diagnosticSettings 'Microsoft.Insights/diagnosticSe workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -478,19 +475,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/service-bus/namespace/main.json b/avm/res/service-bus/namespace/main.json index 6fc1136dc6..eab333df99 100644 --- a/avm/res/service-bus/namespace/main.json +++ b/avm/res/service-bus/namespace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3819001479724310529" + "version": "0.25.53.49325", + "templateHash": "16905316086455363065" }, "name": "Service Bus Namespaces", "description": "This module deploys a Service Bus Namespace.", @@ -330,14 +330,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -348,14 +355,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -1349,12 +1363,30 @@ "scope": "[format('Microsoft.ServiceBus/namespaces/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -1414,8 +1446,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17855800292568144576" + "version": "0.25.53.49325", + "templateHash": "2305438159110957656" }, "name": "Service Bus Namespace Authorization Rules", "description": "This module deploys a Service Bus Namespace Authorization Rule.", @@ -1518,8 +1550,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4224024094198092435" + "version": "0.25.53.49325", + "templateHash": "4852834945333619424" }, "name": "Service Bus Namespace Disaster Recovery Configs", "description": "This module deploys a Service Bus Namespace Disaster Recovery Config", @@ -1623,8 +1655,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12493381024184446601" + "version": "0.25.53.49325", + "templateHash": "7096240042982673427" }, "name": "Service Bus Namespace Migration Configuration", "description": "This module deploys a Service Bus Namespace Migration Configuration.", @@ -1728,8 +1760,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2244317530703231119" + "version": "0.25.53.49325", + "templateHash": "12312948750335282178" }, "name": "Service Bus Namespace Network Rule Sets", "description": "This module deploys a ServiceBus Namespace Network Rule Set.", @@ -1928,8 +1960,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3138463552906663655" + "version": "0.25.53.49325", + "templateHash": "1862386755569893710" }, "name": "Service Bus Namespace Queue", "description": "This module deploys a Service Bus Namespace Queue.", @@ -2313,8 +2345,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7604965450953112683" + "version": "0.25.53.49325", + "templateHash": "11143403540623996438" }, "name": "Service Bus Namespace Queue Authorization Rules", "description": "This module deploys a Service Bus Namespace Queue Authorization Rule.", @@ -2494,8 +2526,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2955596410149501936" + "version": "0.25.53.49325", + "templateHash": "6815063360089408467" }, "name": "Service Bus Namespace Topic", "description": "This module deploys a Service Bus Namespace Topic.", @@ -2977,8 +3009,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6260032632906851888" + "version": "0.25.53.49325", + "templateHash": "7067820889223773244" }, "name": "Service Bus Namespace Topic Authorization Rules", "description": "This module deploys a Service Bus Namespace Topic Authorization Rule.", @@ -3127,8 +3159,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7004523533145561776" + "version": "0.25.53.49325", + "templateHash": "6473689586849909439" }, "name": "Service Bus Namespace Topic Subscription", "description": "This module deploys a Service Bus Namespace Topic Subscription.", diff --git a/avm/res/service-bus/namespace/migration-configuration/main.json b/avm/res/service-bus/namespace/migration-configuration/main.json index beae65fb1f..3de44c3b32 100644 --- a/avm/res/service-bus/namespace/migration-configuration/main.json +++ b/avm/res/service-bus/namespace/migration-configuration/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12493381024184446601" + "version": "0.25.53.49325", + "templateHash": "7096240042982673427" }, "name": "Service Bus Namespace Migration Configuration", "description": "This module deploys a Service Bus Namespace Migration Configuration.", diff --git a/avm/res/service-bus/namespace/network-rule-set/main.json b/avm/res/service-bus/namespace/network-rule-set/main.json index 0e09df5a7c..c7e7350de1 100644 --- a/avm/res/service-bus/namespace/network-rule-set/main.json +++ b/avm/res/service-bus/namespace/network-rule-set/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2244317530703231119" + "version": "0.25.53.49325", + "templateHash": "12312948750335282178" }, "name": "Service Bus Namespace Network Rule Sets", "description": "This module deploys a ServiceBus Namespace Network Rule Set.", diff --git a/avm/res/service-bus/namespace/queue/authorization-rule/main.json b/avm/res/service-bus/namespace/queue/authorization-rule/main.json index 5341df4895..46b1f26e50 100644 --- a/avm/res/service-bus/namespace/queue/authorization-rule/main.json +++ b/avm/res/service-bus/namespace/queue/authorization-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7604965450953112683" + "version": "0.25.53.49325", + "templateHash": "11143403540623996438" }, "name": "Service Bus Namespace Queue Authorization Rules", "description": "This module deploys a Service Bus Namespace Queue Authorization Rule.", diff --git a/avm/res/service-bus/namespace/queue/main.json b/avm/res/service-bus/namespace/queue/main.json index 9240568667..98b2b87112 100644 --- a/avm/res/service-bus/namespace/queue/main.json +++ b/avm/res/service-bus/namespace/queue/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3138463552906663655" + "version": "0.25.53.49325", + "templateHash": "1862386755569893710" }, "name": "Service Bus Namespace Queue", "description": "This module deploys a Service Bus Namespace Queue.", @@ -390,8 +390,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7604965450953112683" + "version": "0.25.53.49325", + "templateHash": "11143403540623996438" }, "name": "Service Bus Namespace Queue Authorization Rules", "description": "This module deploys a Service Bus Namespace Queue Authorization Rule.", diff --git a/avm/res/service-bus/namespace/topic/authorization-rule/main.json b/avm/res/service-bus/namespace/topic/authorization-rule/main.json index 95010b0b89..104532158b 100644 --- a/avm/res/service-bus/namespace/topic/authorization-rule/main.json +++ b/avm/res/service-bus/namespace/topic/authorization-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6260032632906851888" + "version": "0.25.53.49325", + "templateHash": "7067820889223773244" }, "name": "Service Bus Namespace Topic Authorization Rules", "description": "This module deploys a Service Bus Namespace Topic Authorization Rule.", diff --git a/avm/res/service-bus/namespace/topic/main.json b/avm/res/service-bus/namespace/topic/main.json index 109916414a..9939b450d7 100644 --- a/avm/res/service-bus/namespace/topic/main.json +++ b/avm/res/service-bus/namespace/topic/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2955596410149501936" + "version": "0.25.53.49325", + "templateHash": "6815063360089408467" }, "name": "Service Bus Namespace Topic", "description": "This module deploys a Service Bus Namespace Topic.", @@ -488,8 +488,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6260032632906851888" + "version": "0.25.53.49325", + "templateHash": "7067820889223773244" }, "name": "Service Bus Namespace Topic Authorization Rules", "description": "This module deploys a Service Bus Namespace Topic Authorization Rule.", @@ -638,8 +638,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7004523533145561776" + "version": "0.25.53.49325", + "templateHash": "6473689586849909439" }, "name": "Service Bus Namespace Topic Subscription", "description": "This module deploys a Service Bus Namespace Topic Subscription.", diff --git a/avm/res/service-bus/namespace/topic/subscription/main.json b/avm/res/service-bus/namespace/topic/subscription/main.json index 5c7d6a7067..355214dd25 100644 --- a/avm/res/service-bus/namespace/topic/subscription/main.json +++ b/avm/res/service-bus/namespace/topic/subscription/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7004523533145561776" + "version": "0.25.53.49325", + "templateHash": "6473689586849909439" }, "name": "Service Bus Namespace Topic Subscription", "description": "This module deploys a Service Bus Namespace Topic Subscription.", diff --git a/avm/res/sql/server/ORPHANED.md b/avm/res/sql/server/ORPHANED.md deleted file mode 100644 index ef8fa911d2..0000000000 --- a/avm/res/sql/server/ORPHANED.md +++ /dev/null @@ -1,4 +0,0 @@ -⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ - -- Only security and bug fixes are being handled by the AVM core team at present. -- If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! \ No newline at end of file diff --git a/avm/res/sql/server/README.md b/avm/res/sql/server/README.md index d9a6d97d2f..a35700ec06 100644 --- a/avm/res/sql/server/README.md +++ b/avm/res/sql/server/README.md @@ -1,10 +1,5 @@ # Azure SQL Servers `[Microsoft.Sql/servers]` -> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ -> -> - Only security and bug fixes are being handled by the AVM core team at present. -> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! - This module deploys an Azure SQL Server. ## Navigation @@ -1403,6 +1398,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint IP address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private IP addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -1424,6 +1440,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/sql/server/database/README.md b/avm/res/sql/server/database/README.md index 08e5726ee3..96de894601 100644 --- a/avm/res/sql/server/database/README.md +++ b/avm/res/sql/server/database/README.md @@ -148,9 +148,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -185,11 +185,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -199,11 +228,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/sql/server/database/backup-long-term-retention-policy/main.json b/avm/res/sql/server/database/backup-long-term-retention-policy/main.json index 6b4315b581..f40030f6d4 100644 --- a/avm/res/sql/server/database/backup-long-term-retention-policy/main.json +++ b/avm/res/sql/server/database/backup-long-term-retention-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7612753724930678316" + "version": "0.25.53.49325", + "templateHash": "17376471861428793697" }, "name": "SQL Server Database Long Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Long-Term Backup Retention Policy.", diff --git a/avm/res/sql/server/database/backup-short-term-retention-policy/main.json b/avm/res/sql/server/database/backup-short-term-retention-policy/main.json index 8e27902dae..0aea9d0e91 100644 --- a/avm/res/sql/server/database/backup-short-term-retention-policy/main.json +++ b/avm/res/sql/server/database/backup-short-term-retention-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4029220159811407510" + "version": "0.25.53.49325", + "templateHash": "16471212899981632790" }, "name": "Azure SQL Server Database Short Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Short-Term Backup Retention Policy.", diff --git a/avm/res/sql/server/database/main.bicep b/avm/res/sql/server/database/main.bicep index 597f8c073a..9a8b4f4a67 100644 --- a/avm/res/sql/server/database/main.bicep +++ b/avm/res/sql/server/database/main.bicep @@ -173,19 +173,16 @@ resource database_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -234,19 +231,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/sql/server/database/main.json b/avm/res/sql/server/database/main.json index 52114dce09..e1a6b24ba4 100644 --- a/avm/res/sql/server/database/main.json +++ b/avm/res/sql/server/database/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6114696968407769405" + "version": "0.25.53.49325", + "templateHash": "745610238423132217" }, "name": "SQL Server Database", "description": "This module deploys an Azure SQL Server Database.", @@ -41,14 +41,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -59,14 +66,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -413,12 +427,30 @@ "scope": "[format('Microsoft.Sql/servers/{0}/databases/{1}', parameters('serverName'), parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -451,8 +483,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4029220159811407510" + "version": "0.25.53.49325", + "templateHash": "16471212899981632790" }, "name": "Azure SQL Server Database Short Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Short-Term Backup Retention Policy.", @@ -553,8 +585,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7612753724930678316" + "version": "0.25.53.49325", + "templateHash": "17376471861428793697" }, "name": "SQL Server Database Long Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Long-Term Backup Retention Policy.", diff --git a/avm/res/sql/server/elastic-pool/main.json b/avm/res/sql/server/elastic-pool/main.json index 1b5c1fa6d2..04f10a84af 100644 --- a/avm/res/sql/server/elastic-pool/main.json +++ b/avm/res/sql/server/elastic-pool/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10241504273376010600" + "version": "0.25.53.49325", + "templateHash": "3404184459089621320" }, "name": "SQL Server Elastic Pool", "description": "This module deploys an Azure SQL Server Elastic Pool.", diff --git a/avm/res/sql/server/encryption-protector/main.json b/avm/res/sql/server/encryption-protector/main.json index 8ec552a59d..2c6ab81141 100644 --- a/avm/res/sql/server/encryption-protector/main.json +++ b/avm/res/sql/server/encryption-protector/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5640826446798212991" + "version": "0.25.53.49325", + "templateHash": "16485430925993626206" }, "name": "Azure SQL Server Encryption Protector", "description": "This module deploys an Azure SQL Server Encryption Protector.", diff --git a/avm/res/sql/server/firewall-rule/main.json b/avm/res/sql/server/firewall-rule/main.json index 6efe2110f0..211a03cd92 100644 --- a/avm/res/sql/server/firewall-rule/main.json +++ b/avm/res/sql/server/firewall-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7960472599897035207" + "version": "0.25.53.49325", + "templateHash": "6782455844016435325" }, "name": "Azure SQL Server Firewall Rule", "description": "This module deploys an Azure SQL Server Firewall Rule.", diff --git a/avm/res/sql/server/key/main.json b/avm/res/sql/server/key/main.json index 0c84ba7437..f248bb2978 100644 --- a/avm/res/sql/server/key/main.json +++ b/avm/res/sql/server/key/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8275989665318380510" + "version": "0.25.53.49325", + "templateHash": "8993850940520323522" }, "name": "Azure SQL Server Keys", "description": "This module deploys an Azure SQL Server Key.", diff --git a/avm/res/sql/server/main.json b/avm/res/sql/server/main.json index 53002a85aa..70407beb9e 100644 --- a/avm/res/sql/server/main.json +++ b/avm/res/sql/server/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11930269426263350547" + "version": "0.25.53.49325", + "templateHash": "2223159689907478294" }, "name": "Azure SQL Servers", "description": "This module deploys an Azure SQL Server.", @@ -633,8 +633,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6114696968407769405" + "version": "0.25.53.49325", + "templateHash": "745610238423132217" }, "name": "SQL Server Database", "description": "This module deploys an Azure SQL Server Database.", @@ -669,14 +669,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -687,14 +694,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -1041,12 +1055,30 @@ "scope": "[format('Microsoft.Sql/servers/{0}/databases/{1}', parameters('serverName'), parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -1079,8 +1111,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4029220159811407510" + "version": "0.25.53.49325", + "templateHash": "16471212899981632790" }, "name": "Azure SQL Server Database Short Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Short-Term Backup Retention Policy.", @@ -1181,8 +1213,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7612753724930678316" + "version": "0.25.53.49325", + "templateHash": "17376471861428793697" }, "name": "SQL Server Database Long Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Long-Term Backup Retention Policy.", @@ -1359,8 +1391,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10241504273376010600" + "version": "0.25.53.49325", + "templateHash": "3404184459089621320" }, "name": "SQL Server Elastic Pool", "description": "This module deploys an Azure SQL Server Elastic Pool.", @@ -2243,8 +2275,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7960472599897035207" + "version": "0.25.53.49325", + "templateHash": "6782455844016435325" }, "name": "Azure SQL Server Firewall Rule", "description": "This module deploys an Azure SQL Server Firewall Rule.", @@ -2349,8 +2381,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7937154721682653764" + "version": "0.25.53.49325", + "templateHash": "16350137843713909320" }, "name": "Azure SQL Server Virtual Network Rules", "description": "This module deploys an Azure SQL Server Virtual Network Rule.", @@ -2457,8 +2489,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14698752458468288733" + "version": "0.25.53.49325", + "templateHash": "12316453108388638438" }, "name": "Azure SQL Server Security Alert Policies", "description": "This module deploys an Azure SQL Server Security Alert Policy.", @@ -2608,8 +2640,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4829807745876642281" + "version": "0.25.53.49325", + "templateHash": "11132162611657015619" }, "name": "Azure SQL Server Vulnerability Assessments", "description": "This module deploys an Azure SQL Server Vulnerability Assessment.", @@ -2711,8 +2743,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10423099865647735549" + "version": "0.25.53.49325", + "templateHash": "7342984307461208675" } }, "parameters": { @@ -2800,8 +2832,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "8275989665318380510" + "version": "0.25.53.49325", + "templateHash": "8993850940520323522" }, "name": "Azure SQL Server Keys", "description": "This module deploys an Azure SQL Server Key.", @@ -2919,8 +2951,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "5640826446798212991" + "version": "0.25.53.49325", + "templateHash": "16485430925993626206" }, "name": "Azure SQL Server Encryption Protector", "description": "This module deploys an Azure SQL Server Encryption Protector.", diff --git a/avm/res/sql/server/security-alert-policy/main.json b/avm/res/sql/server/security-alert-policy/main.json index 484b737d60..c0350da7f4 100644 --- a/avm/res/sql/server/security-alert-policy/main.json +++ b/avm/res/sql/server/security-alert-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14698752458468288733" + "version": "0.25.53.49325", + "templateHash": "12316453108388638438" }, "name": "Azure SQL Server Security Alert Policies", "description": "This module deploys an Azure SQL Server Security Alert Policy.", diff --git a/avm/res/sql/server/virtual-network-rule/main.json b/avm/res/sql/server/virtual-network-rule/main.json index cafde78438..1520ebf1a8 100644 --- a/avm/res/sql/server/virtual-network-rule/main.json +++ b/avm/res/sql/server/virtual-network-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7937154721682653764" + "version": "0.25.53.49325", + "templateHash": "16350137843713909320" }, "name": "Azure SQL Server Virtual Network Rules", "description": "This module deploys an Azure SQL Server Virtual Network Rule.", diff --git a/avm/res/sql/server/vulnerability-assessment/main.json b/avm/res/sql/server/vulnerability-assessment/main.json index 20dd8fa36c..8dfe8d48a8 100644 --- a/avm/res/sql/server/vulnerability-assessment/main.json +++ b/avm/res/sql/server/vulnerability-assessment/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4829807745876642281" + "version": "0.25.53.49325", + "templateHash": "11132162611657015619" }, "name": "Azure SQL Server Vulnerability Assessments", "description": "This module deploys an Azure SQL Server Vulnerability Assessment.", @@ -107,8 +107,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10423099865647735549" + "version": "0.25.53.49325", + "templateHash": "7342984307461208675" } }, "parameters": { diff --git a/avm/res/storage/storage-account/README.md b/avm/res/storage/storage-account/README.md index a74e09a500..485c01acbc 100644 --- a/avm/res/storage/storage-account/README.md +++ b/avm/res/storage/storage-account/README.md @@ -26,9 +26,9 @@ This module deploys a Storage Account. | `Microsoft.Storage/storageAccounts/blobServices/containers` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices/containers) | | `Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices/containers/immutabilityPolicies) | | `Microsoft.Storage/storageAccounts/fileServices` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/fileServices) | -| `Microsoft.Storage/storageAccounts/fileServices/shares` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/fileServices/shares) | +| `Microsoft.Storage/storageAccounts/fileServices/shares` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-01-01/storageAccounts/fileServices/shares) | | `Microsoft.Storage/storageAccounts/localUsers` | [2022-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-05-01/storageAccounts/localUsers) | -| `Microsoft.Storage/storageAccounts/managementPolicies` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/managementPolicies) | +| `Microsoft.Storage/storageAccounts/managementPolicies` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-01-01/storageAccounts/managementPolicies) | | `Microsoft.Storage/storageAccounts/queueServices` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/queueServices) | | `Microsoft.Storage/storageAccounts/queueServices/queues` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/queueServices/queues) | | `Microsoft.Storage/storageAccounts/tableServices` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/tableServices) | @@ -1081,6 +1081,10 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = { '' ] } + networkAcls: { + bypass: 'AzureServices' + defaultAction: 'Deny' + } privateEndpoints: [ { privateDnsZoneResourceIds: [ @@ -1138,6 +1142,12 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = { ] } }, + "networkAcls": { + "value": { + "bypass": "AzureServices", + "defaultAction": "Deny" + } + }, "privateEndpoints": { "value": [ { @@ -1770,6 +1780,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = { | Parameter | Type | Description | | :-- | :-- | :-- | | [`name`](#parameter-name) | string | Name of the Storage Account. | +| [`networkAcls`](#parameter-networkacls) | object | Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny. | **Conditional parameters** @@ -1807,7 +1818,6 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = { | [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. | | [`managementPolicyRules`](#parameter-managementpolicyrules) | array | The Storage Account ManagementPolicies Rules. | | [`minimumTlsVersion`](#parameter-minimumtlsversion) | string | Set the minimum TLS version on request to storage. | -| [`networkAcls`](#parameter-networkacls) | object | Networks ACLs, this value contains IPs to whitelist and/or Subnet information. For security reasons, it is recommended to set the DefaultAction Deny. | | [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | | [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set. | | [`queueServices`](#parameter-queueservices) | object | Queue service and queues to create. | @@ -1826,6 +1836,90 @@ Name of the Storage Account. - Required: Yes - Type: string +### Parameter: `networkAcls` + +Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny. + +- Required: No +- Type: object +- Default: + ```Bicep + { + bypass: 'AzureServices' + defaultAction: 'Deny' + } + ``` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`bypass`](#parameter-networkaclsbypass) | string | Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, "Logging, Metrics"), or None to bypass none of those traffics. | +| [`defaultAction`](#parameter-networkaclsdefaultaction) | string | Specifies the default action of allow or deny when no other rules match. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`ipRules`](#parameter-networkaclsiprules) | array | Sets the IP ACL rules. | +| [`resourceAccessRules`](#parameter-networkaclsresourceaccessrules) | array | Sets the resource access rules. | +| [`virtualNetworkRules`](#parameter-networkaclsvirtualnetworkrules) | array | Sets the virtual network rules. | + +### Parameter: `networkAcls.bypass` + +Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, "Logging, Metrics"), or None to bypass none of those traffics. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'AzureServices' + 'AzureServices, Logging' + 'AzureServices, Logging, Metrics' + 'AzureServices, Metrics' + 'Logging' + 'Logging, Metrics' + 'Metrics' + 'None' + ] + ``` + +### Parameter: `networkAcls.defaultAction` + +Specifies the default action of allow or deny when no other rules match. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Allow' + 'Deny' + ] + ``` + +### Parameter: `networkAcls.ipRules` + +Sets the IP ACL rules. + +- Required: No +- Type: array + +### Parameter: `networkAcls.resourceAccessRules` + +Sets the resource access rules. + +- Required: No +- Type: array + +### Parameter: `networkAcls.virtualNetworkRules` + +Sets the virtual network rules. + +- Required: No +- Type: array + ### Parameter: `accessTier` Required if the Storage Account kind is set to BlobStorage. The access tier is used for billing. The "Premium" access tier is the default value for premium block blobs storage account type and it cannot be changed for the premium block blobs storage account type. @@ -1994,7 +2088,7 @@ The diagnostic settings of the service. | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -2036,11 +2130,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -2254,23 +2374,6 @@ Set the minimum TLS version on request to storage. ] ``` -### Parameter: `networkAcls` - -Networks ACLs, this value contains IPs to whitelist and/or Subnet information. For security reasons, it is recommended to set the DefaultAction Deny. - -- Required: No -- Type: object -- Default: - ```Bicep - { - bypass: 'AzureServices' - defaultAction: 'Deny' - ipRules: [] - resourceAccessRules: [] - virtualNetworkRules: [] - } - ``` - ### Parameter: `privateEndpoints` Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. @@ -2331,6 +2434,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -2352,6 +2476,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/storage/storage-account/blob-service/README.md b/avm/res/storage/storage-account/blob-service/README.md index 44b3fdfe29..f66c244ced 100644 --- a/avm/res/storage/storage-account/blob-service/README.md +++ b/avm/res/storage/storage-account/blob-service/README.md @@ -164,9 +164,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -201,11 +201,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -215,11 +244,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json b/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json index c5f31a243f..ac3bd2c129 100644 --- a/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json +++ b/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15441426428461937893" + "version": "0.25.53.49325", + "templateHash": "10329548264889228160" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy.", diff --git a/avm/res/storage/storage-account/blob-service/container/main.json b/avm/res/storage/storage-account/blob-service/container/main.json index d74b756e4a..3f3a51ac90 100644 --- a/avm/res/storage/storage-account/blob-service/container/main.json +++ b/avm/res/storage/storage-account/blob-service/container/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1429761296615247722" + "version": "0.25.53.49325", + "templateHash": "11351273351916968732" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container.", @@ -274,8 +274,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15441426428461937893" + "version": "0.25.53.49325", + "templateHash": "10329548264889228160" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy.", diff --git a/avm/res/storage/storage-account/blob-service/main.bicep b/avm/res/storage/storage-account/blob-service/main.bicep index 3ea3746ffa..4a71845d32 100644 --- a/avm/res/storage/storage-account/blob-service/main.bicep +++ b/avm/res/storage/storage-account/blob-service/main.bicep @@ -114,19 +114,16 @@ resource blobServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@ workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -167,19 +164,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/storage/storage-account/blob-service/main.json b/avm/res/storage/storage-account/blob-service/main.json index 92c61009b8..46429e3bb4 100644 --- a/avm/res/storage/storage-account/blob-service/main.json +++ b/avm/res/storage/storage-account/blob-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6670506366627013721" + "version": "0.25.53.49325", + "templateHash": "4746835745355709536" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service.", @@ -41,14 +41,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -59,14 +66,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -303,12 +317,30 @@ "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}', parameters('storageAccountName'), variables('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -371,8 +403,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1429761296615247722" + "version": "0.25.53.49325", + "templateHash": "11351273351916968732" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container.", @@ -640,8 +672,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15441426428461937893" + "version": "0.25.53.49325", + "templateHash": "10329548264889228160" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy.", diff --git a/avm/res/storage/storage-account/file-service/README.md b/avm/res/storage/storage-account/file-service/README.md index 798fbae48e..dbcfac9607 100644 --- a/avm/res/storage/storage-account/file-service/README.md +++ b/avm/res/storage/storage-account/file-service/README.md @@ -16,7 +16,7 @@ This module deploys a Storage Account File Share Service. | :-- | :-- | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `Microsoft.Storage/storageAccounts/fileServices` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/fileServices) | -| `Microsoft.Storage/storageAccounts/fileServices/shares` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/fileServices/shares) | +| `Microsoft.Storage/storageAccounts/fileServices/shares` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-01-01/storageAccounts/fileServices/shares) | ## Parameters @@ -57,9 +57,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -94,11 +94,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -108,11 +137,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/storage/storage-account/file-service/main.bicep b/avm/res/storage/storage-account/file-service/main.bicep index 098a4800a9..541f8a475e 100644 --- a/avm/res/storage/storage-account/file-service/main.bicep +++ b/avm/res/storage/storage-account/file-service/main.bicep @@ -46,19 +46,16 @@ resource fileServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@ workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -95,19 +92,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/storage/storage-account/file-service/main.json b/avm/res/storage/storage-account/file-service/main.json index b64aa99d9d..b2d1773a8a 100644 --- a/avm/res/storage/storage-account/file-service/main.json +++ b/avm/res/storage/storage-account/file-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "685043578297461233" + "version": "0.25.53.49325", + "templateHash": "5288106279947156711" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service.", @@ -41,14 +41,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -59,14 +66,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -195,12 +209,30 @@ "scope": "[format('Microsoft.Storage/storageAccounts/{0}/fileServices/{1}', parameters('storageAccountName'), parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -254,8 +286,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11243515252529303304" + "version": "0.25.53.49325", + "templateHash": "2026482374148202879" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share.", @@ -454,8 +486,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17643632023108067837" + "version": "0.25.53.49325", + "templateHash": "15595600813016932186" } }, "parameters": { diff --git a/avm/res/storage/storage-account/file-service/share/README.md b/avm/res/storage/storage-account/file-service/share/README.md index ad18c11a1c..dc44e02011 100644 --- a/avm/res/storage/storage-account/file-service/share/README.md +++ b/avm/res/storage/storage-account/file-service/share/README.md @@ -14,7 +14,7 @@ This module deploys a Storage Account File Share. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Storage/storageAccounts/fileServices/shares` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/fileServices/shares) | +| `Microsoft.Storage/storageAccounts/fileServices/shares` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-01-01/storageAccounts/fileServices/shares) | ## Parameters diff --git a/avm/res/storage/storage-account/file-service/share/main.json b/avm/res/storage/storage-account/file-service/share/main.json index 13705f6f2d..4d6e95dba4 100644 --- a/avm/res/storage/storage-account/file-service/share/main.json +++ b/avm/res/storage/storage-account/file-service/share/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11243515252529303304" + "version": "0.25.53.49325", + "templateHash": "2026482374148202879" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share.", @@ -205,8 +205,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17643632023108067837" + "version": "0.25.53.49325", + "templateHash": "15595600813016932186" } }, "parameters": { diff --git a/avm/res/storage/storage-account/local-user/main.json b/avm/res/storage/storage-account/local-user/main.json index ac7889af2b..5044c80422 100644 --- a/avm/res/storage/storage-account/local-user/main.json +++ b/avm/res/storage/storage-account/local-user/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "414567084253124464" + "version": "0.25.53.49325", + "templateHash": "17117452291389534361" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication.", diff --git a/avm/res/storage/storage-account/main.bicep b/avm/res/storage/storage-account/main.bicep index 868c087fb5..71526893d3 100644 --- a/avm/res/storage/storage-account/main.bicep +++ b/avm/res/storage/storage-account/main.bicep @@ -68,12 +68,9 @@ param privateEndpoints privateEndpointType @description('Optional. The Storage Account ManagementPolicies Rules.') param managementPolicyRules array? -@description('Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. For security reasons, it is recommended to set the DefaultAction Deny.') -param networkAcls object = { - resourceAccessRules: [] +@description('Required. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny.') +param networkAcls networkAclsType = { bypass: 'AzureServices' - virtualNetworkRules: [] - ipRules: [] defaultAction: 'Deny' } @@ -264,32 +261,33 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { } dnsEndpointType: !empty(dnsEndpointType) ? dnsEndpointType : null isLocalUserEnabled: isLocalUserEnabled - encryption: { - keySource: !empty(customerManagedKey) ? 'Microsoft.Keyvault' : 'Microsoft.Storage' - services: { - blob: supportsBlobService ? { - enabled: true - } : null - file: supportsFileService ? { - enabled: true - } : null - table: { - enabled: true + encryption: union({ + keySource: !empty(customerManagedKey) ? 'Microsoft.Keyvault' : 'Microsoft.Storage' + services: { + blob: supportsBlobService ? { + enabled: true + } : null + file: supportsFileService ? { + enabled: true + } : null + table: { + enabled: true + } + queue: { + enabled: true + } } - queue: { - enabled: true + keyvaultproperties: !empty(customerManagedKey) ? { + keyname: customerManagedKey!.keyName + keyvaulturi: cMKKeyVault.properties.vaultUri + keyversion: !empty(customerManagedKey.?keyVersion ?? '') ? customerManagedKey!.keyVersion : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) + } : null + identity: { + userAssignedIdentity: !empty(customerManagedKey.?userAssignedIdentityResourceId) ? cMKUserAssignedIdentity.id : null } - } - requireInfrastructureEncryption: kind != 'Storage' ? requireInfrastructureEncryption : null - keyvaultproperties: !empty(customerManagedKey) ? { - keyname: customerManagedKey!.keyName - keyvaulturi: cMKKeyVault.properties.vaultUri - keyversion: !empty(customerManagedKey.?keyVersion ?? '') ? customerManagedKey!.keyVersion : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) - } : null - identity: { - userAssignedIdentity: !empty(customerManagedKey.?userAssignedIdentityResourceId) ? cMKUserAssignedIdentity.id : null - } - } + }, (requireInfrastructureEncryption ? { + requireInfrastructureEncryption: kind != 'Storage' ? requireInfrastructureEncryption : null + } : {})) accessTier: kind != 'Storage' ? accessTier : null sasPolicy: !empty(sasExpirationPeriod) ? { expirationAction: 'Log' @@ -320,13 +318,11 @@ resource storageAccount_diagnosticSettings 'Microsoft.Insights/diagnosticSetting workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -370,9 +366,9 @@ module storageAccount_privateEndpoints 'br/public:avm/res/network/private-endpoi } } ] - name: privateEndpoint.?name ?? 'pep-${last(split(storageAccount.id, '/'))}-${privateEndpoint.?service ?? 'vault'}-${index}' + name: privateEndpoint.?name ?? 'pep-${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}' subnetResourceId: privateEndpoint.subnetResourceId - enableTelemetry: enableTelemetry + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location lock: privateEndpoint.?lock ?? lock privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName @@ -532,6 +528,23 @@ type roleAssignmentType = { delegatedManagedIdentityResourceId: string? }[]? +type networkAclsType = { + @description('Optional. Sets the resource access rules.') + resourceAccessRules: array? + + @description('Required. Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, "Logging, Metrics"), or None to bypass none of those traffics.') + bypass: ('None' | 'AzureServices' | 'Logging' | 'Metrics' | 'AzureServices, Logging' | 'AzureServices, Metrics' | 'AzureServices, Logging, Metrics' | 'Logging, Metrics') + + @description('Optional. Sets the virtual network rules.') + virtualNetworkRules: array? + + @description('Optional. Sets the IP ACL rules.') + ipRules: array? + + @description('Required. Specifies the default action of allow or deny when no other rules match.') + defaultAction: ('Allow' | 'Deny') +} + type privateEndpointType = { @description('Optional. The name of the private endpoint.') name: string? @@ -604,10 +617,13 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/storage/storage-account/main.json b/avm/res/storage/storage-account/main.json index 5d212d4f18..fc67003c5b 100644 --- a/avm/res/storage/storage-account/main.json +++ b/avm/res/storage/storage-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "3807395495755723225" + "version": "0.25.53.49325", + "templateHash": "10189933879993819158" }, "name": "Storage Accounts", "description": "This module deploys a Storage Account.", @@ -127,6 +127,58 @@ }, "nullable": true }, + "networkAclsType": { + "type": "object", + "properties": { + "resourceAccessRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Sets the resource access rules." + } + }, + "bypass": { + "type": "string", + "allowedValues": [ + "AzureServices", + "AzureServices, Logging", + "AzureServices, Logging, Metrics", + "AzureServices, Metrics", + "Logging", + "Logging, Metrics", + "Metrics", + "None" + ], + "metadata": { + "description": "Required. Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, \"Logging, Metrics\"), or None to bypass none of those traffics." + } + }, + "virtualNetworkRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Sets the virtual network rules." + } + }, + "ipRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Sets the IP ACL rules." + } + }, + "defaultAction": { + "type": "string", + "allowedValues": [ + "Allow", + "Deny" + ], + "metadata": { + "description": "Required. Specifies the default action of allow or deny when no other rules match." + } + } + } + }, "privateEndpointType": { "type": "array", "items": { @@ -321,14 +373,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -530,16 +589,13 @@ } }, "networkAcls": { - "type": "object", + "$ref": "#/definitions/networkAclsType", "defaultValue": { - "resourceAccessRules": [], "bypass": "AzureServices", - "virtualNetworkRules": [], - "ipRules": [], "defaultAction": "Deny" }, "metadata": { - "description": "Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. For security reasons, it is recommended to set the DefaultAction Deny." + "description": "Required. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny." } }, "requireInfrastructureEncryption": { @@ -838,24 +894,7 @@ }, "dnsEndpointType": "[if(not(empty(parameters('dnsEndpointType'))), parameters('dnsEndpointType'), null())]", "isLocalUserEnabled": "[parameters('isLocalUserEnabled')]", - "encryption": { - "keySource": "[if(not(empty(parameters('customerManagedKey'))), 'Microsoft.Keyvault', 'Microsoft.Storage')]", - "services": { - "blob": "[if(variables('supportsBlobService'), createObject('enabled', true()), null())]", - "file": "[if(variables('supportsFileService'), createObject('enabled', true()), null())]", - "table": { - "enabled": true - }, - "queue": { - "enabled": true - } - }, - "requireInfrastructureEncryption": "[if(not(equals(parameters('kind'), 'Storage')), parameters('requireInfrastructureEncryption'), null())]", - "keyvaultproperties": "[if(not(empty(parameters('customerManagedKey'))), createObject('keyname', parameters('customerManagedKey').keyName, 'keyvaulturi', reference('cMKKeyVault').vaultUri, 'keyversion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/')))), null())]", - "identity": { - "userAssignedIdentity": "[if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))), null())]" - } - }, + "encryption": "[union(createObject('keySource', if(not(empty(parameters('customerManagedKey'))), 'Microsoft.Keyvault', 'Microsoft.Storage'), 'services', createObject('blob', if(variables('supportsBlobService'), createObject('enabled', true()), null()), 'file', if(variables('supportsFileService'), createObject('enabled', true()), null()), 'table', createObject('enabled', true()), 'queue', createObject('enabled', true())), 'keyvaultproperties', if(not(empty(parameters('customerManagedKey'))), createObject('keyname', parameters('customerManagedKey').keyName, 'keyvaulturi', reference('cMKKeyVault').vaultUri, 'keyversion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/')))), null()), 'identity', createObject('userAssignedIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))), null()))), if(parameters('requireInfrastructureEncryption'), createObject('requireInfrastructureEncryption', if(not(equals(parameters('kind'), 'Storage')), parameters('requireInfrastructureEncryption'), null())), createObject()))]", "accessTier": "[if(not(equals(parameters('kind'), 'Storage')), parameters('accessTier'), null())]", "sasPolicy": "[if(not(empty(parameters('sasExpirationPeriod'))), createObject('expirationAction', 'Log', 'sasExpirationPeriod', parameters('sasExpirationPeriod')), null())]", "supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]", @@ -884,11 +923,21 @@ "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -960,13 +1009,13 @@ ] }, "name": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault'), copyIndex()))]" + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex()))]" }, "subnetResourceId": { "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" }, "enableTelemetry": { - "value": "[parameters('enableTelemetry')]" + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" }, "location": { "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" @@ -1624,8 +1673,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17360500138014235250" + "version": "0.25.53.49325", + "templateHash": "774635646248081518" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy.", @@ -1734,8 +1783,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "414567084253124464" + "version": "0.25.53.49325", + "templateHash": "17117452291389534361" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication.", @@ -1952,8 +2001,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6670506366627013721" + "version": "0.25.53.49325", + "templateHash": "4746835745355709536" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service.", @@ -1988,14 +2037,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -2006,14 +2062,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -2250,12 +2313,30 @@ "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}', parameters('storageAccountName'), variables('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -2318,8 +2399,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "1429761296615247722" + "version": "0.25.53.49325", + "templateHash": "11351273351916968732" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container.", @@ -2587,8 +2668,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15441426428461937893" + "version": "0.25.53.49325", + "templateHash": "10329548264889228160" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy.", @@ -2766,8 +2847,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "685043578297461233" + "version": "0.25.53.49325", + "templateHash": "5288106279947156711" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service.", @@ -2802,14 +2883,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -2820,14 +2908,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -2956,12 +3051,30 @@ "scope": "[format('Microsoft.Storage/storageAccounts/{0}/fileServices/{1}', parameters('storageAccountName'), parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -3015,8 +3128,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11243515252529303304" + "version": "0.25.53.49325", + "templateHash": "2026482374148202879" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share.", @@ -3215,8 +3328,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17643632023108067837" + "version": "0.25.53.49325", + "templateHash": "15595600813016932186" } }, "parameters": { @@ -3484,8 +3597,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9901414791831714811" + "version": "0.25.53.49325", + "templateHash": "14446905482734328346" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service.", @@ -3520,14 +3633,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -3538,14 +3658,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -3650,12 +3777,30 @@ "scope": "[format('Microsoft.Storage/storageAccounts/{0}/queueServices/{1}', parameters('storageAccountName'), variables('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -3697,8 +3842,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11104056744955032379" + "version": "0.25.53.49325", + "templateHash": "12411465246702614738" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue.", @@ -3954,8 +4099,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4432761872900647010" + "version": "0.25.53.49325", + "templateHash": "14471460242481977546" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service.", @@ -3990,14 +4135,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -4008,14 +4160,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -4120,12 +4279,30 @@ "scope": "[format('Microsoft.Storage/storageAccounts/{0}/tableServices/{1}', parameters('storageAccountName'), variables('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -4164,8 +4341,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "981180809348713884" + "version": "0.25.53.49325", + "templateHash": "8824223095963877860" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table.", diff --git a/avm/res/storage/storage-account/management-policy/README.md b/avm/res/storage/storage-account/management-policy/README.md index fc3674fd91..02bc4e8fed 100644 --- a/avm/res/storage/storage-account/management-policy/README.md +++ b/avm/res/storage/storage-account/management-policy/README.md @@ -14,7 +14,7 @@ This module deploys a Storage Account Management Policy. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Storage/storageAccounts/managementPolicies` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/managementPolicies) | +| `Microsoft.Storage/storageAccounts/managementPolicies` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-01-01/storageAccounts/managementPolicies) | ## Parameters diff --git a/avm/res/storage/storage-account/management-policy/main.json b/avm/res/storage/storage-account/management-policy/main.json index 3a0a924bdb..3e1730f09b 100644 --- a/avm/res/storage/storage-account/management-policy/main.json +++ b/avm/res/storage/storage-account/management-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "17360500138014235250" + "version": "0.25.53.49325", + "templateHash": "774635646248081518" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy.", diff --git a/avm/res/storage/storage-account/queue-service/README.md b/avm/res/storage/storage-account/queue-service/README.md index 91be577e8e..74a831bd19 100644 --- a/avm/res/storage/storage-account/queue-service/README.md +++ b/avm/res/storage/storage-account/queue-service/README.md @@ -55,9 +55,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -92,11 +92,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -106,11 +135,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/storage/storage-account/queue-service/main.bicep b/avm/res/storage/storage-account/queue-service/main.bicep index 7ba25edbd5..046bbd45f3 100644 --- a/avm/res/storage/storage-account/queue-service/main.bicep +++ b/avm/res/storage/storage-account/queue-service/main.bicep @@ -32,19 +32,16 @@ resource queueServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -78,19 +75,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/storage/storage-account/queue-service/main.json b/avm/res/storage/storage-account/queue-service/main.json index 2700ee78d5..aae35c5012 100644 --- a/avm/res/storage/storage-account/queue-service/main.json +++ b/avm/res/storage/storage-account/queue-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9901414791831714811" + "version": "0.25.53.49325", + "templateHash": "14446905482734328346" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service.", @@ -41,14 +41,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -59,14 +66,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -171,12 +185,30 @@ "scope": "[format('Microsoft.Storage/storageAccounts/{0}/queueServices/{1}', parameters('storageAccountName'), variables('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -218,8 +250,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11104056744955032379" + "version": "0.25.53.49325", + "templateHash": "12411465246702614738" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue.", diff --git a/avm/res/storage/storage-account/queue-service/queue/main.json b/avm/res/storage/storage-account/queue-service/queue/main.json index 888b7f01b5..6ad5c15435 100644 --- a/avm/res/storage/storage-account/queue-service/queue/main.json +++ b/avm/res/storage/storage-account/queue-service/queue/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "11104056744955032379" + "version": "0.25.53.49325", + "templateHash": "12411465246702614738" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue.", diff --git a/avm/res/storage/storage-account/table-service/README.md b/avm/res/storage/storage-account/table-service/README.md index a9327032ba..2d118753cb 100644 --- a/avm/res/storage/storage-account/table-service/README.md +++ b/avm/res/storage/storage-account/table-service/README.md @@ -55,9 +55,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -92,11 +92,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -106,11 +135,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/storage/storage-account/table-service/main.bicep b/avm/res/storage/storage-account/table-service/main.bicep index bf90d9bb02..0ff60b095b 100644 --- a/avm/res/storage/storage-account/table-service/main.bicep +++ b/avm/res/storage/storage-account/table-service/main.bicep @@ -32,19 +32,16 @@ resource tableServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -77,19 +74,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/storage/storage-account/table-service/main.json b/avm/res/storage/storage-account/table-service/main.json index d78b2f001e..4b2089447c 100644 --- a/avm/res/storage/storage-account/table-service/main.json +++ b/avm/res/storage/storage-account/table-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "4432761872900647010" + "version": "0.25.53.49325", + "templateHash": "14471460242481977546" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service.", @@ -41,14 +41,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -59,14 +66,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -171,12 +185,30 @@ "scope": "[format('Microsoft.Storage/storageAccounts/{0}/tableServices/{1}', parameters('storageAccountName'), variables('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -215,8 +247,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "981180809348713884" + "version": "0.25.53.49325", + "templateHash": "8824223095963877860" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table.", diff --git a/avm/res/storage/storage-account/table-service/table/main.json b/avm/res/storage/storage-account/table-service/table/main.json index f8f1671b71..c87d417e99 100644 --- a/avm/res/storage/storage-account/table-service/table/main.json +++ b/avm/res/storage/storage-account/table-service/table/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "981180809348713884" + "version": "0.25.53.49325", + "templateHash": "8824223095963877860" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table.", diff --git a/avm/res/storage/storage-account/tests/e2e/max/dependencies.bicep b/avm/res/storage/storage-account/tests/e2e/max/dependencies.bicep index b7cff8b3d2..6e0fe47d04 100644 --- a/avm/res/storage/storage-account/tests/e2e/max/dependencies.bicep +++ b/avm/res/storage/storage-account/tests/e2e/max/dependencies.bicep @@ -37,6 +37,9 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { name: 'privatelink.blob.${environment().suffixes.storage}' location: 'global' + dependsOn: [ + virtualNetwork + ] resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { name: '${virtualNetwork.name}-vnetlink' diff --git a/avm/res/storage/storage-account/tests/e2e/user-assigned-cmk-encryption/main.test.bicep b/avm/res/storage/storage-account/tests/e2e/user-assigned-cmk-encryption/main.test.bicep index 54c7fa45ac..505551c7aa 100644 --- a/avm/res/storage/storage-account/tests/e2e/user-assigned-cmk-encryption/main.test.bicep +++ b/avm/res/storage/storage-account/tests/e2e/user-assigned-cmk-encryption/main.test.bicep @@ -57,6 +57,10 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' params: { location: resourceLocation name: '${namePrefix}${serviceShort}001' + networkAcls: { + bypass: 'AzureServices' + defaultAction: 'Deny' + } privateEndpoints: [ { service: 'blob' diff --git a/avm/res/storage/storage-account/version.json b/avm/res/storage/storage-account/version.json index 04a0dd1a80..e42c3d9e5f 100644 --- a/avm/res/storage/storage-account/version.json +++ b/avm/res/storage/storage-account/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.5", + "version": "0.6", "pathFilters": [ "./main.json" ] -} +} \ No newline at end of file diff --git a/avm/res/api-management/service/ORPHANED.md b/avm/res/synapse/private-link-hub/ORPHANED.md similarity index 100% rename from avm/res/api-management/service/ORPHANED.md rename to avm/res/synapse/private-link-hub/ORPHANED.md diff --git a/avm/res/synapse/private-link-hub/README.md b/avm/res/synapse/private-link-hub/README.md new file mode 100644 index 0000000000..82e2a891c3 --- /dev/null +++ b/avm/res/synapse/private-link-hub/README.md @@ -0,0 +1,819 @@ +# Azure Synapse Analytics `[Microsoft.Synapse/privateLinkHubs]` + +> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ +> +> - Only security and bug fixes are being handled by the AVM core team at present. +> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! + +This module deploys an Azure Synapse Analytics (Private Link Hub). + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | +| `Microsoft.Synapse/privateLinkHubs` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/privateLinkHubs) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/synapse/private-link-hub:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep +module privateLinkHub 'br/public:avm/res/synapse/private-link-hub:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-splhmin' + params: { + // Required parameters + name: 'splhmin001' + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "splhmin001" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module privateLinkHub 'br/public:avm/res/synapse/private-link-hub:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-splhmax' + params: { + // Required parameters + name: 'splhmax001' + // Non-required parameters + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + '' + ] + service: 'Web' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "splhmax001" + }, + // Non-required parameters + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneResourceIds": [ + "" + ], + "service": "Web", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + +### Example 3: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module privateLinkHub 'br/public:avm/res/synapse/private-link-hub:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-splhwaf' + params: { + // Required parameters + name: 'splhwaf001' + // Non-required parameters + location: '' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + '' + ] + service: 'Web' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "splhwaf001" + }, + // Non-required parameters + "location": { + "value": "" + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneResourceIds": [ + "" + ], + "service": "Web", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the Private Link Hub. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`location`](#parameter-location) | string | The geo-location where the resource lives. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | + +### Parameter: `name` + +The name of the Private Link Hub. + +- Required: Yes +- Type: string + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `location` + +The geo-location where the resource lives. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints` + +Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`service`](#parameter-privateendpointsservice) | string | The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". | +| [`subnetResourceId`](#parameter-privateendpointssubnetresourceid) | string | Resource ID of the subnet where the endpoint needs to be created. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | +| [`manualPrivateLinkServiceConnections`](#parameter-privateendpointsmanualprivatelinkserviceconnections) | array | Manual PrivateLink Service Connections. | +| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | +| [`privateDnsZoneGroupName`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided. | +| [`privateDnsZoneResourceIds`](#parameter-privateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | + +### Parameter: `privateEndpoints.service` + +The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.subnetResourceId` + +Resource ID of the subnet where the endpoint needs to be created. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` + +Application security groups in which the private endpoint IP configuration is included. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.customDnsConfigs` + +Custom DNS configurations. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + +### Parameter: `privateEndpoints.customNetworkInterfaceName` + +The custom name of the network interface attached to the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool + +### Parameter: `privateEndpoints.ipConfigurations` + +A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.location` + +The location to deploy the private endpoint to. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.lock` + +Specify the type of lock. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-privateendpointslockkind) | string | Specify the type of lock. | +| [`name`](#parameter-privateendpointslockname) | string | Specify the name of lock. | + +### Parameter: `privateEndpoints.lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `privateEndpoints.lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.manualPrivateLinkServiceConnections` + +Manual PrivateLink Service Connections. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.name` + +The name of the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroupName` + +The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneResourceIds` + +The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-privateendpointsroleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-privateendpointsroleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-privateendpointsroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-privateendpointsroleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-privateendpointsroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-privateendpointsroleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-privateendpointsroleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `privateEndpoints.roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `privateEndpoints.roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `privateEndpoints.tags` + +Tags to be applied on all resources/resource groups in this deployment. + +- Required: No +- Type: object + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the deployed Synapse Private Link Hub. | +| `resourceGroupName` | string | The resource group of the deployed Synapse Private Link Hub. | +| `resourceId` | string | The resource ID of the deployed Synapse Private Link Hub. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other CARML modules that are referenced in this module) and all remote-referenced files (i.e., Bicep modules that are referenced from a Bicep Registry or Template Specs). + +| Reference | Type | +| :-- | :-- | +| `br/public:avm/res/network/private-endpoint:0.3.1` | Remote reference | + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/synapse/private-link-hub/main.bicep b/avm/res/synapse/private-link-hub/main.bicep new file mode 100644 index 0000000000..ea2d80db82 --- /dev/null +++ b/avm/res/synapse/private-link-hub/main.bicep @@ -0,0 +1,228 @@ +metadata name = 'Azure Synapse Analytics' +metadata description = 'This module deploys an Azure Synapse Analytics (Private Link Hub).' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The name of the Private Link Hub.') +param name string + +@description('Optional. The geo-location where the resource lives.') +param location string = resourceGroup().location + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') +param privateEndpoints privateEndpointType + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.synapse-privatelinkhub.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource privateLinkHub 'Microsoft.Synapse/privateLinkHubs@2021-06-01' = { + name: name + location: location + tags: tags +} + +// Resource Lock +resource privateLinkHub_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: privateLinkHub +} + +// RBAC +resource privateLinkHub_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(privateLinkHub.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: privateLinkHub +}] + +// Private Endpoints +module privateLinkHub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.3.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-privateLinkHub-PrivateEndpoint-${index}' + params: { + privateLinkServiceConnections: [ + { + name: name + properties: { + privateLinkServiceId: privateLinkHub.id + groupIds: [ + privateEndpoint.?service ?? 'privateLinkHubs' + ] + } + } + ] + name: privateEndpoint.?name ?? 'pep-${last(split(privateLinkHub.id, '/'))}-${privateEndpoint.?service ?? privateEndpoint.service}-${index}' + subnetResourceId: privateEndpoint.subnetResourceId + location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location + lock: privateEndpoint.?lock ?? lock + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + } +}] + +@description('The resource ID of the deployed Synapse Private Link Hub.') +output resourceId string = privateLinkHub.id + +@description('The name of the deployed Synapse Private Link Hub.') +output name string = privateLinkHub.name + +@description('The resource group of the deployed Synapse Private Link Hub.') +output resourceGroupName string = resourceGroup().name + +@description('The location the resource was deployed into.') +output location string = privateLinkHub.location + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? + +type privateEndpointType = { + @description('Optional. The name of the private endpoint.') + name: string? + + @description('Optional. The location to deploy the private endpoint to.') + location: string? + + @description('Required. The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob".') + service: string + + @description('Required. Resource ID of the subnet where the endpoint needs to be created.') + subnetResourceId: string + + @description('Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided.') + privateDnsZoneGroupName: string? + + @description('Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneResourceIds: string[]? + + @description('Optional. Custom DNS configurations.') + customDnsConfigs: { + @description('Required. Fqdn that resolves to private endpoint ip address.') + fqdn: string? + + @description('Required. A list of private ip addresses of the private endpoint.') + ipAddresses: string[] + }[]? + + @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') + ipConfigurations: { + @description('Required. The name of the resource that is unique within a resource group.') + name: string + + @description('Required. Properties of private endpoint IP configurations.') + properties: { + @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') + groupId: string + + @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') + memberName: string + + @description('Required. A private ip address obtained from the private endpoint\'s subnet.') + privateIPAddress: string + } + }[]? + + @description('Optional. Application security groups in which the private endpoint IP configuration is included.') + applicationSecurityGroupResourceIds: string[]? + + @description('Optional. The custom name of the network interface attached to the private endpoint.') + customNetworkInterfaceName: string? + + @description('Optional. Specify the type of lock.') + lock: lockType + + @description('Optional. Array of role assignments to create.') + roleAssignments: roleAssignmentType + + @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') + tags: object? + + @description('Optional. Manual PrivateLink Service Connections.') + manualPrivateLinkServiceConnections: array? + + @description('Optional. Enable/Disable usage telemetry for module.') + enableTelemetry: bool? +}[]? diff --git a/avm/res/synapse/private-link-hub/main.json b/avm/res/synapse/private-link-hub/main.json new file mode 100644 index 0000000000..d6a37b5693 --- /dev/null +++ b/avm/res/synapse/private-link-hub/main.json @@ -0,0 +1,1101 @@ +{ + "$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.25.53.49325", + "templateHash": "17829030796536004082" + }, + "name": "Azure Synapse Analytics", + "description": "This module deploys an Azure Synapse Analytics (Private Link Hub).", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "service": { + "type": "string", + "metadata": { + "description": "Required. The service (sub-) type to deploy the private endpoint for. For example \"vault\" or \"blob\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint ip address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private ip addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private ip address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Private Link Hub." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The geo-location where the resource lives." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.synapse-privatelinkhub.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateLinkHub": { + "type": "Microsoft.Synapse/privateLinkHubs", + "apiVersion": "2021-06-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]" + }, + "privateLinkHub_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Synapse/privateLinkHubs/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateLinkHub" + ] + }, + "privateLinkHub_roleAssignments": { + "copy": { + "name": "privateLinkHub_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Synapse/privateLinkHubs/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Synapse/privateLinkHubs', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateLinkHub" + ] + }, + "privateLinkHub_privateEndpoints": { + "copy": { + "name": "privateLinkHub_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-privateLinkHub-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateLinkServiceConnections": { + "value": [ + { + "name": "[parameters('name')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Synapse/privateLinkHubs', parameters('name'))]", + "groupIds": [ + "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'privateLinkHubs')]" + ] + } + } + ] + }, + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Synapse/privateLinkHubs', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), copyIndex()))]" + }, + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "manualPrivateLinkServiceConnections": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections')]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + } + }, + "template": { + "$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.23.1.45101", + "templateHash": "2821141217598568122" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private ip address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint ip address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private ip addresses of the private endpoint." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.3.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "18168683629401652671" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "privateLinkHub" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed Synapse Private Link Hub." + }, + "value": "[resourceId('Microsoft.Synapse/privateLinkHubs', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed Synapse Private Link Hub." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed Synapse Private Link Hub." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateLinkHub', '2021-06-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/synapse/private-link-hub/tests/e2e/defaults/main.test.bicep b/avm/res/synapse/private-link-hub/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..c726100b1d --- /dev/null +++ b/avm/res/synapse/private-link-hub/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,46 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.privatelinkhubs-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'splhmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + } +}] diff --git a/avm/res/synapse/private-link-hub/tests/e2e/max/dependencies.bicep b/avm/res/synapse/private-link-hub/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..d7ca02fccb --- /dev/null +++ b/avm/res/synapse/private-link-hub/tests/e2e/max/dependencies.bicep @@ -0,0 +1,74 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Network Security Group to create.') +param networkSecurityGroupName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +var addressPrefix = '10.0.0.0/16' + +resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-04-01' = { + name: networkSecurityGroupName + location: location + properties: {} +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + networkSecurityGroup: { + id: networkSecurityGroup.id + } + privateEndpointNetworkPolicies: 'Disabled' + privateLinkServiceNetworkPolicies: 'Enabled' + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.azuresynapse.net' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/res/synapse/private-link-hub/tests/e2e/max/main.test.bicep b/avm/res/synapse/private-link-hub/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..edcbcf4ffe --- /dev/null +++ b/avm/res/synapse/private-link-hub/tests/e2e/max/main.test.bicep @@ -0,0 +1,92 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.privatelinkhubs-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'splhmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + networkSecurityGroupName: 'dep-${namePrefix}-nsg-${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'Web' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' + principalType: 'ServicePrincipal' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/synapse/private-link-hub/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/synapse/private-link-hub/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..d7fa917088 --- /dev/null +++ b/avm/res/synapse/private-link-hub/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,64 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Network Security Group to create.') +param networkSecurityGroupName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +var addressPrefix = '10.0.0.0/16' + +resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-04-01' = { + name: networkSecurityGroupName + location: location + properties: {} +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + networkSecurityGroup: { + id: networkSecurityGroup.id + } + privateEndpointNetworkPolicies: 'Disabled' + privateLinkServiceNetworkPolicies: 'Enabled' + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.azuresynapse.net' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + diff --git a/avm/res/synapse/private-link-hub/tests/e2e/waf-aligned/main.test.bicep b/avm/res/synapse/private-link-hub/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..f25303df35 --- /dev/null +++ b/avm/res/synapse/private-link-hub/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,75 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.privatelinkhubs-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'splhwaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + networkSecurityGroupName: 'dep-${namePrefix}-nsg-${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'Web' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/synapse/private-link-hub/version.json b/avm/res/synapse/private-link-hub/version.json new file mode 100644 index 0000000000..83083db694 --- /dev/null +++ b/avm/res/synapse/private-link-hub/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file diff --git a/avm/res/compute/image/ORPHANED.md b/avm/res/synapse/workspace/ORPHANED.md similarity index 100% rename from avm/res/compute/image/ORPHANED.md rename to avm/res/synapse/workspace/ORPHANED.md diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md new file mode 100644 index 0000000000..3c3cea9256 --- /dev/null +++ b/avm/res/synapse/workspace/README.md @@ -0,0 +1,1531 @@ +# Synapse Workspaces `[Microsoft.Synapse/workspaces]` + +> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ +> +> - Only security and bug fixes are being handled by the AVM core team at present. +> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! + +This module deploys a Synapse Workspace. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.KeyVault/vaults/accessPolicies` | [2022-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2022-07-01/vaults/accessPolicies) | +| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | +| `Microsoft.Synapse/workspaces` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces) | +| `Microsoft.Synapse/workspaces/integrationRuntimes` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/integrationRuntimes) | +| `Microsoft.Synapse/workspaces/keys` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/keys) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/synapse/workspace:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using encryption with Customer-Managed-Key](#example-2-using-encryption-with-customer-managed-key) +- [Using encryption with Customer-Managed-Key](#example-3-using-encryption-with-customer-managed-key) +- [Using managed Vnet](#example-4-using-managed-vnet) +- [Using large parameter set](#example-5-using-large-parameter-set) +- [WAF-aligned](#example-6-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-swmin' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swmin001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swmin001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 2: _Using encryption with Customer-Managed-Key_ + +This instance deploys the module using Customer-Managed-Keys using a System-Assigned Identity to access the Customer-Managed-Key secret. + + +

    + +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-swensa' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swensa001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + customerManagedKey: { + keyName: '' + keyVaultResourceId: '' + } + encryptionActivateWorkspace: true + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swensa001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "customerManagedKey": { + "value": { + "keyName": "", + "keyVaultResourceId": "" + } + }, + "encryptionActivateWorkspace": { + "value": true + }, + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 3: _Using encryption with Customer-Managed-Key_ + +This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret. + + +

    + +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-swenua' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swenua001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + customerManagedKey: { + keyName: '' + keyVaultResourceId: '' + userAssignedIdentityResourceId: '' + } + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swenua001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "customerManagedKey": { + "value": { + "keyName": "", + "keyVaultResourceId": "", + "userAssignedIdentityResourceId": "" + } + }, + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 4: _Using managed Vnet_ + +This instance deploys the module using a managed Vnet. + + +

    + +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-swmanv' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swmanv001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + allowedAadTenantIdsForLinking: [ + '' + ] + location: '' + managedVirtualNetwork: true + preventDataExfiltration: true + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swmanv001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "allowedAadTenantIdsForLinking": { + "value": [ + "" + ] + }, + "location": { + "value": "" + }, + "managedVirtualNetwork": { + "value": true + }, + "preventDataExfiltration": { + "value": true + } + } +} +``` + +
    +

    + +### Example 5: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-swmax' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swmax001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + logCategoriesAndGroups: [ + { + category: 'SynapseRbacOperations' + } + { + category: 'SynapseLinkEvent' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + initialWorkspaceAdminObjectID: '' + integrationRuntimes: [ + { + name: 'shir01' + type: 'SelfHosted' + } + ] + location: '' + managedIdentities: { + userAssignedResourceIds: [ + '' + ] + } + managedVirtualNetwork: true + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + '' + ] + service: 'SQL' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swmax001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "logCategoriesAndGroups": [ + { + "category": "SynapseRbacOperations" + }, + { + "category": "SynapseLinkEvent" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, + "initialWorkspaceAdminObjectID": { + "value": "" + }, + "integrationRuntimes": { + "value": [ + { + "name": "shir01", + "type": "SelfHosted" + } + ] + }, + "location": { + "value": "" + }, + "managedIdentities": { + "value": { + "userAssignedResourceIds": [ + "" + ] + } + }, + "managedVirtualNetwork": { + "value": true + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneResourceIds": [ + "" + ], + "service": "SQL", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + } + } +} +``` + +
    +

    + +### Example 6: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-swwaf' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swwaf001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + logCategoriesAndGroups: [ + { + category: 'SynapseRbacOperations' + } + { + category: 'SynapseLinkEvent' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + integrationRuntimes: [ + { + name: 'shir01' + type: 'SelfHosted' + } + ] + location: '' + managedVirtualNetwork: true + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + '' + ] + service: 'SQL' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swwaf001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "logCategoriesAndGroups": [ + { + "category": "SynapseRbacOperations" + }, + { + "category": "SynapseLinkEvent" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, + "integrationRuntimes": { + "value": [ + { + "name": "shir01", + "type": "SelfHosted" + } + ] + }, + "location": { + "value": "" + }, + "managedVirtualNetwork": { + "value": true + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneResourceIds": [ + "" + ], + "service": "SQL", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`defaultDataLakeStorageAccountResourceId`](#parameter-defaultdatalakestorageaccountresourceid) | string | Resource ID of the default ADLS Gen2 storage account. | +| [`defaultDataLakeStorageFilesystem`](#parameter-defaultdatalakestoragefilesystem) | string | The default ADLS Gen2 file system. | +| [`name`](#parameter-name) | string | The name of the Synapse Workspace. | +| [`sqlAdministratorLogin`](#parameter-sqladministratorlogin) | string | Login for administrator access to the workspace's SQL pools. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`allowedAadTenantIdsForLinking`](#parameter-allowedaadtenantidsforlinking) | array | Allowed AAD Tenant IDs For Linking. | +| [`azureADOnlyAuthentication`](#parameter-azureadonlyauthentication) | bool | Enable or Disable AzureADOnlyAuthentication on All Workspace sub-resource. | +| [`customerManagedKey`](#parameter-customermanagedkey) | object | The customer managed key definition. | +| [`defaultDataLakeStorageCreateManagedPrivateEndpoint`](#parameter-defaultdatalakestoragecreatemanagedprivateendpoint) | bool | Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace's primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account. | +| [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`encryptionActivateWorkspace`](#parameter-encryptionactivateworkspace) | bool | Activate workspace by adding the system managed identity in the KeyVault containing the customer managed key and activating the workspace. | +| [`initialWorkspaceAdminObjectID`](#parameter-initialworkspaceadminobjectid) | string | AAD object ID of initial workspace admin. | +| [`integrationRuntimes`](#parameter-integrationruntimes) | array | The Integration Runtimes to create. | +| [`linkedAccessCheckOnTargetResource`](#parameter-linkedaccesscheckontargetresource) | bool | Linked Access Check On Target Resource. | +| [`location`](#parameter-location) | string | The geo-location where the resource lives. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. | +| [`managedResourceGroupName`](#parameter-managedresourcegroupname) | string | Workspace managed resource group. The resource group name uniquely identifies the resource group within the user subscriptionId. The resource group name must be no longer than 90 characters long, and must be alphanumeric characters (Char.IsLetterOrDigit()) and '-', '_', '(', ')' and'.'. Note that the name cannot end with '.'. | +| [`managedVirtualNetwork`](#parameter-managedvirtualnetwork) | bool | Enable this to ensure that connection from your workspace to your data sources use Azure Private Links. You can create managed private endpoints to your data sources. | +| [`preventDataExfiltration`](#parameter-preventdataexfiltration) | bool | Prevent Data Exfiltration. | +| [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | +| [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | Enable or Disable public network access to workspace. | +| [`purviewResourceID`](#parameter-purviewresourceid) | string | Purview Resource ID. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`sqlAdministratorLoginPassword`](#parameter-sqladministratorloginpassword) | securestring | Password for administrator access to the workspace's SQL pools. If you don't provide a password, one will be automatically generated. You can change the password later. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`workspaceRepositoryConfiguration`](#parameter-workspacerepositoryconfiguration) | object | Git integration settings. | + +### Parameter: `defaultDataLakeStorageAccountResourceId` + +Resource ID of the default ADLS Gen2 storage account. + +- Required: Yes +- Type: string + +### Parameter: `defaultDataLakeStorageFilesystem` + +The default ADLS Gen2 file system. + +- Required: Yes +- Type: string + +### Parameter: `name` + +The name of the Synapse Workspace. + +- Required: Yes +- Type: string + +### Parameter: `sqlAdministratorLogin` + +Login for administrator access to the workspace's SQL pools. + +- Required: Yes +- Type: string + +### Parameter: `allowedAadTenantIdsForLinking` + +Allowed AAD Tenant IDs For Linking. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `azureADOnlyAuthentication` + +Enable or Disable AzureADOnlyAuthentication on All Workspace sub-resource. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `customerManagedKey` + +The customer managed key definition. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`keyName`](#parameter-customermanagedkeykeyname) | string | The name of the customer managed key to use for encryption. | +| [`keyVaultResourceId`](#parameter-customermanagedkeykeyvaultresourceid) | string | The resource ID of a key vault to reference a customer managed key for encryption from. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`keyVersion`](#parameter-customermanagedkeykeyversion) | string | The version of the customer managed key to reference for encryption. If not provided, using 'latest'. | +| [`userAssignedIdentityResourceId`](#parameter-customermanagedkeyuserassignedidentityresourceid) | string | User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. | + +### Parameter: `customerManagedKey.keyName` + +The name of the customer managed key to use for encryption. + +- Required: Yes +- Type: string + +### Parameter: `customerManagedKey.keyVaultResourceId` + +The resource ID of a key vault to reference a customer managed key for encryption from. + +- Required: Yes +- Type: string + +### Parameter: `customerManagedKey.keyVersion` + +The version of the customer managed key to reference for encryption. If not provided, using 'latest'. + +- Required: No +- Type: string + +### Parameter: `customerManagedKey.userAssignedIdentityResourceId` + +User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. + +- Required: No +- Type: string + +### Parameter: `defaultDataLakeStorageCreateManagedPrivateEndpoint` + +Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace's primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `diagnosticSettings` + +The diagnostic settings of the service. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | + +### Parameter: `diagnosticSettings.eventHubAuthorizationRuleResourceId` + +Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.eventHubName` + +Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logAnalyticsDestinationType` + +A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AzureDiagnostics' + 'Dedicated' + ] + ``` + +### Parameter: `diagnosticSettings.logCategoriesAndGroups` + +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.marketplacePartnerResourceId` + +The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.name` + +The name of diagnostic setting. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.storageAccountResourceId` + +Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.workspaceResourceId` + +Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `encryptionActivateWorkspace` + +Activate workspace by adding the system managed identity in the KeyVault containing the customer managed key and activating the workspace. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `initialWorkspaceAdminObjectID` + +AAD object ID of initial workspace admin. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `integrationRuntimes` + +The Integration Runtimes to create. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `linkedAccessCheckOnTargetResource` + +Linked Access Check On Target Resource. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `location` + +The geo-location where the resource lives. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `managedIdentities` + +The managed identity definition for this resource. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. | + +### Parameter: `managedIdentities.userAssignedResourceIds` + +The resource ID(s) to assign to the resource. + +- Required: Yes +- Type: array + +### Parameter: `managedResourceGroupName` + +Workspace managed resource group. The resource group name uniquely identifies the resource group within the user subscriptionId. The resource group name must be no longer than 90 characters long, and must be alphanumeric characters (Char.IsLetterOrDigit()) and '-', '_', '(', ')' and'.'. Note that the name cannot end with '.'. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `managedVirtualNetwork` + +Enable this to ensure that connection from your workspace to your data sources use Azure Private Links. You can create managed private endpoints to your data sources. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `preventDataExfiltration` + +Prevent Data Exfiltration. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `privateEndpoints` + +Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`service`](#parameter-privateendpointsservice) | string | The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". | +| [`subnetResourceId`](#parameter-privateendpointssubnetresourceid) | string | Resource ID of the subnet where the endpoint needs to be created. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | +| [`manualPrivateLinkServiceConnections`](#parameter-privateendpointsmanualprivatelinkserviceconnections) | array | Manual PrivateLink Service Connections. | +| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | +| [`privateDnsZoneGroupName`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided. | +| [`privateDnsZoneResourceIds`](#parameter-privateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | + +### Parameter: `privateEndpoints.service` + +The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.subnetResourceId` + +Resource ID of the subnet where the endpoint needs to be created. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` + +Application security groups in which the private endpoint IP configuration is included. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.customDnsConfigs` + +Custom DNS configurations. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + +### Parameter: `privateEndpoints.customNetworkInterfaceName` + +The custom name of the network interface attached to the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool + +### Parameter: `privateEndpoints.ipConfigurations` + +A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.location` + +The location to deploy the private endpoint to. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.lock` + +Specify the type of lock. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-privateendpointslockkind) | string | Specify the type of lock. | +| [`name`](#parameter-privateendpointslockname) | string | Specify the name of lock. | + +### Parameter: `privateEndpoints.lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `privateEndpoints.lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.manualPrivateLinkServiceConnections` + +Manual PrivateLink Service Connections. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.name` + +The name of the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroupName` + +The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneResourceIds` + +The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-privateendpointsroleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-privateendpointsroleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-privateendpointsroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-privateendpointsroleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-privateendpointsroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-privateendpointsroleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-privateendpointsroleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `privateEndpoints.roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `privateEndpoints.roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `privateEndpoints.tags` + +Tags to be applied on all resources/resource groups in this deployment. + +- Required: No +- Type: object + +### Parameter: `publicNetworkAccess` + +Enable or Disable public network access to workspace. + +- Required: No +- Type: string +- Default: `'Enabled'` +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `purviewResourceID` + +Purview Resource ID. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `sqlAdministratorLoginPassword` + +Password for administrator access to the workspace's SQL pools. If you don't provide a password, one will be automatically generated. You can change the password later. + +- Required: No +- Type: securestring +- Default: `''` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `workspaceRepositoryConfiguration` + +Git integration settings. + +- Required: No +- Type: object +- Default: `{}` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `connectivityEndpoints` | object | The workspace connectivity endpoints. | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the deployed Synapse Workspace. | +| `resourceGroupName` | string | The resource group of the deployed Synapse Workspace. | +| `resourceID` | string | The resource ID of the deployed Synapse Workspace. | +| `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other CARML modules that are referenced in this module) and all remote-referenced files (i.e., Bicep modules that are referenced from a Bicep Registry or Template Specs). + +| Reference | Type | +| :-- | :-- | +| `br/public:avm/res/network/private-endpoint:0.3.1` | Remote reference | + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/synapse/workspace/integration-runtime/README.md b/avm/res/synapse/workspace/integration-runtime/README.md new file mode 100644 index 0000000000..c5d6ab1ffd --- /dev/null +++ b/avm/res/synapse/workspace/integration-runtime/README.md @@ -0,0 +1,86 @@ +# Synapse Workspace Integration Runtimes `[Microsoft.Synapse/workspaces/integrationRuntimes]` + +This module deploys a Synapse Workspace Integration Runtime. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Synapse/workspaces/integrationRuntimes` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/integrationRuntimes) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the Integration Runtime. | +| [`type`](#parameter-type) | string | The type of Integration Runtime. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`typeProperties`](#parameter-typeproperties) | object | Integration Runtime type properties. Required if type is "Managed". | +| [`workspaceName`](#parameter-workspacename) | string | The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment. | + +### Parameter: `name` + +The name of the Integration Runtime. + +- Required: Yes +- Type: string + +### Parameter: `type` + +The type of Integration Runtime. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Managed' + 'SelfHosted' + ] + ``` + +### Parameter: `typeProperties` + +Integration Runtime type properties. Required if type is "Managed". + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `workspaceName` + +The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the Integration Runtime. | +| `resourceGroupName` | string | The name of the Resource Group the Integration Runtime was created in. | +| `resourceId` | string | The resource ID of the Integration Runtime. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/synapse/workspace/integration-runtime/main.bicep b/avm/res/synapse/workspace/integration-runtime/main.bicep new file mode 100644 index 0000000000..2734626027 --- /dev/null +++ b/avm/res/synapse/workspace/integration-runtime/main.bicep @@ -0,0 +1,47 @@ +metadata name = 'Synapse Workspace Integration Runtimes' +metadata description = 'This module deploys a Synapse Workspace Integration Runtime.' +metadata owner = 'Azure/module-maintainers' + +@description('Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') +param workspaceName string + +@description('Required. The name of the Integration Runtime.') +param name string + +@allowed([ + 'Managed' + 'SelfHosted' +]) +@description('Required. The type of Integration Runtime.') +param type string + +@description('Conditional. Integration Runtime type properties. Required if type is "Managed".') +param typeProperties object = {} + +resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' existing = { + name: workspaceName +} + +resource integrationRuntime 'Microsoft.Synapse/workspaces/integrationRuntimes@2021-06-01' = { + name: name + parent: workspace + properties: type == 'Managed' ? { + type: type + managedVirtualNetwork: { + referenceName: 'default' + type: 'ManagedVirtualNetworkReference' + } + typeProperties: typeProperties + } : { + type: type + } +} + +@description('The name of the Resource Group the Integration Runtime was created in.') +output resourceGroupName string = resourceGroup().name + +@description('The name of the Integration Runtime.') +output name string = integrationRuntime.name + +@description('The resource ID of the Integration Runtime.') +output resourceId string = integrationRuntime.id diff --git a/avm/res/synapse/workspace/integration-runtime/main.json b/avm/res/synapse/workspace/integration-runtime/main.json new file mode 100644 index 0000000000..97a5e64866 --- /dev/null +++ b/avm/res/synapse/workspace/integration-runtime/main.json @@ -0,0 +1,76 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "7739107907804712060" + }, + "name": "Synapse Workspace Integration Runtimes", + "description": "This module deploys a Synapse Workspace Integration Runtime.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "workspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Integration Runtime." + } + }, + "type": { + "type": "string", + "allowedValues": [ + "Managed", + "SelfHosted" + ], + "metadata": { + "description": "Required. The type of Integration Runtime." + } + }, + "typeProperties": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Conditional. Integration Runtime type properties. Required if type is \"Managed\"." + } + } + }, + "resources": [ + { + "type": "Microsoft.Synapse/workspaces/integrationRuntimes", + "apiVersion": "2021-06-01", + "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", + "properties": "[if(equals(parameters('type'), 'Managed'), createObject('type', parameters('type'), 'managedVirtualNetwork', createObject('referenceName', 'default', 'type', 'ManagedVirtualNetworkReference'), 'typeProperties', parameters('typeProperties')), createObject('type', parameters('type')))]" + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the Integration Runtime was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the Integration Runtime." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Integration Runtime." + }, + "value": "[resourceId('Microsoft.Synapse/workspaces/integrationRuntimes', parameters('workspaceName'), parameters('name'))]" + } + } +} \ No newline at end of file diff --git a/avm/res/synapse/workspace/key/README.md b/avm/res/synapse/workspace/key/README.md new file mode 100644 index 0000000000..68021da16a --- /dev/null +++ b/avm/res/synapse/workspace/key/README.md @@ -0,0 +1,78 @@ +# Synapse Workspaces Keys `[Microsoft.Synapse/workspaces/keys]` + +This module deploys a Synapse Workspaces Key. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Synapse/workspaces/keys` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/keys) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`isActiveCMK`](#parameter-isactivecmk) | bool | Used to activate the workspace after a customer managed key is provided. | +| [`keyVaultResourceId`](#parameter-keyvaultresourceid) | string | The resource ID of a key vault to reference a customer managed key for encryption from. | +| [`name`](#parameter-name) | string | Encryption key name. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`workspaceName`](#parameter-workspacename) | string | The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment. | + +### Parameter: `isActiveCMK` + +Used to activate the workspace after a customer managed key is provided. + +- Required: Yes +- Type: bool + +### Parameter: `keyVaultResourceId` + +The resource ID of a key vault to reference a customer managed key for encryption from. + +- Required: Yes +- Type: string + +### Parameter: `name` + +Encryption key name. + +- Required: Yes +- Type: string + +### Parameter: `workspaceName` + +The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the deployed key. | +| `resourceGroupName` | string | The resource group of the deployed key. | +| `resourceId` | string | The resource ID of the deployed key. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/synapse/workspace/key/main.bicep b/avm/res/synapse/workspace/key/main.bicep new file mode 100644 index 0000000000..e24333f15c --- /dev/null +++ b/avm/res/synapse/workspace/key/main.bicep @@ -0,0 +1,46 @@ +metadata name = 'Synapse Workspaces Keys' +metadata description = 'This module deploys a Synapse Workspaces Key.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Encryption key name.') +param name string + +@description('Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') +param workspaceName string + +@description('Required. Used to activate the workspace after a customer managed key is provided.') +param isActiveCMK bool + +@description('Required. The resource ID of a key vault to reference a customer managed key for encryption from.') +param keyVaultResourceId string + +resource cMKKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = { + name: last(split(keyVaultResourceId, '/')) + scope: resourceGroup(split(keyVaultResourceId, '/')[2], split(keyVaultResourceId, '/')[4]) + + resource cMKKey 'keys@2023-02-01' existing = { + name: name + } +} + +resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' existing = { + name: workspaceName +} + +resource key 'Microsoft.Synapse/workspaces/keys@2021-06-01' = { + name: name + parent: workspace + properties: { + isActiveCMK: isActiveCMK + keyVaultUrl: cMKKeyVault::cMKKey.properties.keyUri + } +} + +@description('The name of the deployed key.') +output name string = key.name + +@description('The resource ID of the deployed key.') +output resourceId string = key.id + +@description('The resource group of the deployed key.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/synapse/workspace/key/main.json b/avm/res/synapse/workspace/key/main.json new file mode 100644 index 0000000000..85aed99df5 --- /dev/null +++ b/avm/res/synapse/workspace/key/main.json @@ -0,0 +1,74 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "2498604793784722860" + }, + "name": "Synapse Workspaces Keys", + "description": "This module deploys a Synapse Workspaces Key.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Encryption key name." + } + }, + "workspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + } + }, + "isActiveCMK": { + "type": "bool", + "metadata": { + "description": "Required. Used to activate the workspace after a customer managed key is provided." + } + }, + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + } + }, + "resources": [ + { + "type": "Microsoft.Synapse/workspaces/keys", + "apiVersion": "2021-06-01", + "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", + "properties": { + "isActiveCMK": "[parameters('isActiveCMK')]", + "keyVaultUrl": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('keyVaultResourceId'), '/')[2], split(parameters('keyVaultResourceId'), '/')[4]), 'Microsoft.KeyVault/vaults/keys', last(split(parameters('keyVaultResourceId'), '/')), parameters('name')), '2023-02-01').keyUri]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed key." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed key." + }, + "value": "[resourceId('Microsoft.Synapse/workspaces/keys', parameters('workspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed key." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep new file mode 100644 index 0000000000..d54a6fa3c5 --- /dev/null +++ b/avm/res/synapse/workspace/main.bicep @@ -0,0 +1,478 @@ +metadata name = 'Synapse Workspaces' +metadata description = 'This module deploys a Synapse Workspace.' +metadata owner = 'Azure/module-maintainers' + +// Parameters +@maxLength(50) +@description('Required. The name of the Synapse Workspace.') +param name string + +@description('Optional. The geo-location where the resource lives.') +param location string = resourceGroup().location + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@description('Optional. Enable or Disable AzureADOnlyAuthentication on All Workspace sub-resource.') +param azureADOnlyAuthentication bool = false + +@description('Optional. AAD object ID of initial workspace admin.') +param initialWorkspaceAdminObjectID string = '' + +@description('Required. Resource ID of the default ADLS Gen2 storage account.') +param defaultDataLakeStorageAccountResourceId string + +@description('Required. The default ADLS Gen2 file system.') +param defaultDataLakeStorageFilesystem string + +@description('Optional. Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace\'s primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account.') +param defaultDataLakeStorageCreateManagedPrivateEndpoint bool = false + +@description('Optional. The customer managed key definition.') +param customerManagedKey customerManagedKeyType + +@description('Optional. Activate workspace by adding the system managed identity in the KeyVault containing the customer managed key and activating the workspace.') +param encryptionActivateWorkspace bool = false + +@maxLength(90) +@description('Optional. Workspace managed resource group. The resource group name uniquely identifies the resource group within the user subscriptionId. The resource group name must be no longer than 90 characters long, and must be alphanumeric characters (Char.IsLetterOrDigit()) and \'-\', \'_\', \'(\', \')\' and\'.\'. Note that the name cannot end with \'.\'.') +param managedResourceGroupName string = '' + +@description('Optional. Enable this to ensure that connection from your workspace to your data sources use Azure Private Links. You can create managed private endpoints to your data sources.') +param managedVirtualNetwork bool = false + +@description('Optional. The Integration Runtimes to create.') +param integrationRuntimes array = [] + +@description('Optional. Allowed AAD Tenant IDs For Linking.') +param allowedAadTenantIdsForLinking array = [] + +@description('Optional. Linked Access Check On Target Resource.') +param linkedAccessCheckOnTargetResource bool = false + +@description('Optional. Prevent Data Exfiltration.') +param preventDataExfiltration bool = false + +@allowed([ + 'Enabled' + 'Disabled' +]) +@description('Optional. Enable or Disable public network access to workspace.') +param publicNetworkAccess string = 'Enabled' + +@description('Optional. Purview Resource ID.') +param purviewResourceID string = '' + +@description('Required. Login for administrator access to the workspace\'s SQL pools.') +param sqlAdministratorLogin string + +@description('Optional. Password for administrator access to the workspace\'s SQL pools. If you don\'t provide a password, one will be automatically generated. You can change the password later.') +@secure() +param sqlAdministratorLoginPassword string = '' + +@description('Optional. Git integration settings.') +param workspaceRepositoryConfiguration object = {} + +@description('Optional. The managed identity definition for this resource.') +param managedIdentities managedIdentitiesType + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') +param privateEndpoints privateEndpointType + +@description('Optional. The diagnostic settings of the service.') +param diagnosticSettings diagnosticSettingType + +// Variables + +var cmkUserAssignedIdentityAsArray = !empty(customerManagedKey.?userAssignedIdentityResourceId ?? []) ? [ customerManagedKey.?userAssignedIdentityResourceId ] : [] + +var userAssignedIdentitiesUnion = !empty(managedIdentities) ? union(managedIdentities.?userAssignedResourceIds ?? [], cmkUserAssignedIdentityAsArray) : cmkUserAssignedIdentityAsArray + +var formattedUserAssignedIdentities = reduce(map((userAssignedIdentitiesUnion ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = { + type: !empty(userAssignedIdentitiesUnion) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned' + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null +} + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.synapse-workspace.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource cMKKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = if (!empty(customerManagedKey.?keyVaultResourceId)) { + name: last(split((customerManagedKey.?keyVaultResourceId ?? 'dummyVault'), '/')) + scope: resourceGroup(split((customerManagedKey.?keyVaultResourceId ?? '//'), '/')[2], split((customerManagedKey.?keyVaultResourceId ?? '////'), '/')[4]) + + resource cMKKey 'keys@2023-02-01' existing = if (!empty(customerManagedKey.?keyVaultResourceId) && !empty(customerManagedKey.?keyName)) { + name: customerManagedKey.?keyName ?? 'dummyKey' + } +} + +resource cMKUserAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = if (!empty(customerManagedKey.?userAssignedIdentityResourceId)) { + name: last(split(customerManagedKey.?userAssignedIdentityResourceId ?? 'dummyMsi', '/')) + scope: resourceGroup(split((customerManagedKey.?userAssignedIdentityResourceId ?? '//'), '/')[2], split((customerManagedKey.?userAssignedIdentityResourceId ?? '////'), '/')[4]) +} + +resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' = { + name: name + location: location + identity: identity + tags: tags + properties: { + azureADOnlyAuthentication: azureADOnlyAuthentication ? azureADOnlyAuthentication : null + cspWorkspaceAdminProperties: !empty(initialWorkspaceAdminObjectID) ? { + initialWorkspaceAdminObjectId: initialWorkspaceAdminObjectID + } : null + defaultDataLakeStorage: { + resourceId: defaultDataLakeStorageAccountResourceId + accountUrl: 'https://${last(split(defaultDataLakeStorageAccountResourceId, '/'))!}.dfs.${environment().suffixes.storage}' + filesystem: defaultDataLakeStorageFilesystem + createManagedPrivateEndpoint: managedVirtualNetwork ? defaultDataLakeStorageCreateManagedPrivateEndpoint : null + } + encryption: !empty(customerManagedKey) ? { + cmk: { + kekIdentity: !empty(customerManagedKey.?userAssignedIdentityResourceId) ? { + userAssignedIdentity: cMKUserAssignedIdentity.id + } : { + useSystemAssignedIdentity: empty(customerManagedKey.?userAssignedIdentityResourceId) + } + key: { + keyVaultUrl: cMKKeyVault::cMKKey.properties.keyUri + name: customerManagedKey!.keyName + } + } + } : null + managedResourceGroupName: !empty(managedResourceGroupName) ? managedResourceGroupName : null + managedVirtualNetwork: managedVirtualNetwork ? 'default' : null + managedVirtualNetworkSettings: managedVirtualNetwork ? { + allowedAadTenantIdsForLinking: allowedAadTenantIdsForLinking + linkedAccessCheckOnTargetResource: linkedAccessCheckOnTargetResource + preventDataExfiltration: preventDataExfiltration + } : null + publicNetworkAccess: managedVirtualNetwork ? publicNetworkAccess : null + purviewConfiguration: !empty(purviewResourceID) ? { + purviewResourceId: purviewResourceID + } : null + sqlAdministratorLogin: sqlAdministratorLogin + sqlAdministratorLoginPassword: !empty(sqlAdministratorLoginPassword) ? sqlAdministratorLoginPassword : null + workspaceRepositoryConfiguration: workspaceRepositoryConfiguration + } +} + +// Workspace integration runtimes +module synapse_integrationRuntimes 'integration-runtime/main.bicep' = [for (integrationRuntime, index) in integrationRuntimes: { + name: '${uniqueString(deployment().name, location)}-Synapse-IntegrationRuntime-${index}' + params: { + workspaceName: workspace.name + name: integrationRuntime.name + type: integrationRuntime.type + typeProperties: contains(integrationRuntime, 'typeProperties') ? integrationRuntime.typeProperties : {} + } +}] + +// Workspace encryption with customer managed keys +// - Assign Synapse Workspace MSI access to encryption key +module workspace_cmk_rbac 'modules/nested_cmkRbac.bicep' = if (encryptionActivateWorkspace) { + name: '${workspace.name}-cmk-rbac' + params: { + workspaceIndentityPrincipalId: workspace.identity.principalId + keyvaultName: !empty(customerManagedKey.?keyVaultResourceId) ? cMKKeyVault.name : '' + usesRbacAuthorization: !empty(customerManagedKey.?keyVaultResourceId) ? cMKKeyVault.properties.enableRbacAuthorization : true + } + scope: encryptionActivateWorkspace ? resourceGroup(split((customerManagedKey.?keyVaultResourceId ?? '//'), '/')[2], split((customerManagedKey.?keyVaultResourceId ?? '////'), '/')[4]) : resourceGroup() +} + +// - Workspace encryption - Activate Workspace +module workspace_key 'key/main.bicep' = if (encryptionActivateWorkspace) { + name: '${workspace.name}-cmk-activation' + params: { + name: customerManagedKey!.keyName + isActiveCMK: true + keyVaultResourceId: cMKKeyVault.id + workspaceName: workspace.name + } + dependsOn: [ + workspace_cmk_rbac + ] +} + +// Resource Lock +resource workspace_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: workspace +} + +// RBAC +resource workspace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(workspace.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: workspace +}] + +// Endpoints +module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.3.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-workspace-PrivateEndpoint-${index}' + params: { + privateLinkServiceConnections: [ + { + name: name + properties: { + privateLinkServiceId: workspace.id + groupIds: [ + privateEndpoint.?service ?? 'SQL' + ] + } + } + ] + name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? privateEndpoint.service}-${index}' + subnetResourceId: privateEndpoint.subnetResourceId + location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location + lock: privateEndpoint.?lock ?? lock + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + } +}] + +// Diagnostics Settings +resource workspace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [for (diagnosticSetting, index) in (diagnosticSettings ?? []): { + name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' + properties: { + storageAccountId: diagnosticSetting.?storageAccountResourceId + workspaceId: diagnosticSetting.?workspaceResourceId + eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId + eventHubName: diagnosticSetting.?eventHubName + logs: diagnosticSetting.?logCategoriesAndGroups ?? [ + { + categoryGroup: 'AllLogs' + enabled: true + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: workspace +}] + +@description('The resource ID of the deployed Synapse Workspace.') +output resourceID string = workspace.id + +@description('The name of the deployed Synapse Workspace.') +output name string = workspace.name + +@description('The resource group of the deployed Synapse Workspace.') +output resourceGroupName string = resourceGroup().name + +@description('The workspace connectivity endpoints.') +output connectivityEndpoints object = workspace.properties.connectivityEndpoints + +@description('The principal ID of the system assigned identity.') +output systemAssignedMIPrincipalId string = workspace.?identity.?principalId ?? '' + +@description('The location the resource was deployed into.') +output location string = workspace.location + +// =============== // +// Definitions // +// =============== // + +type managedIdentitiesType = { + @description('Optional. The resource ID(s) to assign to the resource.') + userAssignedResourceIds: string[] +}? + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? + +type privateEndpointType = { + @description('Optional. The name of the private endpoint.') + name: string? + + @description('Optional. The location to deploy the private endpoint to.') + location: string? + + @description('Required. The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob".') + service: string + + @description('Required. Resource ID of the subnet where the endpoint needs to be created.') + subnetResourceId: string + + @description('Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided.') + privateDnsZoneGroupName: string? + + @description('Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneResourceIds: string[]? + + @description('Optional. Custom DNS configurations.') + customDnsConfigs: { + @description('Required. Fqdn that resolves to private endpoint ip address.') + fqdn: string? + + @description('Required. A list of private ip addresses of the private endpoint.') + ipAddresses: string[] + }[]? + + @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') + ipConfigurations: { + @description('Required. The name of the resource that is unique within a resource group.') + name: string + + @description('Required. Properties of private endpoint IP configurations.') + properties: { + @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') + groupId: string + + @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') + memberName: string + + @description('Required. A private ip address obtained from the private endpoint\'s subnet.') + privateIPAddress: string + } + }[]? + + @description('Optional. Application security groups in which the private endpoint IP configuration is included.') + applicationSecurityGroupResourceIds: string[]? + + @description('Optional. The custom name of the network interface attached to the private endpoint.') + customNetworkInterfaceName: string? + + @description('Optional. Specify the type of lock.') + lock: lockType + + @description('Optional. Array of role assignments to create.') + roleAssignments: roleAssignmentType + + @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') + tags: object? + + @description('Optional. Manual PrivateLink Service Connections.') + manualPrivateLinkServiceConnections: array? + + @description('Optional. Enable/Disable usage telemetry for module.') + enableTelemetry: bool? +}[]? + +type diagnosticSettingType = { + @description('Optional. The name of diagnostic setting.') + name: string? + + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + logCategoriesAndGroups: { + @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') + category: string? + + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + categoryGroup: string? + }[]? + + @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') + logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? + + @description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + workspaceResourceId: string? + + @description('Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + storageAccountResourceId: string? + + @description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') + eventHubAuthorizationRuleResourceId: string? + + @description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + eventHubName: string? + + @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') + marketplacePartnerResourceId: string? +}[]? + +type customerManagedKeyType = { + @description('Required. The resource ID of a key vault to reference a customer managed key for encryption from.') + keyVaultResourceId: string + + @description('Required. The name of the customer managed key to use for encryption.') + keyName: string + + @description('Optional. The version of the customer managed key to reference for encryption. If not provided, using \'latest\'.') + keyVersion: string? + + @description('Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use.') + userAssignedIdentityResourceId: string? +}? diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json new file mode 100644 index 0000000000..1d1b1b6994 --- /dev/null +++ b/avm/res/synapse/workspace/main.json @@ -0,0 +1,1766 @@ +{ + "$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.25.53.49325", + "templateHash": "13895345816421777976" + }, + "name": "Synapse Workspaces", + "description": "This module deploys a Synapse Workspace.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "service": { + "type": "string", + "metadata": { + "description": "Required. The service (sub-) type to deploy the private endpoint for. For example \"vault\" or \"blob\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint ip address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private ip addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private ip address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + } + }, + "nullable": true + }, + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "customerManagedKeyType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + } + }, + "userAssignedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "maxLength": 50, + "metadata": { + "description": "Required. The name of the Synapse Workspace." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The geo-location where the resource lives." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "azureADOnlyAuthentication": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable or Disable AzureADOnlyAuthentication on All Workspace sub-resource." + } + }, + "initialWorkspaceAdminObjectID": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. AAD object ID of initial workspace admin." + } + }, + "defaultDataLakeStorageAccountResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the default ADLS Gen2 storage account." + } + }, + "defaultDataLakeStorageFilesystem": { + "type": "string", + "metadata": { + "description": "Required. The default ADLS Gen2 file system." + } + }, + "defaultDataLakeStorageCreateManagedPrivateEndpoint": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace's primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "metadata": { + "description": "Optional. The customer managed key definition." + } + }, + "encryptionActivateWorkspace": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Activate workspace by adding the system managed identity in the KeyVault containing the customer managed key and activating the workspace." + } + }, + "managedResourceGroupName": { + "type": "string", + "defaultValue": "", + "maxLength": 90, + "metadata": { + "description": "Optional. Workspace managed resource group. The resource group name uniquely identifies the resource group within the user subscriptionId. The resource group name must be no longer than 90 characters long, and must be alphanumeric characters (Char.IsLetterOrDigit()) and '-', '_', '(', ')' and'.'. Note that the name cannot end with '.'." + } + }, + "managedVirtualNetwork": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable this to ensure that connection from your workspace to your data sources use Azure Private Links. You can create managed private endpoints to your data sources." + } + }, + "integrationRuntimes": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The Integration Runtimes to create." + } + }, + "allowedAadTenantIdsForLinking": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Allowed AAD Tenant IDs For Linking." + } + }, + "linkedAccessCheckOnTargetResource": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Linked Access Check On Target Resource." + } + }, + "preventDataExfiltration": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Prevent Data Exfiltration." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Enable or Disable public network access to workspace." + } + }, + "purviewResourceID": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Purview Resource ID." + } + }, + "sqlAdministratorLogin": { + "type": "string", + "metadata": { + "description": "Required. Login for administrator access to the workspace's SQL pools." + } + }, + "sqlAdministratorLoginPassword": { + "type": "securestring", + "defaultValue": "", + "metadata": { + "description": "Optional. Password for administrator access to the workspace's SQL pools. If you don't provide a password, one will be automatically generated. You can change the password later." + } + }, + "workspaceRepositoryConfiguration": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Git integration settings." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "cmkUserAssignedIdentityAsArray": "[if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), createArray()))), createArray(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')), createArray())]", + "userAssignedIdentitiesUnion": "[if(not(empty(parameters('managedIdentities'))), union(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), variables('cmkUserAssignedIdentityAsArray')), variables('cmkUserAssignedIdentityAsArray'))]", + "formattedUserAssignedIdentities": "[reduce(map(coalesce(variables('userAssignedIdentitiesUnion'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": { + "type": "[if(not(empty(variables('userAssignedIdentitiesUnion'))), 'SystemAssigned,UserAssigned', 'SystemAssigned')]", + "userAssignedIdentities": "[if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())]" + }, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "cMKKeyVault::cMKKey": { + "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]", + "dependsOn": [ + "cMKKeyVault" + ] + }, + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.synapse-workspace.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "cMKKeyVault": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" + }, + "cMKUserAssignedIdentity": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" + }, + "workspace": { + "type": "Microsoft.Synapse/workspaces", + "apiVersion": "2021-06-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": "[variables('identity')]", + "tags": "[parameters('tags')]", + "properties": { + "azureADOnlyAuthentication": "[if(parameters('azureADOnlyAuthentication'), parameters('azureADOnlyAuthentication'), null())]", + "cspWorkspaceAdminProperties": "[if(not(empty(parameters('initialWorkspaceAdminObjectID'))), createObject('initialWorkspaceAdminObjectId', parameters('initialWorkspaceAdminObjectID')), null())]", + "defaultDataLakeStorage": { + "resourceId": "[parameters('defaultDataLakeStorageAccountResourceId')]", + "accountUrl": "[format('https://{0}.dfs.{1}', last(split(parameters('defaultDataLakeStorageAccountResourceId'), '/')), environment().suffixes.storage)]", + "filesystem": "[parameters('defaultDataLakeStorageFilesystem')]", + "createManagedPrivateEndpoint": "[if(parameters('managedVirtualNetwork'), parameters('defaultDataLakeStorageCreateManagedPrivateEndpoint'), null())]" + }, + "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('cmk', createObject('kekIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), createObject('userAssignedIdentity', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/')))), createObject('useSystemAssignedIdentity', empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))), 'key', createObject('keyVaultUrl', reference('cMKKeyVault::cMKKey').keyUri, 'name', parameters('customerManagedKey').keyName))), null())]", + "managedResourceGroupName": "[if(not(empty(parameters('managedResourceGroupName'))), parameters('managedResourceGroupName'), null())]", + "managedVirtualNetwork": "[if(parameters('managedVirtualNetwork'), 'default', null())]", + "managedVirtualNetworkSettings": "[if(parameters('managedVirtualNetwork'), createObject('allowedAadTenantIdsForLinking', parameters('allowedAadTenantIdsForLinking'), 'linkedAccessCheckOnTargetResource', parameters('linkedAccessCheckOnTargetResource'), 'preventDataExfiltration', parameters('preventDataExfiltration')), null())]", + "publicNetworkAccess": "[if(parameters('managedVirtualNetwork'), parameters('publicNetworkAccess'), null())]", + "purviewConfiguration": "[if(not(empty(parameters('purviewResourceID'))), createObject('purviewResourceId', parameters('purviewResourceID')), null())]", + "sqlAdministratorLogin": "[parameters('sqlAdministratorLogin')]", + "sqlAdministratorLoginPassword": "[if(not(empty(parameters('sqlAdministratorLoginPassword'))), parameters('sqlAdministratorLoginPassword'), null())]", + "workspaceRepositoryConfiguration": "[parameters('workspaceRepositoryConfiguration')]" + }, + "dependsOn": [ + "cMKKeyVault", + "cMKUserAssignedIdentity" + ] + }, + "workspace_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Synapse/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_roleAssignments": { + "copy": { + "name": "workspace_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Synapse/workspaces/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Synapse/workspaces', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_diagnosticSettings": { + "copy": { + "name": "workspace_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Synapse/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "synapse_integrationRuntimes": { + "copy": { + "name": "synapse_integrationRuntimes", + "count": "[length(parameters('integrationRuntimes'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Synapse-IntegrationRuntime-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "workspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('integrationRuntimes')[copyIndex()].name]" + }, + "type": { + "value": "[parameters('integrationRuntimes')[copyIndex()].type]" + }, + "typeProperties": "[if(contains(parameters('integrationRuntimes')[copyIndex()], 'typeProperties'), createObject('value', parameters('integrationRuntimes')[copyIndex()].typeProperties), createObject('value', createObject()))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "7739107907804712060" + }, + "name": "Synapse Workspace Integration Runtimes", + "description": "This module deploys a Synapse Workspace Integration Runtime.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "workspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Integration Runtime." + } + }, + "type": { + "type": "string", + "allowedValues": [ + "Managed", + "SelfHosted" + ], + "metadata": { + "description": "Required. The type of Integration Runtime." + } + }, + "typeProperties": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Conditional. Integration Runtime type properties. Required if type is \"Managed\"." + } + } + }, + "resources": [ + { + "type": "Microsoft.Synapse/workspaces/integrationRuntimes", + "apiVersion": "2021-06-01", + "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", + "properties": "[if(equals(parameters('type'), 'Managed'), createObject('type', parameters('type'), 'managedVirtualNetwork', createObject('referenceName', 'default', 'type', 'ManagedVirtualNetworkReference'), 'typeProperties', parameters('typeProperties')), createObject('type', parameters('type')))]" + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the Integration Runtime was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the Integration Runtime." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Integration Runtime." + }, + "value": "[resourceId('Microsoft.Synapse/workspaces/integrationRuntimes', parameters('workspaceName'), parameters('name'))]" + } + } + } + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_cmk_rbac": { + "condition": "[parameters('encryptionActivateWorkspace')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-cmk-rbac', parameters('name'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "workspaceIndentityPrincipalId": { + "value": "[reference('workspace', '2021-06-01', 'full').identity.principalId]" + }, + "keyvaultName": "[if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), createObject('value', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))), createObject('value', ''))]", + "usesRbacAuthorization": "[if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), createObject('value', reference('cMKKeyVault').enableRbacAuthorization), createObject('value', true()))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "16862202180408198277" + } + }, + "parameters": { + "keyvaultName": { + "type": "string" + }, + "workspaceIndentityPrincipalId": { + "type": "string" + }, + "usesRbacAuthorization": { + "type": "bool", + "defaultValue": false + } + }, + "resources": [ + { + "condition": "[parameters('usesRbacAuthorization')]", + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('keyvaultName'))]", + "name": "[guid(format('{0}-{1}-Key-Vault-Crypto-User', resourceId('Microsoft.KeyVault/vaults', parameters('keyvaultName')), parameters('workspaceIndentityPrincipalId')))]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424')]", + "principalId": "[parameters('workspaceIndentityPrincipalId')]", + "principalType": "ServicePrincipal" + } + }, + { + "condition": "[not(parameters('usesRbacAuthorization'))]", + "type": "Microsoft.KeyVault/vaults/accessPolicies", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyvaultName'), 'add')]", + "properties": { + "accessPolicies": [ + { + "permissions": { + "keys": [ + "wrapKey", + "unwrapKey", + "get" + ] + }, + "objectId": "[parameters('workspaceIndentityPrincipalId')]", + "tenantId": "[tenant().tenantId]" + } + ] + } + } + ] + } + }, + "dependsOn": [ + "cMKKeyVault", + "workspace" + ] + }, + "workspace_key": { + "condition": "[parameters('encryptionActivateWorkspace')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-cmk-activation', parameters('name'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('customerManagedKey').keyName]" + }, + "isActiveCMK": { + "value": true + }, + "keyVaultResourceId": { + "value": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]), 'Microsoft.KeyVault/vaults', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')))]" + }, + "workspaceName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "2498604793784722860" + }, + "name": "Synapse Workspaces Keys", + "description": "This module deploys a Synapse Workspaces Key.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Encryption key name." + } + }, + "workspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + } + }, + "isActiveCMK": { + "type": "bool", + "metadata": { + "description": "Required. Used to activate the workspace after a customer managed key is provided." + } + }, + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + } + }, + "resources": [ + { + "type": "Microsoft.Synapse/workspaces/keys", + "apiVersion": "2021-06-01", + "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", + "properties": { + "isActiveCMK": "[parameters('isActiveCMK')]", + "keyVaultUrl": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('keyVaultResourceId'), '/')[2], split(parameters('keyVaultResourceId'), '/')[4]), 'Microsoft.KeyVault/vaults/keys', last(split(parameters('keyVaultResourceId'), '/')), parameters('name')), '2023-02-01').keyUri]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed key." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed key." + }, + "value": "[resourceId('Microsoft.Synapse/workspaces/keys', parameters('workspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed key." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "cMKKeyVault", + "workspace", + "workspace_cmk_rbac" + ] + }, + "workspace_privateEndpoints": { + "copy": { + "name": "workspace_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-workspace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateLinkServiceConnections": { + "value": [ + { + "name": "[parameters('name')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Synapse/workspaces', parameters('name'))]", + "groupIds": [ + "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'SQL')]" + ] + } + } + ] + }, + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Synapse/workspaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), copyIndex()))]" + }, + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "manualPrivateLinkServiceConnections": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections')]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + } + }, + "template": { + "$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.23.1.45101", + "templateHash": "2821141217598568122" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private ip address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint ip address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private ip addresses of the private endpoint." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.3.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "18168683629401652671" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "workspace" + ] + } + }, + "outputs": { + "resourceID": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed Synapse Workspace." + }, + "value": "[resourceId('Microsoft.Synapse/workspaces', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed Synapse Workspace." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed Synapse Workspace." + }, + "value": "[resourceGroup().name]" + }, + "connectivityEndpoints": { + "type": "object", + "metadata": { + "description": "The workspace connectivity endpoints." + }, + "value": "[reference('workspace').connectivityEndpoints]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('workspace', '2021-06-01', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('workspace', '2021-06-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/synapse/workspace/modules/nested_cmkRbac.bicep b/avm/res/synapse/workspace/modules/nested_cmkRbac.bicep new file mode 100644 index 0000000000..1c14980eb9 --- /dev/null +++ b/avm/res/synapse/workspace/modules/nested_cmkRbac.bicep @@ -0,0 +1,40 @@ +param keyvaultName string +param workspaceIndentityPrincipalId string +param usesRbacAuthorization bool = false + +// Workspace encryption - Assign Workspace System Identity Keyvault Crypto Reader at Encryption Keyvault +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = { + name: keyvaultName +} + +// Assign RBAC role Key Vault Crypto User +resource workspace_cmk_rbac 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (usesRbacAuthorization) { + name: guid('${keyVault.id}-${workspaceIndentityPrincipalId}-Key-Vault-Crypto-User') + properties: { + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') + principalId: workspaceIndentityPrincipalId + principalType: 'ServicePrincipal' + } + scope: keyVault +} + +// Assign Acess Policy for Keys +resource workspace_cmk_accessPolicy 'Microsoft.KeyVault/vaults/accessPolicies@2022-07-01' = if (!usesRbacAuthorization) { + name: 'add' + parent: keyVault + properties: { + accessPolicies: [ + { + permissions: { + keys: [ + 'wrapKey' + 'unwrapKey' + 'get' + ] + } + objectId: workspaceIndentityPrincipalId + tenantId: tenant().tenantId + } + ] + } +} diff --git a/avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep new file mode 100644 index 0000000000..b057b0b981 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep @@ -0,0 +1,31 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..30ec5ae1be --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,58 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + location: resourceLocation + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + } +}] diff --git a/avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep new file mode 100644 index 0000000000..ef593e0e43 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep @@ -0,0 +1,66 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Key Vault to create.') +param keyVaultName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: true + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' + } + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The resource ID of the created Key Vault.') +output keyVaultResourceId string = keyVault.id + +@description('The name of the Key Vault Encryption Key.') +output keyVaultEncryptionKeyName string = keyVault::key.name + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep new file mode 100644 index 0000000000..3f52c9ae3a --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep @@ -0,0 +1,69 @@ +targetScope = 'subscription' + +metadata name = 'Using encryption with Customer-Managed-Key' +metadata description = 'This instance deploys the module using Customer-Managed-Keys using a System-Assigned Identity to access the Customer-Managed-Key secret.' + + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swensa' + +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + // 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)}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + } + encryptionActivateWorkspace: true + location: resourceLocation + } +}] diff --git a/avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep new file mode 100644 index 0000000000..6faa37afac --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep @@ -0,0 +1,87 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Key Vault to create.') +param keyVaultName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: true + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' + } + } +} + +resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-Key-Reader-RoleAssignment') + scope: keyVault::key + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + principalType: 'ServicePrincipal' + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Key Vault.') +output keyVaultResourceId string = keyVault.id + +@description('The name of the Key Vault Encryption Key.') +output keyVaultEncryptionKeyName string = keyVault::key.name + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep new file mode 100644 index 0000000000..79a8fdebb3 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep @@ -0,0 +1,69 @@ +targetScope = 'subscription' + +metadata name = 'Using encryption with Customer-Managed-Key' +metadata description = 'This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swenua' + +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + // 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)}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + } + } +}] diff --git a/avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep new file mode 100644 index 0000000000..b057b0b981 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep @@ -0,0 +1,31 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep new file mode 100644 index 0000000000..80e9d4ebdb --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep @@ -0,0 +1,64 @@ +targetScope = 'subscription' + +metadata name = 'Using managed Vnet' +metadata description = 'This instance deploys the module using a managed Vnet.' + + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swmanv' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + location: resourceLocation + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + managedVirtualNetwork: true + preventDataExfiltration: true + allowedAadTenantIdsForLinking: [ + tenant().tenantId + ] + } +}] diff --git a/avm/res/synapse/workspace/tests/e2e/max/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..52da267176 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/max/dependencies.bicep @@ -0,0 +1,92 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +var addressPrefix = '10.0.0.0/16' + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.sql.azuresynapse.net' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetworkName}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..623225fb1d --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep @@ -0,0 +1,135 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: resourceLocation + } +} + +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}03' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + initialWorkspaceAdminObjectID: nestedDependencies.outputs.managedIdentityPrincipalId + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'SQL' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + managedVirtualNetwork: true + integrationRuntimes: [ + { + type: 'SelfHosted' + name: 'shir01' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + logCategoriesAndGroups: [ + { + category: 'SynapseRbacOperations' + } + { + category: 'SynapseLinkEvent' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } +}] diff --git a/avm/res/synapse/workspace/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..7468671354 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,78 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.sql.azuresynapse.net' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetworkName}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..8eed631785 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,116 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swwaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + location: resourceLocation + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + } +} + +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}03' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'SQL' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + managedVirtualNetwork: true + integrationRuntimes: [ + { + type: 'SelfHosted' + name: 'shir01' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + logCategoriesAndGroups: [ + { + category: 'SynapseRbacOperations' + } + { + category: 'SynapseLinkEvent' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/synapse/workspace/version.json b/avm/res/synapse/workspace/version.json new file mode 100644 index 0000000000..83083db694 --- /dev/null +++ b/avm/res/synapse/workspace/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file diff --git a/avm/res/virtual-machine-images/image-template/README.md b/avm/res/virtual-machine-images/image-template/README.md new file mode 100644 index 0000000000..3fb6df0ff5 --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/README.md @@ -0,0 +1,903 @@ +# Virtual Machine Image Templates `[Microsoft.VirtualMachineImages/imageTemplates]` + +This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB). + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Notes](#Notes) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.VirtualMachineImages/imageTemplates` | [2022-02-14](https://learn.microsoft.com/en-us/azure/templates/Microsoft.VirtualMachineImages/2022-02-14/imageTemplates) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/virtual-machine-images/image-template:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

    + +via Bicep module + +```bicep +module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-vmiitmin' + params: { + // Required parameters + customizationSteps: [ + { + restartTimeout: '30m' + type: 'WindowsRestart' + } + ] + distributions: [ + { + imageName: 'mi-vmiitmin-001' + type: 'ManagedImage' + } + ] + imageSource: { + offer: 'Windows-10' + publisher: 'MicrosoftWindowsDesktop' + sku: 'win10-22h2-ent' + type: 'PlatformImage' + version: 'latest' + } + managedIdentities: { + userAssignedResourceIds: [ + '' + ] + } + name: 'vmiitmin001' + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "customizationSteps": { + "value": [ + { + "restartTimeout": "30m", + "type": "WindowsRestart" + } + ] + }, + "distributions": { + "value": [ + { + "imageName": "mi-vmiitmin-001", + "type": "ManagedImage" + } + ] + }, + "imageSource": { + "value": { + "offer": "Windows-10", + "publisher": "MicrosoftWindowsDesktop", + "sku": "win10-22h2-ent", + "type": "PlatformImage", + "version": "latest" + } + }, + "managedIdentities": { + "value": { + "userAssignedResourceIds": [ + "" + ] + } + }, + "name": { + "value": "vmiitmin001" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
    +

    + +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-vmiitmax' + params: { + // Required parameters + customizationSteps: [ + { + name: 'PowerShell installation' + scriptUri: '' + type: 'Shell' + } + { + destination: 'Initialize-LinuxSoftware.ps1' + name: 'Initialize-LinuxSoftware' + sourceUri: '' + type: 'File' + } + { + inline: [ + 'pwsh \'Initialize-LinuxSoftware.ps1\'' + ] + name: 'Software installation' + type: 'Shell' + } + ] + distributions: [ + { + imageName: 'mi-vmiitmax-001' + type: 'ManagedImage' + } + { + imageName: 'umi-vmiitmax-001' + type: 'VHD' + } + { + replicationRegions: [ + '' + ] + sharedImageGalleryImageDefinitionResourceId: '' + sharedImageGalleryImageDefinitionTargetVersion: '' + type: 'SharedImage' + } + ] + imageSource: { + offer: '0001-com-ubuntu-server-lunar' + publisher: 'canonical' + sku: '23_04-gen2' + type: 'PlatformImage' + version: 'latest' + } + managedIdentities: { + userAssignedResourceIds: [ + '' + ] + } + name: 'vmiitmax001' + // Non-required parameters + buildTimeoutInMinutes: 60 + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + osDiskSizeGB: 127 + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + stagingResourceGroup: '' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + vmSize: 'Standard_D2s_v3' + vmUserAssignedIdentities: [ + '' + ] + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "customizationSteps": { + "value": [ + { + "name": "PowerShell installation", + "scriptUri": "", + "type": "Shell" + }, + { + "destination": "Initialize-LinuxSoftware.ps1", + "name": "Initialize-LinuxSoftware", + "sourceUri": "", + "type": "File" + }, + { + "inline": [ + "pwsh \"Initialize-LinuxSoftware.ps1\"" + ], + "name": "Software installation", + "type": "Shell" + } + ] + }, + "distributions": { + "value": [ + { + "imageName": "mi-vmiitmax-001", + "type": "ManagedImage" + }, + { + "imageName": "umi-vmiitmax-001", + "type": "VHD" + }, + { + "replicationRegions": [ + "" + ], + "sharedImageGalleryImageDefinitionResourceId": "", + "sharedImageGalleryImageDefinitionTargetVersion": "", + "type": "SharedImage" + } + ] + }, + "imageSource": { + "value": { + "offer": "0001-com-ubuntu-server-lunar", + "publisher": "canonical", + "sku": "23_04-gen2", + "type": "PlatformImage", + "version": "latest" + } + }, + "managedIdentities": { + "value": { + "userAssignedResourceIds": [ + "" + ] + } + }, + "name": { + "value": "vmiitmax001" + }, + // Non-required parameters + "buildTimeoutInMinutes": { + "value": 60 + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "osDiskSizeGB": { + "value": 127 + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "stagingResourceGroup": { + "value": "" + }, + "subnetResourceId": { + "value": "" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "vmSize": { + "value": "Standard_D2s_v3" + }, + "vmUserAssignedIdentities": { + "value": [ + "" + ] + } + } +} +``` + +
    +

    + +### Example 3: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-vmiitwaf' + params: { + // Required parameters + customizationSteps: [ + { + restartTimeout: '10m' + type: 'WindowsRestart' + } + ] + distributions: [ + { + sharedImageGalleryImageDefinitionResourceId: '' + type: 'SharedImage' + } + ] + imageSource: { + offer: 'Windows-11' + publisher: 'MicrosoftWindowsDesktop' + sku: 'win11-22h2-avd' + type: 'PlatformImage' + version: 'latest' + } + managedIdentities: { + userAssignedResourceIds: [ + '' + ] + } + name: 'vmiitwaf001' + // Non-required parameters + location: '' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
    +

    + +

    + +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "customizationSteps": { + "value": [ + { + "restartTimeout": "10m", + "type": "WindowsRestart" + } + ] + }, + "distributions": { + "value": [ + { + "sharedImageGalleryImageDefinitionResourceId": "", + "type": "SharedImage" + } + ] + }, + "imageSource": { + "value": { + "offer": "Windows-11", + "publisher": "MicrosoftWindowsDesktop", + "sku": "win11-22h2-avd", + "type": "PlatformImage", + "version": "latest" + } + }, + "managedIdentities": { + "value": { + "userAssignedResourceIds": [ + "" + ] + } + }, + "name": { + "value": "vmiitwaf001" + }, + // Non-required parameters + "location": { + "value": "" + }, + "subnetResourceId": { + "value": "" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
    +

    + + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`customizationSteps`](#parameter-customizationsteps) | array | Customization steps to be run when building the VM image. | +| [`distributions`](#parameter-distributions) | array | The distribution targets where the image output needs to go to. | +| [`imageSource`](#parameter-imagesource) | object | Image source definition in object format. | +| [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. | +| [`name`](#parameter-name) | string | Name prefix of the Image Template to be built by the Azure Image Builder service. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`buildTimeoutInMinutes`](#parameter-buildtimeoutinminutes) | int | Image build timeout in minutes. 0 means the default 240 minutes. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`location`](#parameter-location) | string | Location for all resources. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`osDiskSizeGB`](#parameter-osdisksizegb) | int | Specifies the size of OS disk. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`stagingResourceGroup`](#parameter-stagingresourcegroup) | string | Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

    If this field is empty, a resource group with a random name will be created.

    If the resource group specified in this field doesn't exist, it will be created with the same name.

    If the resource group specified exists, it must be empty and in the same region as the image template.

    The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn't exist,

    but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain. | +| [`subnetResourceId`](#parameter-subnetresourceid) | string | Resource ID of an already existing subnet, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/.

    If no value is provided, a new temporary VNET and subnet will be created in the staging resource group and will be deleted along with the remaining temporary resources. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`vmSize`](#parameter-vmsize) | string | Specifies the size for the VM. | +| [`vmUserAssignedIdentities`](#parameter-vmuserassignedidentities) | array | List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts.

    Be aware, the user assigned identities specified in the \'managedIdentities\' parameter must have the \'Managed Identity Operator\' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM.

    | + +**Generated parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`baseTime`](#parameter-basetime) | string | Do not provide a value! This date value is used to generate a unique image template name. | + +### Parameter: `customizationSteps` + +Customization steps to be run when building the VM image. + +- Required: Yes +- Type: array + +### Parameter: `distributions` + +The distribution targets where the image output needs to go to. + +- Required: Yes +- Type: array + +### Parameter: `imageSource` + +Image source definition in object format. + +- Required: Yes +- Type: object + +### Parameter: `managedIdentities` + +The managed identity definition for this resource. + +- Required: Yes +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | + +### Parameter: `managedIdentities.userAssignedResourceIds` + +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. + +- Required: Yes +- Type: array + +### Parameter: `name` + +Name prefix of the Image Template to be built by the Azure Image Builder service. + +- Required: Yes +- Type: string + +### Parameter: `buildTimeoutInMinutes` + +Image build timeout in minutes. 0 means the default 240 minutes. + +- Required: No +- Type: int +- Default: `0` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `location` + +Location for all resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `osDiskSizeGB` + +Specifies the size of OS disk. + +- Required: No +- Type: int +- Default: `128` + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `stagingResourceGroup` + +Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

    If this field is empty, a resource group with a random name will be created.

    If the resource group specified in this field doesn't exist, it will be created with the same name.

    If the resource group specified exists, it must be empty and in the same region as the image template.

    The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn't exist,

    but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain. + +- Required: No +- Type: string + +### Parameter: `subnetResourceId` + +Resource ID of an already existing subnet, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/.

    If no value is provided, a new temporary VNET and subnet will be created in the staging resource group and will be deleted along with the remaining temporary resources. + +- Required: No +- Type: string + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `vmSize` + +Specifies the size for the VM. + +- Required: No +- Type: string +- Default: `'Standard_D2s_v3'` + +### Parameter: `vmUserAssignedIdentities` + +List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts.

    Be aware, the user assigned identities specified in the \'managedIdentities\' parameter must have the \'Managed Identity Operator\' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM.

    + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `baseTime` + +Do not provide a value! This date value is used to generate a unique image template name. + +- Required: No +- Type: string +- Default: `[utcNow('yyyy-MM-dd-HH-mm-ss')]` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The full name of the deployed image template. | +| `namePrefix` | string | The prefix of the image template name provided as input. | +| `resourceGroupName` | string | The resource group the image template was deployed into. | +| `resourceId` | string | The resource ID of the image template. | +| `runThisCommand` | string | The command to run in order to trigger the image build. | + +## Cross-referenced modules + +_None_ + +## Notes + +### Parameter Usage: `imageSource` + +Tag names and tag values can be provided as needed. A tag can be left without a value. + +#### Platform Image + +

    + +Parameter JSON format + +```json +"source": { + "type": "PlatformImage", + "publisher": "MicrosoftWindowsDesktop", + "offer": "Windows-10", + "sku": "19h2-evd", + "version": "latest" +} +``` + +
    + +
    + +Bicep format + +```bicep +source: { + type: 'PlatformImage' + publisher: 'MicrosoftWindowsDesktop' + offer: 'Windows-10' + sku: '19h2-evd' + version: 'latest' +} +``` + +
    +

    + +#### Managed Image + +

    + +Parameter JSON format + +```json +"source": { + "type": "ManagedImage", + "imageId": "/subscriptions//resourceGroups/{destinationResourceGroupName}/providers/Microsoft.Compute/images/" +} +``` + +
    + +
    + +Bicep format + +```bicep +source: { + type: 'ManagedImage' + imageId: '/subscriptions//resourceGroups/{destinationResourceGroupName}/providers/Microsoft.Compute/images/' +} +``` + +
    +

    + +#### Shared Image + +

    + +Parameter JSON format + +```json +"source": { + "type": "SharedImageVersion", + "imageVersionID": "/subscriptions//resourceGroups//providers/Microsoft.Compute/galleries//images/" +} +``` + +
    + +
    + +Bicep format + +```bicep +source: { + type: 'SharedImageVersion' + imageVersionID: '/subscriptions//resourceGroups//providers/Microsoft.Compute/galleries//images/' +} +``` + +
    +

    + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/virtual-machine-images/image-template/main.bicep b/avm/res/virtual-machine-images/image-template/main.bicep new file mode 100644 index 0000000000..dd1bd68eb7 --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/main.bicep @@ -0,0 +1,289 @@ +metadata name = 'Virtual Machine Image Templates' +metadata description = 'This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB).' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Name prefix of the Image Template to be built by the Azure Image Builder service.') +param name string + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@description('Optional. Image build timeout in minutes. 0 means the default 240 minutes.') +@minValue(0) +@maxValue(960) +param buildTimeoutInMinutes int = 0 + +@description('Optional. Specifies the size for the VM.') +param vmSize string = 'Standard_D2s_v3' + +@description('Optional. Specifies the size of OS disk.') +param osDiskSizeGB int = 128 + +@description('Optional. Resource ID of an already existing subnet, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/.

    If no value is provided, a new temporary VNET and subnet will be created in the staging resource group and will be deleted along with the remaining temporary resources.') +param subnetResourceId string? + +@description('Required. Image source definition in object format.') +param imageSource object + +@description('Required. Customization steps to be run when building the VM image.') +param customizationSteps array + +@description('Optional. Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

    If this field is empty, a resource group with a random name will be created.

    If the resource group specified in this field doesn\'t exist, it will be created with the same name.

    If the resource group specified exists, it must be empty and in the same region as the image template.

    The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn\'t exist,

    but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain.') +param stagingResourceGroup string? + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Generated. Do not provide a value! This date value is used to generate a unique image template name.') +param baseTime string = utcNow('yyyy-MM-dd-HH-mm-ss') + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Required. The distribution targets where the image output needs to go to.') +param distributions distributionType[] + +@description(''' +Optional. List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts. +Be aware, the user assigned identities specified in the \'managedIdentities\' parameter must have the \'Managed Identity Operator\' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM. +''') +param vmUserAssignedIdentities array = [] + +@description('Required. The managed identity definition for this resource.') +param managedIdentities managedIdentitiesType + +var identity = { + type: 'UserAssigned' + userAssignedIdentities: reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } +} + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.virtualmachineimages-imagetemplate.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource imageTemplate 'Microsoft.VirtualMachineImages/imageTemplates@2022-02-14' = { + #disable-next-line use-stable-resource-identifiers // Disabling as ImageTemplates are not idempotent and hence always must have new name + name: '${name}-${baseTime}' + location: location + tags: tags + identity: identity + properties: { + buildTimeoutInMinutes: buildTimeoutInMinutes + vmProfile: { + vmSize: vmSize + osDiskSizeGB: osDiskSizeGB + userAssignedIdentities: vmUserAssignedIdentities + vnetConfig: !empty(subnetResourceId) ? { + subnetId: subnetResourceId + } : null + } + source: imageSource + customize: customizationSteps + stagingResourceGroup: stagingResourceGroup + distribute: [for distribution in distributions: union({ + type: distribution.type + artifactTags: distribution.?artifactTags ?? { + sourceType: imageSource.type + sourcePublisher: imageSource.?publisher + sourceOffer: imageSource.?offer + sourceSku: imageSource.?sku + sourceVersion: imageSource.?version + sourceImageId: imageSource.?imageId + sourceImageVersionID: imageSource.?imageVersionID + creationTime: baseTime + } + }, + (distribution.type == 'ManagedImage' ? { + runOutputName: distribution.?runOutputName ?? '${distribution.imageName}-${baseTime}-ManagedImage' + location: distribution.?location ?? location + #disable-next-line use-resource-id-functions // Disabling rule as this is an input parameter that is used inside an array. + imageId: distribution.?imageResourceId ?? '${subscription().id}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Compute/images/${distribution.imageName}-${baseTime}' + } : {}), + (distribution.type == 'SharedImage' ? { + runOutputName: distribution.?runOutputName ?? (!empty(distribution.?sharedImageGalleryImageDefinitionResourceId) ? '${last(split((distribution.sharedImageGalleryImageDefinitionResourceId ?? '/'), '/'))}-SharedImage' : 'SharedImage') + galleryImageId: !empty(distribution.?sharedImageGalleryImageDefinitionTargetVersion) ? '${distribution.sharedImageGalleryImageDefinitionResourceId}/versions/${distribution.sharedImageGalleryImageDefinitionTargetVersion}' : distribution.sharedImageGalleryImageDefinitionResourceId + excludeFromLatest: distribution.?excludeFromLatest ?? false + replicationRegions: distribution.?replicationRegions ?? [ location ] + storageAccountType: distribution.?storageAccountType ?? 'Standard_LRS' + } : {}), + (distribution.type == 'VHD' ? { + runOutputName: distribution.?runOutputName ?? '${distribution.imageName}-VHD' + } : {}) + )] + } +} + +resource imageTemplate_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: imageTemplate +} + +resource imageTemplate_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(imageTemplate.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: imageTemplate +}] + +@description('The resource ID of the image template.') +output resourceId string = imageTemplate.id + +@description('The resource group the image template was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The full name of the deployed image template.') +output name string = imageTemplate.name + +@description('The prefix of the image template name provided as input.') +output namePrefix string = name + +@description('The command to run in order to trigger the image build.') +output runThisCommand string = 'Invoke-AzResourceAction -ResourceName ${imageTemplate.name} -ResourceGroupName ${resourceGroup().name} -ResourceType Microsoft.VirtualMachineImages/imageTemplates -Action Run -Force' + +@description('The location the resource was deployed into.') +output location string = imageTemplate.location + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? + +type managedIdentitiesType = { + @description('Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption.') + userAssignedResourceIds: string[] +} + +@discriminator('type') +type distributionType = sharedImageDistributionType | managedImageDistributionType | unManagedDistributionType + +type sharedImageDistributionType = { + + @description('Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated.') + runOutputName: string? + + @description('Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source.') + artifactTags: object? + + @description('Required. The type of distribution.') + type: 'SharedImage' + + @description('Conditional. Resource ID of Compute Gallery Image Definition to distribute image to, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Compute/galleries//images/.') + sharedImageGalleryImageDefinitionResourceId: string + + @description('Optional. Version of the Compute Gallery Image. Supports the following Version Syntax: Major.Minor.Build (i.e., \'1.1.1\' or \'10.1.2\'). If not provided, a version will be calculated.') + sharedImageGalleryImageDefinitionTargetVersion: string? + + @description('Optional. The exclude from latest flag of the image. Defaults to [false].') + excludeFromLatest: bool? + + @description('Optional. The replication regions of the image. Defaults to the value of the \'location\' parameter.') + replicationRegions: string[]? + + @description('Optional. The storage account type of the image. Defaults to [Standard_LRS].') + storageAccountType: ('Standard_LRS' | 'Standard_ZRS')? +} + +type unManagedDistributionType = { + + @description('Required. The type of distribution.') + type: 'VHD' + + @description('Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated.') + runOutputName: string? + + @description('Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source.') + artifactTags: object? + + @description('Conditional. Name of the managed or unmanaged image that will be created.') + imageName: string +} + +type managedImageDistributionType = { + + @description('Required. The type of distribution.') + type: 'ManagedImage' + + @description('Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated.') + runOutputName: string? + + @description('Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source.') + artifactTags: object? + + @description('Optional. Azure location for the image, should match if image already exists. Defaults to the value of the \'location\' parameter.') + location: string? + + @description('Required. The resource ID of the managed image. Defaults to a compute image with name \'imageName-baseTime\' in the current resource group.') + imageResourceId: string? + + @description('Conditional. Name of the managed or unmanaged image that will be created..') + imageName: string +} diff --git a/avm/res/virtual-machine-images/image-template/main.json b/avm/res/virtual-machine-images/image-template/main.json new file mode 100644 index 0000000000..8cc320f399 --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/main.json @@ -0,0 +1,551 @@ +{ + "$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.25.53.49325", + "templateHash": "17204586034528334587" + }, + "name": "Virtual Machine Image Templates", + "description": "This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB).", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "managedIdentitiesType": { + "type": "object", + "properties": { + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." + } + } + } + }, + "distributionType": { + "type": "object", + "discriminator": { + "propertyName": "type", + "mapping": { + "SharedImage": { + "$ref": "#/definitions/sharedImageDistributionType" + }, + "ManagedImage": { + "$ref": "#/definitions/managedImageDistributionType" + }, + "VHD": { + "$ref": "#/definitions/unManagedDistributionType" + } + } + } + }, + "sharedImageDistributionType": { + "type": "object", + "properties": { + "runOutputName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated." + } + }, + "artifactTags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source." + } + }, + "type": { + "type": "string", + "allowedValues": [ + "SharedImage" + ], + "metadata": { + "description": "Required. The type of distribution." + } + }, + "sharedImageGalleryImageDefinitionResourceId": { + "type": "string", + "metadata": { + "description": "Conditional. Resource ID of Compute Gallery Image Definition to distribute image to, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Compute/galleries//images/." + } + }, + "sharedImageGalleryImageDefinitionTargetVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Version of the Compute Gallery Image. Supports the following Version Syntax: Major.Minor.Build (i.e., '1.1.1' or '10.1.2'). If not provided, a version will be calculated." + } + }, + "excludeFromLatest": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. The exclude from latest flag of the image. Defaults to [false]." + } + }, + "replicationRegions": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The replication regions of the image. Defaults to the value of the 'location' parameter." + } + }, + "storageAccountType": { + "type": "string", + "allowedValues": [ + "Standard_LRS", + "Standard_ZRS" + ], + "nullable": true, + "metadata": { + "description": "Optional. The storage account type of the image. Defaults to [Standard_LRS]." + } + } + } + }, + "unManagedDistributionType": { + "type": "object", + "properties": { + "type": { + "type": "string", + "allowedValues": [ + "VHD" + ], + "metadata": { + "description": "Required. The type of distribution." + } + }, + "runOutputName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated." + } + }, + "artifactTags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source." + } + }, + "imageName": { + "type": "string", + "metadata": { + "description": "Conditional. Name of the managed or unmanaged image that will be created." + } + } + } + }, + "managedImageDistributionType": { + "type": "object", + "properties": { + "type": { + "type": "string", + "allowedValues": [ + "ManagedImage" + ], + "metadata": { + "description": "Required. The type of distribution." + } + }, + "runOutputName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated." + } + }, + "artifactTags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Azure location for the image, should match if image already exists. Defaults to the value of the 'location' parameter." + } + }, + "imageResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. The resource ID of the managed image. Defaults to a compute image with name 'imageName-baseTime' in the current resource group." + } + }, + "imageName": { + "type": "string", + "metadata": { + "description": "Conditional. Name of the managed or unmanaged image that will be created.." + } + } + } + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name prefix of the Image Template to be built by the Azure Image Builder service." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "buildTimeoutInMinutes": { + "type": "int", + "defaultValue": 0, + "minValue": 0, + "maxValue": 960, + "metadata": { + "description": "Optional. Image build timeout in minutes. 0 means the default 240 minutes." + } + }, + "vmSize": { + "type": "string", + "defaultValue": "Standard_D2s_v3", + "metadata": { + "description": "Optional. Specifies the size for the VM." + } + }, + "osDiskSizeGB": { + "type": "int", + "defaultValue": 128, + "metadata": { + "description": "Optional. Specifies the size of OS disk." + } + }, + "subnetResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of an already existing subnet, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/.

    If no value is provided, a new temporary VNET and subnet will be created in the staging resource group and will be deleted along with the remaining temporary resources." + } + }, + "imageSource": { + "type": "object", + "metadata": { + "description": "Required. Image source definition in object format." + } + }, + "customizationSteps": { + "type": "array", + "metadata": { + "description": "Required. Customization steps to be run when building the VM image." + } + }, + "stagingResourceGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

    If this field is empty, a resource group with a random name will be created.

    If the resource group specified in this field doesn't exist, it will be created with the same name.

    If the resource group specified exists, it must be empty and in the same region as the image template.

    The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn't exist,

    but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "baseTime": { + "type": "string", + "defaultValue": "[utcNow('yyyy-MM-dd-HH-mm-ss')]", + "metadata": { + "description": "Generated. Do not provide a value! This date value is used to generate a unique image template name." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "distributions": { + "type": "array", + "items": { + "$ref": "#/definitions/distributionType" + }, + "metadata": { + "description": "Required. The distribution targets where the image output needs to go to." + } + }, + "vmUserAssignedIdentities": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts.\nBe aware, the user assigned identities specified in the \\'managedIdentities\\' parameter must have the \\'Managed Identity Operator\\' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM.\n" + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Required. The managed identity definition for this resource." + } + } + }, + "variables": { + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]" + }, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.virtualmachineimages-imagetemplate.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "imageTemplate": { + "type": "Microsoft.VirtualMachineImages/imageTemplates", + "apiVersion": "2022-02-14", + "name": "[format('{0}-{1}', parameters('name'), parameters('baseTime'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "identity": "[variables('identity')]", + "properties": { + "copy": [ + { + "name": "distribute", + "count": "[length(parameters('distributions'))]", + "input": "[union(createObject('type', parameters('distributions')[copyIndex('distribute')].type, 'artifactTags', coalesce(tryGet(parameters('distributions')[copyIndex('distribute')], 'artifactTags'), createObject('sourceType', parameters('imageSource').type, 'sourcePublisher', tryGet(parameters('imageSource'), 'publisher'), 'sourceOffer', tryGet(parameters('imageSource'), 'offer'), 'sourceSku', tryGet(parameters('imageSource'), 'sku'), 'sourceVersion', tryGet(parameters('imageSource'), 'version'), 'sourceImageId', tryGet(parameters('imageSource'), 'imageId'), 'sourceImageVersionID', tryGet(parameters('imageSource'), 'imageVersionID'), 'creationTime', parameters('baseTime')))), if(equals(parameters('distributions')[copyIndex('distribute')].type, 'ManagedImage'), createObject('runOutputName', coalesce(tryGet(parameters('distributions')[copyIndex('distribute')], 'runOutputName'), format('{0}-{1}-ManagedImage', parameters('distributions')[copyIndex('distribute')].imageName, parameters('baseTime'))), 'location', coalesce(tryGet(parameters('distributions')[copyIndex('distribute')], 'location'), parameters('location')), 'imageId', coalesce(tryGet(parameters('distributions')[copyIndex('distribute')], 'imageResourceId'), format('{0}/resourceGroups/{1}/providers/Microsoft.Compute/images/{2}-{3}', subscription().id, resourceGroup().name, parameters('distributions')[copyIndex('distribute')].imageName, parameters('baseTime')))), createObject()), if(equals(parameters('distributions')[copyIndex('distribute')].type, 'SharedImage'), createObject('runOutputName', coalesce(tryGet(parameters('distributions')[copyIndex('distribute')], 'runOutputName'), if(not(empty(tryGet(parameters('distributions')[copyIndex('distribute')], 'sharedImageGalleryImageDefinitionResourceId'))), format('{0}-SharedImage', last(split(coalesce(parameters('distributions')[copyIndex('distribute')].sharedImageGalleryImageDefinitionResourceId, '/'), '/'))), 'SharedImage')), 'galleryImageId', if(not(empty(tryGet(parameters('distributions')[copyIndex('distribute')], 'sharedImageGalleryImageDefinitionTargetVersion'))), format('{0}/versions/{1}', parameters('distributions')[copyIndex('distribute')].sharedImageGalleryImageDefinitionResourceId, parameters('distributions')[copyIndex('distribute')].sharedImageGalleryImageDefinitionTargetVersion), parameters('distributions')[copyIndex('distribute')].sharedImageGalleryImageDefinitionResourceId), 'excludeFromLatest', coalesce(tryGet(parameters('distributions')[copyIndex('distribute')], 'excludeFromLatest'), false()), 'replicationRegions', coalesce(tryGet(parameters('distributions')[copyIndex('distribute')], 'replicationRegions'), createArray(parameters('location'))), 'storageAccountType', coalesce(tryGet(parameters('distributions')[copyIndex('distribute')], 'storageAccountType'), 'Standard_LRS')), createObject()), if(equals(parameters('distributions')[copyIndex('distribute')].type, 'VHD'), createObject('runOutputName', coalesce(tryGet(parameters('distributions')[copyIndex('distribute')], 'runOutputName'), format('{0}-VHD', parameters('distributions')[copyIndex('distribute')].imageName))), createObject()))]" + } + ], + "buildTimeoutInMinutes": "[parameters('buildTimeoutInMinutes')]", + "vmProfile": { + "vmSize": "[parameters('vmSize')]", + "osDiskSizeGB": "[parameters('osDiskSizeGB')]", + "userAssignedIdentities": "[parameters('vmUserAssignedIdentities')]", + "vnetConfig": "[if(not(empty(parameters('subnetResourceId'))), createObject('subnetId', parameters('subnetResourceId')), null())]" + }, + "source": "[parameters('imageSource')]", + "customize": "[parameters('customizationSteps')]", + "stagingResourceGroup": "[parameters('stagingResourceGroup')]" + } + }, + "imageTemplate_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "imageTemplate" + ] + }, + "imageTemplate_roleAssignments": { + "copy": { + "name": "imageTemplate_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]", + "name": "[guid(resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime'))), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "imageTemplate" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the image template." + }, + "value": "[resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime')))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the image template was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The full name of the deployed image template." + }, + "value": "[format('{0}-{1}', parameters('name'), parameters('baseTime'))]" + }, + "namePrefix": { + "type": "string", + "metadata": { + "description": "The prefix of the image template name provided as input." + }, + "value": "[parameters('name')]" + }, + "runThisCommand": { + "type": "string", + "metadata": { + "description": "The command to run in order to trigger the image build." + }, + "value": "[format('Invoke-AzResourceAction -ResourceName {0} -ResourceGroupName {1} -ResourceType Microsoft.VirtualMachineImages/imageTemplates -Action Run -Force', format('{0}-{1}', parameters('name'), parameters('baseTime')), resourceGroup().name)]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('imageTemplate', '2022-02-14', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/virtual-machine-images/image-template/tests/e2e/defaults/dependencies.bicep b/avm/res/virtual-machine-images/image-template/tests/e2e/defaults/dependencies.bicep new file mode 100644 index 0000000000..5de1a5cc92 --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/tests/e2e/defaults/dependencies.bicep @@ -0,0 +1,22 @@ +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource msi_roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, 'Contributor', managedIdentityName) + properties: { + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + principalId: managedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } +} + +@description('The resource Id of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id diff --git a/avm/res/virtual-machine-images/image-template/tests/e2e/defaults/main.test.bicep b/avm/res/virtual-machine-images/image-template/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..9ead9906b8 --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,80 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-virtualmachineimages.imagetemplates-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'vmiitmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + location: resourceLocation + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // +// No idempotency test as the resource is, by design, not idempotent. +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + customizationSteps: [ + { + restartTimeout: '30m' + type: 'WindowsRestart' + } + ] + imageSource: { + offer: 'Windows-10' + publisher: 'MicrosoftWindowsDesktop' + sku: 'win10-22h2-ent' + type: 'PlatformImage' + version: 'latest' + } + + distributions: [ + { + imageName: '${namePrefix}-mi-${serviceShort}-001' + type: 'ManagedImage' + } + ] + + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + } +} diff --git a/avm/res/virtual-machine-images/image-template/tests/e2e/max/dependencies.bicep b/avm/res/virtual-machine-images/image-template/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..3333148724 --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/tests/e2e/max/dependencies.bicep @@ -0,0 +1,308 @@ +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Required. The name of the Shared Image Gallery to create.') +param galleryName string + +@description('Required. The name of the Image Definition to create in the Shared Image Gallery.') +param sigImageDefinitionName string + +@description('Required. The name of the Image Managed Identity to create.') +param imageManagedIdentityName string + +@description('Required. The name of the Deployment Script Managed Identity to create.') +param deploymentScriptManagedIdentityName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Optional. The name of the Image Virtual Network Subnet to create.') +param imageSubnetName string = 'imageSubnet' + +@description('Optional. The name of the Deployment Script Virtual Network Subnet to create.') +param deploymentScriptSubnetName string = 'deploymentScriptSubnet' + +@description('Required. The name of the Assets Storage Account to create.') +param assetStorageAccountkName string + +@description('Required. The name of the Deployment Script Storage Account to create.') +param deploymentScriptStorageAccountkName string + +@description('Required. The name of the Deployment Script used to upload files to the Assets Storage Account.') +param storageDeploymentScriptName string + +resource imageManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: imageManagedIdentityName + location: location +} + +resource deploymentScriptManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: deploymentScriptManagedIdentityName + location: location +} + +var addressPrefix = '10.0.0.0/16' + +// Roles +resource contributorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + name: 'b24988ac-6180-42a0-ab88-20f7382dd24c' // Contributor + scope: tenant() +} +resource managedIdentityOperatorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + name: 'f1a07417-d97a-45cb-824c-7a7467783830' // Managed Identity Operator + scope: tenant() +} +resource storageFileDataPrivilegedContributorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + name: '69566ab7-960f-475b-8e7c-b3118f30c6bd' // Storage File Data Priveleged Contributor + scope: tenant() +} +resource storageBlobDataReaderRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + name: '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' // Storage Blob Data Reader + scope: tenant() +} +resource storageBlobDataContributorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + name: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' // Storage Blob Data Contributor + scope: tenant() +} + +// Resources +resource gallery 'Microsoft.Compute/galleries@2022-03-03' = { + name: galleryName + location: location + properties: {} + + resource imageDefinition 'images@2022-03-03' = { + name: sigImageDefinitionName + location: location + properties: { + architecture: 'x64' + hyperVGeneration: 'V2' + identifier: { + offer: 'devops_linux' + publisher: 'devops' + sku: 'devops_linux_az' + } + osState: 'Generalized' + osType: 'Linux' + recommended: { + memory: { + max: 16 + min: 4 + } + vCPUs: { + max: 8 + min: 2 + } + } + } + } +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: imageSubnetName + properties: { + addressPrefix: cidrSubnet(addressPrefix, 24, 0) + privateLinkServiceNetworkPolicies: 'Disabled' // Required if using Azure Image Builder with existing VNET + serviceEndpoints: [ + { + service: 'Microsoft.Storage' + } + ] + } + } + { + name: deploymentScriptSubnetName + properties: { + addressPrefix: cidrSubnet(addressPrefix, 24, 1) + serviceEndpoints: [ + { + service: 'Microsoft.Storage' + } + ] + delegations: [ + { + name: 'Microsoft.ContainerInstance.containerGroups' + properties: { + serviceName: 'Microsoft.ContainerInstance/containerGroups' + } + } + ] + } + } + ] + } +} + +resource assetsStorageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = { + name: assetStorageAccountkName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + allowBlobPublicAccess: false + allowSharedKeyAccess: false + } + + resource blobService 'blobServices@2023-01-01' = { + name: 'default' + properties: {} + + resource container 'containers@2023-01-01' = { + name: 'assets' + properties: { + publicAccess: 'None' + } + } + } +} + +// Assign permissions to MSI to be allowed to distribute images. Ref: https://learn.microsoft.com/en-us/azure/virtual-machines/linux/image-builder-permissions-cli#allow-vm-image-builder-to-distribute-images +resource imageContributorRbac 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, contributorRole.id, imageManagedIdentity.id) + properties: { + roleDefinitionId: contributorRole.id + principalId: imageManagedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } +} + +// Assign permission to allow AIB to assign the list of User Assigned Identities to the Build VM. +resource imageManagedIdentityOperatorRbac 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, managedIdentityOperatorRole.id, imageManagedIdentity.id) + properties: { + roleDefinitionId: managedIdentityOperatorRole.id + principalId: imageManagedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } +} + +// Allow Deployment Script MSI to access storage account container to upload files +resource storageContributorRbac 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(assetsStorageAccount::blobService::container.id, storageBlobDataContributorRole.id, imageManagedIdentity.id) + scope: assetsStorageAccount::blobService::container + properties: { + roleDefinitionId: storageBlobDataContributorRole.id + principalId: deploymentScriptManagedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } +} + +// Allow image MSI to access storage account container to read files +resource storageReaderRbac 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(assetsStorageAccount::blobService::container.id, storageBlobDataReaderRole.id, imageManagedIdentity.id) + scope: assetsStorageAccount::blobService::container + properties: { + roleDefinitionId: storageBlobDataReaderRole.id + principalId: imageManagedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } +} + +resource dsStorageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = { + name: deploymentScriptStorageAccountkName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + allowSharedKeyAccess: true // May not be disabled to allow deployment script to access storage account files + networkAcls: { + bypass: 'AzureServices' + defaultAction: 'Deny' + virtualNetworkRules: [ + { + // Allow deployment script to use storage account for private networking of container instance + action: 'Allow' + id: resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Network/virtualNetworks/subnets', virtualNetwork.name, deploymentScriptSubnetName) + } + ] + } + } +} + +// Allow Deployment Script MSI to access storage account to upload files +resource storageFileContributorRbac 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(dsStorageAccount.id, storageFileDataPrivilegedContributorRole.id, deploymentScriptManagedIdentity.id) + scope: dsStorageAccount + properties: { + roleDefinitionId: storageFileDataPrivilegedContributorRole.id + principalId: deploymentScriptManagedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } +} + +// Upload storage account files +resource assetsStorageAccount_upload 'Microsoft.Resources/deploymentScripts@2023-08-01' = { + name: storageDeploymentScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${deploymentScriptManagedIdentity.id}': {} + } + } + properties: { + azPowerShellVersion: '9.7' + retentionInterval: 'P1D' + scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Set-StorageContainerContentByEnvVar.ps1') + environmentVariables: [ + { + name: 'script_Install__LinuxPowerShell_sh' // May only be alphanumeric characters & underscores. The upload will replace '_' with '.' and '__' with '-'. + value: loadTextContent('src/Install-LinuxPowerShell.sh') + } + { + name: 'script_Initialize__LinuxSoftware_ps1' // May only be alphanumeric characters & underscores. The upload will replace '_' with '.' and '__' with '-'. + value: loadTextContent('src/Initialize-LinuxSoftware.ps1') + } + ] + arguments: ' -StorageAccountName "${assetsStorageAccount.name}" -TargetContainer "${assetsStorageAccount::blobService::container.name}"' + timeout: 'PT30M' + cleanupPreference: 'Always' + storageAccountSettings: { + storageAccountName: dsStorageAccount.name + } + containerSettings: { + subnetIds: [ + { + id: resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Network/virtualNetworks/subnets', virtualNetwork.name, deploymentScriptSubnetName) + } + ] + } + } + dependsOn: [ + storageContributorRbac + storageFileContributorRbac + ] +} + +@description('The principal ID of the created Image Managed Identity.') +output managedIdentityResourceId string = imageManagedIdentity.id + +@description('The principal ID of the created Image Managed Identity.') +output managedIdentityPrincipalId string = imageManagedIdentity.properties.principalId + +@description('The resource ID of the created Image Definition.') +output sigImageDefinitionId string = gallery::imageDefinition.id + +@description('The subnet resource id of the defaultSubnet of the created Virtual Network.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The blob endpoint of the created Assets Storage Account.') +output assetsStorageAccountNameBlobEndpoint string = assetsStorageAccount.properties.primaryEndpoints.blob + +@description('The name of the created Assets Storage Account Container.') +output assetsStorageAccountContainerName string = assetsStorageAccount::blobService::container.name diff --git a/avm/res/virtual-machine-images/image-template/tests/e2e/max/main.test.bicep b/avm/res/virtual-machine-images/image-template/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..8de9388d3d --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/tests/e2e/max/main.test.bicep @@ -0,0 +1,151 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-virtualmachineimages.imagetemplates-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'vmiitmax' + +@description('Optional. The version of the Azure Compute Gallery Image Definition to be added.') +param sigImageVersion string = utcNow('yyyy.MM.dd') + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + location: resourceLocation + imageManagedIdentityName: 'dep-${namePrefix}-imsi-${serviceShort}' + deploymentScriptManagedIdentityName: 'dep-${namePrefix}-dmsi-${serviceShort}' + sigImageDefinitionName: 'dep-${namePrefix}-imgd-${serviceShort}' + galleryName: 'dep${namePrefix}sig${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + assetStorageAccountkName: 'dep${namePrefix}ast${serviceShort}' + deploymentScriptStorageAccountkName: 'dep${namePrefix}dst${serviceShort}' + storageDeploymentScriptName: 'dep-${namePrefix}-ds-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // +// No idempotency test as the resource is, by design, not idempotent. +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + stagingResourceGroup: '${subscription().id}/resourcegroups/${resourceGroupName}-staging' + customizationSteps: [ + { + type: 'Shell' + name: 'PowerShell installation' + scriptUri: '${nestedDependencies.outputs.assetsStorageAccountNameBlobEndpoint}${nestedDependencies.outputs.assetsStorageAccountContainerName}/Install-LinuxPowerShell.sh' + } + { + type: 'File' + name: 'Initialize-LinuxSoftware' + sourceUri: '${nestedDependencies.outputs.assetsStorageAccountNameBlobEndpoint}${nestedDependencies.outputs.assetsStorageAccountContainerName}/Initialize-LinuxSoftware.ps1' + destination: 'Initialize-LinuxSoftware.ps1' + } + { + type: 'Shell' + name: 'Software installation' + inline: [ + 'pwsh \'Initialize-LinuxSoftware.ps1\'' + ] + } + ] + imageSource: { + type: 'PlatformImage' + publisher: 'canonical' + offer: '0001-com-ubuntu-server-lunar' + sku: '23_04-gen2' + version: 'latest' + } + buildTimeoutInMinutes: 60 + subnetResourceId: nestedDependencies.outputs.subnetResourceId + osDiskSizeGB: 127 + vmSize: 'Standard_D2s_v3' + distributions: [ + { + type: 'ManagedImage' + imageName: '${namePrefix}-mi-${serviceShort}-001' + } + { + type: 'VHD' + imageName: '${namePrefix}-umi-${serviceShort}-001' + } + { + type: 'SharedImage' + sharedImageGalleryImageDefinitionResourceId: nestedDependencies.outputs.sigImageDefinitionId + sharedImageGalleryImageDefinitionTargetVersion: sigImageVersion + replicationRegions: [ + resourceLocation + ] + } + ] + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + vmUserAssignedIdentities: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +} + +@description('The generated name of the image template.') +output imageTemplateName string = testDeployment.outputs.name diff --git a/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Initialize-LinuxSoftware.ps1 b/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Initialize-LinuxSoftware.ps1 new file mode 100644 index 0000000000..6bd6d4a5ad --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Initialize-LinuxSoftware.ps1 @@ -0,0 +1,93 @@ +#region Functions +function LogInfo($message) { + Log 'Info' $message +} +function LogError($message) { + Log 'Error' $message +} +function LogWarning($message) { + Log 'Warning' $message +} + +function Log { + + <# + .SYNOPSIS + Creates a log file and stores logs based on categories with tab seperation + + .PARAMETER category + Category to put into the trace + + .PARAMETER message + Message to be loged + + .EXAMPLE + Log 'Info' 'Message' + + #> + + Param ( + [Parameter(Mandatory = $false)] + [string] $category = 'Info', + + [Parameter(Mandatory = $true)] + [string] $message + ) + + $date = Get-Date + $content = "[$date]`t$category`t`t$message`n" + Write-Verbose $Content -Verbose + + $FilePath = Join-Path ([System.IO.Path]::GetTempPath()) 'log.log' + if (-not (Test-Path $FilePath)) { + Write-Verbose "Log file not found, create new in path: [$FilePath]" -Verbose + $null = New-Item -ItemType 'File' -Path $FilePath -Force + } + Add-Content -Path $FilePath -Value $content -ErrorAction 'Stop' +} +#endregion + +$StartTime = Get-Date +$progressPreference = 'SilentlyContinue' +LogInfo('#############################################') +LogInfo('# Entering Initialize-LinuxSoftware.ps1 #') +LogInfo('#############################################') + +########################### +## Install Azure CLI ## +########################### +LogInfo('Install azure cli start') +curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash +LogInfo('Install azure cli end') + +########################## +## Install Az Bicep # +########################## +LogInfo('Install az bicep exention start') +az bicep install +LogInfo('Install az bicep exention end') + +########################### +## Install BICEP CLI ## +########################### +LogInfo('Install BICEP start') + +# Fetch the latest Bicep CLI binary +curl -Lo bicep 'https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64' +# Mark it as executable +chmod +x ./bicep +# Add bicep to your PATH (requires admin) +sudo mv ./bicep /usr/local/bin/bicep + +LogInfo('Install BICEP end') + + +$elapsedTime = (Get-Date) - $StartTime +$totalTime = '{0:HH:mm:ss}' -f ([datetime]$elapsedTime.Ticks) +LogInfo("Execution took [$totalTime]") +LogInfo('############################################') +LogInfo('# Exiting Initialize-LinuxSoftware.ps1 #') +LogInfo('############################################') + +return 0 +#endregion diff --git a/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh b/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh new file mode 100644 index 0000000000..611be69833 --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh @@ -0,0 +1,43 @@ +# Source: https://learn.microsoft.com/en-us/powershell/scripting/install/install-ubuntu?view=powershell-7.4 + +echo '###########################################' +echo '# Entering Install-LinuxPowerShell.sh #' +echo '###########################################' + +echo '1. Update the list of packages' +sudo apt-get update + +echo '2. Install pre-requisite packages' +sudo apt-get install -y wget apt-transport-https software-properties-common + +echo '3. Get the version of Ubuntu' +# . /etc/os-release - does not work (yet) for image version 23.04. The package is available, but does not contain pwsh +VERSION_ID='22.04' + +echo '4. Determine URL' +url=https://packages.microsoft.com/config/ubuntu/$VERSION_ID/packages-microsoft-prod.deb +echo " Found URL [$url]" + +echo '5. Download the Microsoft repository GPG keys' +wget -q $url + +echo '6. Register the Microsoft repository GPG keys' +sudo dpkg -i packages-microsoft-prod.deb + +echo '7. Delete the Microsoft repository keys file' +rm packages-microsoft-prod.deb + +echo '8. Update the list of products' +sudo apt-get update + +echo '9. Enable the "universe" repositories' +sudo add-apt-repository universe -y + +echo '10. Install PowerShell' +sudo apt-get install -y powershell + +echo '##########################################' +echo '# Exiting Install-LinuxPowerShell.sh #' +echo '##########################################' + +exit 0 diff --git a/avm/res/virtual-machine-images/image-template/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/virtual-machine-images/image-template/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..5869d02161 --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,121 @@ +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Required. The name of the Shared Image Gallery to create.') +param galleryName string + +@description('Required. The name of the Image Definition to create in the Shared Image Gallery.') +param sigImageDefinitionName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Optional. The name of the Virtual Network to create.') +param virtualNetworkName string + +// Roles +resource contributorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + name: 'b24988ac-6180-42a0-ab88-20f7382dd24c' // Contributor + scope: tenant() +} +resource managedIdentityOperatorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + name: 'f1a07417-d97a-45cb-824c-7a7467783830' // Managed Identity Operator + scope: tenant() +} + +// Resources +resource imageManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +var addressPrefix = '10.0.0.0/16' + +resource gallery 'Microsoft.Compute/galleries@2022-03-03' = { + name: galleryName + location: location + properties: {} +} + +resource galleryImageDefinition 'Microsoft.Compute/galleries/images@2022-03-03' = { + name: sigImageDefinitionName + location: location + parent: gallery + properties: { + architecture: 'x64' + hyperVGeneration: 'V2' + identifier: { + offer: 'Windows-11' + publisher: 'MicrosoftWindowsDesktop' + sku: 'Win11-AVD-g2' + } + osState: 'Generalized' + osType: 'Windows' + recommended: { + memory: { + max: 16 + min: 4 + } + vCPUs: { + max: 8 + min: 2 + } + } + } +} + +// Assign permissions to MSI to be allowed to distribute images. Ref: https://learn.microsoft.com/en-us/azure/virtual-machines/linux/image-builder-permissions-cli#allow-vm-image-builder-to-distribute-images +resource imageContributorRbac 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, contributorRole.id, imageManagedIdentity.id) + properties: { + roleDefinitionId: contributorRole.id + principalId: imageManagedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } +} + +// Assign permission to allow AIB to assign the list of User Assigned Identities to the Build VM. +resource imageManagedIdentityOperatorRbac 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, managedIdentityOperatorRole.id, imageManagedIdentity.id) + properties: { + roleDefinitionId: managedIdentityOperatorRole.id + principalId: imageManagedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + privateLinkServiceNetworkPolicies: 'Disabled' + } + } + ] + } +} + +@description('The principal ID of the created Managed Identity.') +output managedIdentityResourceId string = imageManagedIdentity.id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = imageManagedIdentity.properties.principalId + +@description('The name of the created Managed Identity.') +output managedIdentityName string = imageManagedIdentity.name + +@description('The resource ID of the created Image Definition.') +output sigImageDefinitionId string = galleryImageDefinition.id + +@description('The subnet resource id of the defaultSubnet of the created Virtual Network.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id diff --git a/avm/res/virtual-machine-images/image-template/tests/e2e/waf-aligned/main.test.bicep b/avm/res/virtual-machine-images/image-template/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..25528d5fd2 --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,87 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-virtualmachineimages.imagetemplates-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'vmiitwaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + location: resourceLocation + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + sigImageDefinitionName: 'dep-${namePrefix}-imgd-${serviceShort}' + galleryName: 'dep${namePrefix}sig${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // +// No idempotency test as the resource is, by design, not idempotent. +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + customizationSteps: [ + { + restartTimeout: '10m' + type: 'WindowsRestart' + } + ] + imageSource: { + offer: 'Windows-11' + publisher: 'MicrosoftWindowsDesktop' + sku: 'win11-22h2-avd' + type: 'PlatformImage' + version: 'latest' + } + subnetResourceId: nestedDependencies.outputs.subnetResourceId + distributions: [ + { + type: 'SharedImage' + sharedImageGalleryImageDefinitionResourceId: nestedDependencies.outputs.sigImageDefinitionId + } + ] + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +} diff --git a/avm/res/virtual-machine-images/image-template/version.json b/avm/res/virtual-machine-images/image-template/version.json new file mode 100644 index 0000000000..7fa401bdf7 --- /dev/null +++ b/avm/res/virtual-machine-images/image-template/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} diff --git a/avm/res/web/serverfarm/README.md b/avm/res/web/serverfarm/README.md index 285d98effc..1cf7bf6af8 100644 --- a/avm/res/web/serverfarm/README.md +++ b/avm/res/web/serverfarm/README.md @@ -464,7 +464,7 @@ The diagnostic settings of the service. | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -506,11 +506,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. diff --git a/avm/res/web/serverfarm/main.bicep b/avm/res/web/serverfarm/main.bicep index 2e3384f980..64e1cfa263 100644 --- a/avm/res/web/serverfarm/main.bicep +++ b/avm/res/web/serverfarm/main.bicep @@ -134,13 +134,11 @@ resource appServicePlan_diagnosticSettings 'Microsoft.Insights/diagnosticSetting workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -221,10 +219,13 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/web/serverfarm/main.json b/avm/res/web/serverfarm/main.json index ddd084d5a5..a44193aa35 100644 --- a/avm/res/web/serverfarm/main.json +++ b/avm/res/web/serverfarm/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2624470783389936382" + "version": "0.25.53.49325", + "templateHash": "1573932068035500098" }, "name": "App Service Plan", "description": "This module deploys an App Service Plan.", @@ -126,12 +126,19 @@ "metadata": { "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -377,11 +384,21 @@ "scope": "[format('Microsoft.Web/serverfarms/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, diff --git a/avm/res/web/site/README.md b/avm/res/web/site/README.md index b348f7f45b..3fa8c4a1e0 100644 --- a/avm/res/web/site/README.md +++ b/avm/res/web/site/README.md @@ -1121,11 +1121,7 @@ module site 'br/public:avm/res/web/site:' = { | [`clientAffinityEnabled`](#parameter-clientaffinityenabled) | bool | If client affinity is enabled. | | [`clientCertEnabled`](#parameter-clientcertenabled) | bool | To enable client certificate authentication (TLS mutual authentication). | | [`clientCertExclusionPaths`](#parameter-clientcertexclusionpaths) | string | Client certificate authentication comma-separated exclusion paths. | -| [`clientCertMode`](#parameter-clientcertmode) | string | This composes with ClientCertEnabled setting. -- ClientCertEnabled=false means ClientCert is ignored. -- ClientCertEnabled=true and ClientCertMode=Required means ClientCert is required. -- ClientCertEnabled=true and ClientCertMode=Optional means ClientCert is optional or accepted. - | +| [`clientCertMode`](#parameter-clientcertmode) | string | This composes with ClientCertEnabled setting.
  • ClientCertEnabled=false means ClientCert is ignored.
  • ClientCertEnabled=true and ClientCertMode=Required means ClientCert is required.
  • ClientCertEnabled=true and ClientCertMode=Optional means ClientCert is optional or accepted.

    | | [`cloningInfo`](#parameter-cloninginfo) | object | If specified during app creation, the app is cloned from a source app. | | [`containerSize`](#parameter-containersize) | int | Size of the function container. | | [`customDomainVerificationId`](#parameter-customdomainverificationid) | string | Unique identifier that verifies the custom domains assigned to the app. Customer will add this ID to a txt record for verification. | @@ -1248,11 +1244,7 @@ Client certificate authentication comma-separated exclusion paths. ### Parameter: `clientCertMode` -This composes with ClientCertEnabled setting. -- ClientCertEnabled=false means ClientCert is ignored. -- ClientCertEnabled=true and ClientCertMode=Required means ClientCert is required. -- ClientCertEnabled=true and ClientCertMode=Optional means ClientCert is optional or accepted. - +This composes with ClientCertEnabled setting.

  • ClientCertEnabled=false means ClientCert is ignored.
  • ClientCertEnabled=true and ClientCertMode=Required means ClientCert is required.
  • ClientCertEnabled=true and ClientCertMode=Optional means ClientCert is optional or accepted.

    - Required: No - Type: string @@ -1308,9 +1300,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -1345,11 +1337,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1359,11 +1380,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -1563,6 +1610,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -1584,6 +1652,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/web/site/basic-publishing-credentials-policy/main.json b/avm/res/web/site/basic-publishing-credentials-policy/main.json index 654b9952cb..6f99540b9b 100644 --- a/avm/res/web/site/basic-publishing-credentials-policy/main.json +++ b/avm/res/web/site/basic-publishing-credentials-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10399361361481208001" + "version": "0.25.53.49325", + "templateHash": "2268330248918966432" }, "name": "Web Site Basic Publishing Credentials Policies", "description": "This module deploys a Web Site Basic Publishing Credentials Policy.", diff --git a/avm/res/web/site/config--appsettings/main.json b/avm/res/web/site/config--appsettings/main.json index 8e2fffd847..f76ed84607 100644 --- a/avm/res/web/site/config--appsettings/main.json +++ b/avm/res/web/site/config--appsettings/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16772310332668493999" + "version": "0.25.53.49325", + "templateHash": "9880720466726925484" }, "name": "Site App Settings", "description": "This module deploys a Site App Setting.", diff --git a/avm/res/web/site/config--authsettingsv2/main.json b/avm/res/web/site/config--authsettingsv2/main.json index 0a57ccd149..7a5d89405b 100644 --- a/avm/res/web/site/config--authsettingsv2/main.json +++ b/avm/res/web/site/config--authsettingsv2/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14009865534133766790" + "version": "0.25.53.49325", + "templateHash": "9745043167341352785" }, "name": "Site Auth Settings V2 Config", "description": "This module deploys a Site Auth Settings V2 Configuration.", diff --git a/avm/res/web/site/hybrid-connection-namespace/relay/main.json b/avm/res/web/site/hybrid-connection-namespace/relay/main.json index 3f8c1e5d86..127923ade5 100644 --- a/avm/res/web/site/hybrid-connection-namespace/relay/main.json +++ b/avm/res/web/site/hybrid-connection-namespace/relay/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16924628128999801114" + "version": "0.25.53.49325", + "templateHash": "15358142338977814861" }, "name": "Web/Function Apps Hybrid Connection Relay", "description": "This module deploys a Site Hybrid Connection Namespace Relay.", diff --git a/avm/res/web/site/main.bicep b/avm/res/web/site/main.bicep index 61824319ab..7351a9a11f 100644 --- a/avm/res/web/site/main.bicep +++ b/avm/res/web/site/main.bicep @@ -275,7 +275,7 @@ module app_slots 'slot/main.bicep' = [for (slot, index) in (slots ?? []): { appSettingsKeyValuePairs: slot.?appSettingsKeyValuePairs ?? appSettingsKeyValuePairs basicPublishingCredentialsPolicies: slot.?basicPublishingCredentialsPolicies ?? basicPublishingCredentialsPolicies lock: slot.?lock ?? lock - privateEndpoints: slot.?privateEndpoints ?? privateEndpoints + privateEndpoints: slot.?privateEndpoints ?? [] tags: slot.?tags ?? tags clientCertEnabled: slot.?clientCertEnabled clientCertExclusionPaths: slot.?clientCertExclusionPaths @@ -332,19 +332,16 @@ resource app_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-0 workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -538,19 +535,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/web/site/main.json b/avm/res/web/site/main.json index b0f7600a6e..500663e7fb 100644 --- a/avm/res/web/site/main.json +++ b/avm/res/web/site/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "6827854649814438473" + "version": "0.25.53.49325", + "templateHash": "15412423005625899099" }, "name": "Web/Function Apps", "description": "This module deploys a Web or Function App.", @@ -330,14 +330,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -348,14 +355,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -814,12 +828,30 @@ "scope": "[format('Microsoft.Web/sites/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -886,8 +918,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16772310332668493999" + "version": "0.25.53.49325", + "templateHash": "9880720466726925484" }, "name": "Site App Settings", "description": "This module deploys a Site App Setting.", @@ -1036,8 +1068,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14009865534133766790" + "version": "0.25.53.49325", + "templateHash": "9745043167341352785" }, "name": "Site Auth Settings V2 Config", "description": "This module deploys a Site Auth Settings V2 Configuration.", @@ -1191,7 +1223,7 @@ "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" }, "privateEndpoints": { - "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'privateEndpoints'), parameters('privateEndpoints'))]" + "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'privateEndpoints'), createArray())]" }, "tags": { "value": "[coalesce(tryGet(coalesce(parameters('slots'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" @@ -1255,8 +1287,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14287529092911845504" + "version": "0.25.53.49325", + "templateHash": "12905465301950647404" }, "name": "Web/Function App Deployment Slots", "description": "This module deploys a Web or Function App Deployment Slot.", @@ -1580,14 +1612,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -1598,14 +1637,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -2045,12 +2091,30 @@ "scope": "[format('Microsoft.Web/sites/{0}/slots/{1}', parameters('appName'), parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -2120,8 +2184,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9605115891306784861" + "version": "0.25.53.49325", + "templateHash": "10338815995098199032" }, "name": "Site Slot App Settings", "description": "This module deploys a Site Slot App Setting.", @@ -2289,8 +2353,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7901002401130178704" + "version": "0.25.53.49325", + "templateHash": "17486786144236938726" }, "name": "Site Slot Auth Settings V2 Config", "description": "This module deploys a Site Auth Settings V2 Configuration.", @@ -2404,8 +2468,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "95340614388352354" + "version": "0.25.53.49325", + "templateHash": "14855550867941906241" }, "name": "Web Site Slot Basic Publishing Credentials Policies", "description": "This module deploys a Web Site Slot Basic Publishing Credentials Policy.", @@ -2530,8 +2594,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "822472634155315347" + "version": "0.25.53.49325", + "templateHash": "17251933783218724711" }, "name": "Web/Function Apps Slot Hybrid Connection Relay", "description": "This module deploys a Site Slot Hybrid Connection Namespace Relay.", @@ -3357,8 +3421,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "10399361361481208001" + "version": "0.25.53.49325", + "templateHash": "2268330248918966432" }, "name": "Web Site Basic Publishing Credentials Policies", "description": "This module deploys a Web Site Basic Publishing Credentials Policy.", @@ -3473,8 +3537,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "16924628128999801114" + "version": "0.25.53.49325", + "templateHash": "15358142338977814861" }, "name": "Web/Function Apps Hybrid Connection Relay", "description": "This module deploys a Site Hybrid Connection Namespace Relay.", diff --git a/avm/res/web/site/slot/README.md b/avm/res/web/site/slot/README.md index c62bb84a7e..8b82bf1ad9 100644 --- a/avm/res/web/site/slot/README.md +++ b/avm/res/web/site/slot/README.md @@ -230,9 +230,9 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -267,11 +267,40 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -281,11 +310,37 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.name` The name of diagnostic setting. @@ -485,6 +540,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -506,6 +582,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/web/site/slot/basic-publishing-credentials-policy/main.json b/avm/res/web/site/slot/basic-publishing-credentials-policy/main.json index 9179dadb5c..7f350ba33a 100644 --- a/avm/res/web/site/slot/basic-publishing-credentials-policy/main.json +++ b/avm/res/web/site/slot/basic-publishing-credentials-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "95340614388352354" + "version": "0.25.53.49325", + "templateHash": "14855550867941906241" }, "name": "Web Site Slot Basic Publishing Credentials Policies", "description": "This module deploys a Web Site Slot Basic Publishing Credentials Policy.", diff --git a/avm/res/web/site/slot/config--appsettings/main.json b/avm/res/web/site/slot/config--appsettings/main.json index 4dfb78aada..d0031b6fec 100644 --- a/avm/res/web/site/slot/config--appsettings/main.json +++ b/avm/res/web/site/slot/config--appsettings/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9605115891306784861" + "version": "0.25.53.49325", + "templateHash": "10338815995098199032" }, "name": "Site Slot App Settings", "description": "This module deploys a Site Slot App Setting.", diff --git a/avm/res/web/site/slot/config--authsettingsv2/main.json b/avm/res/web/site/slot/config--authsettingsv2/main.json index 803d11333f..95aba0cbc2 100644 --- a/avm/res/web/site/slot/config--authsettingsv2/main.json +++ b/avm/res/web/site/slot/config--authsettingsv2/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7901002401130178704" + "version": "0.25.53.49325", + "templateHash": "17486786144236938726" }, "name": "Site Slot Auth Settings V2 Config", "description": "This module deploys a Site Auth Settings V2 Configuration.", diff --git a/avm/res/web/site/slot/hybrid-connection-namespace/relay/main.json b/avm/res/web/site/slot/hybrid-connection-namespace/relay/main.json index 91d22053e8..814d89b0f7 100644 --- a/avm/res/web/site/slot/hybrid-connection-namespace/relay/main.json +++ b/avm/res/web/site/slot/hybrid-connection-namespace/relay/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "822472634155315347" + "version": "0.25.53.49325", + "templateHash": "17251933783218724711" }, "name": "Web/Function Apps Slot Hybrid Connection Relay", "description": "This module deploys a Site Slot Hybrid Connection Namespace Relay.", diff --git a/avm/res/web/site/slot/main.bicep b/avm/res/web/site/slot/main.bicep index 5c280874e2..9c91ea7372 100644 --- a/avm/res/web/site/slot/main.bicep +++ b/avm/res/web/site/slot/main.bicep @@ -265,19 +265,16 @@ resource slot_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05- workspaceId: diagnosticSetting.?workspaceResourceId eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId eventHubName: diagnosticSetting.?eventHubName - metrics: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType } @@ -459,19 +456,25 @@ type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') logCategoriesAndGroups: { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? }[]? @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') diff --git a/avm/res/web/site/slot/main.json b/avm/res/web/site/slot/main.json index 5d6d5c21d3..a4c60a5730 100644 --- a/avm/res/web/site/slot/main.json +++ b/avm/res/web/site/slot/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "14287529092911845504" + "version": "0.25.53.49325", + "templateHash": "12905465301950647404" }, "name": "Web/Function App Deployment Slots", "description": "This module deploys a Web or Function App Deployment Slot.", @@ -330,14 +330,21 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "metricCategories": { @@ -348,14 +355,21 @@ "category": { "type": "string", "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." } } } }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." } }, "logAnalyticsDestinationType": { @@ -795,12 +809,30 @@ "scope": "[format('Microsoft.Web/sites/{0}/slots/{1}', parameters('appName'), parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, @@ -870,8 +902,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9605115891306784861" + "version": "0.25.53.49325", + "templateHash": "10338815995098199032" }, "name": "Site Slot App Settings", "description": "This module deploys a Site Slot App Setting.", @@ -1039,8 +1071,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7901002401130178704" + "version": "0.25.53.49325", + "templateHash": "17486786144236938726" }, "name": "Site Slot Auth Settings V2 Config", "description": "This module deploys a Site Auth Settings V2 Configuration.", @@ -1154,8 +1186,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "95340614388352354" + "version": "0.25.53.49325", + "templateHash": "14855550867941906241" }, "name": "Web Site Slot Basic Publishing Credentials Policies", "description": "This module deploys a Web Site Slot Basic Publishing Credentials Policy.", @@ -1280,8 +1312,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "822472634155315347" + "version": "0.25.53.49325", + "templateHash": "17251933783218724711" }, "name": "Web/Function Apps Slot Hybrid Connection Relay", "description": "This module deploys a Site Slot Hybrid Connection Namespace Relay.", diff --git a/avm/res/web/static-site/README.md b/avm/res/web/static-site/README.md index 46de728a72..a4a37abdff 100644 --- a/avm/res/web/static-site/README.md +++ b/avm/res/web/static-site/README.md @@ -664,6 +664,27 @@ Custom DNS configurations. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint ip address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private ip addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint ip address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private ip addresses of the private endpoint. + +- Required: Yes +- Type: array + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -685,6 +706,56 @@ A list of IP configurations of the private endpoint. This will be used to map to - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private ip address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private ip address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + ### Parameter: `privateEndpoints.location` The location to deploy the private endpoint to. diff --git a/avm/res/web/static-site/config/main.json b/avm/res/web/static-site/config/main.json index 94cece2fe0..63676de877 100644 --- a/avm/res/web/static-site/config/main.json +++ b/avm/res/web/static-site/config/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12360558347482884602" + "version": "0.25.53.49325", + "templateHash": "17053065769415076723" }, "name": "Static Web App Site Config", "description": "This module deploys a Static Web App Site Config.", diff --git a/avm/res/web/static-site/custom-domain/main.json b/avm/res/web/static-site/custom-domain/main.json index 29a6ad82d3..c208b7bc10 100644 --- a/avm/res/web/static-site/custom-domain/main.json +++ b/avm/res/web/static-site/custom-domain/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15929667345294936427" + "version": "0.25.53.49325", + "templateHash": "3581008276102913900" }, "name": "Static Web App Site Custom Domains", "description": "This module deploys a Static Web App Site Custom Domain.", diff --git a/avm/res/web/static-site/linked-backend/main.json b/avm/res/web/static-site/linked-backend/main.json index 73c8f32387..6a5aba4615 100644 --- a/avm/res/web/static-site/linked-backend/main.json +++ b/avm/res/web/static-site/linked-backend/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7695569913720977108" + "version": "0.25.53.49325", + "templateHash": "3673239578041396478" }, "name": "Static Web App Site Linked Backends", "description": "This module deploys a Custom Function App into a Static Web App Site using the Linked Backends property.", diff --git a/avm/res/web/static-site/main.json b/avm/res/web/static-site/main.json index ec5c11d3ea..bd76acc54e 100644 --- a/avm/res/web/static-site/main.json +++ b/avm/res/web/static-site/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12022767093866974773" + "version": "0.25.53.49325", + "templateHash": "6139621116295404519" }, "name": "Static Web Apps", "description": "This module deploys a Static Web App.", @@ -588,8 +588,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "7695569913720977108" + "version": "0.25.53.49325", + "templateHash": "3673239578041396478" }, "name": "Static Web App Site Linked Backends", "description": "This module deploys a Custom Function App into a Static Web App Site using the Linked Backends property.", @@ -690,8 +690,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12360558347482884602" + "version": "0.25.53.49325", + "templateHash": "17053065769415076723" }, "name": "Static Web App Site Config", "description": "This module deploys a Static Web App Site Config.", @@ -785,8 +785,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "12360558347482884602" + "version": "0.25.53.49325", + "templateHash": "17053065769415076723" }, "name": "Static Web App Site Config", "description": "This module deploys a Static Web App Site Config.", @@ -881,8 +881,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "15929667345294936427" + "version": "0.25.53.49325", + "templateHash": "3581008276102913900" }, "name": "Static Web App Site Custom Domains", "description": "This module deploys a Static Web App Site Custom Domain.", diff --git a/avm/utilities/e2e-template-assets/scripts/Set-StorageContainerContentByEnvVar.ps1 b/avm/utilities/e2e-template-assets/scripts/Set-StorageContainerContentByEnvVar.ps1 new file mode 100644 index 0000000000..d0af03f8c2 --- /dev/null +++ b/avm/utilities/e2e-template-assets/scripts/Set-StorageContainerContentByEnvVar.ps1 @@ -0,0 +1,66 @@ +<# +.SYNOPSIS +Run the Post-Deployment for the storage account deployment & upload required data to the storage account. + +.DESCRIPTION +Run the Post-Deployment for the storage account deployment & upload required data to the storage account. +Any content that should be uploaded must exist as an environment variable with a 'script_' prefix (for example 'script_Initialize-LinuxSoftware_ps1'). +The script will fetch any matching environment variable, store it as a file (for example 'script_Initialize__LinuxSoftware_ps1' is stored as 'Initialize-LinuxSoftware.ps1') +and uploade it as blob to the given container. + +.PARAMETER StorageAccountName +Required. The name of the Storage Account to upload to + +.PARAMETER TargetContainer +Required. The container to upload the files to + +.EXAMPLE +Set-StorageContainerContentByEnvVar -StorageAccountName 'mystorage' -TargetContainer 'myContainer' + +Upload any required data to the storage account 'mystorage' and container 'myContainer'. +#> + +[CmdletBinding(SupportsShouldProcess = $True)] +param( + [Parameter(Mandatory = $true)] + [string] $StorageAccountName, + + [Parameter(Mandatory = $true)] + [string] $TargetContainer +) + +Write-Verbose 'Fetching & storing scripts' -Verbose +$contentDirectoryName = 'scripts' +$contentDirectory = (New-Item $contentDirectoryName -ItemType 'Directory' -Force).FullName +$scriptPaths = @() +foreach ($scriptEnvVar in (Get-ChildItem 'env:*').Name | Where-Object { $_ -like 'script_*' }) { + # Handle value like 'script_Initialize__LinuxSoftware_ps1' + $scriptName = $scriptEnvVar -replace 'script_', '' -replace '__', '-' -replace '_', '.' + $scriptContent = (Get-Item env:$scriptEnvVar).Value + + Write-Verbose ('Storing file [{0}] with length [{1}]' -f $scriptName, $scriptContent.Length) -Verbose + $scriptPaths += (New-Item (Join-Path $contentDirectoryName $scriptName) -ItemType 'File' -Value $scriptContent -Force).FullName +} + +Write-Verbose 'Getting storage account context.' -Verbose +$ctx = New-AzStorageContext -StorageAccountName $storageAccountName -UseConnectedAccount + +Write-Verbose 'Building paths to the local folders to upload.' -Verbose +Write-Verbose "Content directory: '$contentDirectory'" -Verbose + +foreach ($scriptPath in $scriptPaths) { + + try { + Write-Verbose 'Testing blob container' -Verbose + Get-AzStorageContainer -Name $targetContainer -Context $ctx -ErrorAction 'Stop' + Write-Verbose 'Testing blob container SUCCEEDED' -Verbose + + Write-Verbose ('Uploading file [{0}] to container [{1}]' -f (Split-Path $scriptPath -Leaf), $TargetContainer) -Verbose + if ($PSCmdlet.ShouldProcess(('File [{0}] to container [{1}]' -f (Split-Path $scriptPath -Leaf), $TargetContainer), 'Upload')) { + $null = Set-AzStorageBlobContent -File $scriptPath -Container $targetContainer -Context $ctx -Force -ErrorAction 'Stop' + } + Write-Verbose 'Upload successful' -Verbose + } catch { + throw "Upload FAILED: $_" + } +} diff --git a/avm/utilities/pipelines/e2eValidation/regionSelector/Get-AzAvailableResourceLocation.ps1 b/avm/utilities/pipelines/e2eValidation/regionSelector/Get-AzAvailableResourceLocation.ps1 index e63ff53e48..3c6a479e55 100644 --- a/avm/utilities/pipelines/e2eValidation/regionSelector/Get-AzAvailableResourceLocation.ps1 +++ b/avm/utilities/pipelines/e2eValidation/regionSelector/Get-AzAvailableResourceLocation.ps1 @@ -5,6 +5,9 @@ Set the location for the resource deployment. .DESCRIPTION This script is used to set the location for the resource deployment. +.PARAMETER AllowedRegionsList +Optional. The list of regions to be considered for the selection. + .PARAMETER ExcludedRegions Optional. The list of regions to be excluded from the selection. @@ -29,6 +32,14 @@ function Get-AzAvailableResourceLocation { [Parameter(Mandatory = $false)] [string] $RepoRoot = (Get-Item -Path $PSScriptRoot).parent.parent.parent.parent.parent.FullName, + [Parameter(Mandatory = $false)] + [array] $AllowedRegionsList = @( + 'eastus', + 'uksouth', + 'northeurope', + 'eastasia' # Including as Edge Region for services like static-site + ), + [Parameter(Mandatory = $true)] [string] $ModuleRoot, @@ -72,7 +83,7 @@ function Get-AzAvailableResourceLocation { Write-Verbose "Region list: $($resourceRegionList | ConvertTo-Json)" if ($resourceRegionList -eq "global" -or $null -eq $resourceRegionList) { - Write-Verbose "Resource is global, default region [$GlobalResourceGroupLocation] will be used for resource group creation" + Write-Verbose "Resource is global or does not have a location in the Resource Providers API, default region [$GlobalResourceGroupLocation] will be used for resource group creation" $location = $GlobalResourceGroupLocation # Set Location to resource group location. Globabl resources should have hardocded location in `main.bicep` } else { @@ -85,13 +96,13 @@ function Get-AzAvailableResourceLocation { } | Select-Object -ExpandProperty Location Write-Verbose "Available Locations: $($locations | ConvertTo-Json)" - - $index = Get-Random -Maximum ($locations.Count) + $filteredAllowedLocations = @($locations | Where-Object { $_ -in $AllowedRegionsList }) + Write-Verbose "Filtered allowed locations: $($filteredAllowedLocations | ConvertTo-Json)" + $index = Get-Random -Maximum ($filteredAllowedLocations.Count) Write-Verbose "Generated random index [$index]" - - $location = $locations[$index] - + $location = $filteredAllowedLocations[$index] } + Write-Verbose "Selected location [$location]" -Verbose return $location diff --git a/avm/utilities/pipelines/e2eValidation/resourceRemoval/Initialize-DeploymentRemoval.ps1 b/avm/utilities/pipelines/e2eValidation/resourceRemoval/Initialize-DeploymentRemoval.ps1 index 3c2b11eeec..5939f2a474 100644 --- a/avm/utilities/pipelines/e2eValidation/resourceRemoval/Initialize-DeploymentRemoval.ps1 +++ b/avm/utilities/pipelines/e2eValidation/resourceRemoval/Initialize-DeploymentRemoval.ps1 @@ -76,8 +76,10 @@ function Initialize-DeploymentRemoval { 'Microsoft.Authorization/policyDefinitions' 'Microsoft.Sql/managedInstances', 'Microsoft.MachineLearningServices/workspaces', - 'Microsoft.Resources/resourceGroups', - 'Microsoft.Compute/virtualMachines' + 'Microsoft.Compute/virtualMachines', + 'Microsoft.VirtualMachineImages/imageTemplates', # Must be removed before their MSI + 'Microsoft.ManagedIdentity/userAssignedIdentities', + 'Microsoft.Resources/resourceGroups' ) Write-Verbose ('Handling resource removal with deployment names [{0}]' -f ($deploymentNames -join ', ')) -Verbose diff --git a/avm/utilities/pipelines/platform/Publish-ModuleFromTagToPBR.ps1 b/avm/utilities/pipelines/platform/Publish-ModuleFromTagToPBR.ps1 index 8ca1dd5b84..31aecb7cc0 100644 --- a/avm/utilities/pipelines/platform/Publish-ModuleFromTagToPBR.ps1 +++ b/avm/utilities/pipelines/platform/Publish-ModuleFromTagToPBR.ps1 @@ -40,8 +40,8 @@ function Publish-ModuleFromTagToPBR { $targetVersion = Split-Path $ModuleReleaseTagName -Leaf $moduleRelativeFolderPath = $ModuleReleaseTagName -replace "\/$targetVersion$", '' $moduleFolderPath = Join-Path $repositoryRoot $moduleRelativeFolderPath - $moduleJsonFilePath = Join-Path $moduleFolderPath 'main.json' - Write-Verbose "Determined JSON template Path [$moduleJsonFilePath]" + $moduleBicepFilePath = Join-Path $moduleFolderPath 'main.bicep' + Write-Verbose "Determined Bicep template path [$moduleBicepFilePath]" # 2. Get the documentation link $documentationUri = Get-ModuleReadmeLink -TagName $ModuleReleaseTagName -ModuleFolderPath $moduleFolderPath @@ -53,9 +53,10 @@ function Publish-ModuleFromTagToPBR { $plainPublicRegistryServer = ConvertFrom-SecureString $PublicRegistryServer -AsPlainText $publishInput = @( - $moduleJsonFilePath + $moduleBicepFilePath '--target', ("br:{0}/public/bicep/{1}:{2}" -f $plainPublicRegistryServer, $moduleRelativeFolderPath, $targetVersion) '--documentationUri', $documentationUri + '--with-source' '--force' ) diff --git a/avm/utilities/pipelines/publish/Publish-ModuleFromPathToPBR.ps1 b/avm/utilities/pipelines/publish/Publish-ModuleFromPathToPBR.ps1 index deb935a71d..953521d606 100644 --- a/avm/utilities/pipelines/publish/Publish-ModuleFromPathToPBR.ps1 +++ b/avm/utilities/pipelines/publish/Publish-ModuleFromPathToPBR.ps1 @@ -46,7 +46,7 @@ function Publish-ModuleFromPathToPBR { . (Join-Path $RepoRoot 'avm' 'utilities' 'pipelines' 'sharedScripts' 'tokenReplacement' 'Convert-TokensInFileList.ps1') $moduleFolderPath = Split-Path $TemplateFilePath -Parent - $moduleJsonFilePath = Join-Path $moduleFolderPath 'main.json' + $moduleBicepFilePath = Join-Path $moduleFolderPath 'main.bicep' # 1. Test if module qualifies for publishing if (-not (Get-ModulesToPublish -ModuleFolderPath $moduleFolderPath)) { @@ -66,9 +66,9 @@ function Publish-ModuleFromPathToPBR { # 5. Get the documentation link $documentationUri = Get-ModuleReadmeLink -TagName $tagName -ModuleFolderPath $moduleFolderPath - # 6. Replace telemetry version value (in JSON) + # 6. Replace telemetry version value (in Bicep) $tokenConfiguration = @{ - FilePathList = @($moduleJsonFilePath) + FilePathList = @($moduleBicepFilePath) AbsoluteTokens = @{ '-..--..-' = $targetVersion } @@ -77,11 +77,11 @@ function Publish-ModuleFromPathToPBR { $null = Convert-TokensInFileList @tokenConfiguration # Double-check that tokens are correctly replaced - $templateContent = Get-Content -Path $moduleJsonFilePath + $templateContent = Get-Content -Path $moduleBicepFilePath $incorrectLines = @() for ($index = 0; $index -lt $templateContent.Count; $index++) { if ($templateContent[$index] -match '-..--..-') { - $incorrectLines += ('You have the token [{0}] in line [{1}] of file [{2}]. Please seek advice from the AVM team.' -f $matches[0], ($index + 1), $moduleJsonFilePath) + $incorrectLines += ('You have the token [{0}] in line [{1}] of file [{2}]. Please seek advice from the AVM team.' -f $matches[0], ($index + 1), $moduleBicepFilePath) } } if ($incorrectLines) { @@ -94,9 +94,10 @@ function Publish-ModuleFromPathToPBR { $plainPublicRegistryServer = ConvertFrom-SecureString $PublicRegistryServer -AsPlainText $publishInput = @( - $moduleJsonFilePath + $moduleBicepFilePath '--target', ("br:{0}/public/bicep/{1}:{2}" -f $plainPublicRegistryServer, $publishedModuleName, $targetVersion) '--documentationUri', $documentationUri + '--with-source' '--force' ) # TODO move to its own task to show that as skipped if no file qualifies for new version diff --git a/avm/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1 b/avm/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1 index a97548796c..ebb4cdac4d 100644 --- a/avm/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1 +++ b/avm/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1 @@ -299,6 +299,11 @@ function Set-DefinitionSection { $definition = $TemplateFileContent.definitions[$identifier] $type = $definition['type'] $rawAllowedValues = $definition['allowedValues'] + } elseif ($parameter.Keys -contains 'items' -and $parameter.items.type -in @('object', 'array') -or $parameter.type -eq 'object') { + # Array has nested non-primitive type (array/object) + $definition = $parameter + $type = $parameter.type + $rawAllowedValues = $parameter.allowedValues } else { $definition = $null $type = $parameter.type @@ -306,14 +311,14 @@ function Set-DefinitionSection { } $isRequired = (Get-IsParameterRequired -TemplateFileContent $TemplateFileContent -Parameter $parameter) ? 'Yes' : 'No' - $description = $parameter.ContainsKey('metadata') ? $parameter['metadata']['description'] : $null + $description = $parameter.ContainsKey('metadata') ? $parameter['metadata']['description'].substring("$category. ".Length).Replace("`n- ", '

  • ').Replace("`r`n", '

    ').Replace("`n", '

    ') : $null ##################### # Table content # ##################### # build table for definition properties - $tableSectionContent += ('| [`{0}`]({1}) | {2} | {3} |' -f $parameter.name, $paramIdentifierLink, $type, $description.substring("$category. ".Length)) + $tableSectionContent += ('| [`{0}`]({1}) | {2} | {3} |' -f $parameter.name, $paramIdentifierLink, $type, $description) #################### # List content # @@ -394,7 +399,7 @@ function Set-DefinitionSection { $listSectionContent += @( $paramHeader, ($parameter.ContainsKey('metadata') ? '' : $null), - ($parameter.ContainsKey('metadata') ? $parameter['metadata']['description'].substring("$category. ".Length) : $null), + $description ($parameter.ContainsKey('metadata') ? '' : $null), ('- Required: {0}' -f $isRequired), ('- Type: {0}' -f $type), diff --git a/avm/utilities/pipelines/sharedScripts/helper/Get-SpecsAlignedResourceName.ps1 b/avm/utilities/pipelines/sharedScripts/helper/Get-SpecsAlignedResourceName.ps1 index 7ee1bc333b..356a552c48 100644 --- a/avm/utilities/pipelines/sharedScripts/helper/Get-SpecsAlignedResourceName.ps1 +++ b/avm/utilities/pipelines/sharedScripts/helper/Get-SpecsAlignedResourceName.ps1 @@ -66,8 +66,7 @@ function Get-SpecsAlignedResourceName { try { $apiSpecs = Invoke-WebRequest -Uri $ApiSpecsFileUri $specs = ConvertFrom-Json $apiSpecs.Content -AsHashtable - } - catch { + } catch { Write-Warning "Failed to download API specs file from [$ApiSpecsFileUri]" $specs = @{} } @@ -82,8 +81,7 @@ function Get-SpecsAlignedResourceName { if (-not $foundProviderNamespaceMatches) { $providerNamespace = "Microsoft.$rawProviderNamespace" Write-Warning "Failed to identify provider namespace [$rawProviderNamespace]. Falling back to [$providerNamespace]." - } - else { + } else { $providerNamespace = ($foundProviderNamespaceMatches.Count -eq 1) ? $foundProviderNamespaceMatches : $foundProviderNamespaceMatches[0] } @@ -103,7 +101,7 @@ function Get-SpecsAlignedResourceName { if ($resourceType.count -gt 1) { switch ($rawResourceType) { 'service/api/policy' { - # Setting explicitely as both [apimanagement/service/apis/policies] & [apimanagement/service/apis/policy] exist in the specs and the later seem to have been an initial incorrect publish (only one API version exists) + # Setting explicitly as both [apimanagement/service/apis/policies] & [apimanagement/service/apis/policy] exist in the specs and the later seem to have been an initial incorrect publish (only one API version exists) $resourceType = 'service/apis/policies' } Default { @@ -120,8 +118,7 @@ function Get-SpecsAlignedResourceName { # if we still don't find anything (because the resource type straight up does not exist, we fall back to itself as the default) Write-Warning "Resource type [$rawResourceType] does not exist in the API / is custom. Falling back to it as default." $resourceType = $rawResourceType - } - else { + } else { Write-Warning ('Failed to find exact match between core matched resource types and [{0}]. Fallback on [{1}].' -f $rawResourceType, (Split-Path $rawResourceType -Parent)) } } diff --git a/avm/utilities/pipelines/staticValidation/compliance/helper/helper.psm1 b/avm/utilities/pipelines/staticValidation/compliance/helper/helper.psm1 index aa681464aa..a5103f9576 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/helper/helper.psm1 +++ b/avm/utilities/pipelines/staticValidation/compliance/helper/helper.psm1 @@ -245,6 +245,9 @@ function Resolve-ReadMeParameterList { $identifier = Split-Path $parameter.'$ref' -Leaf $definition = $TemplateFileContent.definitions[$identifier] # $type = $definition['type'] + } elseif ($parameter.Keys -contains 'items' -and $parameter.items.type -in @('object', 'array') -or $parameter.type -eq 'object') { + # Array has nested non-primitive type (array/object) + $definition = $parameter } else { $definition = $null } diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 8001642b2f..5ca94a1b60 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -726,7 +726,7 @@ Describe 'Module tests' -Tag 'Module' { $expectedSchema = $expectedSchemaFull[$expectedSchemaStartIndex..$expectedSchemaEndIndex] if ($templateFileContentBicep -match '@sys\.([a-zA-Z]+)\(') { - # Handing cases where the template may use the @sys namespace explicitely + # Handing cases where the template may use the @sys namespace explicitly $expectedSchema = $expectedSchema | ForEach-Object { $_ -replace '@([a-zA-Z]+)\(', '@sys.$1(' } } diff --git a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml index 79f48d21af..a0664f4949 100644 --- a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml +++ b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml @@ -64,7 +64,11 @@ configuration: "secretid", "disablepassword", "sync*passwords", + "sqlAdministratorLogin", "tokenname", + "ssoClientSecretKeyVaultPath", + "ssoSecretType", + "tokenValidityLength" ] rule: diff --git a/avm/utilities/tools/Invoke-WorkflowsForBranch.ps1 b/avm/utilities/tools/Invoke-WorkflowsForBranch.ps1 index 7fdd21f7e3..21c702e886 100644 --- a/avm/utilities/tools/Invoke-WorkflowsForBranch.ps1 +++ b/avm/utilities/tools/Invoke-WorkflowsForBranch.ps1 @@ -175,6 +175,9 @@ Optional. The GitHub repository to run the workfows in. .PARAMETER WorkflowInputs Optional. The inputs to pass into the workflows. Defaults to only run static validation. +.PARAMETER InvokeForDiff +Optional. Trigger workflows only for those who's module files have changed (based on diff of branch to main) + .EXAMPLE Invoke-WorkflowsForBranch -PersonalAccessToken '' -TargetBranch 'feature/branch' -PipelineFilter 'avm.res.*' -WorkflowInputs @{ staticValidation = 'true'; deploymentValidation = 'true'; removeDeployment = 'true' } @@ -203,6 +206,9 @@ function Invoke-WorkflowsForBranch { [Parameter(Mandatory = $false)] [string] $PipelineFilter = 'avm.res.*', + [Parameter(Mandatory = $false)] + [switch] $InvokeForDiff, + [Parameter(Mandatory = $false)] [switch] $SkipPipelineBadges, @@ -212,6 +218,9 @@ function Invoke-WorkflowsForBranch { [Parameter(Mandatory = $false)] [string] $RepositoryName = 'bicep-registry-modules', + [Parameter(Mandatory = $false)] + [string] $RepoRoot = (Get-Item $PSScriptRoot).Parent.Parent.FullName, + [Parameter(Mandatory = $false)] [hashtable] $WorkflowInputs = @{ staticValidation = 'true' @@ -228,6 +237,31 @@ function Invoke-WorkflowsForBranch { Write-Verbose 'Fetching current GitHub workflows' -Verbose $workflows = Get-GitHubModuleWorkflowList @baseInputObject -Filter $PipelineFilter + Write-Verbose ("Fetched [{0}] workflows" -f $workflows.Count) -Verbose + + if ($InvokeForDiff) { + # Load used function + . (Join-Path $RepoRoot 'utilities' 'pipelines' 'sharedScripts' 'Get-PipelineFileName.ps1') + + # Get diff + $diff = git diff 'main' --name-only + + # Identify pipeline names + $pipelineNames = [System.Collections.ArrayList]@() + $pipelineNames = $diff | ForEach-Object { + $folderPath = Split-Path $_ -Parent + $pipelineFileName = Get-PipelineFileName -ResourceIdentifier $folderPath + if ($pipelineFileName -match $PipelineFilter) { + $pipelineFileName + } + } | Select-Object -Unique + + # Filter workflows + $workflows = $workflows | Where-Object { $pipelineNames -contains (Split-Path $_.path -Leaf) } + + Write-Verbose ("As per 'diff', filtered workflows down to [{0}]" -f $workflows.Count) + } + $gitHubWorkflowBadges = [System.Collections.ArrayList]@() diff --git a/avm/utilities/tools/Set-AVMModule.ps1 b/avm/utilities/tools/Set-AVMModule.ps1 index c5280c3cc5..88cae9c114 100644 --- a/avm/utilities/tools/Set-AVMModule.ps1 +++ b/avm/utilities/tools/Set-AVMModule.ps1 @@ -129,6 +129,7 @@ function Set-AVMModule { # Instatiate values to enable safe $using usage $crossReferencedModuleList = $null $ReadMeScriptFilePath = $null + $TelemetryFileContent = $null } # Using threading to speed up the process