From b1ea42b883c0d6de54797342fe85634ae3b4d5b2 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Tue, 26 Mar 2024 22:31:38 +0100 Subject: [PATCH] feat: Re-formatted ALL AVM modules using the V2 formatter (#1368) ## Description - Re-formatted ALL AVM modules using the V2 formatter - Re-build ALL ARM JSON & Readme files - Removed V1 fallback bicep bicepconfig.json cc: @krbar ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.sql.server](https://github.com/AlexanderSehr/bicep-registry-modules/actions/workflows/avm.res.sql.server.yml/badge.svg?branch=users%2Falsehr%2FreformattedV2&event=workflow_dispatch)](https://github.com/AlexanderSehr/bicep-registry-modules/actions/workflows/avm.res.sql.server.yml) | ## Type of Change - [ ] 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 --------- Co-authored-by: Erika Gressi <56914614+eriqua@users.noreply.github.com> --- avm/bicepconfig.json | 3 +- avm/res/analysis-services/server/main.bicep | 134 ++-- avm/res/analysis-services/server/main.json | 4 +- .../server/tests/e2e/defaults/main.test.bicep | 16 +- .../server/tests/e2e/max/main.test.bicep | 135 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 98 +-- .../service/api-version-set/main.json | 4 +- avm/res/api-management/service/api/main.json | 8 +- .../service/api/policy/main.json | 4 +- .../service/authorization-server/main.json | 4 +- .../api-management/service/backend/main.json | 4 +- .../api-management/service/cache/main.json | 4 +- .../service/identity-provider/main.json | 4 +- .../service/named-value/main.json | 4 +- .../api-management/service/policy/main.json | 4 +- .../service/portalsetting/main.json | 4 +- .../service/product/api/main.json | 4 +- .../service/product/group/main.json | 4 +- .../api-management/service/product/main.json | 12 +- .../service/subscription/main.json | 4 +- .../configuration-store/key-value/main.json | 4 +- .../configuration-store/main.bicep | 331 +++++---- .../configuration-store/main.json | 8 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/encr/dependencies.bicep | 5 +- .../tests/e2e/encr/main.test.bicep | 66 +- .../tests/e2e/max/main.test.bicep | 145 ++-- .../tests/e2e/pe/main.test.bicep | 60 +- .../tests/e2e/waf-aligned/main.test.bicep | 60 +- .../automation-account/job-schedule/main.json | 4 +- .../automation/automation-account/main.bicep | 658 +++++++++++------- .../automation/automation-account/main.json | 32 +- .../automation-account/module/main.json | 4 +- .../automation-account/runbook/main.bicep | 27 +- .../automation-account/runbook/main.json | 4 +- .../automation-account/schedule/main.json | 4 +- .../software-update-configuration/main.bicep | 34 +- .../software-update-configuration/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/encr/dependencies.bicep | 63 +- .../tests/e2e/encr/main.test.bicep | 40 +- .../tests/e2e/max/main.test.bicep | 413 +++++------ .../tests/e2e/waf-aligned/main.test.bicep | 352 +++++----- .../automation-account/variable/main.json | 4 +- avm/res/cdn/profile/afdEndpoint/main.bicep | 38 +- avm/res/cdn/profile/afdEndpoint/main.json | 8 +- .../cdn/profile/afdEndpoint/route/main.bicep | 35 +- .../cdn/profile/afdEndpoint/route/main.json | 4 +- avm/res/cdn/profile/customdomain/main.bicep | 31 +- avm/res/cdn/profile/customdomain/main.json | 4 +- avm/res/cdn/profile/endpoint/main.bicep | 36 +- avm/res/cdn/profile/endpoint/main.json | 8 +- .../cdn/profile/endpoint/origin/main.bicep | 38 +- avm/res/cdn/profile/endpoint/origin/main.json | 4 +- avm/res/cdn/profile/main.bicep | 263 ++++--- avm/res/cdn/profile/main.json | 44 +- avm/res/cdn/profile/origingroup/main.bicep | 34 +- avm/res/cdn/profile/origingroup/main.json | 8 +- .../cdn/profile/origingroup/origin/main.json | 4 +- avm/res/cdn/profile/ruleset/main.bicep | 24 +- avm/res/cdn/profile/ruleset/main.json | 8 +- avm/res/cdn/profile/ruleset/rule/main.json | 4 +- avm/res/cdn/profile/secret/main.bicep | 20 +- avm/res/cdn/profile/secret/main.json | 4 +- .../cdn/profile/tests/e2e/afd/main.test.bicep | 140 ++-- .../tests/e2e/defaults/main.test.bicep | 18 +- .../cdn/profile/tests/e2e/max/main.test.bicep | 117 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 82 +-- avm/res/cognitive-services/account/main.bicep | 427 ++++++++---- avm/res/cognitive-services/account/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 18 +- .../account/tests/e2e/max/main.test.bicep | 213 +++--- .../account/tests/e2e/speech/main.test.bicep | 70 +- .../dependencies.bicep | 5 +- .../main.test.bicep | 42 +- .../dependencies.bicep | 5 +- .../main.test.bicep | 48 +- .../tests/e2e/waf-aligned/main.test.bicep | 88 +-- avm/res/compute/availability-set/main.bicep | 112 +-- avm/res/compute/availability-set/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/dependencies.bicep | 8 +- .../tests/e2e/max/main.test.bicep | 67 +- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 34 +- .../compute/disk-encryption-set/main.bicep | 158 +++-- avm/res/compute/disk-encryption-set/main.json | 12 +- .../e2e/accessPolicies/dependencies.bicep | 46 +- .../tests/e2e/accessPolicies/main.test.bicep | 79 ++- .../tests/e2e/defaults/dependencies.bicep | 40 +- .../tests/e2e/defaults/main.test.bicep | 26 +- .../tests/e2e/max/dependencies.bicep | 46 +- .../tests/e2e/max/main.test.bicep | 83 +-- .../tests/e2e/waf-aligned/dependencies.bicep | 46 +- .../tests/e2e/waf-aligned/main.test.bicep | 44 +- avm/res/compute/disk/main.bicep | 127 ++-- avm/res/compute/disk/main.json | 4 +- .../disk/tests/e2e/defaults/main.test.bicep | 20 +- .../disk/tests/e2e/image/dependencies.bicep | 4 +- .../disk/tests/e2e/image/main.test.bicep | 22 +- .../disk/tests/e2e/import/dependencies.bicep | 2 +- .../tests/e2e/import/dependencies_rbac.bicep | 5 +- .../disk/tests/e2e/import/main.test.bicep | 24 +- .../disk/tests/e2e/max/dependencies.bicep | 4 +- .../disk/tests/e2e/max/main.test.bicep | 79 ++- .../tests/e2e/waf-aligned/main.test.bicep | 46 +- .../compute/gallery/application/main.bicep | 45 +- avm/res/compute/gallery/application/main.json | 4 +- avm/res/compute/gallery/image/main.bicep | 63 +- avm/res/compute/gallery/image/main.json | 4 +- avm/res/compute/gallery/main.bicep | 189 ++--- avm/res/compute/gallery/main.json | 12 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../gallery/tests/e2e/max/dependencies.bicep | 4 +- .../gallery/tests/e2e/max/main.test.bicep | 251 +++---- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 52 +- avm/res/compute/image/main.bicep | 99 +-- avm/res/compute/image/main.json | 4 +- .../tests/e2e/defaults/dependencies.bicep | 2 +- .../e2e/defaults/dependencies_rbac.bicep | 5 +- .../image/tests/e2e/defaults/main.test.bicep | 24 +- .../image/tests/e2e/max/dependencies.bicep | 7 +- .../tests/e2e/max/dependencies_rbac.bicep | 5 +- .../image/tests/e2e/max/main.test.bicep | 77 +- .../tests/e2e/waf-aligned/dependencies.bicep | 7 +- .../e2e/waf-aligned/dependencies_rbac.bicep | 5 +- .../tests/e2e/waf-aligned/main.test.bicep | 42 +- .../proximity-placement-group/main.bicep | 84 ++- .../proximity-placement-group/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 95 +-- .../tests/e2e/waf-aligned/main.test.bicep | 54 +- avm/res/compute/ssh-public-key/main.bicep | 84 ++- avm/res/compute/ssh-public-key/main.json | 4 +- .../tests/e2e/max/dependencies.bicep | 57 +- .../tests/e2e/max/main.test.bicep | 5 +- .../tests/e2e/waf-aligned/dependencies.bicep | 57 +- .../tests/e2e/waf-aligned/main.test.bicep | 5 +- .../extension/main.json | 4 +- .../virtual-machine-scale-set/main.bicep | 653 ++++++++++------- .../virtual-machine-scale-set/main.json | 36 +- .../e2e/linux.defaults/dependencies.bicep | 5 +- .../tests/e2e/linux.defaults/main.test.bicep | 86 +-- .../tests/e2e/linux.max/dependencies.bicep | 10 +- .../tests/e2e/linux.max/main.test.bicep | 250 +++---- .../tests/e2e/linux.ssecmk/dependencies.bicep | 10 +- .../tests/e2e/linux.ssecmk/main.test.bicep | 108 +-- .../e2e/windows.defaults/main.test.bicep | 74 +- .../tests/e2e/windows.max/dependencies.bicep | 10 +- .../tests/e2e/windows.max/main.test.bicep | 242 +++---- .../windows.waf-aligned/dependencies.bicep | 10 +- .../e2e/windows.waf-aligned/main.test.bicep | 222 +++--- avm/res/consumption/budget/main.bicep | 67 +- avm/res/consumption/budget/main.json | 4 +- .../budget/tests/e2e/defaults/main.test.bicep | 22 +- .../budget/tests/e2e/max/main.test.bicep | 44 +- .../tests/e2e/waf-aligned/main.test.bicep | 36 +- .../registry/cache-rules/main.json | 4 +- .../container-registry/registry/main.bicep | 422 ++++++----- avm/res/container-registry/registry/main.json | 16 +- .../registry/replication/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/encr/dependencies.bicep | 5 +- .../registry/tests/e2e/encr/main.test.bicep | 44 +- .../registry/tests/e2e/max/dependencies.bicep | 5 +- .../registry/tests/e2e/max/main.test.bicep | 215 +++--- .../tests/e2e/waf-aligned/dependencies.bicep | 5 +- .../tests/e2e/waf-aligned/main.test.bicep | 74 +- .../registry/webhook/main.json | 4 +- .../managed-cluster/agent-pool/main.bicep | 8 +- .../managed-cluster/agent-pool/main.json | 4 +- .../managed-cluster/main.bicep | 545 +++++++++------ .../managed-cluster/main.json | 8 +- .../tests/e2e/azure/dependencies.bicep | 17 +- .../tests/e2e/azure/main.test.bicep | 403 +++++------ .../tests/e2e/defaults/main.test.bicep | 36 +- .../tests/e2e/kubenet/dependencies.bicep | 8 +- .../tests/e2e/kubenet/main.test.bicep | 237 ++++--- .../tests/e2e/priv/dependencies.bicep | 10 +- .../tests/e2e/priv/main.test.bicep | 176 ++--- .../tests/e2e/waf-aligned/dependencies.bicep | 10 +- .../tests/e2e/waf-aligned/main.test.bicep | 258 +++---- .../backup-vault/backup-policy/main.json | 4 +- .../data-protection/backup-vault/main.bicep | 125 ++-- .../data-protection/backup-vault/main.json | 8 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 187 ++--- .../tests/e2e/waf-aligned/main.test.bicep | 146 ++-- .../flexible-server/administrator/main.json | 4 +- .../flexible-server/database/main.json | 4 +- .../flexible-server/firewall-rule/main.json | 4 +- .../db-for-my-sql/flexible-server/main.bicep | 327 +++++---- .../tests/e2e/defaults/main.test.bicep | 24 +- .../tests/e2e/max/dependencies1.bicep | 53 +- .../tests/e2e/max/dependencies2.bicep | 126 ++-- .../tests/e2e/max/main.test.bicep | 206 +++--- .../tests/e2e/private/main.test.bicep | 73 +- .../tests/e2e/waf-aligned/main.test.bicep | 40 +- .../flexible-server/administrator/main.json | 4 +- .../flexible-server/configuration/main.json | 4 +- .../flexible-server/database/main.json | 4 +- .../flexible-server/firewall-rule/main.json | 4 +- .../application-group/application/main.json | 4 +- .../application-group/main.bicep | 144 ++-- .../application-group/main.json | 8 +- .../tests/e2e/defaults/main.test.bicep | 26 +- .../tests/e2e/max/main.test.bicep | 141 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 48 +- .../host-pool/main.bicep | 197 +++--- .../host-pool/main.json | 4 +- .../host-pool/tests/e2e/max/main.test.bicep | 5 +- .../scaling-plan/main.bicep | 112 +-- .../scaling-plan/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 309 ++++---- .../tests/e2e/waf-aligned/main.test.bicep | 42 +- .../workspace/main.bicep | 197 +++--- .../workspace/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../workspace/tests/e2e/max/main.test.bicep | 235 ++++--- .../tests/e2e/waf-aligned/main.test.bicep | 44 +- .../dev-test-lab/lab/artifactsource/main.json | 4 +- avm/res/dev-test-lab/lab/cost/main.json | 4 +- avm/res/dev-test-lab/lab/main.bicep | 346 +++++---- avm/res/dev-test-lab/lab/main.json | 28 +- .../lab/notificationchannel/main.json | 4 +- .../lab/policyset/policy/main.json | 4 +- avm/res/dev-test-lab/lab/schedule/main.bicep | 10 +- avm/res/dev-test-lab/lab/schedule/main.json | 4 +- .../lab/tests/e2e/defaults/main.test.bicep | 16 +- .../lab/tests/e2e/max/dependencies.bicep | 5 +- .../lab/tests/e2e/max/main.test.bicep | 455 ++++++------ .../lab/tests/e2e/waf-aligned/main.test.bicep | 24 +- .../dev-test-lab/lab/virtualnetwork/main.json | 4 +- avm/res/event-grid/domain/main.bicep | 279 +++++--- avm/res/event-grid/domain/main.json | 8 +- .../domain/tests/e2e/defaults/main.test.bicep | 16 +- .../domain/tests/e2e/max/main.test.bicep | 153 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 96 +-- avm/res/event-grid/domain/topic/main.json | 4 +- .../namespace/ca-certificate/main.json | 4 +- .../namespace/client-group/main.json | 4 +- .../event-grid/namespace/client/main.bicep | 19 +- avm/res/event-grid/namespace/client/main.json | 4 +- avm/res/event-grid/namespace/main.bicep | 467 ++++++++----- avm/res/event-grid/namespace/main.json | 32 +- .../namespace/permission-binding/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/dependencies.bicep | 5 +- .../namespace/tests/e2e/max/main.test.bicep | 337 ++++----- .../tests/e2e/mqttct/dependencies.bicep | 5 +- .../tests/e2e/mqttct/main.test.bicep | 269 +++---- .../tests/e2e/mqttnt/main.test.bicep | 269 +++---- .../tests/e2e/waf-aligned/main.test.bicep | 111 +-- .../namespace/topic-space/main.bicep | 80 ++- .../namespace/topic-space/main.json | 4 +- .../topic/event-subscription/main.bicep | 80 ++- .../topic/event-subscription/main.json | 4 +- avm/res/event-grid/namespace/topic/main.bicep | 123 ++-- avm/res/event-grid/namespace/topic/main.json | 8 +- .../event-subscription/main.bicep | 14 +- .../system-topic/event-subscription/main.json | 4 +- avm/res/event-grid/system-topic/main.bicep | 219 +++--- avm/res/event-grid/system-topic/main.json | 8 +- .../tests/e2e/defaults/dependencies.bicep | 12 +- .../tests/e2e/defaults/main.test.bicep | 20 +- .../tests/e2e/max/dependencies.bicep | 30 +- .../tests/e2e/max/main.test.bicep | 141 ++-- .../tests/e2e/waf-aligned/dependencies.bicep | 22 +- .../tests/e2e/waf-aligned/main.test.bicep | 102 +-- .../topic/event-subscription/main.bicep | 16 +- .../topic/event-subscription/main.json | 4 +- avm/res/event-grid/topic/main.bicep | 305 ++++---- avm/res/event-grid/topic/main.json | 8 +- .../topic/tests/e2e/defaults/main.test.bicep | 16 +- .../topic/tests/e2e/max/main.test.bicep | 212 +++--- .../tests/e2e/waf-aligned/main.test.bicep | 132 ++-- .../namespace/authorization-rule/main.json | 4 +- .../disaster-recovery-config/main.json | 4 +- .../eventhub/authorization-rule/main.json | 4 +- .../eventhub/consumergroup/main.json | 4 +- .../event-hub/namespace/eventhub/main.bicep | 120 ++-- .../event-hub/namespace/eventhub/main.json | 12 +- avm/res/event-hub/namespace/main.bicep | 489 ++++++++----- avm/res/event-hub/namespace/main.json | 28 +- .../namespace/network-rule-set/main.bicep | 24 +- .../namespace/network-rule-set/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/encr/dependencies.bicep | 5 +- .../namespace/tests/e2e/encr/main.test.bicep | 1 - .../namespace/tests/e2e/max/main.test.bicep | 317 ++++----- .../tests/e2e/waf-aligned/main.test.bicep | 238 +++---- avm/res/health-bot/health-bot/main.bicep | 102 +-- avm/res/health-bot/health-bot/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 18 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../health-bot/tests/e2e/max/main.test.bicep | 81 ++- .../tests/e2e/waf-aligned/main.test.bicep | 34 +- avm/res/insights/action-group/main.bicep | 67 +- avm/res/insights/action-group/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 18 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 99 +-- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 26 +- .../insights/activity-log-alert/main.bicep | 77 +- avm/res/insights/activity-log-alert/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 76 +- .../tests/e2e/max/main.test.bicep | 139 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 102 +-- .../component/linkedStorageAccounts/main.json | 4 +- avm/res/insights/component/main.bicep | 130 ++-- avm/res/insights/component/main.json | 8 +- .../tests/e2e/defaults/dependencies.bicep | 4 +- .../component/tests/e2e/max/main.test.bicep | 5 +- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../data-collection-endpoint/main.bicep | 84 ++- .../data-collection-endpoint/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 69 +- .../tests/e2e/waf-aligned/main.test.bicep | 26 +- .../insights/data-collection-rule/main.bicep | 84 ++- .../insights/data-collection-rule/main.json | 4 +- .../tests/e2e/customadv/dependencies.bicep | 82 +-- .../tests/e2e/customadv/main.test.bicep | 142 ++-- .../tests/e2e/custombasic/dependencies.bicep | 50 +- .../tests/e2e/custombasic/main.test.bicep | 110 +-- .../tests/e2e/customiis/dependencies.bicep | 18 +- .../tests/e2e/customiis/main.test.bicep | 80 +-- .../tests/e2e/defaults/main.test.bicep | 78 ++- .../tests/e2e/linux/dependencies.bicep | 4 +- .../tests/e2e/linux/main.test.bicep | 295 ++++---- .../tests/e2e/max/dependencies.bicep | 54 +- .../tests/e2e/max/main.test.bicep | 151 ++-- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 203 +++--- .../tests/e2e/windows/dependencies.bicep | 4 +- .../tests/e2e/windows/main.test.bicep | 203 +++--- .../insights/diagnostic-setting/main.bicep | 53 +- avm/res/insights/diagnostic-setting/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 32 +- .../tests/e2e/waf-aligned/main.test.bicep | 32 +- avm/res/insights/metric-alert/main.bicep | 77 +- avm/res/insights/metric-alert/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 42 +- .../tests/e2e/max/dependencies.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 95 +-- .../tests/e2e/waf-aligned/dependencies.bicep | 12 +- .../tests/e2e/waf-aligned/main.test.bicep | 58 +- .../insights/private-link-scope/main.bicep | 249 ++++--- avm/res/insights/private-link-scope/main.json | 8 +- .../scoped-resource/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 299 ++++---- .../tests/e2e/waf-aligned/main.test.bicep | 226 +++--- .../insights/scheduled-query-rule/main.bicep | 67 +- .../insights/scheduled-query-rule/main.json | 4 +- .../tests/e2e/defaults/dependencies.bicep | 4 +- .../tests/e2e/defaults/main.test.bicep | 76 +- .../tests/e2e/max/dependencies.bicep | 8 +- .../tests/e2e/max/main.test.bicep | 125 ++-- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 94 +-- avm/res/insights/webtest/main.bicep | 84 ++- avm/res/insights/webtest/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 26 +- .../webtest/tests/e2e/max/main.test.bicep | 87 +-- .../tests/e2e/waf-aligned/main.test.bicep | 42 +- .../extension/main.bicep | 81 ++- .../extension/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 30 +- .../extension/tests/e2e/max/main.test.bicep | 80 +-- .../tests/e2e/waf-aligned/main.test.bicep | 80 +-- .../flux-configuration/main.bicep | 27 +- .../flux-configuration/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 52 +- .../tests/e2e/max/main.test.bicep | 70 +- .../tests/e2e/waf-aligned/main.test.bicep | 62 +- .../workspace/compute/main.bicep | 70 +- .../workspace/compute/main.json | 4 +- .../workspace/main.bicep | 375 ++++++---- .../workspace/main.json | 8 +- .../tests/e2e/defaults/dependencies.bicep | 48 +- .../tests/e2e/defaults/main.test.bicep | 30 +- .../tests/e2e/encr/dependencies.bicep | 10 +- .../workspace/tests/e2e/encr/main.test.bicep | 52 +- .../tests/e2e/max/dependencies.bicep | 10 +- .../workspace/tests/e2e/max/main.test.bicep | 211 +++--- .../tests/e2e/waf-aligned/dependencies.bicep | 10 +- .../tests/e2e/waf-aligned/main.test.bicep | 78 ++- .../maintenance-configuration/main.bicep | 89 ++- .../maintenance-configuration/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 117 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 78 ++- .../federated-identity-credential/main.json | 4 +- .../user-assigned-identity/main.bicep | 116 +-- .../user-assigned-identity/main.json | 8 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 85 +-- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 50 +- .../management/management-group/main.bicep | 41 +- avm/res/management/management-group/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 14 +- .../tests/e2e/max/main.test.bicep | 18 +- .../tests/e2e/waf-aligned/main.test.bicep | 18 +- .../application-security-group/main.bicep | 84 ++- .../application-security-group/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 65 +- .../tests/e2e/waf-aligned/main.test.bicep | 32 +- avm/res/network/azure-firewall/main.bicep | 361 ++++++---- avm/res/network/azure-firewall/main.json | 4 +- .../tests/e2e/addpip/main.test.bicep | 44 +- .../tests/e2e/custompip/main.test.bicep | 72 +- .../tests/e2e/defaults/main.test.bicep | 18 +- .../tests/e2e/hubcommon/main.test.bicep | 26 +- .../tests/e2e/hubmin/main.test.bicep | 24 +- .../tests/e2e/max/main.test.bicep | 255 +++---- .../tests/e2e/waf-aligned/main.test.bicep | 212 +++--- avm/res/network/bastion-host/main.bicep | 196 +++--- avm/res/network/bastion-host/main.json | 4 +- .../tests/e2e/custompip/main.test.bicep | 96 +-- .../tests/e2e/defaults/main.test.bicep | 24 +- .../tests/e2e/max/main.test.bicep | 107 +-- .../tests/e2e/waf-aligned/main.test.bicep | 64 +- avm/res/network/connection/main.bicep | 70 +- avm/res/network/connection/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 36 +- .../connection/tests/e2e/max/main.test.bicep | 60 +- .../tests/e2e/waf-aligned/main.test.bicep | 54 +- .../network/ddos-protection-plan/main.bicep | 84 ++- .../network/ddos-protection-plan/main.json | 4 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 5 +- .../forwarding-rule/main.json | 4 +- .../network/dns-forwarding-ruleset/main.bicep | 147 ++-- .../network/dns-forwarding-ruleset/main.json | 12 +- .../tests/e2e/defaults/dependencies.bicep | 7 +- .../tests/e2e/defaults/main.test.bicep | 26 +- .../tests/e2e/max/dependencies.bicep | 8 +- .../tests/e2e/max/main.test.bicep | 109 +-- .../tests/e2e/waf-aligned/dependencies.bicep | 8 +- .../tests/e2e/waf-aligned/main.test.bicep | 44 +- .../virtual-network-link/main.json | 4 +- .../dns-resolver/inbound-endpoint/main.json | 4 +- avm/res/network/dns-resolver/main.bicep | 157 +++-- avm/res/network/dns-resolver/main.json | 12 +- .../dns-resolver/outbound-endpoint/main.json | 4 +- .../tests/e2e/defaults/dependencies.bicep | 7 +- .../tests/e2e/defaults/main.test.bicep | 18 +- .../tests/e2e/max/dependencies.bicep | 7 +- .../tests/e2e/max/main.test.bicep | 91 +-- .../tests/e2e/waf-aligned/dependencies.bicep | 7 +- .../tests/e2e/waf-aligned/main.test.bicep | 54 +- avm/res/network/dns-zone/a/main.bicep | 78 ++- avm/res/network/dns-zone/a/main.json | 4 +- avm/res/network/dns-zone/aaaa/main.bicep | 78 ++- avm/res/network/dns-zone/aaaa/main.json | 4 +- avm/res/network/dns-zone/caa/main.bicep | 70 +- avm/res/network/dns-zone/caa/main.json | 4 +- avm/res/network/dns-zone/cname/main.bicep | 78 ++- avm/res/network/dns-zone/cname/main.json | 4 +- avm/res/network/dns-zone/main.bicep | 360 ++++++---- avm/res/network/dns-zone/main.json | 44 +- avm/res/network/dns-zone/mx/main.bicep | 70 +- avm/res/network/dns-zone/mx/main.json | 4 +- avm/res/network/dns-zone/ns/main.bicep | 70 +- avm/res/network/dns-zone/ns/main.json | 4 +- avm/res/network/dns-zone/ptr/main.bicep | 70 +- avm/res/network/dns-zone/ptr/main.json | 4 +- avm/res/network/dns-zone/soa/main.bicep | 70 +- avm/res/network/dns-zone/soa/main.json | 4 +- avm/res/network/dns-zone/srv/main.bicep | 70 +- avm/res/network/dns-zone/srv/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../dns-zone/tests/e2e/max/dependencies.bicep | 32 +- .../dns-zone/tests/e2e/max/main.test.bicep | 516 +++++++------- .../tests/e2e/waf-aligned/dependencies.bicep | 32 +- .../tests/e2e/waf-aligned/main.test.bicep | 32 +- avm/res/network/dns-zone/txt/main.bicep | 70 +- avm/res/network/dns-zone/txt/main.json | 4 +- .../network/express-route-circuit/main.bicep | 175 +++-- .../network/express-route-circuit/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 22 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 107 +-- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 70 +- .../network/express-route-gateway/main.bicep | 89 ++- .../network/express-route-gateway/main.json | 4 +- .../tests/e2e/max/main.test.bicep | 5 +- avm/res/network/firewall-policy/main.bicep | 143 ++-- avm/res/network/firewall-policy/main.json | 8 +- .../rule-collection-group/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 112 +-- .../tests/e2e/waf-aligned/main.test.bicep | 102 +-- .../main.bicep | 86 ++- .../main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 185 ++--- .../tests/e2e/waf-aligned/main.test.bicep | 150 ++-- avm/res/network/front-door/main.bicep | 139 ++-- avm/res/network/front-door/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 156 +++-- .../tests/e2e/max/dependencies.bicep | 4 +- .../front-door/tests/e2e/max/main.test.bicep | 255 +++---- .../tests/e2e/waf-aligned/main.test.bicep | 196 +++--- avm/res/network/ip-group/main.bicep | 89 ++- avm/res/network/ip-group/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../ip-group/tests/e2e/max/dependencies.bicep | 4 +- .../ip-group/tests/e2e/max/main.test.bicep | 73 +- .../tests/e2e/waf-aligned/main.test.bicep | 32 +- .../backend-address-pool/main.json | 4 +- .../load-balancer/inbound-nat-rule/main.bicep | 8 +- .../load-balancer/inbound-nat-rule/main.json | 4 +- avm/res/network/load-balancer/main.bicep | 383 ++++++---- avm/res/network/load-balancer/main.json | 12 +- .../tests/e2e/defaults/main.test.bicep | 38 +- .../tests/e2e/internal/main.test.bicep | 175 ++--- .../tests/e2e/max/main.test.bicep | 259 +++---- .../tests/e2e/waf-aligned/main.test.bicep | 261 +++---- .../network/local-network-gateway/main.bicep | 92 ++- .../network/local-network-gateway/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 24 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 77 +- .../tests/e2e/waf-aligned/main.test.bicep | 44 +- avm/res/network/nat-gateway/main.bicep | 169 +++-- avm/res/network/nat-gateway/main.json | 12 +- .../tests/e2e/defaults/main.test.bicep | 18 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../nat-gateway/tests/e2e/max/main.test.bicep | 152 ++-- .../tests/e2e/prefixCombined/main.test.bicep | 32 +- .../tests/e2e/waf-aligned/main.test.bicep | 80 +-- avm/res/network/network-interface/main.bicep | 215 +++--- avm/res/network/network-interface/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 32 +- .../tests/e2e/max/main.test.bicep | 137 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 96 +-- .../connectivity-configuration/main.json | 4 +- avm/res/network/network-manager/main.bicep | 202 +++--- avm/res/network/network-manager/main.json | 32 +- .../network-manager/network-group/main.bicep | 18 +- .../network-manager/network-group/main.json | 8 +- .../network-group/static-member/main.json | 4 +- .../scope-connection/main.json | 4 +- .../security-admin-configuration/main.bicep | 22 +- .../security-admin-configuration/main.json | 12 +- .../rule-collection/main.bicep | 36 +- .../rule-collection/main.json | 8 +- .../rule-collection/rule/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 28 +- .../tests/e2e/max/main.test.bicep | 419 +++++------ .../tests/e2e/waf-aligned/main.test.bicep | 38 +- .../network/network-security-group/main.bicep | 256 ++++--- .../network/network-security-group/main.json | 8 +- .../security-rule/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 213 +++--- .../tests/e2e/waf-aligned/main.test.bicep | 176 ++--- avm/res/network/private-dns-zone/a/main.bicep | 50 +- avm/res/network/private-dns-zone/a/main.json | 4 +- .../network/private-dns-zone/aaaa/main.bicep | 50 +- .../network/private-dns-zone/aaaa/main.json | 4 +- .../network/private-dns-zone/cname/main.bicep | 50 +- .../network/private-dns-zone/cname/main.json | 4 +- avm/res/network/private-dns-zone/main.bicep | 305 ++++---- avm/res/network/private-dns-zone/main.json | 40 +- .../network/private-dns-zone/mx/main.bicep | 50 +- avm/res/network/private-dns-zone/mx/main.json | 4 +- .../network/private-dns-zone/ptr/main.bicep | 50 +- .../network/private-dns-zone/ptr/main.json | 4 +- .../network/private-dns-zone/soa/main.bicep | 50 +- .../network/private-dns-zone/soa/main.json | 4 +- .../network/private-dns-zone/srv/main.bicep | 50 +- .../network/private-dns-zone/srv/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 520 +++++++------- .../tests/e2e/waf-aligned/main.test.bicep | 32 +- .../network/private-dns-zone/txt/main.bicep | 50 +- .../network/private-dns-zone/txt/main.json | 4 +- .../virtual-network-link/main.json | 4 +- avm/res/network/private-endpoint/main.bicep | 136 ++-- avm/res/network/private-endpoint/main.json | 8 +- .../private-dns-zone-group/main.bicep | 12 +- .../private-dns-zone-group/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 60 +- .../tests/e2e/max/main.test.bicep | 143 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 94 +-- .../network/private-link-service/main.bicep | 94 ++- .../network/private-link-service/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 42 +- .../tests/e2e/max/main.test.bicep | 119 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 78 ++- avm/res/network/public-ip-address/main.bicep | 165 +++-- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 107 +-- .../tests/e2e/waf-aligned/main.test.bicep | 107 +-- avm/res/network/public-ip-prefix/main.bicep | 89 ++- avm/res/network/public-ip-prefix/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 18 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 67 +- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 26 +- avm/res/network/route-table/main.bicep | 92 ++- avm/res/network/route-table/main.json | 4 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../route-table/tests/e2e/max/main.test.bicep | 5 +- .../network/trafficmanagerprofile/main.bicep | 144 ++-- .../network/trafficmanagerprofile/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 95 +-- .../tests/e2e/waf-aligned/main.test.bicep | 112 +-- .../virtual-hub/hub-route-table/main.bicep | 27 +- .../virtual-hub/hub-route-table/main.json | 4 +- .../hub-virtual-network-connection/main.bicep | 27 +- .../hub-virtual-network-connection/main.json | 4 +- avm/res/network/virtual-hub/main.bicep | 149 ++-- avm/res/network/virtual-hub/main.json | 12 +- .../tests/e2e/defaults/main.test.bicep | 21 +- .../tests/e2e/max/dependencies.bicep | 1 - .../virtual-hub/tests/e2e/max/main.test.bicep | 80 +-- .../tests/e2e/waf-aligned/dependencies.bicep | 1 - .../tests/e2e/waf-aligned/main.test.bicep | 80 +-- .../virtual-network-gateway/main.bicep | 366 +++++----- .../network/virtual-network-gateway/main.json | 8 +- .../nat-rule/main.json | 4 +- .../tests/e2e/aadvpn/main.test.bicep | 66 +- .../tests/e2e/defaults/main.test.bicep | 36 +- .../tests/e2e/expressRoute/main.test.bicep | 44 +- .../tests/e2e/max/main.test.bicep | 205 +++--- .../tests/e2e/vpn/main.test.bicep | 58 +- .../tests/e2e/waf-aligned/main.test.bicep | 170 ++--- avm/res/network/virtual-network/main.bicep | 347 +++++---- avm/res/network/virtual-network/main.json | 16 +- .../network/virtual-network/subnet/main.bicep | 71 +- .../network/virtual-network/subnet/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 22 +- .../tests/e2e/max/main.test.bicep | 204 +++--- .../tests/e2e/vnetPeering/main.test.bicep | 90 +-- .../tests/e2e/waf-aligned/main.test.bicep | 190 ++--- .../virtual-network-peering/main.json | 4 +- avm/res/network/virtual-wan/main.bicep | 89 ++- avm/res/network/virtual-wan/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/dependencies.bicep | 4 +- .../virtual-wan/tests/e2e/max/main.test.bicep | 79 ++- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 38 +- avm/res/network/vpn-gateway/main.bicep | 157 +++-- avm/res/network/vpn-gateway/main.json | 12 +- .../network/vpn-gateway/nat-rule/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 24 +- .../vpn-gateway/tests/e2e/max/main.test.bicep | 106 +-- .../tests/e2e/waf-aligned/main.test.bicep | 106 +-- .../vpn-gateway/vpn-connection/main.bicep | 8 +- .../vpn-gateway/vpn-connection/main.json | 4 +- avm/res/network/vpn-site/main.bicep | 100 ++- avm/res/network/vpn-site/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 30 +- .../vpn-site/tests/e2e/max/main.test.bicep | 145 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 110 +-- .../workspace/data-export/main.json | 4 +- .../workspace/data-source/main.bicep | 20 +- .../workspace/data-source/main.json | 4 +- .../workspace/linked-service/main.json | 4 +- .../linked-storage-account/main.json | 4 +- .../operational-insights/workspace/main.bicep | 394 ++++++----- .../operational-insights/workspace/main.json | 32 +- .../workspace/saved-search/main.json | 4 +- .../storage-insight-config/main.json | 4 +- .../workspace/table/main.bicep | 60 +- .../workspace/table/main.json | 4 +- .../workspace/tests/e2e/adv/main.test.bicep | 508 +++++++------- .../tests/e2e/defaults/main.test.bicep | 16 +- .../workspace/tests/e2e/max/main.test.bicep | 521 +++++++------- .../tests/e2e/waf-aligned/main.test.bicep | 298 ++++---- .../operations-management/solution/main.bicep | 27 +- .../operations-management/solution/main.json | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 22 +- .../power-bi-dedicated/capacity/main.bicep | 94 ++- avm/res/power-bi-dedicated/capacity/main.json | 4 +- .../tests/e2e/defaults/dependencies.bicep | 4 +- .../tests/e2e/defaults/main.test.bicep | 26 +- .../capacity/tests/e2e/max/dependencies.bicep | 4 +- .../capacity/tests/e2e/max/main.test.bicep | 81 ++- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 44 +- avm/res/purview/account/main.bicep | 578 ++++++++------- avm/res/purview/account/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../account/tests/e2e/max/dependencies.bicep | 10 +- .../account/tests/e2e/max/main.test.bicep | 267 +++---- .../tests/e2e/waf-aligned/dependencies.bicep | 10 +- .../tests/e2e/waf-aligned/main.test.bicep | 141 ++-- .../vault/backup-config/main.json | 4 +- .../protection-container/main.bicep | 24 +- .../protection-container/main.json | 8 +- .../protected-item/main.json | 4 +- .../vault/backup-policy/main.json | 4 +- .../vault/backup-storage-config/main.json | 4 +- avm/res/recovery-services/vault/main.bicep | 447 +++++++----- avm/res/recovery-services/vault/main.json | 44 +- .../vault/replication-alert-setting/main.json | 4 +- .../vault/replication-fabric/main.bicep | 26 +- .../vault/replication-fabric/main.json | 12 +- .../main.bicep | 38 +- .../main.json | 8 +- .../main.bicep | 17 +- .../main.json | 4 +- .../vault/replication-policy/main.json | 4 +- .../vault/tests/e2e/defaults/main.test.bicep | 38 +- .../vault/tests/e2e/dr/main.test.bicep | 134 ++-- .../vault/tests/e2e/max/main.test.bicep | 619 ++++++++-------- .../tests/e2e/waf-aligned/main.test.bicep | 582 ++++++++-------- avm/res/resource-graph/query/main.bicep | 84 ++- avm/res/resource-graph/query/main.json | 4 +- .../query/tests/e2e/max/main.test.bicep | 5 +- .../resources/deployment-script/main.bicep | 134 ++-- avm/res/resources/deployment-script/main.json | 4 +- .../tests/e2e/max/main.test.bicep | 5 +- avm/res/resources/resource-group/main.bicep | 57 +- avm/res/resources/resource-group/main.json | 12 +- .../tests/e2e/defaults/main.test.bicep | 14 +- .../tests/e2e/max/main.test.bicep | 5 +- avm/res/search/search-service/main.bicep | 267 ++++--- avm/res/search/search-service/main.json | 8 +- .../shared-private-link-resource/main.json | 4 +- .../tests/e2e/max/main.test.bicep | 5 +- .../namespace/authorization-rule/main.json | 4 +- .../disaster-recovery-config/main.json | 4 +- avm/res/service-bus/namespace/main.bicep | 526 ++++++++------ avm/res/service-bus/namespace/main.json | 40 +- .../migration-configuration/main.json | 4 +- .../namespace/network-rule-set/main.bicep | 22 +- .../namespace/network-rule-set/main.json | 4 +- .../queue/authorization-rule/main.json | 4 +- .../service-bus/namespace/queue/main.bicep | 90 ++- avm/res/service-bus/namespace/queue/main.json | 8 +- .../tests/e2e/defaults/main.test.bicep | 20 +- .../tests/e2e/encr/dependencies.bicep | 5 +- .../namespace/tests/e2e/encr/main.test.bicep | 50 +- .../namespace/tests/e2e/max/main.test.bicep | 366 +++++----- .../tests/e2e/waf-aligned/main.test.bicep | 260 +++---- .../topic/authorization-rule/main.json | 4 +- .../service-bus/namespace/topic/main.bicep | 162 +++-- avm/res/service-bus/namespace/topic/main.json | 12 +- .../namespace/topic/subscription/main.json | 4 +- avm/res/signal-r-service/signal-r/main.bicep | 254 ++++--- avm/res/signal-r-service/signal-r/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../signal-r/tests/e2e/max/main.test.bicep | 156 +++-- .../tests/e2e/waf-aligned/main.test.bicep | 99 +-- .../signal-r-service/web-pub-sub/main.bicep | 244 ++++--- .../signal-r-service/web-pub-sub/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../web-pub-sub/tests/e2e/max/main.test.bicep | 153 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 98 +-- .../main.json | 4 +- .../main.json | 4 +- avm/res/sql/server/database/main.bicep | 97 ++- avm/res/sql/server/database/main.json | 12 +- avm/res/sql/server/elastic-pool/main.json | 4 +- .../sql/server/encryption-protector/main.json | 4 +- avm/res/sql/server/firewall-rule/main.json | 4 +- avm/res/sql/server/key/main.bicep | 4 +- avm/res/sql/server/key/main.json | 4 +- avm/res/sql/server/main.bicep | 554 +++++++++------ avm/res/sql/server/main.json | 48 +- .../server/security-alert-policy/main.json | 4 +- .../server/tests/e2e/defaults/main.test.bicep | 20 +- .../server/tests/e2e/max/dependencies.bicep | 12 +- .../sql/server/tests/e2e/max/main.test.bicep | 5 +- .../tests/e2e/waf-aligned/dependencies.bicep | 12 +- .../sql/server/virtual-network-rule/main.json | 4 +- .../vulnerability-assessment/main.bicep | 19 +- .../server/vulnerability-assessment/main.json | 8 +- .../container/immutability-policy/main.json | 4 +- .../blob-service/container/main.json | 8 +- .../storage-account/blob-service/main.json | 12 +- .../storage-account/file-service/main.json | 12 +- .../file-service/share/main.json | 8 +- .../storage-account/local-user/main.json | 4 +- avm/res/storage/storage-account/main.bicep | 594 ++++++++++------ .../management-policy/main.json | 4 +- .../storage-account/queue-service/main.json | 8 +- .../queue-service/queue/main.json | 4 +- .../storage-account/table-service/main.json | 8 +- .../table-service/table/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 21 +- avm/res/synapse/private-link-hub/main.bicep | 170 +++-- avm/res/synapse/private-link-hub/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../tests/e2e/max/main.test.bicep | 96 +-- .../tests/e2e/waf-aligned/dependencies.bicep | 1 - .../tests/e2e/waf-aligned/main.test.bicep | 54 +- .../workspace/integration-runtime/main.bicep | 22 +- .../workspace/integration-runtime/main.json | 4 +- avm/res/synapse/workspace/key/main.json | 4 +- avm/res/synapse/workspace/main.bicep | 377 ++++++---- avm/res/synapse/workspace/main.json | 16 +- .../tests/e2e/defaults/dependencies.bicep | 28 +- .../tests/e2e/defaults/main.test.bicep | 28 +- .../tests/e2e/encrwsai/dependencies.bicep | 68 +- .../tests/e2e/encrwsai/main.test.bicep | 36 +- .../tests/e2e/encrwuai/dependencies.bicep | 89 +-- .../tests/e2e/encrwuai/main.test.bicep | 36 +- .../tests/e2e/managedvnet/dependencies.bicep | 28 +- .../tests/e2e/managedvnet/main.test.bicep | 36 +- .../workspace/tests/e2e/max/main.test.bicep | 203 +++--- .../tests/e2e/waf-aligned/main.test.bicep | 110 +-- .../image-template/main.bicep | 174 +++-- .../image-template/main.json | 4 +- .../tests/e2e/defaults/dependencies.bicep | 5 +- .../tests/e2e/max/dependencies.bicep | 22 +- .../tests/e2e/max/main.test.bicep | 5 +- avm/res/web/serverfarm/main.bicep | 145 ++-- avm/res/web/serverfarm/main.json | 4 +- .../tests/e2e/defaults/main.test.bicep | 28 +- .../serverfarm/tests/e2e/max/main.test.bicep | 113 +-- .../tests/e2e/waf-aligned/main.test.bicep | 78 ++- avm/res/web/site/README.md | 5 +- .../web/site/config--appsettings/main.bicep | 49 +- .../relay/main.bicep | 8 +- avm/res/web/site/main.bicep | 439 +++++++----- .../site/slot/config--appsettings/main.bicep | 47 +- .../relay/main.bicep | 8 +- avm/res/web/site/slot/main.bicep | 314 +++++---- .../functionApp.defaults/dependencies.bicep | 20 +- .../e2e/functionApp.defaults/main.test.bicep | 30 +- .../tests/e2e/functionApp.max/main.test.bicep | 295 ++++---- .../tests/e2e/waf-aligned/main.test.bicep | 84 +-- .../e2e/webApp.defaults/dependencies.bicep | 20 +- .../tests/e2e/webApp.defaults/main.test.bicep | 34 +- .../site/tests/e2e/webApp.max/main.test.bicep | 351 +++++----- .../webAppLinux.defaults/dependencies.bicep | 24 +- .../e2e/webAppLinux.defaults/main.test.bicep | 26 +- .../tests/e2e/webAppLinux.max/main.test.bicep | 351 +++++----- avm/res/web/static-site/config/main.json | 4 +- .../web/static-site/custom-domain/main.json | 4 +- .../web/static-site/linked-backend/main.json | 4 +- avm/res/web/static-site/main.bicep | 265 ++++--- avm/res/web/static-site/main.json | 20 +- .../tests/e2e/defaults/main.test.bicep | 16 +- .../static-site/tests/e2e/max/main.test.bicep | 143 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 90 +-- avm/utilities/tools/helper/src/src.main.bicep | 27 +- .../tools/helper/src/src.main.test.bicep | 18 +- 860 files changed, 32708 insertions(+), 26454 deletions(-) diff --git a/avm/bicepconfig.json b/avm/bicepconfig.json index 439facdc5b..6b8310f4d8 100644 --- a/avm/bicepconfig.json +++ b/avm/bicepconfig.json @@ -2,8 +2,7 @@ // For further information, please refer to the official documentation at: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-config { "experimentalFeaturesEnabled": { - "publishSource": true, - "legacyFormatter": true // Reason: Enables code formatting with the v1 formatter, ensuring a safer transition to the v2 formatter + "publishSource": true }, "analyzers": { "core": { diff --git a/avm/res/analysis-services/server/main.bicep b/avm/res/analysis-services/server/main.bicep index 17aca5df92..0655bf5d17 100644 --- a/avm/res/analysis-services/server/main.bicep +++ b/avm/res/analysis-services/server/main.bicep @@ -45,27 +45,34 @@ 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') + '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.analysisservices-server.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.analysisservices-server.${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 server 'Microsoft.AnalysisServices/servers@2017-08-01' = { name: name @@ -80,51 +87,66 @@ resource server 'Microsoft.AnalysisServices/servers@2017-08-01' = { } } -resource server_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.' +resource server_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: server } - scope: server -} -resource server_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 - 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 +resource server_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 + 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 + } + scope: server } - scope: server -}] - -resource server_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(server.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 +] + +resource server_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(server.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: server } - scope: server -}] +] @description('The name of the analysis service.') output name string = server.name diff --git a/avm/res/analysis-services/server/main.json b/avm/res/analysis-services/server/main.json index f5beb4b850..499b9433a1 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.25.53.49325", - "templateHash": "15159283808347195170" + "version": "0.26.54.24096", + "templateHash": "1590669612196455003" }, "name": "Analysis Services Servers", "description": "This module deploys an Analysis Services Server.", diff --git a/avm/res/analysis-services/server/tests/e2e/defaults/main.test.bicep b/avm/res/analysis-services/server/tests/e2e/defaults/main.test.bicep index 9eff12c840..22f5ddf455 100644 --- a/avm/res/analysis-services/server/tests/e2e/defaults/main.test.bicep +++ b/avm/res/analysis-services/server/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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 + } } -}] +] diff --git a/avm/res/analysis-services/server/tests/e2e/max/main.test.bicep b/avm/res/analysis-services/server/tests/e2e/max/main.test.bicep index 9f52b51d27..36954fb7b2 100644 --- a/avm/res/analysis-services/server/tests/e2e/max/main.test.bicep +++ b/avm/res/analysis-services/server/tests/e2e/max/main.test.bicep @@ -59,75 +59,80 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - } - skuName: 'S0' - skuCapacity: 1 - firewallSettings: { - firewallRules: [ - { - firewallRuleName: 'AllowFromAll' - rangeStart: '0.0.0.0' - rangeEnd: '255.255.255.255' - } - ] - enablePowerBIService: true - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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' } - { - 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' - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ + skuName: 'S0' + skuCapacity: 1 + firewallSettings: { + firewallRules: [ { - category: 'AllMetrics' + firewallRuleName: 'AllowFromAll' + rangeStart: '0.0.0.0' + rangeEnd: '255.255.255.255' } ] - logCategoriesAndGroups: [ - { - category: 'Engine' - } - { - category: 'Service' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + enablePowerBIService: true + } + 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' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + logCategoriesAndGroups: [ + { + category: 'Engine' + } + { + category: 'Service' + } + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/analysis-services/server/tests/e2e/waf-aligned/main.test.bicep b/avm/res/analysis-services/server/tests/e2e/waf-aligned/main.test.bicep index 862f260663..aeab0feba2 100644 --- a/avm/res/analysis-services/server/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/analysis-services/server/tests/e2e/waf-aligned/main.test.bicep @@ -50,57 +50,59 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - } - skuName: 'S0' - skuCapacity: 1 - firewallSettings: { - firewallRules: [ - { - firewallRuleName: 'AllowFromAll' - rangeStart: '0.0.0.0' - rangeEnd: '255.255.255.255' - } - ] - enablePowerBIService: true - } - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - logCategoriesAndGroups: [ - { - category: 'Engine' - } +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' + } + skuName: 'S0' + skuCapacity: 1 + firewallSettings: { + firewallRules: [ { - category: 'Service' + firewallRuleName: 'AllowFromAll' + rangeStart: '0.0.0.0' + rangeEnd: '255.255.255.255' } ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + enablePowerBIService: true + } + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + logCategoriesAndGroups: [ + { + category: 'Engine' + } + { + category: 'Service' + } + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + diagnosticDependencies + ] } - dependsOn: [ - diagnosticDependencies - ] -}] +] 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 bd4daa7b03..b20b0388c7 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.25.53.49325", - "templateHash": "4002198465184356188" + "version": "0.26.54.24096", + "templateHash": "14411287735172753559" }, "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 09a9425d19..149062f9e8 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.25.53.49325", - "templateHash": "857470281336543408" + "version": "0.26.54.24096", + "templateHash": "5827467280453778347" }, "name": "API Management Service APIs", "description": "This module deploys an API Management Service API.", @@ -267,8 +267,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "5383521143080449228" + "version": "0.26.54.24096", + "templateHash": "11734266416309377949" }, "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 4667963a3b..bcbaf1d3bc 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.25.53.49325", - "templateHash": "5383521143080449228" + "version": "0.26.54.24096", + "templateHash": "11734266416309377949" }, "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 10e75c27e4..78869fc966 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.25.53.49325", - "templateHash": "6703063831636643162" + "version": "0.26.54.24096", + "templateHash": "505882801529152233" }, "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 2e1bca38c9..bba5ebcc1f 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.25.53.49325", - "templateHash": "16587888030936573636" + "version": "0.26.54.24096", + "templateHash": "5914852504306173482" }, "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 38eb6d1873..537d4e1259 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.25.53.49325", - "templateHash": "1295772952565058470" + "version": "0.26.54.24096", + "templateHash": "5452536693649070190" }, "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 6d182b6014..d1ac06182d 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.25.53.49325", - "templateHash": "17146377320278316178" + "version": "0.26.54.24096", + "templateHash": "6944159515007886666" }, "name": "API Management Service Identity Providers", "description": "This module deploys an API Management Service Identity Provider.", diff --git a/avm/res/api-management/service/named-value/main.json b/avm/res/api-management/service/named-value/main.json index 860c79be1c..2087682ca4 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.25.53.49325", - "templateHash": "5043439748386656207" + "version": "0.26.54.24096", + "templateHash": "17256518550792037410" }, "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 bb46dd0c56..a2d8a0624c 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.25.53.49325", - "templateHash": "3643398305472631880" + "version": "0.26.54.24096", + "templateHash": "12407621079025229005" }, "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 0e3c01eaf1..510cbe1b2c 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.25.53.49325", - "templateHash": "14726250901514511689" + "version": "0.26.54.24096", + "templateHash": "6528716876560144579" }, "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 fce4061640..6e0c22412b 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.25.53.49325", - "templateHash": "2508310027677163402" + "version": "0.26.54.24096", + "templateHash": "2440306385645798125" }, "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 2091c80834..af4900659f 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.25.53.49325", - "templateHash": "14996351450231036018" + "version": "0.26.54.24096", + "templateHash": "7056381119937736015" }, "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 d1bbdbe274..36c877e581 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.25.53.49325", - "templateHash": "10657321045680066427" + "version": "0.26.54.24096", + "templateHash": "2407987626180908324" }, "name": "API Management Service Products", "description": "This module deploys an API Management Service Product.", @@ -126,8 +126,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2508310027677163402" + "version": "0.26.54.24096", + "templateHash": "2440306385645798125" }, "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.25.53.49325", - "templateHash": "14996351450231036018" + "version": "0.26.54.24096", + "templateHash": "7056381119937736015" }, "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 70e72bc609..7bfb9de555 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.25.53.49325", - "templateHash": "16952030877948084799" + "version": "0.26.54.24096", + "templateHash": "12071485798846786639" }, "name": "API Management Service Subscriptions", "description": "This module deploys an API Management Service Subscription.", diff --git a/avm/res/app-configuration/configuration-store/key-value/main.json b/avm/res/app-configuration/configuration-store/key-value/main.json index 0a888d3aaa..cc5f75de77 100644 --- a/avm/res/app-configuration/configuration-store/key-value/main.json +++ b/avm/res/app-configuration/configuration-store/key-value/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16990071481669469313" + "version": "0.26.54.24096", + "templateHash": "8492150446155311380" }, "name": "App Configuration Stores Key Values", "description": "This module deploys an App Configuration Store Key Value.", diff --git a/avm/res/app-configuration/configuration-store/main.bicep b/avm/res/app-configuration/configuration-store/main.bicep index d80856f18e..124481d13b 100644 --- a/avm/res/app-configuration/configuration-store/main.bicep +++ b/avm/res/app-configuration/configuration-store/main.bicep @@ -67,56 +67,92 @@ param enableTelemetry bool = true @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') param privateEndpoints privateEndpointType -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - 'App Compliance Automation Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f37683f-2463-46b6-9ce7-9b788b988ba2') - 'App Compliance Automation Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ffc6bbe0-e443-4c3b-bf54-26581bb2f78e') - 'App Configuration Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5ae67dd6-50cb-40e7-96ff-dc2bfa4b606b') - 'App Configuration Data Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '516239f1-63e1-4d78-a4de-a74fb236a071') + 'App Compliance Automation Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0f37683f-2463-46b6-9ce7-9b788b988ba2' + ) + 'App Compliance Automation Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'ffc6bbe0-e443-4c3b-bf54-26581bb2f78e' + ) + 'App Configuration Data Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '5ae67dd6-50cb-40e7-96ff-dc2bfa4b606b' + ) + 'App Configuration Data Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '516239f1-63e1-4d78-a4de-a74fb236a071' + ) 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') + '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.appconfiguration-configurationstore.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.appconfiguration-configurationstore.${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 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 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 configurationStore 'Microsoft.AppConfiguration/configurationStores@2023-03-01' = { name: name @@ -130,116 +166,151 @@ resource configurationStore 'Microsoft.AppConfiguration/configurationStores@2023 createMode: createMode disableLocalAuth: disableLocalAuth enablePurgeProtection: sku == 'Free' ? false : enablePurgeProtection - encryption: !empty(customerManagedKey) ? { - keyVaultProperties: { - keyIdentifier: !empty(customerManagedKey.?keyVersion ?? '') ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.keyVersion}' : cMKKeyVault::cMKKey.properties.keyUriWithVersion - identityClientId: !empty(customerManagedKey.?userAssignedIdentityResourceId ?? '') ? cMKUserAssignedIdentity.properties.clientId : null - } - } : null - publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) : (!empty(privateEndpoints) ? 'Disabled' : 'Enabled') + encryption: !empty(customerManagedKey) + ? { + keyVaultProperties: { + keyIdentifier: !empty(customerManagedKey.?keyVersion ?? '') + ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.keyVersion}' + : cMKKeyVault::cMKKey.properties.keyUriWithVersion + identityClientId: !empty(customerManagedKey.?userAssignedIdentityResourceId ?? '') + ? cMKUserAssignedIdentity.properties.clientId + : null + } + } + : null + publicNetworkAccess: !empty(publicNetworkAccess) + ? any(publicNetworkAccess) + : (!empty(privateEndpoints) ? 'Disabled' : 'Enabled') softDeleteRetentionInDays: sku == 'Free' ? 0 : softDeleteRetentionInDays } } -module configurationStore_keyValues 'key-value/main.bicep' = [for (keyValue, index) in (keyValues ?? []): { - name: '${uniqueString(deployment().name, location)}-AppConfig-KeyValues-${index}' - params: { - appConfigurationName: configurationStore.name - name: keyValue.name - value: keyValue.value - contentType: keyValue.?contentType - tags: keyValue.?tags ?? tags +module configurationStore_keyValues 'key-value/main.bicep' = [ + for (keyValue, index) in (keyValues ?? []): { + name: '${uniqueString(deployment().name, location)}-AppConfig-KeyValues-${index}' + params: { + appConfigurationName: configurationStore.name + name: keyValue.name + value: keyValue.value + contentType: keyValue.?contentType + tags: keyValue.?tags ?? tags + } } -}] +] -resource configurationStore_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.' +resource configurationStore_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: configurationStore } - scope: configurationStore -} -resource configurationStore_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 - 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 +resource configurationStore_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 + 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 + } + scope: configurationStore } - scope: configurationStore -}] +] -resource configurationStore_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(configurationStore.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 +resource configurationStore_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(configurationStore.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: configurationStore } - scope: configurationStore -}] +] @batchSize(1) -module configurationStore_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-configurationStore-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(configurationStore.id, '/'))}-${privateEndpoint.?service ?? 'configurationStores'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(configurationStore.id, '/'))}-${privateEndpoint.?service ?? 'configurationStores'}-${index}' - properties: { - privateLinkServiceId: configurationStore.id - groupIds: [ - privateEndpoint.?service ?? 'configurationStores' +module configurationStore_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-configurationStore-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(configurationStore.id, '/'))}-${privateEndpoint.?service ?? 'configurationStores'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(configurationStore.id, '/'))}-${privateEndpoint.?service ?? 'configurationStores'}-${index}' + properties: { + privateLinkServiceId: configurationStore.id + groupIds: [ + privateEndpoint.?service ?? 'configurationStores' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(configurationStore.id, '/'))}-${privateEndpoint.?service ?? 'configurationStores'}-${index}' - properties: { - privateLinkServiceId: configurationStore.id - groupIds: [ - privateEndpoint.?service ?? 'configurationStores' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(configurationStore.id, '/'))}-${privateEndpoint.?service ?? 'configurationStores'}-${index}' + properties: { + privateLinkServiceId: configurationStore.id + groupIds: [ + privateEndpoint.?service ?? 'configurationStores' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] @description('The name of the app configuration.') output name string = configurationStore.name diff --git a/avm/res/app-configuration/configuration-store/main.json b/avm/res/app-configuration/configuration-store/main.json index 558a7bfb28..9f862cd382 100644 --- a/avm/res/app-configuration/configuration-store/main.json +++ b/avm/res/app-configuration/configuration-store/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2210459796702021612" + "version": "0.26.54.24096", + "templateHash": "17308644596595948852" }, "name": "App Configuration Stores", "description": "This module deploys an App Configuration Store.", @@ -779,8 +779,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16990071481669469313" + "version": "0.26.54.24096", + "templateHash": "8492150446155311380" }, "name": "App Configuration Stores Key Values", "description": "This module deploys an App Configuration Store Key Value.", diff --git a/avm/res/app-configuration/configuration-store/tests/e2e/defaults/main.test.bicep b/avm/res/app-configuration/configuration-store/tests/e2e/defaults/main.test.bicep index 89c9a732fb..990968dd9a 100644 --- a/avm/res/app-configuration/configuration-store/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app-configuration/configuration-store/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { // ============== // @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 +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/app-configuration/configuration-store/tests/e2e/encr/dependencies.bicep b/avm/res/app-configuration/configuration-store/tests/e2e/encr/dependencies.bicep index bebad9a289..bd17946f56 100644 --- a/avm/res/app-configuration/configuration-store/tests/e2e/encr/dependencies.bicep +++ b/avm/res/app-configuration/configuration-store/tests/e2e/encr/dependencies.bicep @@ -43,7 +43,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: keyVault::key properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User principalType: 'ServicePrincipal' } } diff --git a/avm/res/app-configuration/configuration-store/tests/e2e/encr/main.test.bicep b/avm/res/app-configuration/configuration-store/tests/e2e/encr/main.test.bicep index ad837aa7c2..6c8874859b 100644 --- a/avm/res/app-configuration/configuration-store/tests/e2e/encr/main.test.bicep +++ b/avm/res/app-configuration/configuration-store/tests/e2e/encr/main.test.bicep @@ -50,40 +50,42 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - createMode: 'Default' - disableLocalAuth: false - enablePurgeProtection: false - keyValues: [ - { - contentType: 'contentType' - name: 'keyName' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId +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 + createMode: 'Default' + disableLocalAuth: false + enablePurgeProtection: false + keyValues: [ + { + contentType: 'contentType' + name: 'keyName' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } + principalType: 'ServicePrincipal' + } + ] + value: 'valueName' + } + ] + softDeleteRetentionInDays: 1 + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] - value: 'valueName' } - ] - softDeleteRetentionInDays: 1 - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - customerManagedKey: { - keyName: nestedDependencies.outputs.keyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + customerManagedKey: { + keyName: nestedDependencies.outputs.keyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + } } } -}] +] diff --git a/avm/res/app-configuration/configuration-store/tests/e2e/max/main.test.bicep b/avm/res/app-configuration/configuration-store/tests/e2e/max/main.test.bicep index a58054c1ea..5028ef0929 100644 --- a/avm/res/app-configuration/configuration-store/tests/e2e/max/main.test.bicep +++ b/avm/res/app-configuration/configuration-store/tests/e2e/max/main.test.bicep @@ -59,79 +59,84 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - createMode: 'Default' - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + createMode: 'Default' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + disableLocalAuth: false + enablePurgeProtection: false + keyValues: [ + { + contentType: 'contentType' + name: 'keyName' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + value: 'valueName' + } + { + name: 'keyName2' + value: 'valueName2' + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - disableLocalAuth: false - enablePurgeProtection: false - keyValues: [ - { - contentType: 'contentType' - name: 'keyName' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } + 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' + } + ] + softDeleteRetentionInDays: 1 + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] - value: 'valueName' } - { - name: 'keyName2' - value: 'valueName2' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - 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' - } - ] - softDeleteRetentionInDays: 1 - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/app-configuration/configuration-store/tests/e2e/pe/main.test.bicep b/avm/res/app-configuration/configuration-store/tests/e2e/pe/main.test.bicep index 26e34c15cb..569c308146 100644 --- a/avm/res/app-configuration/configuration-store/tests/e2e/pe/main.test.bicep +++ b/avm/res/app-configuration/configuration-store/tests/e2e/pe/main.test.bicep @@ -45,34 +45,36 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - createMode: 'Default' - disableLocalAuth: false - enablePurgeProtection: false - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + createMode: 'Default' + disableLocalAuth: false + enablePurgeProtection: false + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] } - } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } - ] - softDeleteRetentionInDays: 1 + ] + softDeleteRetentionInDays: 1 + } } -}] +] diff --git a/avm/res/app-configuration/configuration-store/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app-configuration/configuration-store/tests/e2e/waf-aligned/main.test.bicep index cdd7faa503..6d3b70e64c 100644 --- a/avm/res/app-configuration/configuration-store/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app-configuration/configuration-store/tests/e2e/waf-aligned/main.test.bicep @@ -50,35 +50,37 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - createMode: 'Default' - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - disableLocalAuth: false - enablePurgeProtection: false - keyValues: [ - { - contentType: 'contentType' - name: 'keyName' - value: 'valueName' +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 + createMode: 'Default' + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + disableLocalAuth: false + enablePurgeProtection: false + keyValues: [ + { + contentType: 'contentType' + name: 'keyName' + value: 'valueName' + } + ] + softDeleteRetentionInDays: 1 + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - softDeleteRetentionInDays: 1 - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/automation/automation-account/job-schedule/main.json b/avm/res/automation/automation-account/job-schedule/main.json index 170fa3ee8a..1d7dbb1dfe 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.25.53.49325", - "templateHash": "4183701486282199551" + "version": "0.26.54.24096", + "templateHash": "3709450248827326388" }, "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 9db1af88c2..bbd2b9700e 100644 --- a/avm/res/automation/automation-account/main.bicep +++ b/avm/res/automation/automation-account/main.bicep @@ -74,56 +74,92 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - 'Automation Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f353d9bd-d4a6-484e-a77a-8050b599b867') - 'Automation Job Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4fe576fe-1146-4730-92eb-48519fa6bf9f') - 'Automation Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd3881f73-407a-4167-8283-e981cbba0404') - 'Automation Runbook Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5fb5aef8-1081-4b8e-bb16-9d5d0385bab5') + 'Automation Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f353d9bd-d4a6-484e-a77a-8050b599b867' + ) + 'Automation Job Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4fe576fe-1146-4730-92eb-48519fa6bf9f' + ) + 'Automation Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd3881f73-407a-4167-8283-e981cbba0404' + ) + 'Automation Runbook Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '5fb5aef8-1081-4b8e-bb16-9d5d0385bab5' + ) 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') + '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.automation-automationaccount.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.automation-automationaccount.${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 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 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 automationAccount 'Microsoft.Automation/automationAccounts@2022-08-08' = { name: name @@ -134,255 +170,353 @@ resource automationAccount 'Microsoft.Automation/automationAccounts@2022-08-08' sku: { name: skuName } - encryption: !empty(customerManagedKey) ? { - keySource: 'Microsoft.KeyVault' - identity: !empty(customerManagedKey.?userAssignedIdentityResourceId) ? { - userAssignedIdentity: cMKUserAssignedIdentity.id - } : null - keyVaultProperties: { - keyName: customerManagedKey!.keyName - keyVaultUri: cMKKeyVault.properties.vaultUri - keyVersion: !empty(customerManagedKey.?keyVersion ?? '') ? customerManagedKey!.keyVersion : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) - } - } : null - publicNetworkAccess: !empty(publicNetworkAccess) ? (publicNetworkAccess == 'Disabled' ? false : true) : (!empty(privateEndpoints) ? false : null) + encryption: !empty(customerManagedKey) + ? { + keySource: 'Microsoft.KeyVault' + identity: !empty(customerManagedKey.?userAssignedIdentityResourceId) + ? { + userAssignedIdentity: cMKUserAssignedIdentity.id + } + : null + keyVaultProperties: { + keyName: customerManagedKey!.keyName + keyVaultUri: cMKKeyVault.properties.vaultUri + keyVersion: !empty(customerManagedKey.?keyVersion ?? '') + ? customerManagedKey!.keyVersion + : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) + } + } + : null + publicNetworkAccess: !empty(publicNetworkAccess) + ? (publicNetworkAccess == 'Disabled' ? false : true) + : (!empty(privateEndpoints) ? false : null) disableLocalAuth: disableLocalAuth } } -module automationAccount_modules 'module/main.bicep' = [for (module, index) in modules: { - name: '${uniqueString(deployment().name, location)}-AutoAccount-Module-${index}' - params: { - name: module.name - automationAccountName: automationAccount.name - version: module.version - uri: module.uri - location: location - tags: module.?tags ?? tags +module automationAccount_modules 'module/main.bicep' = [ + for (module, index) in modules: { + name: '${uniqueString(deployment().name, location)}-AutoAccount-Module-${index}' + params: { + name: module.name + automationAccountName: automationAccount.name + version: module.version + uri: module.uri + location: location + tags: module.?tags ?? tags + } } -}] - -module automationAccount_schedules 'schedule/main.bicep' = [for (schedule, index) in schedules: { - name: '${uniqueString(deployment().name, location)}-AutoAccount-Schedule-${index}' - params: { - name: schedule.name - automationAccountName: automationAccount.name - advancedSchedule: contains(schedule, 'advancedSchedule') ? schedule.advancedSchedule : null - description: contains(schedule, 'description') ? schedule.description : '' - expiryTime: contains(schedule, 'expiryTime') ? schedule.expiryTime : '' - frequency: contains(schedule, 'frequency') ? schedule.frequency : 'OneTime' - interval: contains(schedule, 'interval') ? schedule.interval : 0 - startTime: contains(schedule, 'startTime') ? schedule.startTime : '' - timeZone: contains(schedule, 'timeZone') ? schedule.timeZone : '' +] + +module automationAccount_schedules 'schedule/main.bicep' = [ + for (schedule, index) in schedules: { + name: '${uniqueString(deployment().name, location)}-AutoAccount-Schedule-${index}' + params: { + name: schedule.name + automationAccountName: automationAccount.name + advancedSchedule: contains(schedule, 'advancedSchedule') ? schedule.advancedSchedule : null + description: contains(schedule, 'description') ? schedule.description : '' + expiryTime: contains(schedule, 'expiryTime') ? schedule.expiryTime : '' + frequency: contains(schedule, 'frequency') ? schedule.frequency : 'OneTime' + interval: contains(schedule, 'interval') ? schedule.interval : 0 + startTime: contains(schedule, 'startTime') ? schedule.startTime : '' + timeZone: contains(schedule, 'timeZone') ? schedule.timeZone : '' + } } -}] - -module automationAccount_runbooks 'runbook/main.bicep' = [for (runbook, index) in runbooks: { - name: '${uniqueString(deployment().name, location)}-AutoAccount-Runbook-${index}' - params: { - name: runbook.name - automationAccountName: automationAccount.name - type: runbook.type - description: contains(runbook, 'description') ? runbook.description : '' - uri: contains(runbook, 'uri') ? runbook.uri : '' - version: contains(runbook, 'version') ? runbook.version : '' - sasTokenValidityLength: runbook.?sasTokenValidityLength - scriptStorageAccountResourceId: runbook.?scriptStorageAccountResourceId - location: location - tags: runbook.?tags ?? tags +] + +module automationAccount_runbooks 'runbook/main.bicep' = [ + for (runbook, index) in runbooks: { + name: '${uniqueString(deployment().name, location)}-AutoAccount-Runbook-${index}' + params: { + name: runbook.name + automationAccountName: automationAccount.name + type: runbook.type + description: contains(runbook, 'description') ? runbook.description : '' + uri: contains(runbook, 'uri') ? runbook.uri : '' + version: contains(runbook, 'version') ? runbook.version : '' + sasTokenValidityLength: runbook.?sasTokenValidityLength + scriptStorageAccountResourceId: runbook.?scriptStorageAccountResourceId + location: location + tags: runbook.?tags ?? tags + } } -}] - -module automationAccount_jobSchedules 'job-schedule/main.bicep' = [for (jobSchedule, index) in jobSchedules: { - name: '${uniqueString(deployment().name, location)}-AutoAccount-JobSchedule-${index}' - params: { - automationAccountName: automationAccount.name - runbookName: jobSchedule.runbookName - scheduleName: jobSchedule.scheduleName - parameters: contains(jobSchedule, 'parameters') ? jobSchedule.parameters : {} - runOn: contains(jobSchedule, 'runOn') ? jobSchedule.runOn : '' +] + +module automationAccount_jobSchedules 'job-schedule/main.bicep' = [ + for (jobSchedule, index) in jobSchedules: { + name: '${uniqueString(deployment().name, location)}-AutoAccount-JobSchedule-${index}' + params: { + automationAccountName: automationAccount.name + runbookName: jobSchedule.runbookName + scheduleName: jobSchedule.scheduleName + parameters: contains(jobSchedule, 'parameters') ? jobSchedule.parameters : {} + runOn: contains(jobSchedule, 'runOn') ? jobSchedule.runOn : '' + } + dependsOn: [ + automationAccount_schedules + automationAccount_runbooks + ] } - dependsOn: [ - automationAccount_schedules - automationAccount_runbooks - ] -}] - -module automationAccount_variables 'variable/main.bicep' = [for (variable, index) in variables: { - name: '${uniqueString(deployment().name, location)}-AutoAccount-Variable-${index}' - params: { - automationAccountName: automationAccount.name - name: variable.name - description: contains(variable, 'description') ? variable.description : '' - value: variable.value - isEncrypted: contains(variable, 'isEncrypted') ? variable.isEncrypted : true +] + +module automationAccount_variables 'variable/main.bicep' = [ + for (variable, index) in variables: { + name: '${uniqueString(deployment().name, location)}-AutoAccount-Variable-${index}' + params: { + automationAccountName: automationAccount.name + name: variable.name + description: contains(variable, 'description') ? variable.description : '' + value: variable.value + isEncrypted: contains(variable, 'isEncrypted') ? variable.isEncrypted : true + } } -}] - -module automationAccount_linkedService '../../operational-insights/workspace/linked-service/main.bicep' = if (!empty(linkedWorkspaceResourceId)) { - name: '${uniqueString(deployment().name, location)}-AutoAccount-LinkedService' - params: { - name: 'automation' - logAnalyticsWorkspaceName: last(split(linkedWorkspaceResourceId, '/'))! - resourceId: automationAccount.id - tags: tags +] + +module automationAccount_linkedService '../../operational-insights/workspace/linked-service/main.bicep' = + if (!empty(linkedWorkspaceResourceId)) { + name: '${uniqueString(deployment().name, location)}-AutoAccount-LinkedService' + params: { + name: 'automation' + logAnalyticsWorkspaceName: last(split(linkedWorkspaceResourceId, '/'))! + resourceId: automationAccount.id + tags: tags + } + // This is to support linked services to law in different subscription and resource group than the automation account. + // The current scope is used by default if no linked service is intended to be created. + scope: resourceGroup( + (!empty(linkedWorkspaceResourceId) + ? (split((!empty(linkedWorkspaceResourceId) ? linkedWorkspaceResourceId : '//'), '/')[2]) + : subscription().subscriptionId), + !empty(linkedWorkspaceResourceId) + ? (split((!empty(linkedWorkspaceResourceId) ? linkedWorkspaceResourceId : '////'), '/')[4]) + : resourceGroup().name + ) } - // This is to support linked services to law in different subscription and resource group than the automation account. - // The current scope is used by default if no linked service is intended to be created. - scope: resourceGroup((!empty(linkedWorkspaceResourceId) ? (split((!empty(linkedWorkspaceResourceId) ? linkedWorkspaceResourceId : '//'), '/')[2]) : subscription().subscriptionId), !empty(linkedWorkspaceResourceId) ? (split((!empty(linkedWorkspaceResourceId) ? linkedWorkspaceResourceId : '////'), '/')[4]) : resourceGroup().name) -} -module automationAccount_solutions 'br/public:avm/res/operations-management/solution:0.1.0' = [for (gallerySolution, index) in gallerySolutions: if (!empty(linkedWorkspaceResourceId)) { - name: '${uniqueString(deployment().name, location)}-AutoAccount-Solution-${index}' - params: { - name: gallerySolution.name - location: location - logAnalyticsWorkspaceName: last(split(linkedWorkspaceResourceId, '/'))! - product: contains(gallerySolution, 'product') ? gallerySolution.product : 'OMSGallery' - publisher: contains(gallerySolution, 'publisher') ? gallerySolution.publisher : 'Microsoft' - enableTelemetry: enableTelemetry - } - // This is to support solution to law in different subscription and resource group than the automation account. - // The current scope is used by default if no linked service is intended to be created. - scope: resourceGroup((!empty(linkedWorkspaceResourceId) ? (split((!empty(linkedWorkspaceResourceId) ? linkedWorkspaceResourceId : '//'), '/')[2]) : subscription().subscriptionId), !empty(linkedWorkspaceResourceId) ? (split((!empty(linkedWorkspaceResourceId) ? linkedWorkspaceResourceId : '////'), '/')[4]) : resourceGroup().name) - dependsOn: [ - automationAccount_linkedService - ] -}] - -module automationAccount_softwareUpdateConfigurations 'software-update-configuration/main.bicep' = [for (softwareUpdateConfiguration, index) in softwareUpdateConfigurations: { - name: '${uniqueString(deployment().name, location)}-AutoAccount-SwUpdateConfig-${index}' - params: { - name: softwareUpdateConfiguration.name - automationAccountName: automationAccount.name - frequency: softwareUpdateConfiguration.frequency - operatingSystem: softwareUpdateConfiguration.operatingSystem - rebootSetting: softwareUpdateConfiguration.rebootSetting - azureVirtualMachines: contains(softwareUpdateConfiguration, 'azureVirtualMachines') ? softwareUpdateConfiguration.azureVirtualMachines : [] - excludeUpdates: contains(softwareUpdateConfiguration, 'excludeUpdates') ? softwareUpdateConfiguration.excludeUpdates : [] - expiryTime: contains(softwareUpdateConfiguration, 'expiryTime') ? softwareUpdateConfiguration.expiryTime : '' - expiryTimeOffsetMinutes: contains(softwareUpdateConfiguration, 'expiryTimeOffsetMinutes') ? softwareUpdateConfiguration.expiryTimeOffsetMinute : 0 - includeUpdates: contains(softwareUpdateConfiguration, 'includeUpdates') ? softwareUpdateConfiguration.includeUpdates : [] - interval: contains(softwareUpdateConfiguration, 'interval') ? softwareUpdateConfiguration.interval : 1 - isEnabled: contains(softwareUpdateConfiguration, 'isEnabled') ? softwareUpdateConfiguration.isEnabled : true - maintenanceWindow: contains(softwareUpdateConfiguration, 'maintenanceWindow') ? softwareUpdateConfiguration.maintenanceWindow : 'PT2H' - monthDays: contains(softwareUpdateConfiguration, 'monthDays') ? softwareUpdateConfiguration.monthDays : [] - monthlyOccurrences: contains(softwareUpdateConfiguration, 'monthlyOccurrences') ? softwareUpdateConfiguration.monthlyOccurrences : [] - nextRun: contains(softwareUpdateConfiguration, 'nextRun') ? softwareUpdateConfiguration.nextRun : '' - nextRunOffsetMinutes: contains(softwareUpdateConfiguration, 'nextRunOffsetMinutes') ? softwareUpdateConfiguration.nextRunOffsetMinutes : 0 - nonAzureComputerNames: contains(softwareUpdateConfiguration, 'nonAzureComputerNames') ? softwareUpdateConfiguration.nonAzureComputerNames : [] - nonAzureQueries: contains(softwareUpdateConfiguration, 'nonAzureQueries') ? softwareUpdateConfiguration.nonAzureQueries : [] - postTaskParameters: contains(softwareUpdateConfiguration, 'postTaskParameters') ? softwareUpdateConfiguration.postTaskParameters : {} - postTaskSource: contains(softwareUpdateConfiguration, 'postTaskSource') ? softwareUpdateConfiguration.postTaskSource : '' - preTaskParameters: contains(softwareUpdateConfiguration, 'preTaskParameters') ? softwareUpdateConfiguration.preTaskParameters : {} - preTaskSource: contains(softwareUpdateConfiguration, 'preTaskSource') ? softwareUpdateConfiguration.preTaskSource : '' - scheduleDescription: contains(softwareUpdateConfiguration, 'scheduleDescription') ? softwareUpdateConfiguration.scheduleDescription : '' - scopeByLocations: contains(softwareUpdateConfiguration, 'scopeByLocations') ? softwareUpdateConfiguration.scopeByLocations : [] - scopeByResources: contains(softwareUpdateConfiguration, 'scopeByResources') ? softwareUpdateConfiguration.scopeByResources : [ - subscription().id +module automationAccount_solutions 'br/public:avm/res/operations-management/solution:0.1.0' = [ + for (gallerySolution, index) in gallerySolutions: if (!empty(linkedWorkspaceResourceId)) { + name: '${uniqueString(deployment().name, location)}-AutoAccount-Solution-${index}' + params: { + name: gallerySolution.name + location: location + logAnalyticsWorkspaceName: last(split(linkedWorkspaceResourceId, '/'))! + product: contains(gallerySolution, 'product') ? gallerySolution.product : 'OMSGallery' + publisher: contains(gallerySolution, 'publisher') ? gallerySolution.publisher : 'Microsoft' + enableTelemetry: enableTelemetry + } + // This is to support solution to law in different subscription and resource group than the automation account. + // The current scope is used by default if no linked service is intended to be created. + scope: resourceGroup( + (!empty(linkedWorkspaceResourceId) + ? (split((!empty(linkedWorkspaceResourceId) ? linkedWorkspaceResourceId : '//'), '/')[2]) + : subscription().subscriptionId), + !empty(linkedWorkspaceResourceId) + ? (split((!empty(linkedWorkspaceResourceId) ? linkedWorkspaceResourceId : '////'), '/')[4]) + : resourceGroup().name + ) + dependsOn: [ + automationAccount_linkedService ] - scopeByTags: contains(softwareUpdateConfiguration, 'scopeByTags') ? softwareUpdateConfiguration.scopeByTags : {} - scopeByTagsOperation: contains(softwareUpdateConfiguration, 'scopeByTagsOperation') ? softwareUpdateConfiguration.scopeByTagsOperation : 'All' - startTime: contains(softwareUpdateConfiguration, 'startTime') ? softwareUpdateConfiguration.startTime : '' - timeZone: contains(softwareUpdateConfiguration, 'timeZone') ? softwareUpdateConfiguration.timeZone : 'UTC' - updateClassifications: contains(softwareUpdateConfiguration, 'updateClassifications') ? softwareUpdateConfiguration.updateClassifications : [ - 'Critical' - 'Security' + } +] + +module automationAccount_softwareUpdateConfigurations 'software-update-configuration/main.bicep' = [ + for (softwareUpdateConfiguration, index) in softwareUpdateConfigurations: { + name: '${uniqueString(deployment().name, location)}-AutoAccount-SwUpdateConfig-${index}' + params: { + name: softwareUpdateConfiguration.name + automationAccountName: automationAccount.name + frequency: softwareUpdateConfiguration.frequency + operatingSystem: softwareUpdateConfiguration.operatingSystem + rebootSetting: softwareUpdateConfiguration.rebootSetting + azureVirtualMachines: contains(softwareUpdateConfiguration, 'azureVirtualMachines') + ? softwareUpdateConfiguration.azureVirtualMachines + : [] + excludeUpdates: contains(softwareUpdateConfiguration, 'excludeUpdates') + ? softwareUpdateConfiguration.excludeUpdates + : [] + expiryTime: contains(softwareUpdateConfiguration, 'expiryTime') ? softwareUpdateConfiguration.expiryTime : '' + expiryTimeOffsetMinutes: contains(softwareUpdateConfiguration, 'expiryTimeOffsetMinutes') + ? softwareUpdateConfiguration.expiryTimeOffsetMinute + : 0 + includeUpdates: contains(softwareUpdateConfiguration, 'includeUpdates') + ? softwareUpdateConfiguration.includeUpdates + : [] + interval: contains(softwareUpdateConfiguration, 'interval') ? softwareUpdateConfiguration.interval : 1 + isEnabled: contains(softwareUpdateConfiguration, 'isEnabled') ? softwareUpdateConfiguration.isEnabled : true + maintenanceWindow: contains(softwareUpdateConfiguration, 'maintenanceWindow') + ? softwareUpdateConfiguration.maintenanceWindow + : 'PT2H' + monthDays: contains(softwareUpdateConfiguration, 'monthDays') ? softwareUpdateConfiguration.monthDays : [] + monthlyOccurrences: contains(softwareUpdateConfiguration, 'monthlyOccurrences') + ? softwareUpdateConfiguration.monthlyOccurrences + : [] + nextRun: contains(softwareUpdateConfiguration, 'nextRun') ? softwareUpdateConfiguration.nextRun : '' + nextRunOffsetMinutes: contains(softwareUpdateConfiguration, 'nextRunOffsetMinutes') + ? softwareUpdateConfiguration.nextRunOffsetMinutes + : 0 + nonAzureComputerNames: contains(softwareUpdateConfiguration, 'nonAzureComputerNames') + ? softwareUpdateConfiguration.nonAzureComputerNames + : [] + nonAzureQueries: contains(softwareUpdateConfiguration, 'nonAzureQueries') + ? softwareUpdateConfiguration.nonAzureQueries + : [] + postTaskParameters: contains(softwareUpdateConfiguration, 'postTaskParameters') + ? softwareUpdateConfiguration.postTaskParameters + : {} + postTaskSource: contains(softwareUpdateConfiguration, 'postTaskSource') + ? softwareUpdateConfiguration.postTaskSource + : '' + preTaskParameters: contains(softwareUpdateConfiguration, 'preTaskParameters') + ? softwareUpdateConfiguration.preTaskParameters + : {} + preTaskSource: contains(softwareUpdateConfiguration, 'preTaskSource') + ? softwareUpdateConfiguration.preTaskSource + : '' + scheduleDescription: contains(softwareUpdateConfiguration, 'scheduleDescription') + ? softwareUpdateConfiguration.scheduleDescription + : '' + scopeByLocations: contains(softwareUpdateConfiguration, 'scopeByLocations') + ? softwareUpdateConfiguration.scopeByLocations + : [] + scopeByResources: contains(softwareUpdateConfiguration, 'scopeByResources') + ? softwareUpdateConfiguration.scopeByResources + : [ + subscription().id + ] + scopeByTags: contains(softwareUpdateConfiguration, 'scopeByTags') ? softwareUpdateConfiguration.scopeByTags : {} + scopeByTagsOperation: contains(softwareUpdateConfiguration, 'scopeByTagsOperation') + ? softwareUpdateConfiguration.scopeByTagsOperation + : 'All' + startTime: contains(softwareUpdateConfiguration, 'startTime') ? softwareUpdateConfiguration.startTime : '' + timeZone: contains(softwareUpdateConfiguration, 'timeZone') ? softwareUpdateConfiguration.timeZone : 'UTC' + updateClassifications: contains(softwareUpdateConfiguration, 'updateClassifications') + ? softwareUpdateConfiguration.updateClassifications + : [ + 'Critical' + 'Security' + ] + weekDays: contains(softwareUpdateConfiguration, 'weekDays') ? softwareUpdateConfiguration.weekDays : [] + } + dependsOn: [ + automationAccount_solutions ] - weekDays: contains(softwareUpdateConfiguration, 'weekDays') ? softwareUpdateConfiguration.weekDays : [] } - dependsOn: [ - automationAccount_solutions - ] -}] +] -resource automationAccount_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.' +resource automationAccount_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: automationAccount } - scope: automationAccount -} -resource automationAccount_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 - 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 +resource automationAccount_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 + 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 + } + scope: automationAccount } - scope: automationAccount -}] - -module automationAccount_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-automationAccount-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(automationAccount.id, '/'))}-${privateEndpoint.service}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(automationAccount.id, '/'))}-${privateEndpoint.service}-${index}' - properties: { - privateLinkServiceId: automationAccount.id - groupIds: [ - privateEndpoint.service +] + +module automationAccount_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-automationAccount-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(automationAccount.id, '/'))}-${privateEndpoint.service}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(automationAccount.id, '/'))}-${privateEndpoint.service}-${index}' + properties: { + privateLinkServiceId: automationAccount.id + groupIds: [ + privateEndpoint.service + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(automationAccount.id, '/'))}-${privateEndpoint.service}-${index}' - properties: { - privateLinkServiceId: automationAccount.id - groupIds: [ - privateEndpoint.service + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(automationAccount.id, '/'))}-${privateEndpoint.service}-${index}' + properties: { + privateLinkServiceId: automationAccount.id + groupIds: [ + privateEndpoint.service + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource automationAccount_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(automationAccount.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 +resource automationAccount_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(automationAccount.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: automationAccount } - scope: automationAccount -}] +] @description('The name of the deployed automation account.') output name string = automationAccount.name diff --git a/avm/res/automation/automation-account/main.json b/avm/res/automation/automation-account/main.json index c53dc5fcde..0b24e4fed3 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.25.53.49325", - "templateHash": "13780169676814518535" + "version": "0.26.54.24096", + "templateHash": "6662719167579233396" }, "name": "Automation Accounts", "description": "This module deploys an Azure Automation Account.", @@ -816,8 +816,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4277151232699761913" + "version": "0.26.54.24096", + "templateHash": "8037849223912660600" }, "name": "Automation Account Modules", "description": "This module deploys an Azure Automation Account Module.", @@ -958,8 +958,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3130545991088336783" + "version": "0.26.54.24096", + "templateHash": "10057879847143996563" }, "name": "Automation Account Schedules", "description": "This module deploys an Azure Automation Account Schedule.", @@ -1137,8 +1137,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16141039584915226874" + "version": "0.26.54.24096", + "templateHash": "14714097202201612277" }, "name": "Automation Account Runbooks", "description": "This module deploys an Azure Automation Account Runbook.", @@ -1337,8 +1337,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4183701486282199551" + "version": "0.26.54.24096", + "templateHash": "3709450248827326388" }, "name": "Automation Account Job Schedules", "description": "This module deploys an Azure Automation Account Job Schedule.", @@ -1465,8 +1465,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15605588341437540157" + "version": "0.26.54.24096", + "templateHash": "1065450815403209329" }, "name": "Automation Account Variables", "description": "This module deploys an Azure Automation Account Variable.", @@ -1580,8 +1580,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14301767156435143002" + "version": "0.26.54.24096", + "templateHash": "7204307644126778192" }, "name": "Log Analytics Workspace Linked Services", "description": "This module deploys a Log Analytics Workspace Linked Service.", @@ -1899,8 +1899,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6467431009828483672" + "version": "0.26.54.24096", + "templateHash": "7586828544795723203" }, "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 c151060111..546c8505d5 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.25.53.49325", - "templateHash": "4277151232699761913" + "version": "0.26.54.24096", + "templateHash": "8037849223912660600" }, "name": "Automation Account Modules", "description": "This module deploys an Azure Automation Account Module.", diff --git a/avm/res/automation/automation-account/runbook/main.bicep b/avm/res/automation/automation-account/runbook/main.bicep index ec1cd1ab8e..4f41bf68ca 100644 --- a/avm/res/automation/automation-account/runbook/main.bicep +++ b/avm/res/automation/automation-account/runbook/main.bicep @@ -50,20 +50,29 @@ var accountSasProperties = { signedProtocol: 'https' } - resource automationAccount 'Microsoft.Automation/automationAccounts@2022-08-08' existing = { name: automationAccountName } -resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' existing = if (!empty(scriptStorageAccountResourceId)) { - name: last(split((scriptStorageAccountResourceId ?? 'dummyVault'), '/')) - scope: resourceGroup(split((scriptStorageAccountResourceId ?? '//'), '/')[2], split((scriptStorageAccountResourceId ?? '////'), '/')[4]) -} +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' existing = + if (!empty(scriptStorageAccountResourceId)) { + name: last(split((scriptStorageAccountResourceId ?? 'dummyVault'), '/')) + scope: resourceGroup( + split((scriptStorageAccountResourceId ?? '//'), '/')[2], + split((scriptStorageAccountResourceId ?? '////'), '/')[4] + ) + } -var publishContentLink = empty(uri) ? null : { - uri: !empty(uri) ? (empty(scriptStorageAccountResourceId) ? uri : '${uri}?${storageAccount.listAccountSas('2021-04-01', accountSasProperties).accountSasToken}') : null - version: !empty(version) ? version : null -} +var publishContentLink = empty(uri) + ? null + : { + uri: !empty(uri) + ? (empty(scriptStorageAccountResourceId) + ? uri + : '${uri}?${storageAccount.listAccountSas('2021-04-01', accountSasProperties).accountSasToken}') + : null + version: !empty(version) ? version : null + } resource runbook 'Microsoft.Automation/automationAccounts/runbooks@2022-08-08' = { name: name diff --git a/avm/res/automation/automation-account/runbook/main.json b/avm/res/automation/automation-account/runbook/main.json index 0761a0bce4..4f23a696b6 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.25.53.49325", - "templateHash": "16141039584915226874" + "version": "0.26.54.24096", + "templateHash": "14714097202201612277" }, "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 65e59ddfd4..4a8ef6d870 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.25.53.49325", - "templateHash": "3130545991088336783" + "version": "0.26.54.24096", + "templateHash": "10057879847143996563" }, "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.bicep b/avm/res/automation/automation-account/software-update-configuration/main.bicep index 6354fa6b3e..2408a52a41 100644 --- a/avm/res/automation/automation-account/software-update-configuration/main.bicep +++ b/avm/res/automation/automation-account/software-update-configuration/main.bicep @@ -181,7 +181,11 @@ param scheduleDescription string = '' @description('Generated. Do not touch. Is used to provide the base time for time comparison for startTime. If startTime is specified in HH:MM format, baseTime is used to check if the provided startTime has passed, adding one day before setting the deployment schedule.') param baseTime string = utcNow('u') -var updateClassificationsVar = replace(replace(replace(replace(string(updateClassifications), ',', ', '), '[', ''), ']', ''), '"', '') +var updateClassificationsVar = replace( + replace(replace(replace(string(updateClassifications), ',', ', '), '[', ''), ']', ''), + '"', + '' +) resource automationAccount 'Microsoft.Automation/automationAccounts@2022-08-08' existing = { name: automationAccountName @@ -194,18 +198,22 @@ resource softwareUpdateConfiguration 'Microsoft.Automation/automationAccounts/so updateConfiguration: { operatingSystem: operatingSystem duration: maintenanceWindow - linux: ((operatingSystem == 'Linux') ? { - excludedPackageNameMasks: excludeUpdates - includedPackageNameMasks: includeUpdates - includedPackageClassifications: updateClassificationsVar - rebootSetting: rebootSetting - } : null) - windows: ((operatingSystem == 'Windows') ? { - excludedKbNumbers: excludeUpdates - includedKbNumbers: includeUpdates - includedUpdateClassifications: updateClassificationsVar - rebootSetting: rebootSetting - } : null) + linux: ((operatingSystem == 'Linux') + ? { + excludedPackageNameMasks: excludeUpdates + includedPackageNameMasks: includeUpdates + includedPackageClassifications: updateClassificationsVar + rebootSetting: rebootSetting + } + : null) + windows: ((operatingSystem == 'Windows') + ? { + excludedKbNumbers: excludeUpdates + includedKbNumbers: includeUpdates + includedUpdateClassifications: updateClassificationsVar + rebootSetting: rebootSetting + } + : null) targets: { azureQueries: [ { 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 e6d98f28da..62ca53d37e 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.25.53.49325", - "templateHash": "6467431009828483672" + "version": "0.26.54.24096", + "templateHash": "7586828544795723203" }, "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/tests/e2e/defaults/main.test.bicep b/avm/res/automation/automation-account/tests/e2e/defaults/main.test.bicep index 5f0a8e6212..80a79d90f5 100644 --- a/avm/res/automation/automation-account/tests/e2e/defaults/main.test.bicep +++ b/avm/res/automation/automation-account/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/automation/automation-account/tests/e2e/encr/dependencies.bicep b/avm/res/automation/automation-account/tests/e2e/encr/dependencies.bicep index c0fbbed613..49d0dfa3aa 100644 --- a/avm/res/automation/automation-account/tests/e2e/encr/dependencies.bicep +++ b/avm/res/automation/automation-account/tests/e2e/encr/dependencies.bicep @@ -8,44 +8,47 @@ param keyVaultName string param managedIdentityName string 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 - softDeleteRetentionInDays: 7 - enablePurgeProtection: true - 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 + softDeleteRetentionInDays: 7 + enablePurgeProtection: true + 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' - } + 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' + } } @description('The resource ID of the created Key Vault.') diff --git a/avm/res/automation/automation-account/tests/e2e/encr/main.test.bicep b/avm/res/automation/automation-account/tests/e2e/encr/main.test.bicep index df5eef8136..c43435d4af 100644 --- a/avm/res/automation/automation-account/tests/e2e/encr/main.test.bicep +++ b/avm/res/automation/automation-account/tests/e2e/encr/main.test.bicep @@ -50,24 +50,26 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - customerManagedKey: { - keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + } + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + location: resourceLocation } - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - location: resourceLocation + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/automation/automation-account/tests/e2e/max/main.test.bicep b/avm/res/automation/automation-account/tests/e2e/max/main.test.bicep index 0c9b5a710d..e364a54391 100644 --- a/avm/res/automation/automation-account/tests/e2e/max/main.test.bicep +++ b/avm/res/automation/automation-account/tests/e2e/max/main.test.bicep @@ -56,220 +56,225 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - gallerySolutions: [ - { - name: 'Updates' - product: 'OMSGallery' - publisher: 'Microsoft' - } - ] - jobSchedules: [ - { - runbookName: 'TestRunbook' - scheduleName: 'TestSchedule' - } - ] - disableLocalAuth: true - linkedWorkspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - location: resourceLocation - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - modules: [ - { - name: 'PSWindowsUpdate' - uri: 'https://www.powershellgallery.com/api/v2/package' - version: 'latest' - } - ] - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'Webhook' - subnetResourceId: nestedDependencies.outputs.customSubnet1ResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'Webhook' - subnetResourceId: nestedDependencies.outputs.customSubnet2ResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + ] + gallerySolutions: [ + { + name: 'Updates' + product: 'OMSGallery' + publisher: 'Microsoft' } - } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'DSCAndHybridWorker' - subnetResourceId: nestedDependencies.outputs.customSubnet1ResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + ] + jobSchedules: [ + { + runbookName: 'TestRunbook' + scheduleName: 'TestSchedule' } + ] + disableLocalAuth: true + linkedWorkspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + location: resourceLocation + 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' - } - ] - runbooks: [ - { - description: 'Test runbook' - name: 'TestRunbook' - type: 'PowerShell' - uri: 'https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.automation/101-automation/scripts/AzureAutomationTutorial.ps1' - version: '1.0.0.0' - } - ] - schedules: [ - { - advancedSchedule: {} - expiryTime: '9999-12-31T13:00' - frequency: 'Hour' - interval: 12 - name: 'TestSchedule' - startTime: '' - timeZone: 'Europe/Berlin' - } - ] - softwareUpdateConfigurations: [ - { - excludeUpdates: [ - '123456' - ] - frequency: 'Month' - includeUpdates: [ - '654321' - ] - interval: 1 - maintenanceWindow: 'PT4H' - monthlyOccurrences: [ - { - day: 'Friday' - occurrence: 3 + modules: [ + { + name: 'PSWindowsUpdate' + uri: 'https://www.powershellgallery.com/api/v2/package' + version: 'latest' + } + ] + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'Webhook' + subnetResourceId: nestedDependencies.outputs.customSubnet1ResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - name: 'Windows_ZeroDay' - operatingSystem: 'Windows' - rebootSetting: 'IfRequired' - scopeByTags: { - Update: [ - 'Automatic-Wave1' + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId ] + service: 'Webhook' + subnetResourceId: nestedDependencies.outputs.customSubnet2ResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } - startTime: '22:00' - updateClassifications: [ - 'Critical' - 'Definition' - 'FeaturePack' - 'Security' - 'ServicePack' - 'Tools' - 'UpdateRollup' - 'Updates' - ] - } - { - excludeUpdates: [ - 'icacls' - ] - frequency: 'OneTime' - includeUpdates: [ - 'kernel' - ] - maintenanceWindow: 'PT4H' - name: 'Linux_ZeroDay' - operatingSystem: 'Linux' - rebootSetting: 'IfRequired' - startTime: '22:00' - updateClassifications: [ - 'Critical' - 'Other' - 'Security' + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'DSCAndHybridWorker' + subnetResourceId: nestedDependencies.outputs.customSubnet1ResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + 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' + } + ] + runbooks: [ + { + description: 'Test runbook' + name: 'TestRunbook' + type: 'PowerShell' + uri: 'https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.automation/101-automation/scripts/AzureAutomationTutorial.ps1' + version: '1.0.0.0' + } + ] + schedules: [ + { + advancedSchedule: {} + expiryTime: '9999-12-31T13:00' + frequency: 'Hour' + interval: 12 + name: 'TestSchedule' + startTime: '' + timeZone: 'Europe/Berlin' + } + ] + softwareUpdateConfigurations: [ + { + excludeUpdates: [ + '123456' + ] + frequency: 'Month' + includeUpdates: [ + '654321' + ] + interval: 1 + maintenanceWindow: 'PT4H' + monthlyOccurrences: [ + { + day: 'Friday' + occurrence: 3 + } + ] + name: 'Windows_ZeroDay' + operatingSystem: 'Windows' + rebootSetting: 'IfRequired' + scopeByTags: { + Update: [ + 'Automatic-Wave1' + ] + } + startTime: '22:00' + updateClassifications: [ + 'Critical' + 'Definition' + 'FeaturePack' + 'Security' + 'ServicePack' + 'Tools' + 'UpdateRollup' + 'Updates' + ] + } + { + excludeUpdates: [ + 'icacls' + ] + frequency: 'OneTime' + includeUpdates: [ + 'kernel' + ] + maintenanceWindow: 'PT4H' + name: 'Linux_ZeroDay' + operatingSystem: 'Linux' + rebootSetting: 'IfRequired' + startTime: '22:00' + updateClassifications: [ + 'Critical' + 'Other' + 'Security' + ] + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] } - ] - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId + variables: [ + { + description: 'TestStringDescription' + name: 'TestString' + value: '\'TestString\'' + } + { + description: 'TestIntegerDescription' + name: 'TestInteger' + value: '500' + } + { + description: 'TestBooleanDescription' + name: 'TestBoolean' + value: 'false' + } + { + description: 'TestDateTimeDescription' + isEncrypted: false + name: 'TestDateTime' + value: '\'\\/Date(1637934042656)\\/\'' + } + { + description: 'TestEncryptedDescription' + name: 'TestEncryptedVariable' + value: '\'TestEncryptedValue\'' + } ] - } - variables: [ - { - description: 'TestStringDescription' - name: 'TestString' - value: '\'TestString\'' - } - { - description: 'TestIntegerDescription' - name: 'TestInteger' - value: '500' - } - { - description: 'TestBooleanDescription' - name: 'TestBoolean' - value: 'false' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - description: 'TestDateTimeDescription' - isEncrypted: false - name: 'TestDateTime' - value: '\'\\/Date(1637934042656)\\/\'' - } - { - description: 'TestEncryptedDescription' - name: 'TestEncryptedVariable' - value: '\'TestEncryptedValue\'' - } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/automation/automation-account/tests/e2e/waf-aligned/main.test.bicep b/avm/res/automation/automation-account/tests/e2e/waf-aligned/main.test.bicep index d2bbfb2033..d6182ea498 100644 --- a/avm/res/automation/automation-account/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/automation/automation-account/tests/e2e/waf-aligned/main.test.bicep @@ -60,190 +60,192 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - gallerySolutions: [ - { - name: 'Updates' - product: 'OMSGallery' - publisher: 'Microsoft' - } - ] - jobSchedules: [ - { - runbookName: 'TestRunbook' - scheduleName: 'TestSchedule' - } - ] - disableLocalAuth: true - linkedWorkspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - location: resourceLocation - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - modules: [ - { - name: 'PSWindowsUpdate' - uri: 'https://www.powershellgallery.com/api/v2/package' - version: 'latest' - } - ] - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'Webhook' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'DSCAndHybridWorker' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + ] + gallerySolutions: [ + { + name: 'Updates' + product: 'OMSGallery' + publisher: 'Microsoft' } + ] + jobSchedules: [ + { + runbookName: 'TestRunbook' + scheduleName: 'TestSchedule' + } + ] + disableLocalAuth: true + linkedWorkspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + location: resourceLocation + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - runbooks: [ - { - description: 'Test runbook' - name: 'TestRunbook' - type: 'PowerShell' - uri: 'https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.automation/101-automation/scripts/AzureAutomationTutorial.ps1' - version: '1.0.0.0' - } - ] - schedules: [ - { - advancedSchedule: {} - expiryTime: '9999-12-31T13:00' - frequency: 'Hour' - interval: 12 - name: 'TestSchedule' - startTime: '' - timeZone: 'Europe/Berlin' - } - ] - softwareUpdateConfigurations: [ - { - excludeUpdates: [ - '123456' - ] - frequency: 'Month' - includeUpdates: [ - '654321' - ] - interval: 1 - maintenanceWindow: 'PT4H' - monthlyOccurrences: [ - { - day: 'Friday' - occurrence: 3 + modules: [ + { + name: 'PSWindowsUpdate' + uri: 'https://www.powershellgallery.com/api/v2/package' + version: 'latest' + } + ] + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'Webhook' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - name: 'Windows_ZeroDay' - operatingSystem: 'Windows' - rebootSetting: 'IfRequired' - scopeByTags: { - Update: [ - 'Automatic-Wave1' + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId ] + service: 'DSCAndHybridWorker' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } - startTime: '22:00' - updateClassifications: [ - 'Critical' - 'Definition' - 'FeaturePack' - 'Security' - 'ServicePack' - 'Tools' - 'UpdateRollup' - 'Updates' - ] - } - { - excludeUpdates: [ - 'icacls' - ] - frequency: 'OneTime' - includeUpdates: [ - 'kernel' - ] - maintenanceWindow: 'PT4H' - name: 'Linux_ZeroDay' - operatingSystem: 'Linux' - rebootSetting: 'IfRequired' - startTime: '22:00' - updateClassifications: [ - 'Critical' - 'Other' - 'Security' + ] + runbooks: [ + { + description: 'Test runbook' + name: 'TestRunbook' + type: 'PowerShell' + uri: 'https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.automation/101-automation/scripts/AzureAutomationTutorial.ps1' + version: '1.0.0.0' + } + ] + schedules: [ + { + advancedSchedule: {} + expiryTime: '9999-12-31T13:00' + frequency: 'Hour' + interval: 12 + name: 'TestSchedule' + startTime: '' + timeZone: 'Europe/Berlin' + } + ] + softwareUpdateConfigurations: [ + { + excludeUpdates: [ + '123456' + ] + frequency: 'Month' + includeUpdates: [ + '654321' + ] + interval: 1 + maintenanceWindow: 'PT4H' + monthlyOccurrences: [ + { + day: 'Friday' + occurrence: 3 + } + ] + name: 'Windows_ZeroDay' + operatingSystem: 'Windows' + rebootSetting: 'IfRequired' + scopeByTags: { + Update: [ + 'Automatic-Wave1' + ] + } + startTime: '22:00' + updateClassifications: [ + 'Critical' + 'Definition' + 'FeaturePack' + 'Security' + 'ServicePack' + 'Tools' + 'UpdateRollup' + 'Updates' + ] + } + { + excludeUpdates: [ + 'icacls' + ] + frequency: 'OneTime' + includeUpdates: [ + 'kernel' + ] + maintenanceWindow: 'PT4H' + name: 'Linux_ZeroDay' + operatingSystem: 'Linux' + rebootSetting: 'IfRequired' + startTime: '22:00' + updateClassifications: [ + 'Critical' + 'Other' + 'Security' + ] + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] } - ] - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId + variables: [ + { + description: 'TestStringDescription' + name: 'TestString' + value: '\'TestString\'' + } + { + description: 'TestIntegerDescription' + name: 'TestInteger' + value: '500' + } + { + description: 'TestBooleanDescription' + name: 'TestBoolean' + value: 'false' + } + { + description: 'TestDateTimeDescription' + name: 'TestDateTime' + value: '\'\\/Date(1637934042656)\\/\'' + } + { + description: 'TestEncryptedDescription' + name: 'TestEncryptedVariable' + value: '\'TestEncryptedValue\'' + } ] - } - variables: [ - { - description: 'TestStringDescription' - name: 'TestString' - value: '\'TestString\'' - } - { - description: 'TestIntegerDescription' - name: 'TestInteger' - value: '500' - } - { - description: 'TestBooleanDescription' - name: 'TestBoolean' - value: 'false' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - description: 'TestDateTimeDescription' - name: 'TestDateTime' - value: '\'\\/Date(1637934042656)\\/\'' - } - { - description: 'TestEncryptedDescription' - name: 'TestEncryptedVariable' - value: '\'TestEncryptedValue\'' - } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/automation/automation-account/variable/main.json b/avm/res/automation/automation-account/variable/main.json index ec55c87f17..a7d20d69f2 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.25.53.49325", - "templateHash": "15605588341437540157" + "version": "0.26.54.24096", + "templateHash": "1065450815403209329" }, "name": "Automation Account Variables", "description": "This module deploys an Azure Automation Account Variable.", diff --git a/avm/res/cdn/profile/afdEndpoint/main.bicep b/avm/res/cdn/profile/afdEndpoint/main.bicep index 2e915b62ea..b4097732bc 100644 --- a/avm/res/cdn/profile/afdEndpoint/main.bicep +++ b/avm/res/cdn/profile/afdEndpoint/main.bicep @@ -48,25 +48,27 @@ resource afdEndpoint 'Microsoft.Cdn/profiles/afdEndpoints@2023-05-01' = { } } -module afdEndpoint_routes 'route/main.bicep' = [for route in (routes ?? []): { - name: '${uniqueString(deployment().name, route.name)}-Profile-AfdEndpoint-Route' - params: { - name: route.name - profileName: profile.name - afdEndpointName: afdEndpoint.name - cacheConfiguration: route.?cacheConfiguration - customDomainName: route.?customDomainName - enabledState: route.?enabledState - forwardingProtocol: route.?forwardingProtocol - httpsRedirect: route.?httpsRedirect - linkToDefaultDomain: route.?linkToDefaultDomain - originGroupName: route.?originGroupName - originPath: route.?originPath - patternsToMatch: route.?patternsToMatch - ruleSets: route.?ruleSets - supportedProtocols: route.?supportedProtocols +module afdEndpoint_routes 'route/main.bicep' = [ + for route in (routes ?? []): { + name: '${uniqueString(deployment().name, route.name)}-Profile-AfdEndpoint-Route' + params: { + name: route.name + profileName: profile.name + afdEndpointName: afdEndpoint.name + cacheConfiguration: route.?cacheConfiguration + customDomainName: route.?customDomainName + enabledState: route.?enabledState + forwardingProtocol: route.?forwardingProtocol + httpsRedirect: route.?httpsRedirect + linkToDefaultDomain: route.?linkToDefaultDomain + originGroupName: route.?originGroupName + originPath: route.?originPath + patternsToMatch: route.?patternsToMatch + ruleSets: route.?ruleSets + supportedProtocols: route.?supportedProtocols + } } -}] +] @description('The name of the AFD Endpoint.') output name string = afdEndpoint.name diff --git a/avm/res/cdn/profile/afdEndpoint/main.json b/avm/res/cdn/profile/afdEndpoint/main.json index 8d680f92d5..dbaf3c9233 100644 --- a/avm/res/cdn/profile/afdEndpoint/main.json +++ b/avm/res/cdn/profile/afdEndpoint/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "694786816081848742" + "version": "0.26.54.24096", + "templateHash": "8869132357079269087" }, "name": "CDN Profiles AFD Endpoints", "description": "This module deploys a CDN Profile AFD Endpoint.", @@ -156,8 +156,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16844846729595835268" + "version": "0.26.54.24096", + "templateHash": "8525791914559803218" }, "name": "CDN Profiles AFD Endpoint Route", "description": "This module deploys a CDN Profile AFD Endpoint route.", diff --git a/avm/res/cdn/profile/afdEndpoint/route/main.bicep b/avm/res/cdn/profile/afdEndpoint/route/main.bicep index 072eeae74d..a18fa37fb2 100644 --- a/avm/res/cdn/profile/afdEndpoint/route/main.bicep +++ b/avm/res/cdn/profile/afdEndpoint/route/main.bicep @@ -58,7 +58,7 @@ param patternsToMatch array? @description('Optional. The rule sets of the rule. The rule sets must be defined in the profile ruleSets.') param ruleSets array = [] -@allowed([ 'Http', 'Https' ]) +@allowed(['Http', 'Https']) @description('Optional. The supported protocols of the rule.') param supportedProtocols array? @@ -69,17 +69,20 @@ resource profile 'Microsoft.Cdn/profiles@2023-05-01' existing = { name: afdEndpointName } - resource customDomain 'customDomains@2023-05-01' existing = if (!empty(customDomainName)) { - name: customDomainName ?? '' - } + resource customDomain 'customDomains@2023-05-01' existing = + if (!empty(customDomainName)) { + name: customDomainName ?? '' + } resource originGroup 'originGroups@2023-05-01' existing = { name: originGroupName } - resource ruleSet 'ruleSets@2023-05-01' existing = [for ruleSet in ruleSets: { - name: ruleSet.name - }] + resource ruleSet 'ruleSets@2023-05-01' existing = [ + for ruleSet in ruleSets: { + name: ruleSet.name + } + ] } resource route 'Microsoft.Cdn/profiles/afdEndpoints/routes@2023-05-01' = { @@ -87,9 +90,13 @@ resource route 'Microsoft.Cdn/profiles/afdEndpoints/routes@2023-05-01' = { parent: profile::afdEndpoint properties: { cacheConfiguration: cacheConfiguration - customDomains: !empty(customDomainName) ? [ { - id: profile::customDomain.id - } ] : [] + customDomains: !empty(customDomainName) + ? [ + { + id: profile::customDomain.id + } + ] + : [] enabledState: enabledState forwardingProtocol: forwardingProtocol httpsRedirect: httpsRedirect @@ -99,9 +106,11 @@ resource route 'Microsoft.Cdn/profiles/afdEndpoints/routes@2023-05-01' = { } originPath: originPath patternsToMatch: patternsToMatch - ruleSets: [for (item, index) in ruleSets: { - id: profile::ruleSet[index].id - }] + ruleSets: [ + for (item, index) in ruleSets: { + id: profile::ruleSet[index].id + } + ] supportedProtocols: supportedProtocols } } diff --git a/avm/res/cdn/profile/afdEndpoint/route/main.json b/avm/res/cdn/profile/afdEndpoint/route/main.json index a57d1b974f..ce9f9ea2c5 100644 --- a/avm/res/cdn/profile/afdEndpoint/route/main.json +++ b/avm/res/cdn/profile/afdEndpoint/route/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16844846729595835268" + "version": "0.26.54.24096", + "templateHash": "8525791914559803218" }, "name": "CDN Profiles AFD Endpoint Route", "description": "This module deploys a CDN Profile AFD Endpoint route.", diff --git a/avm/res/cdn/profile/customdomain/main.bicep b/avm/res/cdn/profile/customdomain/main.bicep index 22eafb347f..a0a4f4477f 100644 --- a/avm/res/cdn/profile/customdomain/main.bicep +++ b/avm/res/cdn/profile/customdomain/main.bicep @@ -40,29 +40,36 @@ param secretName string = '' resource profile 'Microsoft.Cdn/profiles@2023-05-01' existing = { name: profileName - resource secrect 'secrets@2023-05-01' existing = if (!empty(secretName)) { - name: secretName - } + resource secrect 'secrets@2023-05-01' existing = + if (!empty(secretName)) { + name: secretName + } } resource customDomain 'Microsoft.Cdn/profiles/customDomains@2023-05-01' = { name: name parent: profile properties: { - azureDnsZone: !empty(azureDnsZoneResourceId) ? { - id: azureDnsZoneResourceId - } : null + azureDnsZone: !empty(azureDnsZoneResourceId) + ? { + id: azureDnsZoneResourceId + } + : null extendedProperties: !empty(extendedProperties) ? extendedProperties : null hostName: hostName - preValidatedCustomDomainResourceId: !empty(preValidatedCustomDomainResourceId) ? { - id: preValidatedCustomDomainResourceId - } : null + preValidatedCustomDomainResourceId: !empty(preValidatedCustomDomainResourceId) + ? { + id: preValidatedCustomDomainResourceId + } + : null tlsSettings: { certificateType: certificateType minimumTlsVersion: minimumTlsVersion - secret: !(empty(secretName)) ? { - id: profile::secrect.id - } : null + secret: !(empty(secretName)) + ? { + id: profile::secrect.id + } + : null } } } diff --git a/avm/res/cdn/profile/customdomain/main.json b/avm/res/cdn/profile/customdomain/main.json index 1f9c03364e..54f6fa7a8d 100644 --- a/avm/res/cdn/profile/customdomain/main.json +++ b/avm/res/cdn/profile/customdomain/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14057037772702090927" + "version": "0.26.54.24096", + "templateHash": "15657388199001378642" }, "name": "CDN Profiles Custom Domains", "description": "This module deploys a CDN Profile Custom Domains.", diff --git a/avm/res/cdn/profile/endpoint/main.bicep b/avm/res/cdn/profile/endpoint/main.bicep index c5fcaadb99..2379bba4d0 100644 --- a/avm/res/cdn/profile/endpoint/main.bicep +++ b/avm/res/cdn/profile/endpoint/main.bicep @@ -29,24 +29,26 @@ resource endpoint 'microsoft.cdn/profiles/endpoints@2021-06-01' = { tags: tags } -module endpoint_origins 'origin/main.bicep' = [for origin in properties.origins: { - name: '${name}-origins-${origin.name}' - params: { - profileName: profile.name - endpointName: endpoint.name - name: origin.name - hostName: origin.properties.hostName - httpPort: origin.properties.?httpPort - httpsPort: origin.properties.?httpsPort - enabled: origin.properties.enabled - priority: origin.properties.?priority - weight: origin.properties.?weight - originHostHeader: origin.properties.?originHostHeader - privateLinkAlias: origin.properties.?privateLinkAlias - privateLinkLocation: origin.properties.?privateLinkLocation - privateLinkResourceId: origin.properties.?privateLinkResourceId +module endpoint_origins 'origin/main.bicep' = [ + for origin in properties.origins: { + name: '${name}-origins-${origin.name}' + params: { + profileName: profile.name + endpointName: endpoint.name + name: origin.name + hostName: origin.properties.hostName + httpPort: origin.properties.?httpPort + httpsPort: origin.properties.?httpsPort + enabled: origin.properties.enabled + priority: origin.properties.?priority + weight: origin.properties.?weight + originHostHeader: origin.properties.?originHostHeader + privateLinkAlias: origin.properties.?privateLinkAlias + privateLinkLocation: origin.properties.?privateLinkLocation + privateLinkResourceId: origin.properties.?privateLinkResourceId + } } -}] +] @description('The name of the endpoint.') output name string = endpoint.name diff --git a/avm/res/cdn/profile/endpoint/main.json b/avm/res/cdn/profile/endpoint/main.json index e0e3dcc3a3..4866a4cf53 100644 --- a/avm/res/cdn/profile/endpoint/main.json +++ b/avm/res/cdn/profile/endpoint/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12552673613712108877" + "version": "0.26.54.24096", + "templateHash": "5516612458443504281" }, "name": "CDN Profiles Endpoints", "description": "This module deploys a CDN Profile Endpoint.", @@ -125,8 +125,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17135058845123401414" + "version": "0.26.54.24096", + "templateHash": "11112660703037023992" }, "name": "CDN Profiles Endpoints Origins", "description": "This module deploys a CDN Profile Endpoint Origin.", diff --git a/avm/res/cdn/profile/endpoint/origin/main.bicep b/avm/res/cdn/profile/endpoint/origin/main.bicep index 18a571818d..74a9076547 100644 --- a/avm/res/cdn/profile/endpoint/origin/main.bicep +++ b/avm/res/cdn/profile/endpoint/origin/main.bicep @@ -53,22 +53,36 @@ resource endpoint 'Microsoft.Cdn/profiles/endpoints@2021-06-01' existing = { resource origin 'Microsoft.Cdn/profiles/endpoints/origins@2021-06-01' = { parent: endpoint name: name - properties: union({ + properties: union( + { hostName: hostName httpPort: httpPort enabled: enabled httpsPort: httpsPort - }, ((priority > 0 || weight > 0) ? { - priority: priority - weight: weight - } : {}), (!empty(privateLinkAlias) && !empty(privateLinkLocation) ? { - privateLinkAlias: privateLinkAlias - privateLinkLocation: privateLinkLocation - } : {}), (!empty(privateLinkResourceId) ? { - privateLinkResourceId: privateLinkResourceId - } : {}), (!empty(originHostHeader) ? { - originHostHeader: originHostHeader - } : {})) + }, + ((priority > 0 || weight > 0) + ? { + priority: priority + weight: weight + } + : {}), + (!empty(privateLinkAlias) && !empty(privateLinkLocation) + ? { + privateLinkAlias: privateLinkAlias + privateLinkLocation: privateLinkLocation + } + : {}), + (!empty(privateLinkResourceId) + ? { + privateLinkResourceId: privateLinkResourceId + } + : {}), + (!empty(originHostHeader) + ? { + originHostHeader: originHostHeader + } + : {}) + ) } @description('The name of the endpoint.') diff --git a/avm/res/cdn/profile/endpoint/origin/main.json b/avm/res/cdn/profile/endpoint/origin/main.json index 8604bb0323..bb4eefa74d 100644 --- a/avm/res/cdn/profile/endpoint/origin/main.json +++ b/avm/res/cdn/profile/endpoint/origin/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17135058845123401414" + "version": "0.26.54.24096", + "templateHash": "11112660703037023992" }, "name": "CDN Profiles Endpoints Origins", "description": "This module deploys a CDN Profile Endpoint Origin.", diff --git a/avm/res/cdn/profile/main.bicep b/avm/res/cdn/profile/main.bicep index 3ea5c23fa9..27d05ae8c1 100644 --- a/avm/res/cdn/profile/main.bicep +++ b/avm/res/cdn/profile/main.bicep @@ -63,34 +63,53 @@ param roleAssignments roleAssignmentType param enableTelemetry bool = true var builtInRoleNames = { - 'CDN Endpoint Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '426e0c7f-0c7e-4658-b36f-ff54d6c29b45') - 'CDN Endpoint Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '871e35f6-b5c1-49cc-a043-bde969a0f2cd') - 'CDN Profile Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ec156ff8-a8d1-4d15-830c-5b80698ca432') - 'CDN Profile Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8f96442b-4075-438f-813d-ad51ab4019af') + 'CDN Endpoint Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '426e0c7f-0c7e-4658-b36f-ff54d6c29b45' + ) + 'CDN Endpoint Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '871e35f6-b5c1-49cc-a043-bde969a0f2cd' + ) + 'CDN Profile Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'ec156ff8-a8d1-4d15-830c-5b80698ca432' + ) + 'CDN Profile Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '8f96442b-4075-438f-813d-ad51ab4019af' + ) 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') + '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.cdn-profile.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.cdn-profile.${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 profile 'Microsoft.Cdn/profiles@2023-05-01' = { name: name @@ -104,109 +123,129 @@ resource profile 'Microsoft.Cdn/profiles@2023-05-01' = { tags: tags } -resource profile_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.' +resource profile_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: profile } - scope: profile -} -resource profile_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(profile.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 +resource profile_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(profile.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: profile } - scope: profile -}] - -module profile_endpoint 'endpoint/main.bicep' = if (!empty(endpointProperties)) { - name: '${uniqueString(deployment().name, location)}-Profile-Endpoint' - params: { - name: endpointName ?? '${profile.name}-endpoint' - properties: endpointProperties ?? {} - location: location - profileName: profile.name +] + +module profile_endpoint 'endpoint/main.bicep' = + if (!empty(endpointProperties)) { + name: '${uniqueString(deployment().name, location)}-Profile-Endpoint' + params: { + name: endpointName ?? '${profile.name}-endpoint' + properties: endpointProperties ?? {} + location: location + profileName: profile.name + } } -} -module profile_secrets 'secret/main.bicep' = [for (secret, index) in secrets: { - name: '${uniqueString(deployment().name)}-Profile-Secret-${index}' - params: { - name: secret.name - profileName: profile.name - type: secret.type - secretSourceResourceId: secret.secretSourceResourceId - subjectAlternativeNames: secret.?subjectAlternativeNames - useLatestVersion: secret.?useLatestVersion - secretVersion: secret.secretVersion +module profile_secrets 'secret/main.bicep' = [ + for (secret, index) in secrets: { + name: '${uniqueString(deployment().name)}-Profile-Secret-${index}' + params: { + name: secret.name + profileName: profile.name + type: secret.type + secretSourceResourceId: secret.secretSourceResourceId + subjectAlternativeNames: secret.?subjectAlternativeNames + useLatestVersion: secret.?useLatestVersion + secretVersion: secret.secretVersion + } } -}] - -module profile_customDomains 'customdomain/main.bicep' = [for (customDomain, index) in customDomains: { - name: '${uniqueString(deployment().name)}-CustomDomain-${index}' - dependsOn: [ - profile_secrets - ] - params: { - name: customDomain.name - profileName: profile.name - hostName: customDomain.hostName - azureDnsZoneResourceId: customDomain.?azureDnsZoneResourceId - extendedProperties: customDomain.?extendedProperties - certificateType: customDomain.certificateType - minimumTlsVersion: customDomain.?minimumTlsVersion - preValidatedCustomDomainResourceId: customDomain.?preValidatedCustomDomainResourceId - secretName: customDomain.?secretName +] + +module profile_customDomains 'customdomain/main.bicep' = [ + for (customDomain, index) in customDomains: { + name: '${uniqueString(deployment().name)}-CustomDomain-${index}' + dependsOn: [ + profile_secrets + ] + params: { + name: customDomain.name + profileName: profile.name + hostName: customDomain.hostName + azureDnsZoneResourceId: customDomain.?azureDnsZoneResourceId + extendedProperties: customDomain.?extendedProperties + certificateType: customDomain.certificateType + minimumTlsVersion: customDomain.?minimumTlsVersion + preValidatedCustomDomainResourceId: customDomain.?preValidatedCustomDomainResourceId + secretName: customDomain.?secretName + } } -}] - -module profile_originGroups 'origingroup/main.bicep' = [for (origingroup, index) in origionGroups: { - name: '${uniqueString(deployment().name)}-Profile-OrigionGroup-${index}' - params: { - name: origingroup.name - profileName: profile.name - loadBalancingSettings: origingroup.loadBalancingSettings - healthProbeSettings: origingroup.?healthProbeSettings - sessionAffinityState: origingroup.?sessionAffinityState - trafficRestorationTimeToHealedOrNewEndpointsInMinutes: origingroup.?trafficRestorationTimeToHealedOrNewEndpointsInMinutes - origins: origingroup.origins +] + +module profile_originGroups 'origingroup/main.bicep' = [ + for (origingroup, index) in origionGroups: { + name: '${uniqueString(deployment().name)}-Profile-OrigionGroup-${index}' + params: { + name: origingroup.name + profileName: profile.name + loadBalancingSettings: origingroup.loadBalancingSettings + healthProbeSettings: origingroup.?healthProbeSettings + sessionAffinityState: origingroup.?sessionAffinityState + trafficRestorationTimeToHealedOrNewEndpointsInMinutes: origingroup.?trafficRestorationTimeToHealedOrNewEndpointsInMinutes + origins: origingroup.origins + } } -}] - -module profile_ruleSets 'ruleset/main.bicep' = [for (ruleSet, index) in ruleSets: { - name: '${uniqueString(deployment().name)}-Profile-RuleSet-${index}' - params: { - name: ruleSet.name - profileName: profile.name - rules: ruleSet.rules +] + +module profile_ruleSets 'ruleset/main.bicep' = [ + for (ruleSet, index) in ruleSets: { + name: '${uniqueString(deployment().name)}-Profile-RuleSet-${index}' + params: { + name: ruleSet.name + profileName: profile.name + rules: ruleSet.rules + } } -}] - -module profile_afdEndpoints 'afdEndpoint/main.bicep' = [for (afdEndpoint, index) in afdEndpoints: { - name: '${uniqueString(deployment().name)}-Profile-AfdEndpoint-${index}' - dependsOn: [ - profile_originGroups - profile_customDomains - profile_ruleSets - ] - params: { - name: afdEndpoint.name - location: location - profileName: profile.name - autoGeneratedDomainNameLabelScope: afdEndpoint.?autoGeneratedDomainNameLabelScope - enabledState: afdEndpoint.?enabledState - routes: afdEndpoint.?routes - tags: afdEndpoint.?tags ?? tags +] + +module profile_afdEndpoints 'afdEndpoint/main.bicep' = [ + for (afdEndpoint, index) in afdEndpoints: { + name: '${uniqueString(deployment().name)}-Profile-AfdEndpoint-${index}' + dependsOn: [ + profile_originGroups + profile_customDomains + profile_ruleSets + ] + params: { + name: afdEndpoint.name + location: location + profileName: profile.name + autoGeneratedDomainNameLabelScope: afdEndpoint.?autoGeneratedDomainNameLabelScope + enabledState: afdEndpoint.?enabledState + routes: afdEndpoint.?routes + tags: afdEndpoint.?tags ?? tags + } } -}] +] @description('The name of the CDN profile.') output name string = profile.name diff --git a/avm/res/cdn/profile/main.json b/avm/res/cdn/profile/main.json index 81acb14639..c0f0f30a68 100644 --- a/avm/res/cdn/profile/main.json +++ b/avm/res/cdn/profile/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "5590822157258383721" + "version": "0.26.54.24096", + "templateHash": "9474385640753599051" }, "name": "CDN Profiles", "description": "This module deploys a CDN Profile.", @@ -337,8 +337,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12552673613712108877" + "version": "0.26.54.24096", + "templateHash": "5516612458443504281" }, "name": "CDN Profiles Endpoints", "description": "This module deploys a CDN Profile Endpoint.", @@ -457,8 +457,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17135058845123401414" + "version": "0.26.54.24096", + "templateHash": "11112660703037023992" }, "name": "CDN Profiles Endpoints Origins", "description": "This module deploys a CDN Profile Endpoint Origin.", @@ -703,8 +703,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3645784765890890733" + "version": "0.26.54.24096", + "templateHash": "7298174434641608123" }, "name": "CDN Profiles Secret", "description": "This module deploys a CDN Profile Secret.", @@ -852,8 +852,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14057037772702090927" + "version": "0.26.54.24096", + "templateHash": "15657388199001378642" }, "name": "CDN Profiles Custom Domains", "description": "This module deploys a CDN Profile Custom Domains.", @@ -1019,8 +1019,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8675132561244182118" + "version": "0.26.54.24096", + "templateHash": "8706007645911322422" }, "name": "CDN Profiles Origin Group", "description": "This module deploys a CDN Profile Origin Group.", @@ -1156,8 +1156,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17323276561210856523" + "version": "0.26.54.24096", + "templateHash": "16657064743499074369" }, "name": "CDN Profiles Origin", "description": "This module deploys a CDN Profile Origin.", @@ -1382,8 +1382,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4615747470717464878" + "version": "0.26.54.24096", + "templateHash": "1809010747275335698" }, "name": "CDN Profiles Rule Sets", "description": "This module deploys a CDN Profile rule set.", @@ -1468,8 +1468,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "9936176531232217343" + "version": "0.26.54.24096", + "templateHash": "8195283154733773558" }, "name": "CDN Profiles Rules", "description": "This module deploys a CDN Profile rule.", @@ -1656,8 +1656,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "694786816081848742" + "version": "0.26.54.24096", + "templateHash": "8869132357079269087" }, "name": "CDN Profiles AFD Endpoints", "description": "This module deploys a CDN Profile AFD Endpoint.", @@ -1807,8 +1807,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16844846729595835268" + "version": "0.26.54.24096", + "templateHash": "8525791914559803218" }, "name": "CDN Profiles AFD Endpoint Route", "description": "This module deploys a CDN Profile AFD Endpoint route.", diff --git a/avm/res/cdn/profile/origingroup/main.bicep b/avm/res/cdn/profile/origingroup/main.bicep index adc29691b5..258f75686f 100644 --- a/avm/res/cdn/profile/origingroup/main.bicep +++ b/avm/res/cdn/profile/origingroup/main.bicep @@ -42,23 +42,25 @@ resource originGroup 'Microsoft.Cdn/profiles/originGroups@2023-05-01' = { } } -module originGroup_origins 'origin/main.bicep' = [for (origin, index) in origins: { - name: '${uniqueString(deployment().name)}-OriginGroup-Origin-${index}' - params: { - name: origin.name - profileName: profileName - hostName: origin.hostName - originGroupName: originGroup.name - enabledState: origin.?enabledState - enforceCertificateNameCheck: origin.?enforceCertificateNameCheck - httpPort: origin.?httpPort - httpsPort: origin.?httpsPort - originHostHeader: origin.?originHostHeader ?? origin.hostName - priority: origin.?priority - weight: origin.?weight - sharedPrivateLinkResource: origin.?sharedPrivateLinkResource +module originGroup_origins 'origin/main.bicep' = [ + for (origin, index) in origins: { + name: '${uniqueString(deployment().name)}-OriginGroup-Origin-${index}' + params: { + name: origin.name + profileName: profileName + hostName: origin.hostName + originGroupName: originGroup.name + enabledState: origin.?enabledState + enforceCertificateNameCheck: origin.?enforceCertificateNameCheck + httpPort: origin.?httpPort + httpsPort: origin.?httpsPort + originHostHeader: origin.?originHostHeader ?? origin.hostName + priority: origin.?priority + weight: origin.?weight + sharedPrivateLinkResource: origin.?sharedPrivateLinkResource + } } -}] +] @description('The name of the origin group.') output name string = originGroup.name diff --git a/avm/res/cdn/profile/origingroup/main.json b/avm/res/cdn/profile/origingroup/main.json index a2f6cb1d54..4dce9e8ca3 100644 --- a/avm/res/cdn/profile/origingroup/main.json +++ b/avm/res/cdn/profile/origingroup/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8675132561244182118" + "version": "0.26.54.24096", + "templateHash": "8706007645911322422" }, "name": "CDN Profiles Origin Group", "description": "This module deploys a CDN Profile Origin Group.", @@ -142,8 +142,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17323276561210856523" + "version": "0.26.54.24096", + "templateHash": "16657064743499074369" }, "name": "CDN Profiles Origin", "description": "This module deploys a CDN Profile Origin.", diff --git a/avm/res/cdn/profile/origingroup/origin/main.json b/avm/res/cdn/profile/origingroup/origin/main.json index 1988abc0e8..fb48ec8744 100644 --- a/avm/res/cdn/profile/origingroup/origin/main.json +++ b/avm/res/cdn/profile/origingroup/origin/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17323276561210856523" + "version": "0.26.54.24096", + "templateHash": "16657064743499074369" }, "name": "CDN Profiles Origin", "description": "This module deploys a CDN Profile Origin.", diff --git a/avm/res/cdn/profile/ruleset/main.bicep b/avm/res/cdn/profile/ruleset/main.bicep index c62e53d469..9d96381236 100644 --- a/avm/res/cdn/profile/ruleset/main.bicep +++ b/avm/res/cdn/profile/ruleset/main.bicep @@ -20,18 +20,20 @@ resource ruleSet 'Microsoft.Cdn/profiles/ruleSets@2023-05-01' = { parent: profile } -module ruleSet_rules 'rule/main.bicep' = [for (rule, index) in (rules ?? []): { - name: '${uniqueString(deployment().name)}-RuleSet-Rule-${rule.name}-${index}' - params: { - profileName: profileName - ruleSetName: name - name: rule.name - order: rule.order - actions: rule.?actions - conditions: rule.?conditions - matchProcessingBehavior: rule.?matchProcessingBehavior +module ruleSet_rules 'rule/main.bicep' = [ + for (rule, index) in (rules ?? []): { + name: '${uniqueString(deployment().name)}-RuleSet-Rule-${rule.name}-${index}' + params: { + profileName: profileName + ruleSetName: name + name: rule.name + order: rule.order + actions: rule.?actions + conditions: rule.?conditions + matchProcessingBehavior: rule.?matchProcessingBehavior + } } -}] +] @description('The name of the rule set.') output name string = ruleSet.name diff --git a/avm/res/cdn/profile/ruleset/main.json b/avm/res/cdn/profile/ruleset/main.json index 7220e258e3..349d081644 100644 --- a/avm/res/cdn/profile/ruleset/main.json +++ b/avm/res/cdn/profile/ruleset/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4615747470717464878" + "version": "0.26.54.24096", + "templateHash": "1809010747275335698" }, "name": "CDN Profiles Rule Sets", "description": "This module deploys a CDN Profile rule set.", @@ -91,8 +91,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "9936176531232217343" + "version": "0.26.54.24096", + "templateHash": "8195283154733773558" }, "name": "CDN Profiles Rules", "description": "This module deploys a CDN Profile rule.", diff --git a/avm/res/cdn/profile/ruleset/rule/main.json b/avm/res/cdn/profile/ruleset/rule/main.json index 2d3057f19b..dc817e69f6 100644 --- a/avm/res/cdn/profile/ruleset/rule/main.json +++ b/avm/res/cdn/profile/ruleset/rule/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "9936176531232217343" + "version": "0.26.54.24096", + "templateHash": "8195283154733773558" }, "name": "CDN Profiles Rules", "description": "This module deploys a CDN Profile rule.", diff --git a/avm/res/cdn/profile/secret/main.bicep b/avm/res/cdn/profile/secret/main.bicep index 29cd8dbe71..1f910147e8 100644 --- a/avm/res/cdn/profile/secret/main.bicep +++ b/avm/res/cdn/profile/secret/main.bicep @@ -38,15 +38,17 @@ resource secret 'Microsoft.Cdn/profiles/secrets@2023-05-01' = { name: name parent: profile properties: { - parameters: (type == 'CustomerCertificate') ? { - type: type - secretSource: { - id: secretSourceResourceId - } - secretVersion: secretVersion - subjectAlternativeNames: subjectAlternativeNames - useLatestVersion: useLatestVersion - } : null + parameters: (type == 'CustomerCertificate') + ? { + type: type + secretSource: { + id: secretSourceResourceId + } + secretVersion: secretVersion + subjectAlternativeNames: subjectAlternativeNames + useLatestVersion: useLatestVersion + } + : null } } diff --git a/avm/res/cdn/profile/secret/main.json b/avm/res/cdn/profile/secret/main.json index 657d94853b..9ba045e7be 100644 --- a/avm/res/cdn/profile/secret/main.json +++ b/avm/res/cdn/profile/secret/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3645784765890890733" + "version": "0.26.54.24096", + "templateHash": "7298174434641608123" }, "name": "CDN Profiles Secret", "description": "This module deploys a CDN Profile Secret.", diff --git a/avm/res/cdn/profile/tests/e2e/afd/main.test.bicep b/avm/res/cdn/profile/tests/e2e/afd/main.test.bicep index 6394e8e2ae..b559a41236 100644 --- a/avm/res/cdn/profile/tests/e2e/afd/main.test.bicep +++ b/avm/res/cdn/profile/tests/e2e/afd/main.test.bicep @@ -36,76 +36,78 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: 'dep-${namePrefix}-test-${serviceShort}' - location: 'global' - originResponseTimeoutSeconds: 60 - sku: 'Standard_AzureFrontDoor' - customDomains: [ - { - name: 'dep-${namePrefix}-test-${serviceShort}-custom-domain' - hostName: 'dep-${namePrefix}-test-${serviceShort}-custom-domain.azurewebsites.net' - certificateType: 'ManagedCertificate' - } - ] - origionGroups: [ - { - name: 'dep-${namePrefix}-test-${serviceShort}-origin-group' - loadBalancingSettings: { - additionalLatencyInMilliseconds: 50 - sampleSize: 4 - successfulSamplesRequired: 3 +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: 'dep-${namePrefix}-test-${serviceShort}' + location: 'global' + originResponseTimeoutSeconds: 60 + sku: 'Standard_AzureFrontDoor' + customDomains: [ + { + name: 'dep-${namePrefix}-test-${serviceShort}-custom-domain' + hostName: 'dep-${namePrefix}-test-${serviceShort}-custom-domain.azurewebsites.net' + certificateType: 'ManagedCertificate' } - origins: [ - { - name: 'dep-${namePrefix}-test-${serviceShort}-origin' - hostName: 'dep-${namePrefix}-test-${serviceShort}-origin.azurewebsites.net' + ] + origionGroups: [ + { + name: 'dep-${namePrefix}-test-${serviceShort}-origin-group' + loadBalancingSettings: { + additionalLatencyInMilliseconds: 50 + sampleSize: 4 + successfulSamplesRequired: 3 } - ] - } - ] - ruleSets: [ - { - name: 'dep${namePrefix}test${serviceShort}ruleset' - rules: [ - { - name: 'dep${namePrefix}test${serviceShort}rule' - order: 1 - actions: [ - { - name: 'UrlRedirect' - parameters: { - typeName: 'DeliveryRuleUrlRedirectActionParameters' - redirectType: 'PermanentRedirect' - destinationProtocol: 'Https' - customPath: '/test123' - customHostname: 'dev-etradefd.trade.azure.defra.cloud' + origins: [ + { + name: 'dep-${namePrefix}-test-${serviceShort}-origin' + hostName: 'dep-${namePrefix}-test-${serviceShort}-origin.azurewebsites.net' + } + ] + } + ] + ruleSets: [ + { + name: 'dep${namePrefix}test${serviceShort}ruleset' + rules: [ + { + name: 'dep${namePrefix}test${serviceShort}rule' + order: 1 + actions: [ + { + name: 'UrlRedirect' + parameters: { + typeName: 'DeliveryRuleUrlRedirectActionParameters' + redirectType: 'PermanentRedirect' + destinationProtocol: 'Https' + customPath: '/test123' + customHostname: 'dev-etradefd.trade.azure.defra.cloud' + } } - } - ] - } - ] - } - ] - afdEndpoints: [ - { - name: 'dep-${namePrefix}-test-${serviceShort}-afd-endpoint' - routes: [ - { - name: 'dep-${namePrefix}-test-${serviceShort}-afd-route' - originGroupName: 'dep-${namePrefix}-test-${serviceShort}-origin-group' - customDomainName: 'dep-${namePrefix}-test-${serviceShort}-custom-domain' - ruleSets: [ - { - name: 'dep${namePrefix}test${serviceShort}ruleset' - } - ] - } - ] - } - ] + ] + } + ] + } + ] + afdEndpoints: [ + { + name: 'dep-${namePrefix}-test-${serviceShort}-afd-endpoint' + routes: [ + { + name: 'dep-${namePrefix}-test-${serviceShort}-afd-route' + originGroupName: 'dep-${namePrefix}-test-${serviceShort}-origin-group' + customDomainName: 'dep-${namePrefix}-test-${serviceShort}-custom-domain' + ruleSets: [ + { + name: 'dep${namePrefix}test${serviceShort}ruleset' + } + ] + } + ] + } + ] + } } -}] +] diff --git a/avm/res/cdn/profile/tests/e2e/defaults/main.test.bicep b/avm/res/cdn/profile/tests/e2e/defaults/main.test.bicep index 3573faeab4..68c415ae4d 100644 --- a/avm/res/cdn/profile/tests/e2e/defaults/main.test.bicep +++ b/avm/res/cdn/profile/tests/e2e/defaults/main.test.bicep @@ -32,12 +32,14 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: 'dep-${namePrefix}-test-${serviceShort}' - location: resourceLocation - sku: 'Standard_Microsoft' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: 'dep-${namePrefix}-test-${serviceShort}' + location: resourceLocation + sku: 'Standard_Microsoft' + } } -}] +] diff --git a/avm/res/cdn/profile/tests/e2e/max/main.test.bicep b/avm/res/cdn/profile/tests/e2e/max/main.test.bicep index 268b935d3b..4a66b858fa 100644 --- a/avm/res/cdn/profile/tests/e2e/max/main.test.bicep +++ b/avm/res/cdn/profile/tests/e2e/max/main.test.bicep @@ -46,64 +46,69 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: 'dep-${namePrefix}-test-${serviceShort}' - location: resourceLocation - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - originResponseTimeoutSeconds: 60 - sku: 'Standard_Verizon' - endpointProperties: { - originHostHeader: '${nestedDependencies.outputs.storageAccountName}.blob.${environment().suffixes.storage}' - contentTypesToCompress: [ - 'text/plain' - 'text/html' - 'text/css' - 'text/javascript' - 'application/x-javascript' - 'application/javascript' - 'application/json' - 'application/xml' - ] - isCompressionEnabled: true - isHttpAllowed: true - isHttpsAllowed: true - queryStringCachingBehavior: 'IgnoreQueryString' - origins: [ - { - name: 'dep-${namePrefix}-cdn-endpoint01' - properties: { - hostName: '${nestedDependencies.outputs.storageAccountName}.blob.${environment().suffixes.storage}' - httpPort: 80 - httpsPort: 443 - enabled: true +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: 'dep-${namePrefix}-test-${serviceShort}' + location: resourceLocation + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + originResponseTimeoutSeconds: 60 + sku: 'Standard_Verizon' + endpointProperties: { + originHostHeader: '${nestedDependencies.outputs.storageAccountName}.blob.${environment().suffixes.storage}' + contentTypesToCompress: [ + 'text/plain' + 'text/html' + 'text/css' + 'text/javascript' + 'application/x-javascript' + 'application/javascript' + 'application/json' + 'application/xml' + ] + isCompressionEnabled: true + isHttpAllowed: true + isHttpsAllowed: true + queryStringCachingBehavior: 'IgnoreQueryString' + origins: [ + { + name: 'dep-${namePrefix}-cdn-endpoint01' + properties: { + hostName: '${nestedDependencies.outputs.storageAccountName}.blob.${environment().suffixes.storage}' + httpPort: 80 + httpsPort: 443 + enabled: true + } } + ] + originGroups: [] + geoFilters: [] + } + 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' } ] - originGroups: [] - geoFilters: [] } - 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' - } - ] } -}] +] diff --git a/avm/res/cdn/profile/tests/e2e/waf-aligned/main.test.bicep b/avm/res/cdn/profile/tests/e2e/waf-aligned/main.test.bicep index 5cc49fb6c5..7d70c1af4c 100644 --- a/avm/res/cdn/profile/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/cdn/profile/tests/e2e/waf-aligned/main.test.bicep @@ -45,46 +45,48 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: 'dep-${namePrefix}-test-${serviceShort}' - location: resourceLocation - originResponseTimeoutSeconds: 60 - sku: 'Standard_Verizon' - endpointProperties: { - originHostHeader: '${nestedDependencies.outputs.storageAccountName}.blob.${environment().suffixes.storage}' - contentTypesToCompress: [ - 'text/plain' - 'text/html' - 'text/css' - 'text/javascript' - 'application/x-javascript' - 'application/javascript' - 'application/json' - 'application/xml' - ] - isCompressionEnabled: true - isHttpAllowed: true - isHttpsAllowed: true - queryStringCachingBehavior: 'IgnoreQueryString' - origins: [ - { - name: 'dep-${namePrefix}-cdn-endpoint01' - properties: { - hostName: '${nestedDependencies.outputs.storageAccountName}.blob.${environment().suffixes.storage}' - httpPort: 80 - httpsPort: 443 - enabled: true +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: 'dep-${namePrefix}-test-${serviceShort}' + location: resourceLocation + originResponseTimeoutSeconds: 60 + sku: 'Standard_Verizon' + endpointProperties: { + originHostHeader: '${nestedDependencies.outputs.storageAccountName}.blob.${environment().suffixes.storage}' + contentTypesToCompress: [ + 'text/plain' + 'text/html' + 'text/css' + 'text/javascript' + 'application/x-javascript' + 'application/javascript' + 'application/json' + 'application/xml' + ] + isCompressionEnabled: true + isHttpAllowed: true + isHttpsAllowed: true + queryStringCachingBehavior: 'IgnoreQueryString' + origins: [ + { + name: 'dep-${namePrefix}-cdn-endpoint01' + properties: { + hostName: '${nestedDependencies.outputs.storageAccountName}.blob.${environment().suffixes.storage}' + httpPort: 80 + httpsPort: 443 + enabled: true + } } - } - ] - originGroups: [] - geoFilters: [] + ] + originGroups: [] + geoFilters: [] + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/cognitive-services/account/main.bicep b/avm/res/cognitive-services/account/main.bicep index 55a51646ae..b207c3e276 100644 --- a/avm/res/cognitive-services/account/main.bicep +++ b/avm/res/cognitive-services/account/main.bicep @@ -126,75 +126,171 @@ param managedIdentities managedIdentitiesType @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - 'Cognitive Services Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '25fbc0a9-bd7c-42a3-aa1a-3b75d497ee68') - 'Cognitive Services Custom Vision Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c1ff6cc2-c111-46fe-8896-e0ef812ad9f3') - 'Cognitive Services Custom Vision Deployment': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5c4089e1-6d96-4d2f-b296-c1bc7137275f') - 'Cognitive Services Custom Vision Labeler': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '88424f51-ebe7-446f-bc41-7fa16989e96c') - 'Cognitive Services Custom Vision Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '93586559-c37d-4a6b-ba08-b9f0940c2d73') - 'Cognitive Services Custom Vision Trainer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a5ae4ab-0d65-4eeb-be61-29fc9b54394b') - 'Cognitive Services Data Reader (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b59867f0-fa02-499b-be73-45a86b5b3e1c') - 'Cognitive Services Face Recognizer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9894cab4-e18a-44aa-828b-cb588cd6f2d7') - 'Cognitive Services Immersive Reader User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b2de6794-95db-4659-8781-7e080d3f2b9d') - 'Cognitive Services Language Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f07febfe-79bc-46b1-8b37-790e26e6e498') - 'Cognitive Services Language Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7628b7b8-a8b2-4cdc-b46f-e9b35248918e') - 'Cognitive Services Language Writer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f2310ca1-dc64-4889-bb49-c8e0fa3d47a8') - 'Cognitive Services LUIS Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f72c8140-2111-481c-87ff-72b910f6e3f8') - 'Cognitive Services LUIS Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18e81cdc-4e98-4e29-a639-e7d10c5a6226') - 'Cognitive Services LUIS Writer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6322a993-d5c9-4bed-b113-e49bbea25b27') - 'Cognitive Services Metrics Advisor Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cb43c632-a144-4ec5-977c-e80c4affc34a') - 'Cognitive Services Metrics Advisor User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3b20f47b-3825-43cb-8114-4bd2201156a8') - 'Cognitive Services OpenAI Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a001fd3d-188f-4b5d-821b-7da978bf7442') - 'Cognitive Services OpenAI User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd') - 'Cognitive Services QnA Maker Editor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f4cc2bf9-21be-47a1-bdf1-5c5804381025') - 'Cognitive Services QnA Maker Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '466ccd10-b268-4a11-b098-b4849f024126') - 'Cognitive Services Speech Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0e75ca1e-0464-4b4d-8b93-68208a576181') - 'Cognitive Services Speech User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f2dc8367-1007-4938-bd23-fe263f013447') - 'Cognitive Services User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a97b65f3-24c7-4388-baec-2e87135dc908') + 'Cognitive Services Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '25fbc0a9-bd7c-42a3-aa1a-3b75d497ee68' + ) + 'Cognitive Services Custom Vision Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'c1ff6cc2-c111-46fe-8896-e0ef812ad9f3' + ) + 'Cognitive Services Custom Vision Deployment': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '5c4089e1-6d96-4d2f-b296-c1bc7137275f' + ) + 'Cognitive Services Custom Vision Labeler': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '88424f51-ebe7-446f-bc41-7fa16989e96c' + ) + 'Cognitive Services Custom Vision Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '93586559-c37d-4a6b-ba08-b9f0940c2d73' + ) + 'Cognitive Services Custom Vision Trainer': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0a5ae4ab-0d65-4eeb-be61-29fc9b54394b' + ) + 'Cognitive Services Data Reader (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b59867f0-fa02-499b-be73-45a86b5b3e1c' + ) + 'Cognitive Services Face Recognizer': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '9894cab4-e18a-44aa-828b-cb588cd6f2d7' + ) + 'Cognitive Services Immersive Reader User': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b2de6794-95db-4659-8781-7e080d3f2b9d' + ) + 'Cognitive Services Language Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f07febfe-79bc-46b1-8b37-790e26e6e498' + ) + 'Cognitive Services Language Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7628b7b8-a8b2-4cdc-b46f-e9b35248918e' + ) + 'Cognitive Services Language Writer': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f2310ca1-dc64-4889-bb49-c8e0fa3d47a8' + ) + 'Cognitive Services LUIS Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f72c8140-2111-481c-87ff-72b910f6e3f8' + ) + 'Cognitive Services LUIS Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18e81cdc-4e98-4e29-a639-e7d10c5a6226' + ) + 'Cognitive Services LUIS Writer': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '6322a993-d5c9-4bed-b113-e49bbea25b27' + ) + 'Cognitive Services Metrics Advisor Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'cb43c632-a144-4ec5-977c-e80c4affc34a' + ) + 'Cognitive Services Metrics Advisor User': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '3b20f47b-3825-43cb-8114-4bd2201156a8' + ) + 'Cognitive Services OpenAI Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a001fd3d-188f-4b5d-821b-7da978bf7442' + ) + 'Cognitive Services OpenAI User': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd' + ) + 'Cognitive Services QnA Maker Editor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f4cc2bf9-21be-47a1-bdf1-5c5804381025' + ) + 'Cognitive Services QnA Maker Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '466ccd10-b268-4a11-b098-b4849f024126' + ) + 'Cognitive Services Speech Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0e75ca1e-0464-4b4d-8b93-68208a576181' + ) + 'Cognitive Services Speech User': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f2dc8367-1007-4938-bd23-fe263f013447' + ) + 'Cognitive Services User': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a97b65f3-24c7-4388-baec-2e87135dc908' + ) 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') + '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.cognitiveservices-account.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.cognitiveservices-account.${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 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 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 cognitiveService 'Microsoft.CognitiveServices/accounts@2023-05-01' = { name: name @@ -207,24 +303,34 @@ resource cognitiveService 'Microsoft.CognitiveServices/accounts@2023-05-01' = { } properties: { customSubDomainName: customSubDomainName - networkAcls: !empty(networkAcls ?? {}) ? { - defaultAction: networkAcls.?defaultAction - virtualNetworkRules: networkAcls.?virtualNetworkRules ?? [] - ipRules: networkAcls.?ipRules ?? [] - } : null - publicNetworkAccess: !empty(publicNetworkAccess) ? publicNetworkAccess : (!empty(networkAcls) ? 'Enabled' : 'Disabled') + networkAcls: !empty(networkAcls ?? {}) + ? { + defaultAction: networkAcls.?defaultAction + virtualNetworkRules: networkAcls.?virtualNetworkRules ?? [] + ipRules: networkAcls.?ipRules ?? [] + } + : null + publicNetworkAccess: !empty(publicNetworkAccess) + ? publicNetworkAccess + : (!empty(networkAcls) ? 'Enabled' : 'Disabled') allowedFqdnList: allowedFqdnList apiProperties: apiProperties disableLocalAuth: disableLocalAuth - encryption: !empty(customerManagedKey) ? { - keySource: 'Microsoft.KeyVault' - keyVaultProperties: { - identityClientId: !empty(customerManagedKey.?userAssignedIdentityResourceId ?? '') ? cMKUserAssignedIdentity.properties.clientId : null - keyVaultUri: cMKKeyVault.properties.vaultUri - keyName: customerManagedKey!.keyName - keyVersion: !empty(customerManagedKey.?keyVersion ?? '') ? customerManagedKey!.keyVersion : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) - } - } : null + encryption: !empty(customerManagedKey) + ? { + keySource: 'Microsoft.KeyVault' + keyVaultProperties: { + identityClientId: !empty(customerManagedKey.?userAssignedIdentityResourceId ?? '') + ? cMKUserAssignedIdentity.properties.clientId + : null + keyVaultUri: cMKKeyVault.properties.vaultUri + keyName: customerManagedKey!.keyName + keyVersion: !empty(customerManagedKey.?keyVersion ?? '') + ? customerManagedKey!.keyVersion + : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) + } + } + : null migrationToken: migrationToken restore: restore restrictOutboundNetworkAccess: restrictOutboundNetworkAccess @@ -233,93 +339,116 @@ resource cognitiveService 'Microsoft.CognitiveServices/accounts@2023-05-01' = { } } -resource cognitiveService_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.' +resource cognitiveService_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: cognitiveService } - scope: cognitiveService -} -resource cognitiveService_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 - 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 +resource cognitiveService_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 + 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 + } + scope: cognitiveService } - scope: cognitiveService -}] - -module cognitiveService_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-CognitiveService-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(cognitiveService.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' - privateLinkServiceConnections: [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(cognitiveService.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' - properties: { - privateLinkServiceId: cognitiveService.id - groupIds: [ - privateEndpoint.?service ?? 'account' - ] +] + +module cognitiveService_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-CognitiveService-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(cognitiveService.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' + privateLinkServiceConnections: [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(cognitiveService.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' + properties: { + privateLinkServiceId: cognitiveService.id + groupIds: [ + privateEndpoint.?service ?? 'account' + ] + } } - } - ] - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(cognitiveService.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' - properties: { - privateLinkServiceId: cognitiveService.id - groupIds: [ - privateEndpoint.?service ?? 'account' + ] + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(cognitiveService.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' + properties: { + privateLinkServiceId: cognitiveService.id + groupIds: [ + privateEndpoint.?service ?? 'account' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource cognitiveService_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(cognitiveService.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 +resource cognitiveService_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(cognitiveService.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: cognitiveService } - scope: cognitiveService -}] +] @description('The name of the cognitive services account.') output name string = cognitiveService.name diff --git a/avm/res/cognitive-services/account/main.json b/avm/res/cognitive-services/account/main.json index a45302ba9e..6fd6d4050a 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.25.53.49325", - "templateHash": "6670691272648355802" + "version": "0.26.54.24096", + "templateHash": "4593361593861215330" }, "name": "Cognitive Services", "description": "This module deploys a Cognitive Service.", diff --git a/avm/res/cognitive-services/account/tests/e2e/defaults/main.test.bicep b/avm/res/cognitive-services/account/tests/e2e/defaults/main.test.bicep index 37a7e34a26..2b282ac938 100644 --- a/avm/res/cognitive-services/account/tests/e2e/defaults/main.test.bicep +++ b/avm/res/cognitive-services/account/tests/e2e/defaults/main.test.bicep @@ -36,12 +36,14 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { // ============== // @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' - kind: 'SpeechServices' - location: resourceLocation +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + kind: 'SpeechServices' + location: resourceLocation + } } -}] +] 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 c133cecb59..1ba0cf8985 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 @@ -59,124 +59,129 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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' - kind: 'Face' - customSubDomainName: '${namePrefix}x${serviceShort}' - location: resourceLocation - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + kind: 'Face' + customSubDomainName: '${namePrefix}x${serviceShort}' + location: resourceLocation + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + logCategoriesAndGroups: [ + { + category: 'RequestResponse' + } + { + category: 'Audit' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + networkAcls: { + defaultAction: 'Deny' + ipRules: [ { - category: 'AllMetrics' + value: '40.74.28.0/23' } ] - logCategoriesAndGroups: [ - { - category: 'RequestResponse' - } + virtualNetworkRules: [ { - category: 'Audit' + id: nestedDependencies.outputs.subnetResourceId + ignoreMissingVnetServiceEndpoint: false } ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - networkAcls: { - defaultAction: 'Deny' - ipRules: [ + publicNetworkAccess: 'Disabled' + roleAssignments: [ { - value: '40.74.28.0/23' + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - ] - virtualNetworkRules: [ { - id: nestedDependencies.outputs.subnetResourceId - ignoreMissingVnetServiceEndpoint: false + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - ] - } - publicNetworkAccess: 'Disabled' - 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' - } - ] - sku: 'S0' - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + { + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - ipConfigurations: [ - { - name: 'myIPconfig' - properties: { - groupId: 'account' - memberName: 'default' - privateIPAddress: '10.0.0.10' - } - } - ] - customDnsConfigs: [ - { - fqdn: 'abc.account.com' - ipAddresses: [ - '10.0.0.10' - ] - } + ] + sku: 'S0' + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + ipConfigurations: [ + { + name: 'myIPconfig' + properties: { + groupId: 'account' + memberName: 'default' + privateIPAddress: '10.0.0.10' + } + } + ] + customDnsConfigs: [ + { + fqdn: 'abc.account.com' + ipAddresses: [ + '10.0.0.10' + ] + } + ] + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + 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' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/cognitive-services/account/tests/e2e/speech/main.test.bicep b/avm/res/cognitive-services/account/tests/e2e/speech/main.test.bicep index d115398bf1..a4c8eb799b 100644 --- a/avm/res/cognitive-services/account/tests/e2e/speech/main.test.bicep +++ b/avm/res/cognitive-services/account/tests/e2e/speech/main.test.bicep @@ -45,41 +45,43 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - kind: 'SpeechServices' - location: resourceLocation - customSubDomainName: '${namePrefix}speechdomain' - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + kind: 'SpeechServices' + location: resourceLocation + customSubDomainName: '${namePrefix}speechdomain' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } - } - ] - sku: 'S0' - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId ] + sku: 'S0' + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + 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' - } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/cognitive-services/account/tests/e2e/system-assigned-cmk-encryption/dependencies.bicep b/avm/res/cognitive-services/account/tests/e2e/system-assigned-cmk-encryption/dependencies.bicep index 3fe7da6af3..64f4ad94b8 100644 --- a/avm/res/cognitive-services/account/tests/e2e/system-assigned-cmk-encryption/dependencies.bicep +++ b/avm/res/cognitive-services/account/tests/e2e/system-assigned-cmk-encryption/dependencies.bicep @@ -53,7 +53,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: keyVault::key properties: { principalId: cognitiveService.identity.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User principalType: 'ServicePrincipal' } } diff --git a/avm/res/cognitive-services/account/tests/e2e/system-assigned-cmk-encryption/main.test.bicep b/avm/res/cognitive-services/account/tests/e2e/system-assigned-cmk-encryption/main.test.bicep index 3e79483631..b9120e533a 100644 --- a/avm/res/cognitive-services/account/tests/e2e/system-assigned-cmk-encryption/main.test.bicep +++ b/avm/res/cognitive-services/account/tests/e2e/system-assigned-cmk-encryption/main.test.bicep @@ -50,25 +50,27 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: nestedDependencies.outputs.cognitiveServiceName - kind: 'SpeechServices' - location: resourceLocation - customerManagedKey: { - keyName: nestedDependencies.outputs.keyVaultKeyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - } - publicNetworkAccess: 'Enabled' - sku: 'S0' - managedIdentities: { - systemAssigned: true +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: nestedDependencies.outputs.cognitiveServiceName + kind: 'SpeechServices' + location: resourceLocation + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultKeyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + } + publicNetworkAccess: 'Enabled' + sku: 'S0' + managedIdentities: { + systemAssigned: true + } + restrictOutboundNetworkAccess: false } - restrictOutboundNetworkAccess: false + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/cognitive-services/account/tests/e2e/user-assigned-cmk-encryption/dependencies.bicep b/avm/res/cognitive-services/account/tests/e2e/user-assigned-cmk-encryption/dependencies.bicep index 5aefaea511..1ad042356a 100644 --- a/avm/res/cognitive-services/account/tests/e2e/user-assigned-cmk-encryption/dependencies.bicep +++ b/avm/res/cognitive-services/account/tests/e2e/user-assigned-cmk-encryption/dependencies.bicep @@ -43,7 +43,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: keyVault::key properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User principalType: 'ServicePrincipal' } } diff --git a/avm/res/cognitive-services/account/tests/e2e/user-assigned-cmk-encryption/main.test.bicep b/avm/res/cognitive-services/account/tests/e2e/user-assigned-cmk-encryption/main.test.bicep index f161025c18..8d4a1ed277 100644 --- a/avm/res/cognitive-services/account/tests/e2e/user-assigned-cmk-encryption/main.test.bicep +++ b/avm/res/cognitive-services/account/tests/e2e/user-assigned-cmk-encryption/main.test.bicep @@ -50,28 +50,30 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - kind: 'SpeechServices' - location: resourceLocation - customerManagedKey: { - keyName: nestedDependencies.outputs.keyVaultKeyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId - } - publicNetworkAccess: 'Enabled' - sku: 'S0' - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + kind: 'SpeechServices' + location: resourceLocation + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultKeyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + } + publicNetworkAccess: 'Enabled' + sku: 'S0' + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + restrictOutboundNetworkAccess: false } - restrictOutboundNetworkAccess: false + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/cognitive-services/account/tests/e2e/waf-aligned/main.test.bicep b/avm/res/cognitive-services/account/tests/e2e/waf-aligned/main.test.bicep index 362a8ade16..53649ec3f4 100644 --- a/avm/res/cognitive-services/account/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/cognitive-services/account/tests/e2e/waf-aligned/main.test.bicep @@ -59,51 +59,53 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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' - kind: 'Face' - location: resourceLocation - customSubDomainName: '${namePrefix}x${serviceShort}' - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + kind: 'Face' + location: resourceLocation + customSubDomainName: '${namePrefix}x${serviceShort}' + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - sku: 'S0' - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + sku: 'S0' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + 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' + } + managedIdentities: { + systemAssigned: true } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - managedIdentities: { - systemAssigned: true } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/compute/availability-set/main.bicep b/avm/res/compute/availability-set/main.bicep index 62191c9814..778c4e4048 100644 --- a/avm/res/compute/availability-set/main.bicep +++ b/avm/res/compute/availability-set/main.bicep @@ -36,31 +36,50 @@ 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': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') - 'Virtual Machine Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4') - 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c') - 'Virtual Machine Data Access Administrator (preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '66f75aeb-eabe-4b70-9f1e-c350c4c9ad04') - 'Virtual Machine User Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52') + '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' + ) + 'Virtual Machine Administrator Login': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1c0163c0-47e6-4577-8991-ea5c82e286e4' + ) + 'Virtual Machine Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '9980e02c-c2be-4d73-94e8-173b1dc7cf3c' + ) + 'Virtual Machine Data Access Administrator (preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '66f75aeb-eabe-4b70-9f1e-c350c4c9ad04' + ) + 'Virtual Machine User Login': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'fb879df8-f326-4884-b1cf-06f3ad86be52' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.compute-availabilityset.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.compute-availabilityset.${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 availabilitySet 'Microsoft.Compute/availabilitySets@2023-03-01' = { name: name @@ -69,37 +88,48 @@ resource availabilitySet 'Microsoft.Compute/availabilitySets@2023-03-01' = { properties: { platformFaultDomainCount: platformFaultDomainCount platformUpdateDomainCount: platformUpdateDomainCount - proximityPlacementGroup: !empty(proximityPlacementGroupResourceId) ? { - id: proximityPlacementGroupResourceId - } : null + proximityPlacementGroup: !empty(proximityPlacementGroupResourceId) + ? { + id: proximityPlacementGroupResourceId + } + : null } sku: { name: skuName } } -resource availabilitySet_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.' +resource availabilitySet_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: availabilitySet } - scope: availabilitySet -} -resource availabilitySet_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(availabilitySet.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 +resource availabilitySet_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(availabilitySet.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: availabilitySet } - scope: availabilitySet -}] +] @description('The name of the availability set.') output name string = availabilitySet.name diff --git a/avm/res/compute/availability-set/main.json b/avm/res/compute/availability-set/main.json index 038249ef1f..290131af55 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.25.53.49325", - "templateHash": "142072316382977028" + "version": "0.26.54.24096", + "templateHash": "9732921541323544854" }, "name": "Availability Sets", "description": "This module deploys an Availability Set.", diff --git a/avm/res/compute/availability-set/tests/e2e/defaults/main.test.bicep b/avm/res/compute/availability-set/tests/e2e/defaults/main.test.bicep index aca453a803..35b2cca188 100644 --- a/avm/res/compute/availability-set/tests/e2e/defaults/main.test.bicep +++ b/avm/res/compute/availability-set/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/compute/availability-set/tests/e2e/max/dependencies.bicep b/avm/res/compute/availability-set/tests/e2e/max/dependencies.bicep index 2c78999e90..5ac87aacbb 100644 --- a/avm/res/compute/availability-set/tests/e2e/max/dependencies.bicep +++ b/avm/res/compute/availability-set/tests/e2e/max/dependencies.bicep @@ -8,13 +8,13 @@ param managedIdentityName string param proximityPlacementGroupName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2022-03-01' = { - name: proximityPlacementGroupName - location: location + name: proximityPlacementGroupName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/compute/availability-set/tests/e2e/max/main.test.bicep b/avm/res/compute/availability-set/tests/e2e/max/main.test.bicep index 4ee1160903..bc1a62c7df 100644 --- a/avm/res/compute/availability-set/tests/e2e/max/main.test.bicep +++ b/avm/res/compute/availability-set/tests/e2e/max/main.test.bicep @@ -46,38 +46,43 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - } - proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/compute/availability-set/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/compute/availability-set/tests/e2e/waf-aligned/dependencies.bicep index 9233175e2e..db26ceda3e 100644 --- a/avm/res/compute/availability-set/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/compute/availability-set/tests/e2e/waf-aligned/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param proximityPlacementGroupName string resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2022-03-01' = { - name: proximityPlacementGroupName - location: location + name: proximityPlacementGroupName + location: location } @description('The resource ID of the created Proximity Placement Group.') diff --git a/avm/res/compute/availability-set/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/availability-set/tests/e2e/waf-aligned/main.test.bicep index a27ce67f2b..3fa0902e06 100644 --- a/avm/res/compute/availability-set/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/availability-set/tests/e2e/waf-aligned/main.test.bicep @@ -45,21 +45,23 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - } - proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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' + } + proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/compute/disk-encryption-set/main.bicep b/avm/res/compute/disk-encryption-set/main.bicep index 18113c865c..5932efeac2 100644 --- a/avm/res/compute/disk-encryption-set/main.bicep +++ b/avm/res/compute/disk-encryption-set/main.bicep @@ -47,44 +47,73 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Data Operator for Managed Disks': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '959f8984-c045-4866-89c7-12bf9737be2e') - 'Disk Backup Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24') - 'Disk Pool Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60fc6e62-5479-42d4-8bf4-67625fcc2840') - 'Disk Restore Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b50d9833-a0cb-478e-945f-707fcc997c13') - 'Disk Snapshot Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7efff54f-a5b4-42b5-a1c5-5411624893ce') + 'Data Operator for Managed Disks': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '959f8984-c045-4866-89c7-12bf9737be2e' + ) + 'Disk Backup Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24' + ) + 'Disk Pool Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '60fc6e62-5479-42d4-8bf4-67625fcc2840' + ) + 'Disk Restore Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b50d9833-a0cb-478e-945f-707fcc997c13' + ) + 'Disk Snapshot Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7efff54f-a5b4-42b5-a1c5-5411624893ce' + ) 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') + '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.compute-diskencryptionset.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.compute-diskencryptionset.${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 keyVault 'Microsoft.KeyVault/vaults@2021-10-01' existing = { name: last(split(keyVaultResourceId, '/'))! @@ -96,17 +125,19 @@ resource keyVault 'Microsoft.KeyVault/vaults@2021-10-01' existing = { } // Note: This is only enabled for user-assigned identities as the service's system-assigned identity isn't available during its initial deployment -module keyVaultPermissions 'modules/nested_keyVaultPermissions.bicep' = [for (userAssignedIdentityResourceId, index) in (managedIdentities.?userAssignedResourceIds ?? []): { - name: '${uniqueString(deployment().name, location)}-DiskEncrSet-KVPermissions-${index}' - params: { - keyName: keyName - keyVaultResourceId: keyVaultResourceId - userAssignedIdentityResourceId: userAssignedIdentityResourceId - rbacAuthorizationEnabled: keyVault.properties.enableRbacAuthorization - location: location +module keyVaultPermissions 'modules/nested_keyVaultPermissions.bicep' = [ + for (userAssignedIdentityResourceId, index) in (managedIdentities.?userAssignedResourceIds ?? []): { + name: '${uniqueString(deployment().name, location)}-DiskEncrSet-KVPermissions-${index}' + params: { + keyName: keyName + keyVaultResourceId: keyVaultResourceId + userAssignedIdentityResourceId: userAssignedIdentityResourceId + rbacAuthorizationEnabled: keyVault.properties.enableRbacAuthorization + location: location + } + scope: resourceGroup(split(keyVaultResourceId, '/')[2], split(keyVaultResourceId, '/')[4]) } - scope: resourceGroup(split(keyVaultResourceId, '/')[2], split(keyVaultResourceId, '/')[4]) -}] +] resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2022-07-02' = { name: name @@ -118,7 +149,9 @@ resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2022-07-02' = { sourceVault: { id: keyVaultResourceId } - keyUrl: !empty(keyVersion) ? '${keyVault::key.properties.keyUri}/${keyVersion}' : keyVault::key.properties.keyUriWithVersion + keyUrl: !empty(keyVersion) + ? '${keyVault::key.properties.keyUri}/${keyVersion}' + : keyVault::key.properties.keyUriWithVersion } encryptionType: encryptionType federatedClientId: federatedClientId @@ -129,28 +162,37 @@ resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2022-07-02' = { ] } -resource diskEncryptionSet_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(diskEncryptionSet.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 +resource diskEncryptionSet_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(diskEncryptionSet.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: diskEncryptionSet } - scope: diskEncryptionSet -}] - -resource diskEncryptionSet_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.' +] + +resource diskEncryptionSet_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: diskEncryptionSet } - scope: diskEncryptionSet -} @description('The resource ID of the disk encryption set.') output resourceId string = diskEncryptionSet.id diff --git a/avm/res/compute/disk-encryption-set/main.json b/avm/res/compute/disk-encryption-set/main.json index 74797dbc2d..da2764ea80 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.25.53.49325", - "templateHash": "2337982856441594532" + "version": "0.26.54.24096", + "templateHash": "15675582132137222221" }, "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.25.53.49325", - "templateHash": "4340767234132084239" + "version": "0.26.54.24096", + "templateHash": "11328049361610922964" } }, "parameters": { @@ -462,8 +462,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "9781242464769385318" + "version": "0.26.54.24096", + "templateHash": "3020199531226338329" }, "name": "Key Vault Access Policies", "description": "This module deploys a Key Vault Access Policy.", diff --git a/avm/res/compute/disk-encryption-set/tests/e2e/accessPolicies/dependencies.bicep b/avm/res/compute/disk-encryption-set/tests/e2e/accessPolicies/dependencies.bicep index 2024e8644e..4bc293926f 100644 --- a/avm/res/compute/disk-encryption-set/tests/e2e/accessPolicies/dependencies.bicep +++ b/avm/res/compute/disk-encryption-set/tests/e2e/accessPolicies/dependencies.bicep @@ -8,34 +8,34 @@ param keyVaultName string param managedIdentityName string 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 disk encryption set - softDeleteRetentionInDays: 7 - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: false - 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 disk encryption set + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: false + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' } + } } @description('The resource ID of the created Key Vault.') diff --git a/avm/res/compute/disk-encryption-set/tests/e2e/accessPolicies/main.test.bicep b/avm/res/compute/disk-encryption-set/tests/e2e/accessPolicies/main.test.bicep index af904fb339..5730cc4f3c 100644 --- a/avm/res/compute/disk-encryption-set/tests/e2e/accessPolicies/main.test.bicep +++ b/avm/res/compute/disk-encryption-set/tests/e2e/accessPolicies/main.test.bicep @@ -50,44 +50,49 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - keyName: nestedDependencies.outputs.keyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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 + keyName: nestedDependencies.outputs.keyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + 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' + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] } - { - 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' } - ] - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/compute/disk-encryption-set/tests/e2e/defaults/dependencies.bicep b/avm/res/compute/disk-encryption-set/tests/e2e/defaults/dependencies.bicep index 22b4344b68..a79f18bab3 100644 --- a/avm/res/compute/disk-encryption-set/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/compute/disk-encryption-set/tests/e2e/defaults/dependencies.bicep @@ -5,29 +5,29 @@ param location string = resourceGroup().location param keyVaultName string 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 disk encryption set - softDeleteRetentionInDays: 7 - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: true - accessPolicies: [] + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' } + tenantId: tenant().tenantId + enablePurgeProtection: true // Required by disk encryption set + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } - resource key 'keys@2022-07-01' = { - name: 'keyEncryptionKey' - properties: { - kty: 'RSA' - } + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' } + } } @description('The resource ID of the created Key Vault.') diff --git a/avm/res/compute/disk-encryption-set/tests/e2e/defaults/main.test.bicep b/avm/res/compute/disk-encryption-set/tests/e2e/defaults/main.test.bicep index d8302d5a8b..26d731b9ff 100644 --- a/avm/res/compute/disk-encryption-set/tests/e2e/defaults/main.test.bicep +++ b/avm/res/compute/disk-encryption-set/tests/e2e/defaults/main.test.bicep @@ -49,16 +49,18 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - keyName: nestedDependencies.outputs.keyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - location: resourceLocation +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + keyName: nestedDependencies.outputs.keyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + location: resourceLocation + } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/compute/disk-encryption-set/tests/e2e/max/dependencies.bicep b/avm/res/compute/disk-encryption-set/tests/e2e/max/dependencies.bicep index 62321ebe98..e6e79856d7 100644 --- a/avm/res/compute/disk-encryption-set/tests/e2e/max/dependencies.bicep +++ b/avm/res/compute/disk-encryption-set/tests/e2e/max/dependencies.bicep @@ -8,34 +8,34 @@ param keyVaultName string param managedIdentityName string 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 disk encryption set - 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 disk encryption set + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' } + } } @description('The resource ID of the created Key Vault.') diff --git a/avm/res/compute/disk-encryption-set/tests/e2e/max/main.test.bicep b/avm/res/compute/disk-encryption-set/tests/e2e/max/main.test.bicep index 2ad07c7a66..bd27d88592 100644 --- a/avm/res/compute/disk-encryption-set/tests/e2e/max/main.test.bicep +++ b/avm/res/compute/disk-encryption-set/tests/e2e/max/main.test.bicep @@ -50,47 +50,52 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - } - keyName: nestedDependencies.outputs.keyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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' } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + keyName: nestedDependencies.outputs.keyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + 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' + } + ] + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] } - { - 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' } - ] - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/compute/disk-encryption-set/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/compute/disk-encryption-set/tests/e2e/waf-aligned/dependencies.bicep index a893a4e5de..336e29b226 100644 --- a/avm/res/compute/disk-encryption-set/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/compute/disk-encryption-set/tests/e2e/waf-aligned/dependencies.bicep @@ -8,34 +8,34 @@ param keyVaultName string param managedIdentityName string 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 disk encryption set - 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 disk encryption set + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' } + } } @description('The resource ID of the created Key Vault.') diff --git a/avm/res/compute/disk-encryption-set/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/disk-encryption-set/tests/e2e/waf-aligned/main.test.bicep index 3c325e9232..d0438eb915 100644 --- a/avm/res/compute/disk-encryption-set/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/disk-encryption-set/tests/e2e/waf-aligned/main.test.bicep @@ -50,26 +50,28 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - keyName: nestedDependencies.outputs.keyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + keyName: nestedDependencies.outputs.keyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/compute/disk/main.bicep b/avm/res/compute/disk/main.bicep index 00701ce256..a4f07803e8 100644 --- a/avm/res/compute/disk/main.bicep +++ b/avm/res/compute/disk/main.bicep @@ -132,34 +132,56 @@ param enableTelemetry bool = true var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Data Operator for Managed Disks': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '959f8984-c045-4866-89c7-12bf9737be2e') - 'Disk Backup Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24') - 'Disk Pool Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60fc6e62-5479-42d4-8bf4-67625fcc2840') - 'Disk Restore Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b50d9833-a0cb-478e-945f-707fcc997c13') - 'Disk Snapshot Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7efff54f-a5b4-42b5-a1c5-5411624893ce') + 'Data Operator for Managed Disks': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '959f8984-c045-4866-89c7-12bf9737be2e' + ) + 'Disk Backup Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24' + ) + 'Disk Pool Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '60fc6e62-5479-42d4-8bf4-67625fcc2840' + ) + 'Disk Restore Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b50d9833-a0cb-478e-945f-707fcc997c13' + ) + 'Disk Snapshot Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7efff54f-a5b4-42b5-a1c5-5411624893ce' + ) 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') + '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.compute-disk.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.compute-disk.${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 disk 'Microsoft.Compute/disks@2022-07-02' = { name: name @@ -173,9 +195,11 @@ resource disk 'Microsoft.Compute/disks@2022-07-02' = { completionPercent: completionPercent creationData: { createOption: createOption - imageReference: createOption == 'FromImage' ? { - id: imageReferenceId - } : null + imageReference: createOption == 'FromImage' + ? { + id: imageReferenceId + } + : null logicalSectorSize: contains(sku, 'Ultra') ? logicalSectorSize : null securityDataUri: createOption == 'ImportSecure' ? securityDataUri : null sourceResourceId: createOption == 'Copy' ? sourceResourceId : null @@ -192,35 +216,46 @@ resource disk 'Microsoft.Compute/disks@2022-07-02' = { optimizedForFrequentAttach: optimizedForFrequentAttach osType: !empty(osType) ? osType : any(null) publicNetworkAccess: publicNetworkAccess - supportedCapabilities: !empty(osType) ? { - acceleratedNetwork: acceleratedNetwork - architecture: !empty(architecture) ? architecture : null - } : {} + supportedCapabilities: !empty(osType) + ? { + acceleratedNetwork: acceleratedNetwork + architecture: !empty(architecture) ? architecture : null + } + : {} } } -resource disk_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.' +resource disk_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: disk } - scope: disk -} -resource disk_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(disk.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 +resource disk_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(disk.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: disk } - scope: disk -}] +] @description('The resource group the disk was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/compute/disk/main.json b/avm/res/compute/disk/main.json index 7c41b3cc5d..c786f7e240 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.25.53.49325", - "templateHash": "6226788182357954709" + "version": "0.26.54.24096", + "templateHash": "5405955290856274825" }, "name": "Compute Disks", "description": "This module deploys a Compute Disk", diff --git a/avm/res/compute/disk/tests/e2e/defaults/main.test.bicep b/avm/res/compute/disk/tests/e2e/defaults/main.test.bicep index 97e32b8ad4..1e04040508 100644 --- a/avm/res/compute/disk/tests/e2e/defaults/main.test.bicep +++ b/avm/res/compute/disk/tests/e2e/defaults/main.test.bicep @@ -35,13 +35,15 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-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 - sku: 'Standard_LRS' - diskSizeGB: 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 + sku: 'Standard_LRS' + diskSizeGB: 1 + } } -}] +] diff --git a/avm/res/compute/disk/tests/e2e/image/dependencies.bicep b/avm/res/compute/disk/tests/e2e/image/dependencies.bicep index 616cf219fe..2c8183e726 100644 --- a/avm/res/compute/disk/tests/e2e/image/dependencies.bicep +++ b/avm/res/compute/disk/tests/e2e/image/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created managed identity.') diff --git a/avm/res/compute/disk/tests/e2e/image/main.test.bicep b/avm/res/compute/disk/tests/e2e/image/main.test.bicep index 3ebbb0e17d..cd850c0c4f 100644 --- a/avm/res/compute/disk/tests/e2e/image/main.test.bicep +++ b/avm/res/compute/disk/tests/e2e/image/main.test.bicep @@ -44,14 +44,16 @@ module nestedDependencies 'dependencies.bicep' = { // 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 - sku: 'Standard_LRS' - createOption: 'FromImage' - imageReferenceId: '${subscription().id}/Providers/Microsoft.Compute/Locations/westeurope/Publishers/MicrosoftWindowsServer/ArtifactTypes/VMImage/Offers/WindowsServer/Skus/2022-datacenter-azure-edition/Versions/20348.1006.220908' +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 + sku: 'Standard_LRS' + createOption: 'FromImage' + imageReferenceId: '${subscription().id}/Providers/Microsoft.Compute/Locations/westeurope/Publishers/MicrosoftWindowsServer/ArtifactTypes/VMImage/Offers/WindowsServer/Skus/2022-datacenter-azure-edition/Versions/20348.1006.220908' + } } -}] +] diff --git a/avm/res/compute/disk/tests/e2e/import/dependencies.bicep b/avm/res/compute/disk/tests/e2e/import/dependencies.bicep index 038eb6f8ac..3d1a1dac7e 100644 --- a/avm/res/compute/disk/tests/e2e/import/dependencies.bicep +++ b/avm/res/compute/disk/tests/e2e/import/dependencies.bicep @@ -136,7 +136,7 @@ resource copyVhdDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10- cleanupPreference: 'OnSuccess' forceUpdateTag: baseTime } - dependsOn: [ triggerImageDeploymentScript ] + dependsOn: [triggerImageDeploymentScript] } @description('The URI of the created VHD.') diff --git a/avm/res/compute/disk/tests/e2e/import/dependencies_rbac.bicep b/avm/res/compute/disk/tests/e2e/import/dependencies_rbac.bicep index cdca1b63bd..f28142392e 100644 --- a/avm/res/compute/disk/tests/e2e/import/dependencies_rbac.bicep +++ b/avm/res/compute/disk/tests/e2e/import/dependencies_rbac.bicep @@ -9,7 +9,10 @@ param managedIdentityPrincipalId string resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(subscription().subscriptionId, 'Contributor', managedIdentityResourceId) properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalId: managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/compute/disk/tests/e2e/import/main.test.bicep b/avm/res/compute/disk/tests/e2e/import/main.test.bicep index 66553f7301..6acc81a6dd 100644 --- a/avm/res/compute/disk/tests/e2e/import/main.test.bicep +++ b/avm/res/compute/disk/tests/e2e/import/main.test.bicep @@ -51,15 +51,17 @@ module nestedDependencies 'dependencies.bicep' = { // 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 - sku: 'Standard_LRS' - createOption: 'Import' - sourceUri: nestedDependencies.outputs.vhdUri - storageAccountId: nestedDependencies.outputs.storageAccountResourceId +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 + sku: 'Standard_LRS' + createOption: 'Import' + sourceUri: nestedDependencies.outputs.vhdUri + storageAccountId: nestedDependencies.outputs.storageAccountResourceId + } } -}] +] diff --git a/avm/res/compute/disk/tests/e2e/max/dependencies.bicep b/avm/res/compute/disk/tests/e2e/max/dependencies.bicep index 616cf219fe..2c8183e726 100644 --- a/avm/res/compute/disk/tests/e2e/max/dependencies.bicep +++ b/avm/res/compute/disk/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created managed identity.') diff --git a/avm/res/compute/disk/tests/e2e/max/main.test.bicep b/avm/res/compute/disk/tests/e2e/max/main.test.bicep index 9052419c5e..0bbafb98e5 100644 --- a/avm/res/compute/disk/tests/e2e/max/main.test.bicep +++ b/avm/res/compute/disk/tests/e2e/max/main.test.bicep @@ -44,44 +44,49 @@ module nestedDependencies 'dependencies.bicep' = { // 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 - sku: 'UltraSSD_LRS' - diskIOPSReadWrite: 500 - diskMBpsReadWrite: 60 - diskSizeGB: 128 - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - logicalSectorSize: 512 - osType: 'Windows' - publicNetworkAccess: 'Enabled' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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 + sku: 'UltraSSD_LRS' + diskIOPSReadWrite: 500 + diskMBpsReadWrite: 60 + diskSizeGB: 128 + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + logicalSectorSize: 512 + osType: 'Windows' + publicNetworkAccess: 'Enabled' + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/compute/disk/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/disk/tests/e2e/waf-aligned/main.test.bicep index d1b92bda7a..b6f4589566 100644 --- a/avm/res/compute/disk/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/disk/tests/e2e/waf-aligned/main.test.bicep @@ -35,27 +35,29 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-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 - sku: 'UltraSSD_LRS' - diskIOPSReadWrite: 500 - diskMBpsReadWrite: 60 - diskSizeGB: 128 - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - logicalSectorSize: 512 - osType: 'Windows' - publicNetworkAccess: 'Enabled' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + sku: 'UltraSSD_LRS' + diskIOPSReadWrite: 500 + diskMBpsReadWrite: 60 + diskSizeGB: 128 + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + logicalSectorSize: 512 + osType: 'Windows' + publicNetworkAccess: 'Enabled' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/compute/gallery/application/main.bicep b/avm/res/compute/gallery/application/main.bicep index f0f1ed2a3f..c17ac86830 100644 --- a/avm/res/compute/gallery/application/main.bicep +++ b/avm/res/compute/gallery/application/main.bicep @@ -44,12 +44,21 @@ param tags object? param customActions array? var builtInRoleNames = { - 'Compute Gallery Sharing Admin': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1ef6a3be-d0ac-425d-8c01-acb62866290b') + 'Compute Gallery Sharing Admin': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1ef6a3be-d0ac-425d-8c01-acb62866290b' + ) 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') + '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 gallery 'Microsoft.Compute/galleries@2022-03-03' existing = { @@ -72,19 +81,25 @@ resource application 'Microsoft.Compute/galleries/applications@2022-03-03' = { } } -resource application_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(application.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 +resource application_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(application.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: application } - scope: application -}] +] @sys.description('The resource group the image was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/compute/gallery/application/main.json b/avm/res/compute/gallery/application/main.json index c6ccc00385..9c8df87f87 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.25.53.49325", - "templateHash": "1766982665283226409" + "version": "0.26.54.24096", + "templateHash": "3817884050778525461" }, "name": "Compute Galleries Applications", "description": "This module deploys an Azure Compute Gallery Application.", diff --git a/avm/res/compute/gallery/image/main.bicep b/avm/res/compute/gallery/image/main.bicep index 8c8411fdf0..976535121b 100644 --- a/avm/res/compute/gallery/image/main.bicep +++ b/avm/res/compute/gallery/image/main.bicep @@ -117,12 +117,21 @@ param roleAssignments roleAssignmentType param tags object? var builtInRoleNames = { - 'Compute Gallery Sharing Admin': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1ef6a3be-d0ac-425d-8c01-acb62866290b') + 'Compute Gallery Sharing Admin': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1ef6a3be-d0ac-425d-8c01-acb62866290b' + ) 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') + '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 gallery 'Microsoft.Compute/galleries@2022-03-03' existing = { @@ -153,7 +162,8 @@ resource image 'Microsoft.Compute/galleries/images@2022-03-03' = { } } hyperVGeneration: hyperVGeneration ?? (!empty(securityType) ? 'V2' : 'V1') - features: union([ + features: union( + [ { name: 'IsAcceleratedNetworkSupported' value: '${isAcceleratedNetworkSupported}' @@ -163,12 +173,15 @@ resource image 'Microsoft.Compute/galleries/images@2022-03-03' = { value: '${isHibernateSupported}' } ], - (securityType != 'Standard' ? [ - { - name: 'SecurityType' - value: securityType - } - ] : [])) + (securityType != 'Standard' + ? [ + { + name: 'SecurityType' + value: securityType + } + ] + : []) + ) description: description eula: eula privacyStatementUri: privacyStatementUri @@ -185,19 +198,25 @@ resource image 'Microsoft.Compute/galleries/images@2022-03-03' = { } } -resource image_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(image.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 +resource image_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(image.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: image } - scope: image -}] +] @sys.description('The resource group the image was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/compute/gallery/image/main.json b/avm/res/compute/gallery/image/main.json index 8558b28df4..6ff4eedb7d 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.25.53.49325", - "templateHash": "3529471060432554863" + "version": "0.26.54.24096", + "templateHash": "15034895982698413313" }, "name": "Compute Galleries Image Definitions", "description": "This module deploys an Azure Compute Gallery Image Definition.", diff --git a/avm/res/compute/gallery/main.bicep b/avm/res/compute/gallery/main.bicep index bd2d9e7ddd..58b61a145b 100644 --- a/avm/res/compute/gallery/main.bicep +++ b/avm/res/compute/gallery/main.bicep @@ -37,31 +37,41 @@ param sharingProfile object? param softDeletePolicy object? var builtInRoleNames = { - 'Compute Gallery Sharing Admin': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1ef6a3be-d0ac-425d-8c01-acb62866290b') + 'Compute Gallery Sharing Admin': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1ef6a3be-d0ac-425d-8c01-acb62866290b' + ) 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') + '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.compute-gallery.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.compute-gallery.${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 gallery 'Microsoft.Compute/galleries@2022-03-03' = { name: name @@ -75,78 +85,91 @@ resource gallery 'Microsoft.Compute/galleries@2022-03-03' = { } } -resource gallery_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.' +resource gallery_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: gallery } - scope: gallery -} -resource gallery_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(gallery.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 +resource gallery_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(gallery.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: gallery } - scope: gallery -}] - -module galleries_applications 'application/main.bicep' = [for (application, index) in (applications ?? []): { - name: '${uniqueString(deployment().name, location)}-Gallery-Application-${index}' - params: { - location: location - name: application.name - galleryName: gallery.name - supportedOSType: application.supportedOSType - description: application.?description - eula: application.?eula - privacyStatementUri: application.?privacyStatementUri - releaseNoteUri: application.?releaseNoteUri - endOfLifeDate: application.?endOfLifeDate - roleAssignments: application.?roleAssignments - customActions: application.?customActions - tags: application.?tags ?? tags +] + +module galleries_applications 'application/main.bicep' = [ + for (application, index) in (applications ?? []): { + name: '${uniqueString(deployment().name, location)}-Gallery-Application-${index}' + params: { + location: location + name: application.name + galleryName: gallery.name + supportedOSType: application.supportedOSType + description: application.?description + eula: application.?eula + privacyStatementUri: application.?privacyStatementUri + releaseNoteUri: application.?releaseNoteUri + endOfLifeDate: application.?endOfLifeDate + roleAssignments: application.?roleAssignments + customActions: application.?customActions + tags: application.?tags ?? tags + } } -}] - -module galleries_images 'image/main.bicep' = [for (image, index) in (images ?? []): { - name: '${uniqueString(deployment().name, location)}-Gallery-Image-${index}' - params: { - location: location - name: image.name - galleryName: gallery.name - osType: image.osType - osState: image.?osState - publisher: image.publisher - offer: image.offer - sku: image.sku - minRecommendedvCPUs: image.?minRecommendedvCPUs - maxRecommendedvCPUs: image.?maxRecommendedvCPUs - minRecommendedMemory: image.?minRecommendedMemory - maxRecommendedMemory: image.?maxRecommendedMemory - hyperVGeneration: image.?hyperVGeneration - securityType: image.?securityType - isAcceleratedNetworkSupported: image.?isAcceleratedNetworkSupported - description: image.?description - eula: image.?eula - privacyStatementUri: image.?privacyStatementUri - releaseNoteUri: image.?releaseNoteUri - productName: image.?productName - planName: image.?planName - planPublisherName: image.?planPublisherName - endOfLife: image.?endOfLife - excludedDiskTypes: image.?excludedDiskTypes - roleAssignments: image.?roleAssignments - tags: image.?tags ?? tags +] + +module galleries_images 'image/main.bicep' = [ + for (image, index) in (images ?? []): { + name: '${uniqueString(deployment().name, location)}-Gallery-Image-${index}' + params: { + location: location + name: image.name + galleryName: gallery.name + osType: image.osType + osState: image.?osState + publisher: image.publisher + offer: image.offer + sku: image.sku + minRecommendedvCPUs: image.?minRecommendedvCPUs + maxRecommendedvCPUs: image.?maxRecommendedvCPUs + minRecommendedMemory: image.?minRecommendedMemory + maxRecommendedMemory: image.?maxRecommendedMemory + hyperVGeneration: image.?hyperVGeneration + securityType: image.?securityType + isAcceleratedNetworkSupported: image.?isAcceleratedNetworkSupported + description: image.?description + eula: image.?eula + privacyStatementUri: image.?privacyStatementUri + releaseNoteUri: image.?releaseNoteUri + productName: image.?productName + planName: image.?planName + planPublisherName: image.?planPublisherName + endOfLife: image.?endOfLife + excludedDiskTypes: image.?excludedDiskTypes + roleAssignments: image.?roleAssignments + tags: image.?tags ?? tags + } } -}] +] @sys.description('The resource ID of the deployed image gallery.') output resourceId string = gallery.id diff --git a/avm/res/compute/gallery/main.json b/avm/res/compute/gallery/main.json index cebcd05b97..c2863f574c 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.25.53.49325", - "templateHash": "7407411978239812730" + "version": "0.26.54.24096", + "templateHash": "5329218260776835511" }, "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.25.53.49325", - "templateHash": "1766982665283226409" + "version": "0.26.54.24096", + "templateHash": "3817884050778525461" }, "name": "Compute Galleries Applications", "description": "This module deploys an Azure Compute Gallery Application.", @@ -676,8 +676,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3529471060432554863" + "version": "0.26.54.24096", + "templateHash": "15034895982698413313" }, "name": "Compute Galleries Image Definitions", "description": "This module deploys an Azure Compute Gallery Image Definition.", diff --git a/avm/res/compute/gallery/tests/e2e/defaults/main.test.bicep b/avm/res/compute/gallery/tests/e2e/defaults/main.test.bicep index 56716b94c4..e4e7235dca 100644 --- a/avm/res/compute/gallery/tests/e2e/defaults/main.test.bicep +++ b/avm/res/compute/gallery/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/compute/gallery/tests/e2e/max/dependencies.bicep b/avm/res/compute/gallery/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/compute/gallery/tests/e2e/max/dependencies.bicep +++ b/avm/res/compute/gallery/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') 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 4fc0d88218..d00744b531 100644 --- a/avm/res/compute/gallery/tests/e2e/max/main.test.bicep +++ b/avm/res/compute/gallery/tests/e2e/max/main.test.bicep @@ -45,130 +45,135 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - applications: [ - { - name: '${namePrefix}-${serviceShort}-appd-001' - supportedOSType: 'Linux' - } - { - name: '${namePrefix}-${serviceShort}-appd-002' - supportedOSType: 'Windows' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - } - ] - images: [ - { - hyperVGeneration: 'V1' - name: '${namePrefix}-az-imgd-ws-001' - offer: 'WindowsServer' - osType: 'Windows' - publisher: 'MicrosoftWindowsServer' - sku: '2022-datacenter-azure-edition' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - } - { - hyperVGeneration: 'V2' - isHibernateSupported: true - isAcceleratedNetworkSupported: false - maxRecommendedMemory: 16 - maxRecommendedvCPUs: 8 - minRecommendedMemory: 4 - minRecommendedvCPUs: 2 - name: '${namePrefix}-az-imgd-ws-002' - offer: 'WindowsServer' - osState: 'Generalized' - osType: 'Windows' - publisher: 'MicrosoftWindowsServer' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - sku: '2022-datacenter-azure-edition-hibernate' +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' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - hyperVGeneration: 'V2' - securityType: 'TrustedLaunch' - maxRecommendedMemory: 16 - maxRecommendedvCPUs: 4 - minRecommendedMemory: 4 - minRecommendedvCPUs: 2 - name: '${namePrefix}-az-imgd-wdtl-001' - offer: 'WindowsDesktop' - osState: 'Generalized' - osType: 'Windows' - publisher: 'MicrosoftWindowsDesktop' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - sku: 'Win11-21H2' + applications: [ + { + name: '${namePrefix}-${serviceShort}-appd-001' + supportedOSType: 'Linux' + } + { + name: '${namePrefix}-${serviceShort}-appd-002' + supportedOSType: 'Windows' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + } + ] + images: [ + { + hyperVGeneration: 'V1' + name: '${namePrefix}-az-imgd-ws-001' + offer: 'WindowsServer' + osType: 'Windows' + publisher: 'MicrosoftWindowsServer' + sku: '2022-datacenter-azure-edition' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + } + { + hyperVGeneration: 'V2' + isHibernateSupported: true + isAcceleratedNetworkSupported: false + maxRecommendedMemory: 16 + maxRecommendedvCPUs: 8 + minRecommendedMemory: 4 + minRecommendedvCPUs: 2 + name: '${namePrefix}-az-imgd-ws-002' + offer: 'WindowsServer' + osState: 'Generalized' + osType: 'Windows' + publisher: 'MicrosoftWindowsServer' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + sku: '2022-datacenter-azure-edition-hibernate' + } + { + hyperVGeneration: 'V2' + securityType: 'TrustedLaunch' + maxRecommendedMemory: 16 + maxRecommendedvCPUs: 4 + minRecommendedMemory: 4 + minRecommendedvCPUs: 2 + name: '${namePrefix}-az-imgd-wdtl-001' + offer: 'WindowsDesktop' + osState: 'Generalized' + osType: 'Windows' + publisher: 'MicrosoftWindowsDesktop' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + sku: 'Win11-21H2' + } + { + hyperVGeneration: 'V2' + maxRecommendedMemory: 32 + maxRecommendedvCPUs: 4 + minRecommendedMemory: 4 + minRecommendedvCPUs: 1 + name: '${namePrefix}-az-imgd-us-001' + offer: '0001-com-ubuntu-server-focal' + osState: 'Generalized' + osType: 'Linux' + publisher: 'canonical' + sku: '20_04-lts-gen2' + } + ] + 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' } - { - hyperVGeneration: 'V2' - maxRecommendedMemory: 32 - maxRecommendedvCPUs: 4 - minRecommendedMemory: 4 - minRecommendedvCPUs: 1 - name: '${namePrefix}-az-imgd-us-001' - offer: '0001-com-ubuntu-server-focal' - osState: 'Generalized' - osType: 'Linux' - publisher: 'canonical' - sku: '20_04-lts-gen2' - } - ] - 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' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/compute/gallery/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/compute/gallery/tests/e2e/waf-aligned/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/compute/gallery/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/compute/gallery/tests/e2e/waf-aligned/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/compute/gallery/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/gallery/tests/e2e/waf-aligned/main.test.bicep index e31da2c17f..ca7ee02323 100644 --- a/avm/res/compute/gallery/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/gallery/tests/e2e/waf-aligned/main.test.bicep @@ -36,31 +36,33 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - applications: [ - { - name: '${namePrefix}-${serviceShort}-appd-001' - supportedOSType: 'Windows' +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' + applications: [ + { + name: '${namePrefix}-${serviceShort}-appd-001' + supportedOSType: 'Windows' + } + ] + images: [ + { + name: '${namePrefix}-az-imgd-ws-001' + offer: 'WindowsServer' + osType: 'Windows' + publisher: 'MicrosoftWindowsServer' + sku: '2022-datacenter-azure-edition' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - images: [ - { - name: '${namePrefix}-az-imgd-ws-001' - offer: 'WindowsServer' - osType: 'Windows' - publisher: 'MicrosoftWindowsServer' - sku: '2022-datacenter-azure-edition' - } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/compute/image/main.bicep b/avm/res/compute/image/main.bicep index 4498d30df6..d094eaa081 100644 --- a/avm/res/compute/image/main.bicep +++ b/avm/res/compute/image/main.bicep @@ -67,27 +67,34 @@ 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') + '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.compute-image.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.compute-image.${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 image 'Microsoft.Compute/images@2022-11-01' = { name: name @@ -102,40 +109,54 @@ resource image 'Microsoft.Compute/images@2022-11-01' = { caching: osDiskCaching storageAccountType: osAccountType osState: osState - diskEncryptionSet: !empty(diskEncryptionSetResourceId) ? { - id: diskEncryptionSetResourceId - } : null + diskEncryptionSet: !empty(diskEncryptionSetResourceId) + ? { + id: diskEncryptionSetResourceId + } + : null diskSizeGB: diskSizeGB - managedDisk: !empty(managedDiskResourceId) ? { - id: managedDiskResourceId - } : null - snapshot: !empty(snapshotResourceId) ? { - id: snapshotResourceId - } : null + managedDisk: !empty(managedDiskResourceId) + ? { + id: managedDiskResourceId + } + : null + snapshot: !empty(snapshotResourceId) + ? { + id: snapshotResourceId + } + : null } dataDisks: dataDisks zoneResilient: zoneResilient } hyperVGeneration: hyperVGeneration - sourceVirtualMachine: !empty(sourceVirtualMachineResourceId) ? { - id: sourceVirtualMachineResourceId - } : null + sourceVirtualMachine: !empty(sourceVirtualMachineResourceId) + ? { + id: sourceVirtualMachineResourceId + } + : null } } -resource image_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(image.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 +resource image_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(image.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: image } - scope: image -}] +] @description('The resource ID of the image.') output resourceId string = image.id diff --git a/avm/res/compute/image/main.json b/avm/res/compute/image/main.json index 3ce18d1b64..0b5e128f2f 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.25.53.49325", - "templateHash": "262853591906300834" + "version": "0.26.54.24096", + "templateHash": "7672407789517238611" }, "name": "Images", "description": "This module deploys a Compute Image.", diff --git a/avm/res/compute/image/tests/e2e/defaults/dependencies.bicep b/avm/res/compute/image/tests/e2e/defaults/dependencies.bicep index 7614a52892..fb10204820 100644 --- a/avm/res/compute/image/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/compute/image/tests/e2e/defaults/dependencies.bicep @@ -137,7 +137,7 @@ resource copyVhdDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10- cleanupPreference: 'OnSuccess' forceUpdateTag: baseTime } - dependsOn: [ triggerImageDeploymentScript ] + dependsOn: [triggerImageDeploymentScript] } @description('The URI of the created VHD.') diff --git a/avm/res/compute/image/tests/e2e/defaults/dependencies_rbac.bicep b/avm/res/compute/image/tests/e2e/defaults/dependencies_rbac.bicep index cdca1b63bd..f28142392e 100644 --- a/avm/res/compute/image/tests/e2e/defaults/dependencies_rbac.bicep +++ b/avm/res/compute/image/tests/e2e/defaults/dependencies_rbac.bicep @@ -9,7 +9,10 @@ param managedIdentityPrincipalId string resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(subscription().subscriptionId, 'Contributor', managedIdentityResourceId) properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalId: managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/compute/image/tests/e2e/defaults/main.test.bicep b/avm/res/compute/image/tests/e2e/defaults/main.test.bicep index 00f8c5b612..1bdd354168 100644 --- a/avm/res/compute/image/tests/e2e/defaults/main.test.bicep +++ b/avm/res/compute/image/tests/e2e/defaults/main.test.bicep @@ -54,15 +54,17 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - osAccountType: 'Standard_LRS' - osDiskBlobUri: nestedDependencies.outputs.vhdUri - osDiskCaching: 'ReadWrite' - osType: 'Windows' +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 + osAccountType: 'Standard_LRS' + osDiskBlobUri: nestedDependencies.outputs.vhdUri + osDiskCaching: 'ReadWrite' + osType: 'Windows' + } } -}] +] diff --git a/avm/res/compute/image/tests/e2e/max/dependencies.bicep b/avm/res/compute/image/tests/e2e/max/dependencies.bicep index b37c3cf39f..6a26edc6cf 100644 --- a/avm/res/compute/image/tests/e2e/max/dependencies.bicep +++ b/avm/res/compute/image/tests/e2e/max/dependencies.bicep @@ -143,7 +143,7 @@ resource copyVhdDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10- cleanupPreference: 'OnSuccess' forceUpdateTag: baseTime } - dependsOn: [ triggerImageDeploymentScript ] + dependsOn: [triggerImageDeploymentScript] } resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { @@ -177,7 +177,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: keyVault::key properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User principalType: 'ServicePrincipal' } } diff --git a/avm/res/compute/image/tests/e2e/max/dependencies_rbac.bicep b/avm/res/compute/image/tests/e2e/max/dependencies_rbac.bicep index cdca1b63bd..f28142392e 100644 --- a/avm/res/compute/image/tests/e2e/max/dependencies_rbac.bicep +++ b/avm/res/compute/image/tests/e2e/max/dependencies_rbac.bicep @@ -9,7 +9,10 @@ param managedIdentityPrincipalId string resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(subscription().subscriptionId, 'Contributor', managedIdentityResourceId) properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalId: managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/compute/image/tests/e2e/max/main.test.bicep b/avm/res/compute/image/tests/e2e/max/main.test.bicep index a5d2fb7516..2c88a950cd 100644 --- a/avm/res/compute/image/tests/e2e/max/main.test.bicep +++ b/avm/res/compute/image/tests/e2e/max/main.test.bicep @@ -54,42 +54,47 @@ module nestedDependencies 'dependencies.bicep' = { // 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 - osAccountType: 'Premium_LRS' - osDiskBlobUri: nestedDependencies.outputs.vhdUri - osDiskCaching: 'ReadWrite' - osType: 'Windows' - hyperVGeneration: 'V1' - 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' +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 + osAccountType: 'Premium_LRS' + osDiskBlobUri: nestedDependencies.outputs.vhdUri + osDiskCaching: 'ReadWrite' + osType: 'Windows' + hyperVGeneration: 'V1' + 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' + } + ] + zoneResilient: true + diskEncryptionSetResourceId: nestedDependencies.outputs.diskEncryptionSetResourceId + osState: 'Generalized' + diskSizeGB: 128 + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - zoneResilient: true - diskEncryptionSetResourceId: nestedDependencies.outputs.diskEncryptionSetResourceId - osState: 'Generalized' - diskSizeGB: 128 - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/compute/image/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/compute/image/tests/e2e/waf-aligned/dependencies.bicep index b37c3cf39f..6a26edc6cf 100644 --- a/avm/res/compute/image/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/compute/image/tests/e2e/waf-aligned/dependencies.bicep @@ -143,7 +143,7 @@ resource copyVhdDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10- cleanupPreference: 'OnSuccess' forceUpdateTag: baseTime } - dependsOn: [ triggerImageDeploymentScript ] + dependsOn: [triggerImageDeploymentScript] } resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { @@ -177,7 +177,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: keyVault::key properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User principalType: 'ServicePrincipal' } } diff --git a/avm/res/compute/image/tests/e2e/waf-aligned/dependencies_rbac.bicep b/avm/res/compute/image/tests/e2e/waf-aligned/dependencies_rbac.bicep index cdca1b63bd..f28142392e 100644 --- a/avm/res/compute/image/tests/e2e/waf-aligned/dependencies_rbac.bicep +++ b/avm/res/compute/image/tests/e2e/waf-aligned/dependencies_rbac.bicep @@ -9,7 +9,10 @@ param managedIdentityPrincipalId string resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(subscription().subscriptionId, 'Contributor', managedIdentityResourceId) properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalId: managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/compute/image/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/image/tests/e2e/waf-aligned/main.test.bicep index ca784f4643..c4d8bed406 100644 --- a/avm/res/compute/image/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/image/tests/e2e/waf-aligned/main.test.bicep @@ -54,25 +54,27 @@ module nestedDependencies 'dependencies.bicep' = { // 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 - osAccountType: 'Premium_LRS' - osDiskBlobUri: nestedDependencies.outputs.vhdUri - osDiskCaching: 'ReadWrite' - osType: 'Windows' - hyperVGeneration: 'V1' - zoneResilient: true - diskEncryptionSetResourceId: nestedDependencies.outputs.diskEncryptionSetResourceId - osState: 'Generalized' - diskSizeGB: 128 - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + osAccountType: 'Premium_LRS' + osDiskBlobUri: nestedDependencies.outputs.vhdUri + osDiskCaching: 'ReadWrite' + osType: 'Windows' + hyperVGeneration: 'V1' + zoneResilient: true + diskEncryptionSetResourceId: nestedDependencies.outputs.diskEncryptionSetResourceId + osState: 'Generalized' + diskSizeGB: 128 + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/compute/proximity-placement-group/main.bicep b/avm/res/compute/proximity-placement-group/main.bicep index e7f657084b..f0a723246d 100644 --- a/avm/res/compute/proximity-placement-group/main.bicep +++ b/avm/res/compute/proximity-placement-group/main.bicep @@ -40,27 +40,34 @@ 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') + '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.compute-proximityplacementgroup.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.compute-proximityplacementgroup.${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 proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2022-08-01' = { name: name @@ -74,28 +81,37 @@ resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@202 } } -resource proximityPlacementGroup_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.' +resource proximityPlacementGroup_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: proximityPlacementGroup } - scope: proximityPlacementGroup -} -resource proximityPlacementGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(proximityPlacementGroup.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 +resource proximityPlacementGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(proximityPlacementGroup.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: proximityPlacementGroup } - scope: proximityPlacementGroup -}] +] @description('The name of the proximity placement group.') output name string = proximityPlacementGroup.name diff --git a/avm/res/compute/proximity-placement-group/main.json b/avm/res/compute/proximity-placement-group/main.json index 779f0be773..20a1e3cf90 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.25.53.49325", - "templateHash": "2998974371512711861" + "version": "0.26.54.24096", + "templateHash": "10197969165198837306" }, "name": "Proximity Placement Groups", "description": "This module deploys a Proximity Placement Group.", diff --git a/avm/res/compute/proximity-placement-group/tests/e2e/defaults/main.test.bicep b/avm/res/compute/proximity-placement-group/tests/e2e/defaults/main.test.bicep index 4ec0e48342..31714c6f06 100644 --- a/avm/res/compute/proximity-placement-group/tests/e2e/defaults/main.test.bicep +++ b/avm/res/compute/proximity-placement-group/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/compute/proximity-placement-group/tests/e2e/max/dependencies.bicep b/avm/res/compute/proximity-placement-group/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/compute/proximity-placement-group/tests/e2e/max/dependencies.bicep +++ b/avm/res/compute/proximity-placement-group/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/compute/proximity-placement-group/tests/e2e/max/main.test.bicep b/avm/res/compute/proximity-placement-group/tests/e2e/max/main.test.bicep index 71760632e6..f8225519b8 100644 --- a/avm/res/compute/proximity-placement-group/tests/e2e/max/main.test.bicep +++ b/avm/res/compute/proximity-placement-group/tests/e2e/max/main.test.bicep @@ -45,53 +45,58 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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' + } + 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' + } + ] + zones: [ + '1' + ] + type: 'Standard' + tags: { + 'hidden-title': 'This is visible in the resource name' + TagA: 'Would you kindly...' + TagB: 'Tags for sale' } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + colocationStatus: { + code: 'ColocationStatus/Aligned' + displayStatus: 'Aligned' + level: 'Info' + message: 'I\'m a default error message' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + intent: { + vmSizes: [ + 'Standard_B1ms' + 'Standard_B4ms' + ] } - ] - zones: [ - '1' - ] - type: 'Standard' - tags: { - 'hidden-title': 'This is visible in the resource name' - TagA: 'Would you kindly...' - TagB: 'Tags for sale' - } - colocationStatus: { - code: 'ColocationStatus/Aligned' - displayStatus: 'Aligned' - level: 'Info' - message: 'I\'m a default error message' - } - intent: { - vmSizes: [ - 'Standard_B1ms' - 'Standard_B4ms' - ] } } -}] +] diff --git a/avm/res/compute/proximity-placement-group/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/proximity-placement-group/tests/e2e/waf-aligned/main.test.bicep index 38aece098e..b98da12996 100644 --- a/avm/res/compute/proximity-placement-group/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/proximity-placement-group/tests/e2e/waf-aligned/main.test.bicep @@ -36,32 +36,34 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - zones: [ - '1' - ] - type: 'Standard' - tags: { - 'hidden-title': 'This is visible in the resource name' - TagA: 'Would you kindly...' - TagB: 'Tags for sale' - } - colocationStatus: { - code: 'ColocationStatus/Aligned' - displayStatus: 'Aligned' - level: 'Info' - message: 'I\'m a default error message' - } - intent: { - vmSizes: [ - 'Standard_B1ms' - 'Standard_B4ms' +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 + zones: [ + '1' ] + type: 'Standard' + tags: { + 'hidden-title': 'This is visible in the resource name' + TagA: 'Would you kindly...' + TagB: 'Tags for sale' + } + colocationStatus: { + code: 'ColocationStatus/Aligned' + displayStatus: 'Aligned' + level: 'Info' + message: 'I\'m a default error message' + } + intent: { + vmSizes: [ + 'Standard_B1ms' + 'Standard_B4ms' + ] + } } } -}] +] diff --git a/avm/res/compute/ssh-public-key/main.bicep b/avm/res/compute/ssh-public-key/main.bicep index 19204bf4e6..0225692160 100644 --- a/avm/res/compute/ssh-public-key/main.bicep +++ b/avm/res/compute/ssh-public-key/main.bicep @@ -30,27 +30,34 @@ 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') + '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.compute-sshpublickey.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.compute-sshpublickey.${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 sshPublicKey 'Microsoft.Compute/sshPublicKeys@2023-07-01' = { name: name @@ -61,28 +68,37 @@ resource sshPublicKey 'Microsoft.Compute/sshPublicKeys@2023-07-01' = { } } -resource sshPublicKeyLock '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.' +resource sshPublicKeyLock '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: sshPublicKey } - scope: sshPublicKey -} -resource sshPublicKeyRoleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(sshPublicKey.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 +resource sshPublicKeyRoleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(sshPublicKey.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: sshPublicKey } - scope: sshPublicKey -}] +] @description('The name of the Resource Group the Public SSH Key was created in.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/compute/ssh-public-key/main.json b/avm/res/compute/ssh-public-key/main.json index b33a3e997c..9c4e8ac8b6 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.25.53.49325", - "templateHash": "8813930198344883772" + "version": "0.26.54.24096", + "templateHash": "10976156692729855046" }, "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/ssh-public-key/tests/e2e/max/dependencies.bicep b/avm/res/compute/ssh-public-key/tests/e2e/max/dependencies.bicep index 3665ddc00e..24bbd4da01 100644 --- a/avm/res/compute/ssh-public-key/tests/e2e/max/dependencies.bicep +++ b/avm/res/compute/ssh-public-key/tests/e2e/max/dependencies.bicep @@ -14,41 +14,44 @@ param sshKeyName string param utcValue string = utcNow() resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } // required for the deployment script to create a new temporary ssh public key object resource msi_ContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, 'ManagedIdentityContributor', '#_namePrefix_#') - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor - principalId: managedIdentity.properties.principalId - principalType: 'ServicePrincipal' - } + name: guid(resourceGroup().id, 'ManagedIdentityContributor', '#_namePrefix_#') + properties: { + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor + principalId: managedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } } resource createPubKeyScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: generateSshPubKeyScriptName - location: location - kind: 'AzurePowerShell' - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - azPowerShellVersion: '8.0' - retentionInterval: 'P1D' - arguments: '-ResourceGroupName ${resourceGroup().name} -SSHKeyName ${sshKeyName}' - scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/New-SSHKey.ps1') - cleanupPreference: 'OnExpiration' - forceUpdateTag: utcValue + name: generateSshPubKeyScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} } - dependsOn: [ - msi_ContributorRoleAssignment - ] + } + properties: { + azPowerShellVersion: '8.0' + retentionInterval: 'P1D' + arguments: '-ResourceGroupName ${resourceGroup().name} -SSHKeyName ${sshKeyName}' + scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/New-SSHKey.ps1') + cleanupPreference: 'OnExpiration' + forceUpdateTag: utcValue + } + dependsOn: [ + msi_ContributorRoleAssignment + ] } @description('The public key to be added to the SSH Public Key resource.') diff --git a/avm/res/compute/ssh-public-key/tests/e2e/max/main.test.bicep b/avm/res/compute/ssh-public-key/tests/e2e/max/main.test.bicep index 41e4e6d25e..edacd11616 100644 --- a/avm/res/compute/ssh-public-key/tests/e2e/max/main.test.bicep +++ b/avm/res/compute/ssh-public-key/tests/e2e/max/main.test.bicep @@ -68,7 +68,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/compute/ssh-public-key/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/compute/ssh-public-key/tests/e2e/waf-aligned/dependencies.bicep index 374cdd66a6..7de3a73841 100644 --- a/avm/res/compute/ssh-public-key/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/compute/ssh-public-key/tests/e2e/waf-aligned/dependencies.bicep @@ -14,41 +14,44 @@ param sshKeyName string param utcValue string = utcNow() resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } // required for the deployment script to create a new temporary ssh public key object resource msi_ContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, 'ManagedIdentityContributor', managedIdentityName) - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor - principalId: managedIdentity.properties.principalId - principalType: 'ServicePrincipal' - } + name: guid(resourceGroup().id, 'ManagedIdentityContributor', managedIdentityName) + properties: { + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor + principalId: managedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } } resource createPubKeyScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: generateSshPubKeyScriptName - location: location - kind: 'AzurePowerShell' - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - azPowerShellVersion: '8.0' - retentionInterval: 'P1D' - arguments: '-ResourceGroupName ${resourceGroup().name} -SSHKeyName ${sshKeyName}' - scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/New-SSHKey.ps1') - cleanupPreference: 'OnExpiration' - forceUpdateTag: utcValue + name: generateSshPubKeyScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} } - dependsOn: [ - msi_ContributorRoleAssignment - ] + } + properties: { + azPowerShellVersion: '8.0' + retentionInterval: 'P1D' + arguments: '-ResourceGroupName ${resourceGroup().name} -SSHKeyName ${sshKeyName}' + scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/New-SSHKey.ps1') + cleanupPreference: 'OnExpiration' + forceUpdateTag: utcValue + } + dependsOn: [ + msi_ContributorRoleAssignment + ] } @description('The public key to be added to the SSH Public Key resource.') diff --git a/avm/res/compute/ssh-public-key/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/ssh-public-key/tests/e2e/waf-aligned/main.test.bicep index ed12fc9e2c..868248aa83 100644 --- a/avm/res/compute/ssh-public-key/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/ssh-public-key/tests/e2e/waf-aligned/main.test.bicep @@ -69,7 +69,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/compute/virtual-machine-scale-set/extension/main.json b/avm/res/compute/virtual-machine-scale-set/extension/main.json index 36751fb40e..936509ea01 100644 --- a/avm/res/compute/virtual-machine-scale-set/extension/main.json +++ b/avm/res/compute/virtual-machine-scale-set/extension/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3680417048986934448" + "version": "0.26.54.24096", + "templateHash": "8948100547542268397" }, "name": "Virtual Machine Scale Set Extensions", "description": "This module deploys a Virtual Machine Scale Set Extension.", diff --git a/avm/res/compute/virtual-machine-scale-set/main.bicep b/avm/res/compute/virtual-machine-scale-set/main.bicep index d9cdc509ca..0d4fc210a6 100644 --- a/avm/res/compute/virtual-machine-scale-set/main.bicep +++ b/avm/res/compute/virtual-machine-scale-set/main.bicep @@ -232,7 +232,7 @@ param skuName string param skuCapacity int = 1 @description('Optional. The virtual machine scale set zones. NOTE: Availability zones can only be set when you create the scale set.') -param availabilityZones array = [ 1, 2, 3 ] +param availabilityZones array = [1, 2, 3] @description('Optional. Tags of the resource.') param tags object? @@ -256,10 +256,12 @@ param sasTokenValidityLength string = 'PT8H' @description('Optional. The managed identity definition for this resource.') param managedIdentities managedIdentitiesType -var publicKeysFormatted = [for publicKey in publicKeys: { - path: publicKey.path - keyData: publicKey.keyData -}] +var publicKeysFormatted = [ + for publicKey in publicKeys: { + path: publicKey.path + keyData: publicKey.keyData + } +] var linuxConfiguration = { disablePasswordAuthentication: disablePasswordAuthentication @@ -274,9 +276,11 @@ var windowsConfiguration = { enableAutomaticUpdates: enableAutomaticUpdates timeZone: empty(timeZone) ? null : timeZone additionalUnattendContent: empty(additionalUnattendContent) ? null : additionalUnattendContent - winRM: !empty(winRM) ? { - listeners: winRM - } : null + winRM: !empty(winRM) + ? { + listeners: winRM + } + : null } var accountSasProperties = { @@ -287,53 +291,107 @@ var accountSasProperties = { signedProtocol: 'https' } -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var enableReferencedModulesTelemetry = false var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Data Operator for Managed Disks': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '959f8984-c045-4866-89c7-12bf9737be2e') - 'Desktop Virtualization Power On Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '489581de-a3bd-480d-9518-53dea7416b33') - 'Desktop Virtualization Power On Off Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '40c5ff49-9181-41f8-ae61-143b0e78555e') - 'Desktop Virtualization Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c') - 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64') - 'Disk Backup Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24') - 'Disk Pool Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60fc6e62-5479-42d4-8bf4-67625fcc2840') - 'Disk Restore Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b50d9833-a0cb-478e-945f-707fcc997c13') - 'Disk Snapshot Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7efff54f-a5b4-42b5-a1c5-5411624893ce') + 'Data Operator for Managed Disks': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '959f8984-c045-4866-89c7-12bf9737be2e' + ) + 'Desktop Virtualization Power On Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '489581de-a3bd-480d-9518-53dea7416b33' + ) + 'Desktop Virtualization Power On Off Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '40c5ff49-9181-41f8-ae61-143b0e78555e' + ) + 'Desktop Virtualization Virtual Machine Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a959dbd1-f747-45e3-8ba6-dd80f235f97c' + ) + 'DevTest Labs User': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '76283e04-6283-4c54-8f91-bcf1374a3c64' + ) + 'Disk Backup Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24' + ) + 'Disk Pool Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '60fc6e62-5479-42d4-8bf4-67625fcc2840' + ) + 'Disk Restore Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b50d9833-a0cb-478e-945f-707fcc997c13' + ) + 'Disk Snapshot Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7efff54f-a5b4-42b5-a1c5-5411624893ce' + ) 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') - 'Virtual Machine Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4') - 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c') - 'Virtual Machine User Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52') - 'VM Scanner Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd24ecba3-c1f4-40fa-a7bb-4588a071e8fd') + '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' + ) + 'Virtual Machine Administrator Login': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1c0163c0-47e6-4577-8991-ea5c82e286e4' + ) + 'Virtual Machine Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '9980e02c-c2be-4d73-94e8-173b1dc7cf3c' + ) + 'Virtual Machine User Login': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'fb879df8-f326-4884-b1cf-06f3ad86be52' + ) + 'VM Scanner Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd24ecba3-c1f4-40fa-a7bb-4588a071e8fd' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.compute-virtualmachinescaleset.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.compute-virtualmachinescaleset.${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 vmss 'Microsoft.Compute/virtualMachineScaleSets@2022-11-01' = { name: name @@ -342,9 +400,11 @@ resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2022-11-01' = { identity: identity zones: availabilityZones properties: { - proximityPlacementGroup: !empty(proximityPlacementGroupResourceId) ? { - id: proximityPlacementGroupResourceId - } : null + proximityPlacementGroup: !empty(proximityPlacementGroupResourceId) + ? { + id: proximityPlacementGroupResourceId + } + : null upgradePolicy: { mode: upgradePolicyMode rollingUpgradePolicy: { @@ -375,10 +435,12 @@ resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2022-11-01' = { securityProfile: { encryptionAtHost: encryptionAtHost ? encryptionAtHost : null securityType: securityType - uefiSettings: securityType == 'TrustedLaunch' ? { - secureBootEnabled: secureBootEnabled - vTpmEnabled: vTpmEnabled - } : null + uefiSettings: securityType == 'TrustedLaunch' + ? { + secureBootEnabled: secureBootEnabled + vTpmEnabled: vTpmEnabled + } + : null } storageProfile: { imageReference: imageReference @@ -393,52 +455,68 @@ resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2022-11-01' = { vhdContainers: contains(osDisk, 'vhdContainers') ? osDisk.vhdContainers : null managedDisk: { storageAccountType: osDisk.managedDisk.storageAccountType - diskEncryptionSet: contains(osDisk.managedDisk, 'diskEncryptionSet') ? { - id: osDisk.managedDisk.diskEncryptionSet.id - } : null + diskEncryptionSet: contains(osDisk.managedDisk, 'diskEncryptionSet') + ? { + id: osDisk.managedDisk.diskEncryptionSet.id + } + : null } } - dataDisks: [for (dataDisk, index) in dataDisks: { - lun: index - diskSizeGB: dataDisk.diskSizeGB - createOption: dataDisk.createOption - caching: dataDisk.caching - writeAcceleratorEnabled: contains(osDisk, 'writeAcceleratorEnabled') ? osDisk.writeAcceleratorEnabled : null - managedDisk: { - storageAccountType: dataDisk.managedDisk.storageAccountType - diskEncryptionSet: contains(dataDisk.managedDisk, 'diskEncryptionSet') ? { - id: dataDisk.managedDisk.diskEncryptionSet.id - } : null + dataDisks: [ + for (dataDisk, index) in dataDisks: { + lun: index + diskSizeGB: dataDisk.diskSizeGB + createOption: dataDisk.createOption + caching: dataDisk.caching + writeAcceleratorEnabled: contains(osDisk, 'writeAcceleratorEnabled') ? osDisk.writeAcceleratorEnabled : null + managedDisk: { + storageAccountType: dataDisk.managedDisk.storageAccountType + diskEncryptionSet: contains(dataDisk.managedDisk, 'diskEncryptionSet') + ? { + id: dataDisk.managedDisk.diskEncryptionSet.id + } + : null + } + diskIOPSReadWrite: contains(osDisk, 'diskIOPSReadWrite') ? dataDisk.diskIOPSReadWrite : null + diskMBpsReadWrite: contains(osDisk, 'diskMBpsReadWrite') ? dataDisk.diskMBpsReadWrite : null } - diskIOPSReadWrite: contains(osDisk, 'diskIOPSReadWrite') ? dataDisk.diskIOPSReadWrite : null - diskMBpsReadWrite: contains(osDisk, 'diskMBpsReadWrite') ? dataDisk.diskMBpsReadWrite : null - }] + ] } networkProfile: { - networkInterfaceConfigurations: [for (nicConfiguration, index) in nicConfigurations: { - name: '${name}${nicConfiguration.nicSuffix}configuration-${index}' - properties: { - primary: (index == 0) ? true : any(null) - enableAcceleratedNetworking: contains(nicConfiguration, 'enableAcceleratedNetworking') ? nicConfiguration.enableAcceleratedNetworking : true - networkSecurityGroup: contains(nicConfiguration, 'nsgId') ? { - id: nicConfiguration.nsgId - } : null - ipConfigurations: nicConfiguration.ipConfigurations + networkInterfaceConfigurations: [ + for (nicConfiguration, index) in nicConfigurations: { + name: '${name}${nicConfiguration.nicSuffix}configuration-${index}' + properties: { + primary: (index == 0) ? true : any(null) + enableAcceleratedNetworking: contains(nicConfiguration, 'enableAcceleratedNetworking') + ? nicConfiguration.enableAcceleratedNetworking + : true + networkSecurityGroup: contains(nicConfiguration, 'nsgId') + ? { + id: nicConfiguration.nsgId + } + : null + ipConfigurations: nicConfiguration.ipConfigurations + } } - }] + ] } diagnosticsProfile: { bootDiagnostics: { enabled: !empty(bootDiagnosticStorageAccountName) - storageUri: !empty(bootDiagnosticStorageAccountName) ? 'https://${bootDiagnosticStorageAccountName}${bootDiagnosticStorageAccountUri}' : null + storageUri: !empty(bootDiagnosticStorageAccountName) + ? 'https://${bootDiagnosticStorageAccountName}${bootDiagnosticStorageAccountUri}' + : null } } licenseType: empty(licenseType) ? null : licenseType priority: vmPriority evictionPolicy: enableEvictionPolicy ? 'Deallocate' : null - billingProfile: !empty(vmPriority) && !empty(maxPriceForLowPriorityVm) ? { - maxPrice: maxPriceForLowPriorityVm - } : null + billingProfile: !empty(vmPriority) && !empty(maxPriceForLowPriorityVm) + ? { + maxPrice: maxPriceForLowPriorityVm + } + : null scheduledEventsProfile: scheduledEventsProfile } overprovision: overprovision @@ -458,196 +536,279 @@ resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2022-11-01' = { plan: !empty(plan) ? plan : null } -module vmss_domainJoinExtension 'extension/main.bicep' = if (extensionDomainJoinConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-VMSS-DomainJoin' - params: { - virtualMachineScaleSetName: vmss.name - name: 'DomainJoin' - publisher: 'Microsoft.Compute' - type: 'JsonADDomainExtension' - typeHandlerVersion: contains(extensionDomainJoinConfig, 'typeHandlerVersion') ? extensionDomainJoinConfig.typeHandlerVersion : '1.3' - autoUpgradeMinorVersion: contains(extensionDomainJoinConfig, 'autoUpgradeMinorVersion') ? extensionDomainJoinConfig.autoUpgradeMinorVersion : true - enableAutomaticUpgrade: contains(extensionDomainJoinConfig, 'enableAutomaticUpgrade') ? extensionDomainJoinConfig.enableAutomaticUpgrade : false - settings: extensionDomainJoinConfig.settings - protectedSettings: { - Password: extensionDomainJoinPassword +module vmss_domainJoinExtension 'extension/main.bicep' = + if (extensionDomainJoinConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VMSS-DomainJoin' + params: { + virtualMachineScaleSetName: vmss.name + name: 'DomainJoin' + publisher: 'Microsoft.Compute' + type: 'JsonADDomainExtension' + typeHandlerVersion: contains(extensionDomainJoinConfig, 'typeHandlerVersion') + ? extensionDomainJoinConfig.typeHandlerVersion + : '1.3' + autoUpgradeMinorVersion: contains(extensionDomainJoinConfig, 'autoUpgradeMinorVersion') + ? extensionDomainJoinConfig.autoUpgradeMinorVersion + : true + enableAutomaticUpgrade: contains(extensionDomainJoinConfig, 'enableAutomaticUpgrade') + ? extensionDomainJoinConfig.enableAutomaticUpgrade + : false + settings: extensionDomainJoinConfig.settings + protectedSettings: { + Password: extensionDomainJoinPassword + } } } -} -module vmss_microsoftAntiMalwareExtension 'extension/main.bicep' = if (extensionAntiMalwareConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-VMSS-MicrosoftAntiMalware' - params: { - virtualMachineScaleSetName: vmss.name - name: 'MicrosoftAntiMalware' - publisher: 'Microsoft.Azure.Security' - type: 'IaaSAntimalware' - typeHandlerVersion: contains(extensionAntiMalwareConfig, 'typeHandlerVersion') ? extensionAntiMalwareConfig.typeHandlerVersion : '1.3' - autoUpgradeMinorVersion: contains(extensionAntiMalwareConfig, 'autoUpgradeMinorVersion') ? extensionAntiMalwareConfig.autoUpgradeMinorVersion : true - enableAutomaticUpgrade: contains(extensionAntiMalwareConfig, 'enableAutomaticUpgrade') ? extensionAntiMalwareConfig.enableAutomaticUpgrade : false - settings: extensionAntiMalwareConfig.settings +module vmss_microsoftAntiMalwareExtension 'extension/main.bicep' = + if (extensionAntiMalwareConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VMSS-MicrosoftAntiMalware' + params: { + virtualMachineScaleSetName: vmss.name + name: 'MicrosoftAntiMalware' + publisher: 'Microsoft.Azure.Security' + type: 'IaaSAntimalware' + typeHandlerVersion: contains(extensionAntiMalwareConfig, 'typeHandlerVersion') + ? extensionAntiMalwareConfig.typeHandlerVersion + : '1.3' + autoUpgradeMinorVersion: contains(extensionAntiMalwareConfig, 'autoUpgradeMinorVersion') + ? extensionAntiMalwareConfig.autoUpgradeMinorVersion + : true + enableAutomaticUpgrade: contains(extensionAntiMalwareConfig, 'enableAutomaticUpgrade') + ? extensionAntiMalwareConfig.enableAutomaticUpgrade + : false + settings: extensionAntiMalwareConfig.settings + } + dependsOn: [ + vmss_domainJoinExtension + ] } - dependsOn: [ - vmss_domainJoinExtension - ] -} -resource vmss_logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = if (!empty(monitoringWorkspaceId)) { - name: last(split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : 'law'), '/'))! - scope: az.resourceGroup(split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : '//'), '/')[2], split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : '////'), '/')[4]) -} +resource vmss_logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = + if (!empty(monitoringWorkspaceId)) { + name: last(split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : 'law'), '/'))! + scope: az.resourceGroup( + split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : '//'), '/')[2], + split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : '////'), '/')[4] + ) + } -module vmss_azureMonitorAgentExtension 'extension/main.bicep' = if (extensionMonitoringAgentConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-VMSS-AzureMonitorAgent' - params: { - virtualMachineScaleSetName: vmss.name - name: 'AzureMonitorAgent' - publisher: 'Microsoft.Azure.Monitor' - type: osType == 'Windows' ? 'AzureMonitorWindowsAgent' : 'AzureMonitorLinuxAgent' - typeHandlerVersion: contains(extensionMonitoringAgentConfig, 'typeHandlerVersion') ? extensionMonitoringAgentConfig.typeHandlerVersion : (osType == 'Windows' ? '1.22' : '1.29') - autoUpgradeMinorVersion: contains(extensionMonitoringAgentConfig, 'autoUpgradeMinorVersion') ? extensionMonitoringAgentConfig.autoUpgradeMinorVersion : true - enableAutomaticUpgrade: contains(extensionMonitoringAgentConfig, 'enableAutomaticUpgrade') ? extensionMonitoringAgentConfig.enableAutomaticUpgrade : false - settings: { - workspaceId: !empty(monitoringWorkspaceId) ? reference(vmss_logAnalyticsWorkspace.id, vmss_logAnalyticsWorkspace.apiVersion).customerId : '' - GCS_AUTO_CONFIG: osType == 'Linux' ? true : null - } - protectedSettings: { - workspaceKey: !empty(monitoringWorkspaceId) ? vmss_logAnalyticsWorkspace.listKeys().primarySharedKey : '' +module vmss_azureMonitorAgentExtension 'extension/main.bicep' = + if (extensionMonitoringAgentConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VMSS-AzureMonitorAgent' + params: { + virtualMachineScaleSetName: vmss.name + name: 'AzureMonitorAgent' + publisher: 'Microsoft.Azure.Monitor' + type: osType == 'Windows' ? 'AzureMonitorWindowsAgent' : 'AzureMonitorLinuxAgent' + typeHandlerVersion: contains(extensionMonitoringAgentConfig, 'typeHandlerVersion') + ? extensionMonitoringAgentConfig.typeHandlerVersion + : (osType == 'Windows' ? '1.22' : '1.29') + autoUpgradeMinorVersion: contains(extensionMonitoringAgentConfig, 'autoUpgradeMinorVersion') + ? extensionMonitoringAgentConfig.autoUpgradeMinorVersion + : true + enableAutomaticUpgrade: contains(extensionMonitoringAgentConfig, 'enableAutomaticUpgrade') + ? extensionMonitoringAgentConfig.enableAutomaticUpgrade + : false + settings: { + workspaceId: !empty(monitoringWorkspaceId) + ? reference(vmss_logAnalyticsWorkspace.id, vmss_logAnalyticsWorkspace.apiVersion).customerId + : '' + GCS_AUTO_CONFIG: osType == 'Linux' ? true : null + } + protectedSettings: { + workspaceKey: !empty(monitoringWorkspaceId) ? vmss_logAnalyticsWorkspace.listKeys().primarySharedKey : '' + } } + dependsOn: [ + vmss_microsoftAntiMalwareExtension + ] } - dependsOn: [ - vmss_microsoftAntiMalwareExtension - ] -} -module vmss_dependencyAgentExtension 'extension/main.bicep' = if (extensionDependencyAgentConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-VMSS-DependencyAgent' - params: { - virtualMachineScaleSetName: vmss.name - name: 'DependencyAgent' - publisher: 'Microsoft.Azure.Monitoring.DependencyAgent' - type: osType == 'Windows' ? 'DependencyAgentWindows' : 'DependencyAgentLinux' - typeHandlerVersion: contains(extensionDependencyAgentConfig, 'typeHandlerVersion') ? extensionDependencyAgentConfig.typeHandlerVersion : '9.5' - autoUpgradeMinorVersion: contains(extensionDependencyAgentConfig, 'autoUpgradeMinorVersion') ? extensionDependencyAgentConfig.autoUpgradeMinorVersion : true - enableAutomaticUpgrade: contains(extensionDependencyAgentConfig, 'enableAutomaticUpgrade') ? extensionDependencyAgentConfig.enableAutomaticUpgrade : true +module vmss_dependencyAgentExtension 'extension/main.bicep' = + if (extensionDependencyAgentConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VMSS-DependencyAgent' + params: { + virtualMachineScaleSetName: vmss.name + name: 'DependencyAgent' + publisher: 'Microsoft.Azure.Monitoring.DependencyAgent' + type: osType == 'Windows' ? 'DependencyAgentWindows' : 'DependencyAgentLinux' + typeHandlerVersion: contains(extensionDependencyAgentConfig, 'typeHandlerVersion') + ? extensionDependencyAgentConfig.typeHandlerVersion + : '9.5' + autoUpgradeMinorVersion: contains(extensionDependencyAgentConfig, 'autoUpgradeMinorVersion') + ? extensionDependencyAgentConfig.autoUpgradeMinorVersion + : true + enableAutomaticUpgrade: contains(extensionDependencyAgentConfig, 'enableAutomaticUpgrade') + ? extensionDependencyAgentConfig.enableAutomaticUpgrade + : true + } + dependsOn: [ + vmss_azureMonitorAgentExtension + ] } - dependsOn: [ - vmss_azureMonitorAgentExtension - ] -} -module vmss_networkWatcherAgentExtension 'extension/main.bicep' = if (extensionNetworkWatcherAgentConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-VMSS-NetworkWatcherAgent' - params: { - virtualMachineScaleSetName: vmss.name - name: 'NetworkWatcherAgent' - publisher: 'Microsoft.Azure.NetworkWatcher' - type: osType == 'Windows' ? 'NetworkWatcherAgentWindows' : 'NetworkWatcherAgentLinux' - typeHandlerVersion: contains(extensionNetworkWatcherAgentConfig, 'typeHandlerVersion') ? extensionNetworkWatcherAgentConfig.typeHandlerVersion : '1.4' - autoUpgradeMinorVersion: contains(extensionNetworkWatcherAgentConfig, 'autoUpgradeMinorVersion') ? extensionNetworkWatcherAgentConfig.autoUpgradeMinorVersion : true - enableAutomaticUpgrade: contains(extensionNetworkWatcherAgentConfig, 'enableAutomaticUpgrade') ? extensionNetworkWatcherAgentConfig.enableAutomaticUpgrade : false +module vmss_networkWatcherAgentExtension 'extension/main.bicep' = + if (extensionNetworkWatcherAgentConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VMSS-NetworkWatcherAgent' + params: { + virtualMachineScaleSetName: vmss.name + name: 'NetworkWatcherAgent' + publisher: 'Microsoft.Azure.NetworkWatcher' + type: osType == 'Windows' ? 'NetworkWatcherAgentWindows' : 'NetworkWatcherAgentLinux' + typeHandlerVersion: contains(extensionNetworkWatcherAgentConfig, 'typeHandlerVersion') + ? extensionNetworkWatcherAgentConfig.typeHandlerVersion + : '1.4' + autoUpgradeMinorVersion: contains(extensionNetworkWatcherAgentConfig, 'autoUpgradeMinorVersion') + ? extensionNetworkWatcherAgentConfig.autoUpgradeMinorVersion + : true + enableAutomaticUpgrade: contains(extensionNetworkWatcherAgentConfig, 'enableAutomaticUpgrade') + ? extensionNetworkWatcherAgentConfig.enableAutomaticUpgrade + : false + } + dependsOn: [ + vmss_dependencyAgentExtension + ] } - dependsOn: [ - vmss_dependencyAgentExtension - ] -} -module vmss_desiredStateConfigurationExtension 'extension/main.bicep' = if (extensionDSCConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-VMSS-DesiredStateConfiguration' - params: { - virtualMachineScaleSetName: vmss.name - name: 'DesiredStateConfiguration' - publisher: 'Microsoft.Powershell' - type: 'DSC' - typeHandlerVersion: contains(extensionDSCConfig, 'typeHandlerVersion') ? extensionDSCConfig.typeHandlerVersion : '2.77' - autoUpgradeMinorVersion: contains(extensionDSCConfig, 'autoUpgradeMinorVersion') ? extensionDSCConfig.autoUpgradeMinorVersion : true - enableAutomaticUpgrade: contains(extensionDSCConfig, 'enableAutomaticUpgrade') ? extensionDSCConfig.enableAutomaticUpgrade : false - settings: contains(extensionDSCConfig, 'settings') ? extensionDSCConfig.settings : {} - protectedSettings: contains(extensionDSCConfig, 'protectedSettings') ? extensionDSCConfig.protectedSettings : {} +module vmss_desiredStateConfigurationExtension 'extension/main.bicep' = + if (extensionDSCConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VMSS-DesiredStateConfiguration' + params: { + virtualMachineScaleSetName: vmss.name + name: 'DesiredStateConfiguration' + publisher: 'Microsoft.Powershell' + type: 'DSC' + typeHandlerVersion: contains(extensionDSCConfig, 'typeHandlerVersion') + ? extensionDSCConfig.typeHandlerVersion + : '2.77' + autoUpgradeMinorVersion: contains(extensionDSCConfig, 'autoUpgradeMinorVersion') + ? extensionDSCConfig.autoUpgradeMinorVersion + : true + enableAutomaticUpgrade: contains(extensionDSCConfig, 'enableAutomaticUpgrade') + ? extensionDSCConfig.enableAutomaticUpgrade + : false + settings: contains(extensionDSCConfig, 'settings') ? extensionDSCConfig.settings : {} + protectedSettings: contains(extensionDSCConfig, 'protectedSettings') ? extensionDSCConfig.protectedSettings : {} + } + dependsOn: [ + vmss_networkWatcherAgentExtension + ] } - dependsOn: [ - vmss_networkWatcherAgentExtension - ] -} -module vmss_customScriptExtension 'extension/main.bicep' = if (extensionCustomScriptConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-VMSS-CustomScriptExtension' - params: { - virtualMachineScaleSetName: vmss.name - name: 'CustomScriptExtension' - publisher: osType == 'Windows' ? 'Microsoft.Compute' : 'Microsoft.Azure.Extensions' - type: osType == 'Windows' ? 'CustomScriptExtension' : 'CustomScript' - typeHandlerVersion: contains(extensionCustomScriptConfig, 'typeHandlerVersion') ? extensionCustomScriptConfig.typeHandlerVersion : (osType == 'Windows' ? '1.10' : '2.1') - autoUpgradeMinorVersion: contains(extensionCustomScriptConfig, 'autoUpgradeMinorVersion') ? extensionCustomScriptConfig.autoUpgradeMinorVersion : true - enableAutomaticUpgrade: contains(extensionCustomScriptConfig, 'enableAutomaticUpgrade') ? extensionCustomScriptConfig.enableAutomaticUpgrade : false - settings: { - fileUris: [for fileData in extensionCustomScriptConfig.fileData: contains(fileData, 'storageAccountId') ? '${fileData.uri}?${listAccountSas(fileData.storageAccountId, '2019-04-01', accountSasProperties).accountSasToken}' : fileData.uri] +module vmss_customScriptExtension 'extension/main.bicep' = + if (extensionCustomScriptConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VMSS-CustomScriptExtension' + params: { + virtualMachineScaleSetName: vmss.name + name: 'CustomScriptExtension' + publisher: osType == 'Windows' ? 'Microsoft.Compute' : 'Microsoft.Azure.Extensions' + type: osType == 'Windows' ? 'CustomScriptExtension' : 'CustomScript' + typeHandlerVersion: contains(extensionCustomScriptConfig, 'typeHandlerVersion') + ? extensionCustomScriptConfig.typeHandlerVersion + : (osType == 'Windows' ? '1.10' : '2.1') + autoUpgradeMinorVersion: contains(extensionCustomScriptConfig, 'autoUpgradeMinorVersion') + ? extensionCustomScriptConfig.autoUpgradeMinorVersion + : true + enableAutomaticUpgrade: contains(extensionCustomScriptConfig, 'enableAutomaticUpgrade') + ? extensionCustomScriptConfig.enableAutomaticUpgrade + : false + settings: { + fileUris: [ + for fileData in extensionCustomScriptConfig.fileData: contains(fileData, 'storageAccountId') + ? '${fileData.uri}?${listAccountSas(fileData.storageAccountId, '2019-04-01', accountSasProperties).accountSasToken}' + : fileData.uri + ] + } + protectedSettings: contains(extensionCustomScriptConfig, 'protectedSettings') + ? extensionCustomScriptConfig.protectedSettings + : {} } - protectedSettings: contains(extensionCustomScriptConfig, 'protectedSettings') ? extensionCustomScriptConfig.protectedSettings : {} + dependsOn: [ + vmss_desiredStateConfigurationExtension + ] } - dependsOn: [ - vmss_desiredStateConfigurationExtension - ] -} -module vmss_azureDiskEncryptionExtension 'extension/main.bicep' = if (extensionAzureDiskEncryptionConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-VMSS-AzureDiskEncryption' - params: { - virtualMachineScaleSetName: vmss.name - name: 'AzureDiskEncryption' - publisher: 'Microsoft.Azure.Security' - type: osType == 'Windows' ? 'AzureDiskEncryption' : 'AzureDiskEncryptionForLinux' - typeHandlerVersion: contains(extensionAzureDiskEncryptionConfig, 'typeHandlerVersion') ? extensionAzureDiskEncryptionConfig.typeHandlerVersion : (osType == 'Windows' ? '2.2' : '1.1') - autoUpgradeMinorVersion: contains(extensionAzureDiskEncryptionConfig, 'autoUpgradeMinorVersion') ? extensionAzureDiskEncryptionConfig.autoUpgradeMinorVersion : true - enableAutomaticUpgrade: contains(extensionAzureDiskEncryptionConfig, 'enableAutomaticUpgrade') ? extensionAzureDiskEncryptionConfig.enableAutomaticUpgrade : false - forceUpdateTag: contains(extensionAzureDiskEncryptionConfig, 'forceUpdateTag') ? extensionAzureDiskEncryptionConfig.forceUpdateTag : '1.0' - settings: extensionAzureDiskEncryptionConfig.settings +module vmss_azureDiskEncryptionExtension 'extension/main.bicep' = + if (extensionAzureDiskEncryptionConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VMSS-AzureDiskEncryption' + params: { + virtualMachineScaleSetName: vmss.name + name: 'AzureDiskEncryption' + publisher: 'Microsoft.Azure.Security' + type: osType == 'Windows' ? 'AzureDiskEncryption' : 'AzureDiskEncryptionForLinux' + typeHandlerVersion: contains(extensionAzureDiskEncryptionConfig, 'typeHandlerVersion') + ? extensionAzureDiskEncryptionConfig.typeHandlerVersion + : (osType == 'Windows' ? '2.2' : '1.1') + autoUpgradeMinorVersion: contains(extensionAzureDiskEncryptionConfig, 'autoUpgradeMinorVersion') + ? extensionAzureDiskEncryptionConfig.autoUpgradeMinorVersion + : true + enableAutomaticUpgrade: contains(extensionAzureDiskEncryptionConfig, 'enableAutomaticUpgrade') + ? extensionAzureDiskEncryptionConfig.enableAutomaticUpgrade + : false + forceUpdateTag: contains(extensionAzureDiskEncryptionConfig, 'forceUpdateTag') + ? extensionAzureDiskEncryptionConfig.forceUpdateTag + : '1.0' + settings: extensionAzureDiskEncryptionConfig.settings + } + dependsOn: [ + vmss_customScriptExtension + ] } - dependsOn: [ - vmss_customScriptExtension - ] -} -resource vmss_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.' +resource vmss_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: vmss } - scope: vmss -} -resource vmss_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 - metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { - category: group.category - enabled: group.?enabled ?? true - timeGrain: null - }] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType +resource vmss_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 + metrics: [ + for group in (diagnosticSetting.?metricCategories ?? [{ category: 'AllMetrics' }]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: vmss } - scope: vmss -}] - -resource vmss_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(vmss.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 +] + +resource vmss_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(vmss.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: vmss } - scope: vmss -}] +] @description('The resource ID of the virtual machine scale set.') output resourceId string = vmss.id diff --git a/avm/res/compute/virtual-machine-scale-set/main.json b/avm/res/compute/virtual-machine-scale-set/main.json index 631b4efcc3..518c5e8df8 100644 --- a/avm/res/compute/virtual-machine-scale-set/main.json +++ b/avm/res/compute/virtual-machine-scale-set/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14475705222828543049" + "version": "0.26.54.24096", + "templateHash": "15325819648954627762" }, "name": "Virtual Machine Scale Sets", "description": "This module deploys a Virtual Machine Scale Set.", @@ -1054,8 +1054,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3680417048986934448" + "version": "0.26.54.24096", + "templateHash": "8948100547542268397" }, "name": "Virtual Machine Scale Set Extensions", "description": "This module deploys a Virtual Machine Scale Set Extension.", @@ -1216,8 +1216,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3680417048986934448" + "version": "0.26.54.24096", + "templateHash": "8948100547542268397" }, "name": "Virtual Machine Scale Set Extensions", "description": "This module deploys a Virtual Machine Scale Set Extension.", @@ -1385,8 +1385,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3680417048986934448" + "version": "0.26.54.24096", + "templateHash": "8948100547542268397" }, "name": "Virtual Machine Scale Set Extensions", "description": "This module deploys a Virtual Machine Scale Set Extension.", @@ -1544,8 +1544,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3680417048986934448" + "version": "0.26.54.24096", + "templateHash": "8948100547542268397" }, "name": "Virtual Machine Scale Set Extensions", "description": "This module deploys a Virtual Machine Scale Set Extension.", @@ -1702,8 +1702,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3680417048986934448" + "version": "0.26.54.24096", + "templateHash": "8948100547542268397" }, "name": "Virtual Machine Scale Set Extensions", "description": "This module deploys a Virtual Machine Scale Set Extension.", @@ -1864,8 +1864,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3680417048986934448" + "version": "0.26.54.24096", + "templateHash": "8948100547542268397" }, "name": "Virtual Machine Scale Set Extensions", "description": "This module deploys a Virtual Machine Scale Set Extension.", @@ -2032,8 +2032,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3680417048986934448" + "version": "0.26.54.24096", + "templateHash": "8948100547542268397" }, "name": "Virtual Machine Scale Set Extensions", "description": "This module deploys a Virtual Machine Scale Set Extension.", @@ -2194,8 +2194,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3680417048986934448" + "version": "0.26.54.24096", + "templateHash": "8948100547542268397" }, "name": "Virtual Machine Scale Set Extensions", "description": "This module deploys a Virtual Machine Scale Set Extension.", diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.defaults/dependencies.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.defaults/dependencies.bicep index 9edda99f16..a7e3e62938 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.defaults/dependencies.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.defaults/dependencies.bicep @@ -45,7 +45,10 @@ resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022- scope: resourceGroup() properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalType: 'ServicePrincipal' } } diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.defaults/main.test.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.defaults/main.test.bicep index e775db83ba..f2bda65417 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.defaults/main.test.bicep @@ -48,49 +48,51 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - adminUsername: 'scaleSetAdmin' - imageReference: { - publisher: 'Canonical' - offer: '0001-com-ubuntu-server-jammy' - sku: '22_04-lts-gen2' - version: 'latest' - } - osDisk: { - createOption: 'fromImage' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' +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' + adminUsername: 'scaleSetAdmin' + imageReference: { + publisher: 'Canonical' + offer: '0001-com-ubuntu-server-jammy' + sku: '22_04-lts-gen2' + version: 'latest' } - } - osType: 'Linux' - skuName: 'Standard_B12ms' - disablePasswordAuthentication: true - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig1' - properties: { - subnet: { - id: nestedDependencies.outputs.subnetResourceId + osDisk: { + createOption: 'fromImage' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + skuName: 'Standard_B12ms' + disablePasswordAuthentication: true + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig1' + properties: { + subnet: { + id: nestedDependencies.outputs.subnetResourceId + } } } - } - ] - nicSuffix: '-nic01' - } - ] - publicKeys: [ - { - keyData: nestedDependencies.outputs.SSHKeyPublicKey - path: '/home/scaleSetAdmin/.ssh/authorized_keys' - } - ] + ] + nicSuffix: '-nic01' + } + ] + publicKeys: [ + { + keyData: nestedDependencies.outputs.SSHKeyPublicKey + path: '/home/scaleSetAdmin/.ssh/authorized_keys' + } + ] + } } -}] +] diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.max/dependencies.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.max/dependencies.bicep index cb6cff2726..65cf9669af 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.max/dependencies.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.max/dependencies.bicep @@ -80,7 +80,10 @@ resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022- scope: resourceGroup() properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalType: 'ServicePrincipal' } } @@ -90,7 +93,10 @@ resource msiKVCryptoUserRoleAssignment 'Microsoft.Authorization/roleAssignments@ scope: keyVault::key properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User principalType: 'ServicePrincipal' } } diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.max/main.test.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.max/main.test.bicep index 80b7f9e661..1794bd0571 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.max/main.test.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.max/main.test.bicep @@ -65,147 +65,149 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - adminUsername: 'scaleSetAdmin' - imageReference: { - publisher: 'Canonical' - offer: '0001-com-ubuntu-server-jammy' - sku: '22_04-lts-gen2' - version: 'latest' - } - osDisk: { - createOption: 'fromImage' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Linux' - skuName: 'Standard_B12ms' - availabilityZones: [ - '2' - ] - bootDiagnosticStorageAccountName: nestedDependencies.outputs.storageAccountName - dataDisks: [ - { - caching: 'ReadOnly' - createOption: 'Empty' - diskSizeGB: '256' - managedDisk: { - storageAccountType: 'Premium_LRS' - } +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' + adminUsername: 'scaleSetAdmin' + imageReference: { + publisher: 'Canonical' + offer: '0001-com-ubuntu-server-jammy' + sku: '22_04-lts-gen2' + version: 'latest' } - { - caching: 'ReadOnly' - createOption: 'Empty' + osDisk: { + createOption: 'fromImage' diskSizeGB: '128' managedDisk: { storageAccountType: 'Premium_LRS' } } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ + osType: 'Linux' + skuName: 'Standard_B12ms' + availabilityZones: [ + '2' + ] + bootDiagnosticStorageAccountName: nestedDependencies.outputs.storageAccountName + dataDisks: [ + { + caching: 'ReadOnly' + createOption: 'Empty' + diskSizeGB: '256' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + { + caching: 'ReadOnly' + createOption: 'Empty' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + disablePasswordAuthentication: true + encryptionAtHost: false + extensionCustomScriptConfig: { + enabled: true + fileData: [ { - category: 'AllMetrics' + storageAccountId: nestedDependencies.outputs.storageAccountResourceId + uri: nestedDependencies.outputs.storageAccountCSEFileUrl } ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + protectedSettings: { + commandToExecute: 'sudo apt-get update' + } } - ] - disablePasswordAuthentication: true - encryptionAtHost: false - extensionCustomScriptConfig: { - enabled: true - fileData: [ - { - storageAccountId: nestedDependencies.outputs.storageAccountResourceId - uri: nestedDependencies.outputs.storageAccountCSEFileUrl + extensionDependencyAgentConfig: { + enabled: true + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: nestedDependencies.outputs.keyVaultEncryptionKeyUrl + KeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyVaultURL: nestedDependencies.outputs.keyVaultUrl + ResizeOSDisk: 'false' + VolumeType: 'All' } - ] - protectedSettings: { - commandToExecute: 'sudo apt-get update' } - } - extensionDependencyAgentConfig: { - enabled: true - } - extensionAzureDiskEncryptionConfig: { - enabled: true - settings: { - EncryptionOperation: 'EnableEncryption' - KekVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - KeyEncryptionAlgorithm: 'RSA-OAEP' - KeyEncryptionKeyURL: nestedDependencies.outputs.keyVaultEncryptionKeyUrl - KeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - KeyVaultURL: nestedDependencies.outputs.keyVaultUrl - ResizeOSDisk: 'false' - VolumeType: 'All' + extensionMonitoringAgentConfig: { + enabled: true } - } - extensionMonitoringAgentConfig: { - enabled: true - } - extensionNetworkWatcherAgentConfig: { - enabled: true - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig1' - properties: { - subnet: { - id: nestedDependencies.outputs.subnetResourceId + extensionNetworkWatcherAgentConfig: { + enabled: true + } + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig1' + properties: { + subnet: { + id: nestedDependencies.outputs.subnetResourceId + } } } - } + ] + nicSuffix: '-nic01' + } + ] + publicKeys: [ + { + keyData: nestedDependencies.outputs.SSHKeyPublicKey + path: '/home/scaleSetAdmin/.ssh/authorized_keys' + } + ] + roleAssignments: [ + { + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + roleDefinitionIdOrName: 'Reader' + principalType: 'ServicePrincipal' + } + ] + scaleSetFaultDomain: 1 + skuCapacity: 1 + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] - nicSuffix: '-nic01' - } - ] - publicKeys: [ - { - keyData: nestedDependencies.outputs.SSHKeyPublicKey - path: '/home/scaleSetAdmin/.ssh/authorized_keys' } - ] - roleAssignments: [ - { - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - roleDefinitionIdOrName: 'Reader' - principalType: 'ServicePrincipal' + upgradePolicyMode: 'Manual' + vmNamePrefix: 'vmsslinvm' + vmPriority: 'Regular' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - scaleSetFaultDomain: 1 - skuCapacity: 1 - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - upgradePolicyMode: 'Manual' - vmNamePrefix: 'vmsslinvm' - vmPriority: 'Regular' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.ssecmk/dependencies.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.ssecmk/dependencies.bicep index c6780826ea..324e66e29f 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.ssecmk/dependencies.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.ssecmk/dependencies.bicep @@ -89,7 +89,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: keyVault properties: { principalId: diskEncryptionSet.identity.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6') // Key Vault Crypto Service Encryption User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'e147488a-f6f5-4113-8e2d-b22465e65bf6' + ) // Key Vault Crypto Service Encryption User principalType: 'ServicePrincipal' } } @@ -104,7 +107,10 @@ resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022- scope: resourceGroup() properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalType: 'ServicePrincipal' } } diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.ssecmk/main.test.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.ssecmk/main.test.bicep index b071b2f69c..035f41d15f 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.ssecmk/main.test.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/linux.ssecmk/main.test.bicep @@ -53,51 +53,40 @@ module nestedDependencies 'dependencies.bicep' = { // Test Execution // // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - extensionMonitoringAgentConfig: { - enabled: true - } - location: resourceLocation - name: '${namePrefix}${serviceShort}001' - adminUsername: 'scaleSetAdmin' - imageReference: { - publisher: 'Canonical' - offer: '0001-com-ubuntu-server-jammy' - sku: '22_04-lts-gen2' - version: 'latest' - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig1' - properties: { - subnet: { - id: nestedDependencies.outputs.subnetResourceId +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + extensionMonitoringAgentConfig: { + enabled: true + } + location: resourceLocation + name: '${namePrefix}${serviceShort}001' + adminUsername: 'scaleSetAdmin' + imageReference: { + publisher: 'Canonical' + offer: '0001-com-ubuntu-server-jammy' + sku: '22_04-lts-gen2' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig1' + properties: { + subnet: { + id: nestedDependencies.outputs.subnetResourceId + } } } - } - ] - nicSuffix: '-nic01' - } - ] - osDisk: { - createOption: 'fromImage' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - diskEncryptionSet: { - id: nestedDependencies.outputs.diskEncryptionSetResourceId + ] + nicSuffix: '-nic01' } - } - } - dataDisks: [ - { - caching: 'ReadOnly' - createOption: 'Empty' + ] + osDisk: { + createOption: 'fromImage' diskSizeGB: '128' managedDisk: { storageAccountType: 'Premium_LRS' @@ -106,15 +95,28 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } } } - ] - osType: 'Linux' - skuName: 'Standard_B12ms' - disablePasswordAuthentication: true - publicKeys: [ - { - keyData: nestedDependencies.outputs.SSHKeyPublicKey - path: '/home/scaleSetAdmin/.ssh/authorized_keys' - } - ] + dataDisks: [ + { + caching: 'ReadOnly' + createOption: 'Empty' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + diskEncryptionSet: { + id: nestedDependencies.outputs.diskEncryptionSetResourceId + } + } + } + ] + osType: 'Linux' + skuName: 'Standard_B12ms' + disablePasswordAuthentication: true + publicKeys: [ + { + keyData: nestedDependencies.outputs.SSHKeyPublicKey + path: '/home/scaleSetAdmin/.ssh/authorized_keys' + } + ] + } } -}] +] diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.defaults/main.test.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.defaults/main.test.bicep index 8275ac5bef..085ffb5828 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.defaults/main.test.bicep @@ -49,43 +49,45 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - adminUsername: 'localAdminUser' - adminPassword: password - imageReference: { - publisher: 'MicrosoftWindowsServer' - offer: 'WindowsServer' - sku: '2022-datacenter-azure-edition' - version: 'latest' - } - osDisk: { - createOption: 'fromImage' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' +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' + adminUsername: 'localAdminUser' + adminPassword: password + imageReference: { + publisher: 'MicrosoftWindowsServer' + offer: 'WindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' } - } - osType: 'Windows' - skuName: 'Standard_B12ms' - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig1' - properties: { - subnet: { - id: nestedDependencies.outputs.subnetResourceId + osDisk: { + createOption: 'fromImage' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + skuName: 'Standard_B12ms' + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig1' + properties: { + subnet: { + id: nestedDependencies.outputs.subnetResourceId + } } } - } - ] - nicSuffix: '-nic01' - } - ] + ] + nicSuffix: '-nic01' + } + ] + } } -}] +] diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.max/dependencies.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.max/dependencies.bicep index 2b1b70bb91..38258f3bc7 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.max/dependencies.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.max/dependencies.bicep @@ -74,7 +74,10 @@ resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022- scope: resourceGroup() properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalType: 'ServicePrincipal' } } @@ -84,7 +87,10 @@ resource msiKVCryptoUserRoleAssignment 'Microsoft.Authorization/roleAssignments@ scope: keyVault::key properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User principalType: 'ServicePrincipal' } } diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.max/main.test.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.max/main.test.bicep index d3524669f6..ecc12d03d8 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.max/main.test.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.max/main.test.bicep @@ -67,139 +67,141 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - adminUsername: 'localAdminUser' - imageReference: { - publisher: 'MicrosoftWindowsServer' - offer: 'WindowsServer' - sku: '2022-datacenter-azure-edition' - version: 'latest' - } - osDisk: { - createOption: 'fromImage' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' +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' + adminUsername: 'localAdminUser' + imageReference: { + publisher: 'MicrosoftWindowsServer' + offer: 'WindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' } - } - osType: 'Windows' - skuName: 'Standard_B12ms' - adminPassword: password - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ + osDisk: { + createOption: 'fromImage' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + skuName: 'Standard_B12ms' + adminPassword: password + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + encryptionAtHost: false + extensionAntiMalwareConfig: { + enabled: true + settings: { + AntimalwareEnabled: true + Exclusions: { + Extensions: '.log;.ldf' + Paths: 'D:\\IISlogs;D:\\DatabaseLogs' + Processes: 'mssence.svc' + } + RealtimeProtectionEnabled: true + ScheduledScanSettings: { + day: '7' + isEnabled: 'true' + scanType: 'Quick' + time: '120' + } + } + } + extensionCustomScriptConfig: { + enabled: true + fileData: [ { - category: 'AllMetrics' + storageAccountId: nestedDependencies.outputs.storageAccountResourceId + uri: nestedDependencies.outputs.storageAccountCSEFileUrl } ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - encryptionAtHost: false - extensionAntiMalwareConfig: { - enabled: true - settings: { - AntimalwareEnabled: true - Exclusions: { - Extensions: '.log;.ldf' - Paths: 'D:\\IISlogs;D:\\DatabaseLogs' - Processes: 'mssence.svc' - } - RealtimeProtectionEnabled: true - ScheduledScanSettings: { - day: '7' - isEnabled: 'true' - scanType: 'Quick' - time: '120' + protectedSettings: { + commandToExecute: 'powershell -ExecutionPolicy Unrestricted -Command "& ./${nestedDependencies.outputs.storageAccountCSEFileName}"' } } - } - extensionCustomScriptConfig: { - enabled: true - fileData: [ - { - storageAccountId: nestedDependencies.outputs.storageAccountResourceId - uri: nestedDependencies.outputs.storageAccountCSEFileUrl + extensionDependencyAgentConfig: { + enabled: true + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: nestedDependencies.outputs.keyVaultEncryptionKeyUrl + KeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyVaultURL: nestedDependencies.outputs.keyVaultUrl + ResizeOSDisk: 'false' + VolumeType: 'All' } - ] - protectedSettings: { - commandToExecute: 'powershell -ExecutionPolicy Unrestricted -Command "& ./${nestedDependencies.outputs.storageAccountCSEFileName}"' } - } - extensionDependencyAgentConfig: { - enabled: true - } - extensionAzureDiskEncryptionConfig: { - enabled: true - settings: { - EncryptionOperation: 'EnableEncryption' - KekVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - KeyEncryptionAlgorithm: 'RSA-OAEP' - KeyEncryptionKeyURL: nestedDependencies.outputs.keyVaultEncryptionKeyUrl - KeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - KeyVaultURL: nestedDependencies.outputs.keyVaultUrl - ResizeOSDisk: 'false' - VolumeType: 'All' + extensionDSCConfig: { + enabled: true } - } - extensionDSCConfig: { - enabled: true - } - extensionMonitoringAgentConfig: { - enabled: true - } - extensionNetworkWatcherAgentConfig: { - enabled: true - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig1' - properties: { - subnet: { - id: nestedDependencies.outputs.subnetResourceId + extensionMonitoringAgentConfig: { + enabled: true + } + extensionNetworkWatcherAgentConfig: { + enabled: true + } + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig1' + properties: { + subnet: { + id: nestedDependencies.outputs.subnetResourceId + } } } - } + ] + nicSuffix: '-nic01' + } + ] + roleAssignments: [ + { + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + roleDefinitionIdOrName: 'Reader' + principalType: 'ServicePrincipal' + } + ] + skuCapacity: 1 + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] - nicSuffix: '-nic01' } - ] - roleAssignments: [ - { - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - roleDefinitionIdOrName: 'Reader' - principalType: 'ServicePrincipal' + upgradePolicyMode: 'Manual' + vmNamePrefix: 'vmsswinvm' + vmPriority: 'Regular' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - skuCapacity: 1 - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - upgradePolicyMode: 'Manual' - vmNamePrefix: 'vmsswinvm' - vmPriority: 'Regular' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.waf-aligned/dependencies.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.waf-aligned/dependencies.bicep index 2b1b70bb91..38258f3bc7 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.waf-aligned/dependencies.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.waf-aligned/dependencies.bicep @@ -74,7 +74,10 @@ resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022- scope: resourceGroup() properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalType: 'ServicePrincipal' } } @@ -84,7 +87,10 @@ resource msiKVCryptoUserRoleAssignment 'Microsoft.Authorization/roleAssignments@ scope: keyVault::key properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User principalType: 'ServicePrincipal' } } diff --git a/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.waf-aligned/main.test.bicep index 337487ca49..761f393356 100644 --- a/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine-scale-set/tests/e2e/windows.waf-aligned/main.test.bicep @@ -67,128 +67,130 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - adminUsername: 'localAdminUser' - imageReference: { - publisher: 'MicrosoftWindowsServer' - offer: 'WindowsServer' - sku: '2022-datacenter-azure-edition' - version: 'latest' - } - osDisk: { - createOption: 'fromImage' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' +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' + adminUsername: 'localAdminUser' + imageReference: { + publisher: 'MicrosoftWindowsServer' + offer: 'WindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' } - } - osType: 'Windows' - skuName: 'Standard_B12ms' - adminPassword: password - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ + osDisk: { + createOption: 'fromImage' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + skuName: 'Standard_B12ms' + adminPassword: password + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + encryptionAtHost: false // Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your virtual machine scale sets. + extensionAntiMalwareConfig: { + enabled: true + settings: { + AntimalwareEnabled: true + Exclusions: { + Extensions: '.log;.ldf' + Paths: 'D:\\IISlogs;D:\\DatabaseLogs' + Processes: 'mssence.svc' + } + RealtimeProtectionEnabled: true + ScheduledScanSettings: { + day: '7' + isEnabled: 'true' + scanType: 'Quick' + time: '120' + } + } + } + extensionCustomScriptConfig: { + enabled: true + fileData: [ { - category: 'AllMetrics' + storageAccountId: nestedDependencies.outputs.storageAccountResourceId + uri: nestedDependencies.outputs.storageAccountCSEFileUrl } ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - encryptionAtHost: false // Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your virtual machine scale sets. - extensionAntiMalwareConfig: { - enabled: true - settings: { - AntimalwareEnabled: true - Exclusions: { - Extensions: '.log;.ldf' - Paths: 'D:\\IISlogs;D:\\DatabaseLogs' - Processes: 'mssence.svc' - } - RealtimeProtectionEnabled: true - ScheduledScanSettings: { - day: '7' - isEnabled: 'true' - scanType: 'Quick' - time: '120' + protectedSettings: { + commandToExecute: 'powershell -ExecutionPolicy Unrestricted -Command "& ./${nestedDependencies.outputs.storageAccountCSEFileName}"' } } - } - extensionCustomScriptConfig: { - enabled: true - fileData: [ - { - storageAccountId: nestedDependencies.outputs.storageAccountResourceId - uri: nestedDependencies.outputs.storageAccountCSEFileUrl + extensionDependencyAgentConfig: { + enabled: true + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: nestedDependencies.outputs.keyVaultEncryptionKeyUrl + KeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyVaultURL: nestedDependencies.outputs.keyVaultUrl + ResizeOSDisk: 'false' + VolumeType: 'All' } - ] - protectedSettings: { - commandToExecute: 'powershell -ExecutionPolicy Unrestricted -Command "& ./${nestedDependencies.outputs.storageAccountCSEFileName}"' } - } - extensionDependencyAgentConfig: { - enabled: true - } - extensionAzureDiskEncryptionConfig: { - enabled: true - settings: { - EncryptionOperation: 'EnableEncryption' - KekVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - KeyEncryptionAlgorithm: 'RSA-OAEP' - KeyEncryptionKeyURL: nestedDependencies.outputs.keyVaultEncryptionKeyUrl - KeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - KeyVaultURL: nestedDependencies.outputs.keyVaultUrl - ResizeOSDisk: 'false' - VolumeType: 'All' + extensionDSCConfig: { + enabled: true } - } - extensionDSCConfig: { - enabled: true - } - extensionMonitoringAgentConfig: { - enabled: true - } - extensionNetworkWatcherAgentConfig: { - enabled: true - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig1' - properties: { - subnet: { - id: nestedDependencies.outputs.subnetResourceId + extensionMonitoringAgentConfig: { + enabled: true + } + extensionNetworkWatcherAgentConfig: { + enabled: true + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig1' + properties: { + subnet: { + id: nestedDependencies.outputs.subnetResourceId + } } } - } + ] + nicSuffix: '-nic01' + } + ] + skuCapacity: 1 + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] - nicSuffix: '-nic01' } - ] - skuCapacity: 1 - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - upgradePolicyMode: 'Manual' - vmNamePrefix: 'vmsswinvm' - vmPriority: 'Regular' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + upgradePolicyMode: 'Manual' + vmNamePrefix: 'vmsswinvm' + vmPriority: 'Regular' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/consumption/budget/main.bicep b/avm/res/consumption/budget/main.bicep index 00fd7b662b..d5558266d9 100644 --- a/avm/res/consumption/budget/main.bicep +++ b/avm/res/consumption/budget/main.bicep @@ -80,36 +80,39 @@ param enableTelemetry bool = true @description('Optional. Location deployment metadata.') param location string = deployment().location -var notificationsArray = [for threshold in thresholds: { - 'Actual_GreaterThan_${threshold}_Percentage': { - enabled: true - operator: operator - threshold: threshold - contactEmails: contactEmails - contactRoles: contactRoles - contactGroups: actionGroups - thresholdType: thresholdType +var notificationsArray = [ + for threshold in thresholds: { + 'Actual_GreaterThan_${threshold}_Percentage': { + enabled: true + operator: operator + threshold: threshold + contactEmails: contactEmails + contactRoles: contactRoles + contactGroups: actionGroups + thresholdType: thresholdType + } } -}] +] -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 - 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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.consumption-budget.${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 budget 'Microsoft.Consumption/budgets@2023-11-01' = { name: name @@ -121,13 +124,15 @@ resource budget 'Microsoft.Consumption/budgets@2023-11-01' = { startDate: startDate endDate: endDate } - filter: filter ?? (!empty(resourceGroupFilter) ? { - dimensions: { - name: 'ResourceGroupName' - operator: 'In' - values: resourceGroupFilter - } - } : {}) + 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 ca59c5284d..13b0e199e7 100644 --- a/avm/res/consumption/budget/main.json +++ b/avm/res/consumption/budget/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4486017492010556264" + "version": "0.26.54.24096", + "templateHash": "9911588770976622603" }, "name": "Consumption Budgets", "description": "This module deploys a Consumption Budget for Subscriptions.", diff --git a/avm/res/consumption/budget/tests/e2e/defaults/main.test.bicep b/avm/res/consumption/budget/tests/e2e/defaults/main.test.bicep index 4b3537ec84..403a99c156 100644 --- a/avm/res/consumption/budget/tests/e2e/defaults/main.test.bicep +++ b/avm/res/consumption/budget/tests/e2e/defaults/main.test.bicep @@ -21,14 +21,16 @@ param namePrefix string = '#_namePrefix_#' // ============== // @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 - amount: 500 - contactEmails: [ - 'dummy@contoso.com' - ] +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + name: '${uniqueString(deployment().name)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + amount: 500 + contactEmails: [ + 'dummy@contoso.com' + ] + } } -}] +] 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 e581db3199..778c4ff7bb 100644 --- a/avm/res/consumption/budget/tests/e2e/max/main.test.bicep +++ b/avm/res/consumption/budget/tests/e2e/max/main.test.bicep @@ -21,25 +21,27 @@ param namePrefix string = '#_namePrefix_#' // ============== // @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 - amount: 500 - contactEmails: [ - 'dummy@contoso.com' - ] - resourceGroupFilter: [ - 'rg-group1' - 'rg-group2' - ] - thresholds: [ - 50 - 75 - 90 - 100 - 110 - ] +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + name: '${uniqueString(deployment().name)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + amount: 500 + contactEmails: [ + 'dummy@contoso.com' + ] + resourceGroupFilter: [ + 'rg-group1' + 'rg-group2' + ] + thresholds: [ + 50 + 75 + 90 + 100 + 110 + ] + } } -}] +] diff --git a/avm/res/consumption/budget/tests/e2e/waf-aligned/main.test.bicep b/avm/res/consumption/budget/tests/e2e/waf-aligned/main.test.bicep index 329c4ea51a..81c8db287d 100644 --- a/avm/res/consumption/budget/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/consumption/budget/tests/e2e/waf-aligned/main.test.bicep @@ -21,21 +21,23 @@ param namePrefix string = '#_namePrefix_#' // ============== // @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 - amount: 500 - contactEmails: [ - 'dummy@contoso.com' - ] - thresholds: [ - 50 - 75 - 90 - 100 - 110 - ] +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + name: '${uniqueString(deployment().name)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + amount: 500 + contactEmails: [ + 'dummy@contoso.com' + ] + thresholds: [ + 50 + 75 + 90 + 100 + 110 + ] + } } -}] +] diff --git a/avm/res/container-registry/registry/cache-rules/main.json b/avm/res/container-registry/registry/cache-rules/main.json index 52b54dce7e..426616994e 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.25.53.49325", - "templateHash": "6942960102258463312" + "version": "0.26.54.24096", + "templateHash": "17108035841365544326" }, "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 05bd6d96d4..126074e066 100644 --- a/avm/res/container-registry/registry/main.bicep +++ b/avm/res/container-registry/registry/main.bicep @@ -139,58 +139,91 @@ param customerManagedKey customerManagedKeyType @description('Optional. Array of Cache Rules. Note: This is a preview feature ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache#cache-for-acr-preview)).') param cacheRules array? -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { AcrDelete: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11') - AcrImageSigner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6cef56e8-d556-48e5-a04f-b8e64114680f') + AcrImageSigner: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '6cef56e8-d556-48e5-a04f-b8e64114680f' + ) AcrPull: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') AcrPush: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec') - AcrQuarantineReader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cdda3590-29a3-44f6-95f2-9f980659eb04') - AcrQuarantineWriter: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c8d4ff99-41c3-41a8-9f60-21dfdad59608') + AcrQuarantineReader: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'cdda3590-29a3-44f6-95f2-9f980659eb04' + ) + AcrQuarantineWriter: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'c8d4ff99-41c3-41a8-9f60-21dfdad59608' + ) 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') + '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.containerregistry-registry.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.containerregistry-registry.${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 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 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 registry 'Microsoft.ContainerRegistry/registries@2023-06-01-preview' = { name: name @@ -203,20 +236,28 @@ resource registry 'Microsoft.ContainerRegistry/registries@2023-06-01-preview' = properties: { anonymousPullEnabled: anonymousPullEnabled adminUserEnabled: acrAdminUserEnabled - encryption: !empty(customerManagedKey) ? { - status: 'enabled' - keyVaultProperties: { - identity: !empty(customerManagedKey.?userAssignedIdentityResourceId ?? '') ? cMKUserAssignedIdentity.properties.clientId : null - keyIdentifier: !empty(customerManagedKey.?keyVersion ?? '') ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.keyVersion}' : cMKKeyVault::cMKKey.properties.keyUriWithVersion - } - } : null + encryption: !empty(customerManagedKey) + ? { + status: 'enabled' + keyVaultProperties: { + identity: !empty(customerManagedKey.?userAssignedIdentityResourceId ?? '') + ? cMKUserAssignedIdentity.properties.clientId + : null + keyIdentifier: !empty(customerManagedKey.?keyVersion ?? '') + ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.keyVersion}' + : cMKKeyVault::cMKKey.properties.keyUriWithVersion + } + } + : null policies: { azureADAuthenticationAsArmPolicy: { status: azureADAuthenticationAsArmPolicyStatus } - exportPolicy: acrSku == 'Premium' ? { - status: exportPolicyStatus - } : null + exportPolicy: acrSku == 'Premium' + ? { + status: exportPolicyStatus + } + : null quarantinePolicy: { status: quarantinePolicyStatus } @@ -224,157 +265,192 @@ resource registry 'Microsoft.ContainerRegistry/registries@2023-06-01-preview' = type: 'Notary' status: trustPolicyStatus } - retentionPolicy: acrSku == 'Premium' ? { - days: retentionPolicyDays - status: retentionPolicyStatus - } : null + retentionPolicy: acrSku == 'Premium' + ? { + days: retentionPolicyDays + status: retentionPolicyStatus + } + : null softDeletePolicy: { retentionDays: softDeletePolicyDays status: softDeletePolicyStatus } } dataEndpointEnabled: dataEndpointEnabled - publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) : (!empty(privateEndpoints) && empty(networkRuleSetIpRules) ? 'Disabled' : null) + publicNetworkAccess: !empty(publicNetworkAccess) + ? any(publicNetworkAccess) + : (!empty(privateEndpoints) && empty(networkRuleSetIpRules) ? 'Disabled' : null) networkRuleBypassOptions: networkRuleBypassOptions - networkRuleSet: !empty(networkRuleSetIpRules) ? { - defaultAction: networkRuleSetDefaultAction - ipRules: networkRuleSetIpRules - } : null + networkRuleSet: !empty(networkRuleSetIpRules) + ? { + defaultAction: networkRuleSetDefaultAction + ipRules: networkRuleSetIpRules + } + : null zoneRedundancy: acrSku == 'Premium' ? zoneRedundancy : null } } -module registry_replications 'replication/main.bicep' = [for (replication, index) in (replications ?? []): { - name: '${uniqueString(deployment().name, location)}-Registry-Replication-${index}' - params: { - name: replication.name - registryName: registry.name - location: replication.location - regionEndpointEnabled: replication.?regionEndpointEnabled - zoneRedundancy: replication.?zoneRedundancy - tags: replication.?tags ?? tags +module registry_replications 'replication/main.bicep' = [ + for (replication, index) in (replications ?? []): { + name: '${uniqueString(deployment().name, location)}-Registry-Replication-${index}' + params: { + name: replication.name + registryName: registry.name + location: replication.location + regionEndpointEnabled: replication.?regionEndpointEnabled + zoneRedundancy: replication.?zoneRedundancy + tags: replication.?tags ?? tags + } } -}] - -module registry_cacheRules 'cache-rules/main.bicep' = [for (cacheRule, index) in (cacheRules ?? []): { - name: '${uniqueString(deployment().name, location)}-Registry-Cache-${index}' - params: { - registryName: registry.name - sourceRepository: cacheRule.sourceRepository - name: cacheRule.?name ?? replace(replace(cacheRule.sourceRepository, '/', '-'), '.', '-') - targetRepository: cacheRule.?targetRepository ?? cacheRule.sourceRepository - credentialSetResourceId: cacheRule.?credentialSetResourceId +] + +module registry_cacheRules 'cache-rules/main.bicep' = [ + for (cacheRule, index) in (cacheRules ?? []): { + name: '${uniqueString(deployment().name, location)}-Registry-Cache-${index}' + params: { + registryName: registry.name + sourceRepository: cacheRule.sourceRepository + name: cacheRule.?name ?? replace(replace(cacheRule.sourceRepository, '/', '-'), '.', '-') + targetRepository: cacheRule.?targetRepository ?? cacheRule.sourceRepository + credentialSetResourceId: cacheRule.?credentialSetResourceId + } } -}] - -module registry_webhooks 'webhook/main.bicep' = [for (webhook, index) in (webhooks ?? []): { - name: '${uniqueString(deployment().name, location)}-Registry-Webhook-${index}' - params: { - name: webhook.name - registryName: registry.name - location: webhook.?location ?? location - action: webhook.?action ?? [ - 'chart_delete' - 'chart_push' - 'delete' - 'push' - 'quarantine' - ] - customHeaders: webhook.?customHeaders - scope: webhook.?scope - status: webhook.?status - serviceUri: webhook.serviceUri - tags: webhook.?tags ?? tags +] + +module registry_webhooks 'webhook/main.bicep' = [ + for (webhook, index) in (webhooks ?? []): { + name: '${uniqueString(deployment().name, location)}-Registry-Webhook-${index}' + params: { + name: webhook.name + registryName: registry.name + location: webhook.?location ?? location + action: webhook.?action ?? [ + 'chart_delete' + 'chart_push' + 'delete' + 'push' + 'quarantine' + ] + customHeaders: webhook.?customHeaders + scope: webhook.?scope + status: webhook.?status + serviceUri: webhook.serviceUri + tags: webhook.?tags ?? tags + } } -}] +] -resource registry_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.' +resource registry_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: registry } - scope: registry -} -resource registry_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 - 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 +resource registry_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 + 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 + } + scope: registry } - scope: registry -}] +] -resource registry_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(registry.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 +resource registry_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(registry.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: registry } - scope: registry -}] - -module registry_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-registry-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(registry.id, '/'))}-${privateEndpoint.?service ?? 'registry'}-${index}' - privateLinkServiceConnections: [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(registry.id, '/'))}-${privateEndpoint.?service ?? 'registry'}-${index}' - properties: { - privateLinkServiceId: registry.id - groupIds: [ - privateEndpoint.?service ?? 'registry' - ] +] + +module registry_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-registry-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(registry.id, '/'))}-${privateEndpoint.?service ?? 'registry'}-${index}' + privateLinkServiceConnections: [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(registry.id, '/'))}-${privateEndpoint.?service ?? 'registry'}-${index}' + properties: { + privateLinkServiceId: registry.id + groupIds: [ + privateEndpoint.?service ?? 'registry' + ] + } } - } - ] - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(registry.id, '/'))}-${privateEndpoint.?service ?? 'registry'}-${index}' - properties: { - privateLinkServiceId: registry.id - groupIds: [ - privateEndpoint.?service ?? 'registry' + ] + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(registry.id, '/'))}-${privateEndpoint.?service ?? 'registry'}-${index}' + properties: { + privateLinkServiceId: registry.id + groupIds: [ + privateEndpoint.?service ?? 'registry' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] @description('The Name of the Azure container registry.') output name string = registry.name diff --git a/avm/res/container-registry/registry/main.json b/avm/res/container-registry/registry/main.json index e08259390f..b176210972 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.25.53.49325", - "templateHash": "9195818754355186204" + "version": "0.26.54.24096", + "templateHash": "15445287807627348186" }, "name": "Azure Container Registries (ACR)", "description": "This module deploys an Azure Container Registry (ACR).", @@ -943,8 +943,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10714256463183699741" + "version": "0.26.54.24096", + "templateHash": "16451316437757175736" }, "name": "Azure Container Registry (ACR) Replications", "description": "This module deploys an Azure Container Registry (ACR) Replication.", @@ -1091,8 +1091,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6942960102258463312" + "version": "0.26.54.24096", + "templateHash": "17108035841365544326" }, "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)).", @@ -1232,8 +1232,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3986666280667981658" + "version": "0.26.54.24096", + "templateHash": "10731035117081750792" }, "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 ea887b53b1..61c5d1a182 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.25.53.49325", - "templateHash": "10714256463183699741" + "version": "0.26.54.24096", + "templateHash": "16451316437757175736" }, "name": "Azure Container Registry (ACR) Replications", "description": "This module deploys an Azure Container Registry (ACR) Replication.", diff --git a/avm/res/container-registry/registry/tests/e2e/defaults/main.test.bicep b/avm/res/container-registry/registry/tests/e2e/defaults/main.test.bicep index c9ee60ee98..4913076429 100644 --- a/avm/res/container-registry/registry/tests/e2e/defaults/main.test.bicep +++ b/avm/res/container-registry/registry/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/container-registry/registry/tests/e2e/encr/dependencies.bicep b/avm/res/container-registry/registry/tests/e2e/encr/dependencies.bicep index 2a44c0d13c..3d3446c847 100644 --- a/avm/res/container-registry/registry/tests/e2e/encr/dependencies.bicep +++ b/avm/res/container-registry/registry/tests/e2e/encr/dependencies.bicep @@ -69,7 +69,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { properties: { principalId: managedIdentity.properties.principalId // Key Vault Crypto User - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) principalType: 'ServicePrincipal' } } diff --git a/avm/res/container-registry/registry/tests/e2e/encr/main.test.bicep b/avm/res/container-registry/registry/tests/e2e/encr/main.test.bicep index 740e8c19d6..7e947cfc34 100644 --- a/avm/res/container-registry/registry/tests/e2e/encr/main.test.bicep +++ b/avm/res/container-registry/registry/tests/e2e/encr/main.test.bicep @@ -51,26 +51,28 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - acrSku: 'Premium' - customerManagedKey: { - keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId - } - publicNetworkAccess: 'Disabled' - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] +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 + acrSku: 'Premium' + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + } + publicNetworkAccess: 'Disabled' + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/container-registry/registry/tests/e2e/max/dependencies.bicep b/avm/res/container-registry/registry/tests/e2e/max/dependencies.bicep index 73256e4598..16d9a64d1b 100644 --- a/avm/res/container-registry/registry/tests/e2e/max/dependencies.bicep +++ b/avm/res/container-registry/registry/tests/e2e/max/dependencies.bicep @@ -57,7 +57,10 @@ resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid('msi-${location}-${managedIdentity.id}-Reader-RoleAssignment') properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') // Reader + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) // Reader principalType: 'ServicePrincipal' } } diff --git a/avm/res/container-registry/registry/tests/e2e/max/main.test.bicep b/avm/res/container-registry/registry/tests/e2e/max/main.test.bicep index 6153fdefb5..c7b9f5e186 100644 --- a/avm/res/container-registry/registry/tests/e2e/max/main.test.bicep +++ b/avm/res/container-registry/registry/tests/e2e/max/main.test.bicep @@ -62,116 +62,121 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - acrAdminUserEnabled: false - acrSku: 'Premium' - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - exportPolicyStatus: 'enabled' - azureADAuthenticationAsArmPolicyStatus: 'enabled' - softDeletePolicyStatus: 'disabled' - softDeletePolicyDays: 7 - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + acrAdminUserEnabled: false + acrSku: 'Premium' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } + ] + exportPolicyStatus: 'enabled' + azureADAuthenticationAsArmPolicyStatus: 'enabled' + softDeletePolicyStatus: 'disabled' + softDeletePolicyDays: 7 + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + } + ] + networkRuleSetIpRules: [ + { + action: 'Allow' + value: '40.74.28.0/23' + } + ] + quarantinePolicyStatus: 'enabled' + replications: [ + { + location: nestedDependencies.outputs.pairedRegionName + name: nestedDependencies.outputs.pairedRegionName + } + ] + 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' + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] } - ] - networkRuleSetIpRules: [ - { - action: 'Allow' - value: '40.74.28.0/23' - } - ] - quarantinePolicyStatus: 'enabled' - replications: [ - { - location: nestedDependencies.outputs.pairedRegionName - name: nestedDependencies.outputs.pairedRegionName - } - ] - 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' - } - ] - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId + trustPolicyStatus: 'enabled' + cacheRules: [ + { + name: 'customRule' + sourceRepository: 'docker.io/library/hello-world' + targetRepository: 'cached-docker-hub/hello-world' + } + { + sourceRepository: 'docker.io/library/hello-world' + } ] - } - trustPolicyStatus: 'enabled' - cacheRules: [ - { - name: 'customRule' - sourceRepository: 'docker.io/library/hello-world' - targetRepository: 'cached-docker-hub/hello-world' - } - { - sourceRepository: 'docker.io/library/hello-world' - } - ] - webhooks: [ - { - name: '${namePrefix}acrx001webhook' - serviceUri: 'https://www.contoso.com/webhook' + webhooks: [ + { + name: '${namePrefix}acrx001webhook' + serviceUri: 'https://www.contoso.com/webhook' + } + ] + 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' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/container-registry/registry/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/container-registry/registry/tests/e2e/waf-aligned/dependencies.bicep index 04abeed1bb..0e56a92b7a 100644 --- a/avm/res/container-registry/registry/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/container-registry/registry/tests/e2e/waf-aligned/dependencies.bicep @@ -16,7 +16,10 @@ resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid('msi-${location}-${managedIdentity.id}-Reader-RoleAssignment') properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') // Reader + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) // Reader principalType: 'ServicePrincipal' } } diff --git a/avm/res/container-registry/registry/tests/e2e/waf-aligned/main.test.bicep b/avm/res/container-registry/registry/tests/e2e/waf-aligned/main.test.bicep index c046264a97..4b99ab2618 100644 --- a/avm/res/container-registry/registry/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/container-registry/registry/tests/e2e/waf-aligned/main.test.bicep @@ -60,42 +60,44 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - acrAdminUserEnabled: false - acrSku: 'Premium' - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + acrAdminUserEnabled: false + acrSku: 'Premium' + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + exportPolicyStatus: 'enabled' + azureADAuthenticationAsArmPolicyStatus: 'enabled' + softDeletePolicyStatus: 'disabled' + softDeletePolicyDays: 7 + quarantinePolicyStatus: 'enabled' + replications: [ + { + location: nestedDependencies.outputs.pairedRegionName + name: nestedDependencies.outputs.pairedRegionName + } + ] + trustPolicyStatus: 'enabled' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - exportPolicyStatus: 'enabled' - azureADAuthenticationAsArmPolicyStatus: 'enabled' - softDeletePolicyStatus: 'disabled' - softDeletePolicyDays: 7 - quarantinePolicyStatus: 'enabled' - replications: [ - { - location: nestedDependencies.outputs.pairedRegionName - name: nestedDependencies.outputs.pairedRegionName - } - ] - trustPolicyStatus: 'enabled' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/container-registry/registry/webhook/main.json b/avm/res/container-registry/registry/webhook/main.json index c5520f2893..4c7f571ed7 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.25.53.49325", - "templateHash": "3986666280667981658" + "version": "0.26.54.24096", + "templateHash": "10731035117081750792" }, "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/agent-pool/main.bicep b/avm/res/container-service/managed-cluster/agent-pool/main.bicep index f34cd88385..d1daa97efe 100644 --- a/avm/res/container-service/managed-cluster/agent-pool/main.bicep +++ b/avm/res/container-service/managed-cluster/agent-pool/main.bicep @@ -156,9 +156,11 @@ resource agentPool 'Microsoft.ContainerService/managedClusters/agentPools@2023-0 properties: { availabilityZones: availabilityZones count: count - creationData: !empty(sourceResourceId) ? { - sourceResourceId: sourceResourceId - } : null + creationData: !empty(sourceResourceId) + ? { + sourceResourceId: sourceResourceId + } + : null enableAutoScaling: enableAutoScaling enableEncryptionAtHost: enableEncryptionAtHost enableFIPS: enableFIPS 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 4238233b6a..f6fc6ebeb9 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.25.53.49325", - "templateHash": "11449186283530676915" + "version": "0.26.54.24096", + "templateHash": "8772299678418708256" }, "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 29f1e1fea5..99ed22d4c5 100644 --- a/avm/res/container-service/managed-cluster/main.bicep +++ b/avm/res/container-service/managed-cluster/main.bicep @@ -372,65 +372,127 @@ param metricAnnotationsAllowList string = '' // Variables // // =========== // -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? 'SystemAssigned' : (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? 'SystemAssigned' + : (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - 'Azure Kubernetes Fleet Manager Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '63bb64ad-9799-4770-b5c3-24ed299a07bf') - 'Azure Kubernetes Fleet Manager RBAC Admin': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '434fb43a-c01c-447e-9f67-c3ad923cfaba') - 'Azure Kubernetes Fleet Manager RBAC Cluster Admin': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ab4d3d-a1bf-4477-8ad9-8359bc988f69') - 'Azure Kubernetes Fleet Manager RBAC Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '30b27cfc-9c84-438e-b0ce-70e35255df80') - 'Azure Kubernetes Fleet Manager RBAC Writer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5af6afb3-c06c-4fa4-8848-71a8aee05683') - 'Azure Kubernetes Service Cluster Admin Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8') - 'Azure Kubernetes Service Cluster Monitoring User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1afdec4b-e479-420e-99e7-f82237c7c5e6') - 'Azure Kubernetes Service Cluster User Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4abbcc35-e782-43d8-92c5-2d3f1bd2253f') - 'Azure Kubernetes Service Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ed7f3fbd-7b88-4dd4-9017-9adb7ce333f8') - 'Azure Kubernetes Service RBAC Admin': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3498e952-d568-435e-9b2c-8d77e338d7f7') - 'Azure Kubernetes Service RBAC Cluster Admin': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b1ff04bb-8a4e-4dc4-8eb5-8693973ce19b') - 'Azure Kubernetes Service RBAC Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f6c6a51-bcf8-42ba-9220-52d62157d7db') - 'Azure Kubernetes Service RBAC Writer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7ffa36f-339b-4b5c-8bdf-e2c188b2c0eb') + 'Azure Kubernetes Fleet Manager Contributor Role': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '63bb64ad-9799-4770-b5c3-24ed299a07bf' + ) + 'Azure Kubernetes Fleet Manager RBAC Admin': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '434fb43a-c01c-447e-9f67-c3ad923cfaba' + ) + 'Azure Kubernetes Fleet Manager RBAC Cluster Admin': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18ab4d3d-a1bf-4477-8ad9-8359bc988f69' + ) + 'Azure Kubernetes Fleet Manager RBAC Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '30b27cfc-9c84-438e-b0ce-70e35255df80' + ) + 'Azure Kubernetes Fleet Manager RBAC Writer': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '5af6afb3-c06c-4fa4-8848-71a8aee05683' + ) + 'Azure Kubernetes Service Cluster Admin Role': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8' + ) + 'Azure Kubernetes Service Cluster Monitoring User': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1afdec4b-e479-420e-99e7-f82237c7c5e6' + ) + 'Azure Kubernetes Service Cluster User Role': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4abbcc35-e782-43d8-92c5-2d3f1bd2253f' + ) + 'Azure Kubernetes Service Contributor Role': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'ed7f3fbd-7b88-4dd4-9017-9adb7ce333f8' + ) + 'Azure Kubernetes Service RBAC Admin': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '3498e952-d568-435e-9b2c-8d77e338d7f7' + ) + 'Azure Kubernetes Service RBAC Cluster Admin': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b1ff04bb-8a4e-4dc4-8eb5-8693973ce19b' + ) + 'Azure Kubernetes Service RBAC Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7f6c6a51-bcf8-42ba-9220-52d62157d7db' + ) + 'Azure Kubernetes Service RBAC Writer': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a7ffa36f-339b-4b5c-8bdf-e2c188b2c0eb' + ) Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Kubernetes Agentless Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a2ae44-610b-4500-93be-660a0c5f5ca6') + 'Kubernetes Agentless Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd5a2ae44-610b-4500-93be-660a0c5f5ca6' + ) 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') + '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' + ) } // ============ // // Dependencies // // ============ // -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.containerservice-managedcluster.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.containerservice-managedcluster.${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 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' + } } -} // ============== // // Main Resources // @@ -452,23 +514,27 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2023-07-02-p kubernetesVersion: kubernetesVersion dnsPrefix: dnsPrefix agentPoolProfiles: primaryAgentPoolProfile - linuxProfile: !empty(sshPublicKey) ? { - adminUsername: adminUsername - ssh: { - publicKeys: [ - { - keyData: sshPublicKey ?? '' + linuxProfile: !empty(sshPublicKey) + ? { + adminUsername: adminUsername + ssh: { + publicKeys: [ + { + keyData: sshPublicKey ?? '' + } + ] } - ] - } - } : null + } + : null servicePrincipalProfile: aksServicePrincipalProfile ingressProfile: { webAppRouting: { enabled: webApplicationRoutingEnabled - dnsZoneResourceIds: !empty(dnsZoneResourceId) ? [ - any(dnsZoneResourceId) - ] : null + dnsZoneResourceIds: !empty(dnsZoneResourceId) + ? [ + any(dnsZoneResourceId) + ] + : null } } addonProfiles: { @@ -478,26 +544,32 @@ 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 - } : null + config: ingressApplicationGatewayEnabled && !empty(appGatewayResourceId) + ? { + applicationGatewayId: appGatewayResourceId + effectiveApplicationGatewayId: appGatewayResourceId + } + : null } 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 + config: omsAgentEnabled && !empty(monitoringWorkspaceId) + ? { + logAnalyticsWorkspaceResourceID: monitoringWorkspaceId + } + : null } aciConnectorLinux: { enabled: aciConnectorLinuxEnabled } azurepolicy: { enabled: azurePolicyEnabled - config: azurePolicyEnabled ? { - version: azurePolicyVersion - } : null + config: azurePolicyEnabled + ? { + version: azurePolicyVersion + } + : null } openServiceMesh: { enabled: openServiceMeshEnabled @@ -508,14 +580,18 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2023-07-02-p } azureKeyvaultSecretsProvider: { enabled: enableKeyvaultSecretsProvider - config: enableKeyvaultSecretsProvider ? { - enableSecretRotation: enableSecretRotation - } : null + config: enableKeyvaultSecretsProvider + ? { + enableSecretRotation: enableSecretRotation + } + : null } } - oidcIssuerProfile: enableOidcIssuerProfile ? { - enabled: enableOidcIssuerProfile - } : null + oidcIssuerProfile: enableOidcIssuerProfile + ? { + enabled: enableOidcIssuerProfile + } + : null enableRBAC: enableRBAC disableLocalAccounts: disableLocalAccounts nodeResourceGroup: nodeResourceGroup @@ -530,12 +606,14 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2023-07-02-p dnsServiceIP: dnsServiceIP outboundType: outboundType loadBalancerSku: loadBalancerSku - loadBalancerProfile: managedOutboundIPCount != 0 ? { - managedOutboundIPs: { - count: managedOutboundIPCount - } - effectiveOutboundIPs: [] - } : null + loadBalancerProfile: managedOutboundIPCount != 0 + ? { + managedOutboundIPs: { + count: managedOutboundIPCount + } + effectiveOutboundIPs: [] + } + : null } aadProfile: { clientAppID: aadProfileClientAppID @@ -576,28 +654,32 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2023-07-02-p privateDNSZone: privateDNSZone } azureMonitorProfile: { - logs: enableAzureMonitorProfileLogs ? { - appMonitoring: { - enabled: enableAppMonitoring - } - containerInsights: { - enabled: enableContainerInsights - logAnalyticsWorkspaceResourceId: !empty(monitoringWorkspaceId) ? monitoringWorkspaceId : null - windowsHostLogs: { - enabled: enableWindowsHostLogs + logs: enableAzureMonitorProfileLogs + ? { + appMonitoring: { + enabled: enableAppMonitoring + } + containerInsights: { + enabled: enableContainerInsights + logAnalyticsWorkspaceResourceId: !empty(monitoringWorkspaceId) ? monitoringWorkspaceId : null + windowsHostLogs: { + enabled: enableWindowsHostLogs + } + } } - } - } : null - metrics: enableAzureMonitorProfileMetrics ? { - enabled: enableAzureMonitorProfileMetrics - appMonitoringOpenTelemetryMetrics: { - enabled: enableAppMonitoringOpenTelemetryMetrics - } - kubeStateMetrics: { - metricLabelsAllowlist: metricLabelsAllowlist - metricAnnotationsAllowList: metricAnnotationsAllowList - } - } : null + : null + metrics: enableAzureMonitorProfileMetrics + ? { + enabled: enableAzureMonitorProfileMetrics + appMonitoringOpenTelemetryMetrics: { + enabled: enableAppMonitoringOpenTelemetryMetrics + } + kubeStateMetrics: { + metricLabelsAllowlist: metricLabelsAllowlist + metricAnnotationsAllowList: metricAnnotationsAllowList + } + } + : null } podIdentityProfile: { allowNetworkPluginKubenet: podIdentityProfileAllowNetworkPluginKubenet @@ -606,15 +688,19 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2023-07-02-p userAssignedIdentityExceptions: podIdentityProfileUserAssignedIdentityExceptions } securityProfile: { - defender: enableAzureDefender ? { - securityMonitoring: { - enabled: enableAzureDefender - } - logAnalyticsWorkspaceResourceId: monitoringWorkspaceId - } : null - workloadIdentity: enableWorkloadIdentity ? { - enabled: enableWorkloadIdentity - } : null + defender: enableAzureDefender + ? { + securityMonitoring: { + enabled: enableAzureDefender + } + logAnalyticsWorkspaceResourceId: monitoringWorkspaceId + } + : null + workloadIdentity: enableWorkloadIdentity + ? { + enabled: enableWorkloadIdentity + } + : null } storageProfile: { blobCSIDriver: { @@ -634,124 +720,151 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2023-07-02-p } } -module managedCluster_agentPools 'agent-pool/main.bicep' = [for (agentPool, index) in (agentPools ?? []): { - name: '${uniqueString(deployment().name, location)}-ManagedCluster-AgentPool-${index}' - params: { - managedClusterName: managedCluster.?name - name: agentPool.name - availabilityZones: agentPool.?availabilityZones - count: agentPool.?count - sourceResourceId: agentPool.?sourceResourceId - enableAutoScaling: agentPool.?enableAutoScaling - enableEncryptionAtHost: agentPool.?enableEncryptionAtHost - enableFIPS: agentPool.?enableFIPS - enableNodePublicIP: agentPool.?enableNodePublicIP - enableUltraSSD: agentPool.?enableUltraSSD - gpuInstanceProfile: agentPool.?gpuInstanceProfile - kubeletDiskType: agentPool.?kubeletDiskType - maxCount: agentPool.?maxCount - maxPods: agentPool.?maxPods - minCount: agentPool.?minCount - mode: agentPool.?mode - nodeLabels: agentPool.?nodeLabels - nodePublicIpPrefixId: agentPool.?nodePublicIpPrefixId - nodeTaints: agentPool.?nodeTaints - orchestratorVersion: agentPool.?orchestratorVersion ?? kubernetesVersion - osDiskSizeGB: agentPool.?osDiskSizeGB - osDiskType: agentPool.?osDiskType - osSku: agentPool.?osSku - osType: agentPool.?osType - podSubnetId: agentPool.?podSubnetId - proximityPlacementGroupResourceId: agentPool.?proximityPlacementGroupResourceId - scaleDownMode: agentPool.?scaleDownMode - scaleSetEvictionPolicy: agentPool.?scaleSetEvictionPolicy - scaleSetPriority: agentPool.?scaleSetPriority - spotMaxPrice: agentPool.?spotMaxPrice - tags: agentPool.?tags ?? tags - type: agentPool.?type - maxSurge: agentPool.?maxSurge - vmSize: agentPool.?vmSize - vnetSubnetId: agentPool.?vnetSubnetId - workloadRuntime: agentPool.?workloadRuntime +module managedCluster_agentPools 'agent-pool/main.bicep' = [ + for (agentPool, index) in (agentPools ?? []): { + name: '${uniqueString(deployment().name, location)}-ManagedCluster-AgentPool-${index}' + params: { + managedClusterName: managedCluster.?name + name: agentPool.name + availabilityZones: agentPool.?availabilityZones + count: agentPool.?count + sourceResourceId: agentPool.?sourceResourceId + enableAutoScaling: agentPool.?enableAutoScaling + enableEncryptionAtHost: agentPool.?enableEncryptionAtHost + enableFIPS: agentPool.?enableFIPS + enableNodePublicIP: agentPool.?enableNodePublicIP + enableUltraSSD: agentPool.?enableUltraSSD + gpuInstanceProfile: agentPool.?gpuInstanceProfile + kubeletDiskType: agentPool.?kubeletDiskType + maxCount: agentPool.?maxCount + maxPods: agentPool.?maxPods + minCount: agentPool.?minCount + mode: agentPool.?mode + nodeLabels: agentPool.?nodeLabels + nodePublicIpPrefixId: agentPool.?nodePublicIpPrefixId + nodeTaints: agentPool.?nodeTaints + orchestratorVersion: agentPool.?orchestratorVersion ?? kubernetesVersion + osDiskSizeGB: agentPool.?osDiskSizeGB + osDiskType: agentPool.?osDiskType + osSku: agentPool.?osSku + osType: agentPool.?osType + podSubnetId: agentPool.?podSubnetId + proximityPlacementGroupResourceId: agentPool.?proximityPlacementGroupResourceId + scaleDownMode: agentPool.?scaleDownMode + scaleSetEvictionPolicy: agentPool.?scaleSetEvictionPolicy + scaleSetPriority: agentPool.?scaleSetPriority + spotMaxPrice: agentPool.?spotMaxPrice + tags: agentPool.?tags ?? tags + type: agentPool.?type + maxSurge: agentPool.?maxSurge + vmSize: agentPool.?vmSize + vnetSubnetId: agentPool.?vnetSubnetId + workloadRuntime: agentPool.?workloadRuntime + } } -}] - -module managedCluster_extension 'br/public:avm/res/kubernetes-configuration/extension:0.2.0' = if (!empty(fluxExtension)) { - name: '${uniqueString(deployment().name, location)}-ManagedCluster-FluxExtension' - params: { - clusterName: managedCluster.name - configurationProtectedSettings: fluxExtension.?configurationProtectedSettings - configurationSettings: fluxExtension.?configurationSettings - enableTelemetry: enableTelemetry - extensionType: 'microsoft.flux' - fluxConfigurations: fluxExtension.?configurations - location: location - name: 'flux' - releaseNamespace: fluxExtension.?releaseNamespace ?? 'flux-system' - releaseTrain: fluxExtension.?releaseTrain ?? 'Stable' - version: fluxExtension.?version +] + +module managedCluster_extension 'br/public:avm/res/kubernetes-configuration/extension:0.2.0' = + if (!empty(fluxExtension)) { + name: '${uniqueString(deployment().name, location)}-ManagedCluster-FluxExtension' + params: { + clusterName: managedCluster.name + configurationProtectedSettings: fluxExtension.?configurationProtectedSettings + configurationSettings: fluxExtension.?configurationSettings + enableTelemetry: enableTelemetry + extensionType: 'microsoft.flux' + fluxConfigurations: fluxExtension.?configurations + location: location + name: 'flux' + releaseNamespace: fluxExtension.?releaseNamespace ?? 'flux-system' + releaseTrain: fluxExtension.?releaseTrain ?? 'Stable' + version: fluxExtension.?version + } } -} -resource managedCluster_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.' +resource managedCluster_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: managedCluster } - scope: managedCluster -} -resource managedCluster_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 - 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 +resource managedCluster_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 + 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 + } + scope: managedCluster } - scope: managedCluster -}] - -resource managedCluster_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(managedCluster.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 +] + +resource managedCluster_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(managedCluster.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: managedCluster } - scope: managedCluster -}] +] -resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = if (enableDnsZoneContributorRoleAssignment == true && dnsZoneResourceId != null && webApplicationRoutingEnabled) { - name: last(split((!empty(dnsZoneResourceId) ? any(dnsZoneResourceId) : '/dummmyZone'), '/'))! -} +resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = + if (enableDnsZoneContributorRoleAssignment == true && dnsZoneResourceId != null && webApplicationRoutingEnabled) { + name: last(split((!empty(dnsZoneResourceId) ? any(dnsZoneResourceId) : '/dummmyZone'), '/'))! + } -resource dnsZone_roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (enableDnsZoneContributorRoleAssignment == true && dnsZoneResourceId != null && webApplicationRoutingEnabled) { - name: guid(dnsZone.id, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314'), 'DNS Zone Contributor') - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314') // 'DNS Zone Contributor' - principalId: managedCluster.properties.ingressProfile.webAppRouting.identity.objectId - principalType: 'ServicePrincipal' +resource dnsZone_roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = + if (enableDnsZoneContributorRoleAssignment == true && dnsZoneResourceId != null && webApplicationRoutingEnabled) { + name: guid( + dnsZone.id, + subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314'), + 'DNS Zone Contributor' + ) + properties: { + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'befefa01-2a29-4197-83a8-272ff33ce314' + ) // 'DNS Zone Contributor' + principalId: managedCluster.properties.ingressProfile.webAppRouting.identity.objectId + principalType: 'ServicePrincipal' + } + scope: dnsZone } - scope: dnsZone -} @description('The resource ID of the managed cluster.') output resourceId string = managedCluster.id @@ -763,7 +876,9 @@ output resourceGroupName string = resourceGroup().name output name string = managedCluster.name @description('The control plane FQDN of the managed cluster.') -output controlPlaneFQDN string = enablePrivateCluster ? managedCluster.properties.privateFQDN : managedCluster.properties.fqdn +output controlPlaneFQDN string = enablePrivateCluster + ? managedCluster.properties.privateFQDN + : managedCluster.properties.fqdn @description('The principal ID of the system assigned identity.') output systemAssignedMIPrincipalId string = managedCluster.?identity.?principalId ?? '' diff --git a/avm/res/container-service/managed-cluster/main.json b/avm/res/container-service/managed-cluster/main.json index c5098ced93..38965b9632 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.25.53.49325", - "templateHash": "15404583857670962921" + "version": "0.26.54.24096", + "templateHash": "1556415774507310743" }, "name": "Azure Kubernetes Service (AKS) Managed Clusters", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster.", @@ -1862,8 +1862,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11449186283530676915" + "version": "0.26.54.24096", + "templateHash": "8772299678418708256" }, "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 813a8a74ba..e2274a7fbb 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 @@ -36,12 +36,15 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { addressPrefix ] } - subnets: map(range(0, 3), i => { + subnets: map( + range(0, 3), + i => { name: 'subnet-${i}' properties: { addressPrefix: cidrSubnet(addressPrefix, 24, i) } - }) + } + ) } } @@ -93,7 +96,10 @@ resource keyPermissionsKeyVaultCryptoUser 'Microsoft.Authorization/roleAssignmen scope: keyVault properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // KeyVault-Crypto-User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // KeyVault-Crypto-User principalType: 'ServicePrincipal' } } @@ -148,7 +154,10 @@ resource roleAssignmentKubeletIdentity 'Microsoft.Authorization/roleAssignments@ scope: managedIdentityKubeletIdentity properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f1a07417-d97a-45cb-824c-7a7467783830') // Managed Identity Operator Role used for Kubelet identity. + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f1a07417-d97a-45cb-824c-7a7467783830' + ) // Managed Identity Operator Role used for Kubelet identity. principalType: 'ServicePrincipal' } } diff --git a/avm/res/container-service/managed-cluster/tests/e2e/azure/main.test.bicep b/avm/res/container-service/managed-cluster/tests/e2e/azure/main.test.bicep index a2ee31ff00..618c2153ac 100644 --- a/avm/res/container-service/managed-cluster/tests/e2e/azure/main.test.bicep +++ b/avm/res/container-service/managed-cluster/tests/e2e/azure/main.test.bicep @@ -69,217 +69,222 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - primaryAgentPoolProfile: [ - { - availabilityZones: [ - '3' - ] - count: 1 - enableAutoScaling: true - maxCount: 3 - maxPods: 30 - minCount: 1 - mode: 'System' - name: 'systempool' - osDiskSizeGB: 0 - osType: 'Linux' - serviceCidr: '' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' - vnetSubnetID: nestedDependencies.outputs.subnetResourceIds[0] - } - ] - agentPools: [ - { - availabilityZones: [ - '3' - ] - count: 2 - enableAutoScaling: true - maxCount: 3 - maxPods: 30 - minCount: 1 - minPods: 2 - mode: 'User' - name: 'userpool1' - nodeLabels: {} - nodeTaints: [ - 'CriticalAddonsOnly=true:NoSchedule' - ] - osDiskSizeGB: 128 - osType: 'Linux' - scaleSetEvictionPolicy: 'Delete' - scaleSetPriority: 'Regular' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' - vnetSubnetID: nestedDependencies.outputs.subnetResourceIds[1] - proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId - } - { - availabilityZones: [ - '3' - ] - count: 2 - enableAutoScaling: true - maxCount: 3 - maxPods: 30 - minCount: 1 - minPods: 2 - mode: 'User' - name: 'userpool2' - nodeLabels: {} - nodeTaints: [ - 'CriticalAddonsOnly=true:NoSchedule' - ] - osDiskSizeGB: 128 - osType: 'Linux' - scaleSetEvictionPolicy: 'Delete' - scaleSetPriority: 'Regular' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' - vnetSubnetID: nestedDependencies.outputs.subnetResourceIds[2] - } - ] - autoUpgradeProfileUpgradeChannel: 'stable' - enableWorkloadIdentity: true - enableOidcIssuerProfile: true - networkPlugin: 'azure' - networkDataplane: 'azure' - networkPluginMode: 'overlay' - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - diskEncryptionSetResourceId: nestedDependencies.outputs.diskEncryptionSetResourceId - openServiceMeshEnabled: true - enableStorageProfileBlobCSIDriver: true - enableStorageProfileDiskCSIDriver: true - enableStorageProfileFileCSIDriver: true - enableStorageProfileSnapshotController: true - managedIdentities: { - userAssignedResourcesIds: [ - nestedDependencies.outputs.managedIdentityResourceId +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' + primaryAgentPoolProfile: [ + { + availabilityZones: [ + '3' + ] + count: 1 + enableAutoScaling: true + maxCount: 3 + maxPods: 30 + minCount: 1 + mode: 'System' + name: 'systempool' + osDiskSizeGB: 0 + osType: 'Linux' + serviceCidr: '' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + vnetSubnetID: nestedDependencies.outputs.subnetResourceIds[0] + } ] - } - identityProfile: { - kubeletidentity: { - resourceId: nestedDependencies.outputs.managedIdentityKubeletIdentityResourceId - } - } - omsAgentEnabled: true - monitoringWorkspaceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - enableAzureDefender: true - enableKeyvaultSecretsProvider: true - enablePodSecurityPolicy: false - enableAzureMonitorProfileMetrics: true - customerManagedKey: { - keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName - keyVaultNetworkAccess: 'Public' - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + agentPools: [ + { + availabilityZones: [ + '3' + ] + count: 2 + enableAutoScaling: true + maxCount: 3 + maxPods: 30 + minCount: 1 + minPods: 2 + mode: 'User' + name: 'userpool1' + nodeLabels: {} + nodeTaints: [ + 'CriticalAddonsOnly=true:NoSchedule' + ] + osDiskSizeGB: 128 + osType: 'Linux' + scaleSetEvictionPolicy: 'Delete' + scaleSetPriority: 'Regular' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + vnetSubnetID: nestedDependencies.outputs.subnetResourceIds[1] + proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId + } + { + availabilityZones: [ + '3' + ] + count: 2 + enableAutoScaling: true + maxCount: 3 + maxPods: 30 + minCount: 1 + minPods: 2 + mode: 'User' + name: 'userpool2' + nodeLabels: {} + nodeTaints: [ + 'CriticalAddonsOnly=true:NoSchedule' + ] + osDiskSizeGB: 128 + osType: 'Linux' + scaleSetEvictionPolicy: 'Delete' + scaleSetPriority: 'Regular' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + vnetSubnetID: nestedDependencies.outputs.subnetResourceIds[2] + } + ] + autoUpgradeProfileUpgradeChannel: 'stable' + enableWorkloadIdentity: true + enableOidcIssuerProfile: true + networkPlugin: 'azure' + networkDataplane: 'azure' + networkPluginMode: 'overlay' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + diskEncryptionSetResourceId: nestedDependencies.outputs.diskEncryptionSetResourceId + openServiceMeshEnabled: true + enableStorageProfileBlobCSIDriver: true + enableStorageProfileDiskCSIDriver: true + enableStorageProfileFileCSIDriver: true + enableStorageProfileSnapshotController: true + managedIdentities: { + userAssignedResourcesIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + identityProfile: { + kubeletidentity: { + resourceId: nestedDependencies.outputs.managedIdentityKubeletIdentityResourceId + } } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + omsAgentEnabled: true + monitoringWorkspaceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + enableAzureDefender: true + enableKeyvaultSecretsProvider: true + enablePodSecurityPolicy: false + enableAzureMonitorProfileMetrics: true + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName + keyVaultNetworkAccess: 'Public' + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - fluxExtension: { - configurationSettings: { - 'helm-controller.enabled': 'true' - 'source-controller.enabled': 'true' - 'kustomize-controller.enabled': 'true' - 'notification-controller.enabled': 'true' - 'image-automation-controller.enabled': 'false' - 'image-reflector-controller.enabled': 'false' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - configurations: [ + roleAssignments: [ { - namespace: 'flux-system' - scope: 'cluster' - gitRepository: { - repositoryRef: { - branch: 'main' - } - sshKnownHosts: '' - syncIntervalInSeconds: 300 - timeoutInSeconds: 180 - url: 'https://github.com/mspnp/aks-baseline' - } + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } { - namespace: 'flux-system-helm' - scope: 'cluster' - gitRepository: { - repositoryRef: { - branch: 'main' + 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' + } + fluxExtension: { + configurationSettings: { + 'helm-controller.enabled': 'true' + 'source-controller.enabled': 'true' + 'kustomize-controller.enabled': 'true' + 'notification-controller.enabled': 'true' + 'image-automation-controller.enabled': 'false' + 'image-reflector-controller.enabled': 'false' + } + configurations: [ + { + namespace: 'flux-system' + scope: 'cluster' + gitRepository: { + repositoryRef: { + branch: 'main' + } + sshKnownHosts: '' + syncIntervalInSeconds: 300 + timeoutInSeconds: 180 + url: 'https://github.com/mspnp/aks-baseline' } - sshKnownHosts: '' - syncIntervalInSeconds: 300 - timeoutInSeconds: 180 - url: 'https://github.com/Azure/gitops-flux2-kustomize-helm-mt' } - kustomizations: { - infra: { - path: './infrastructure' - dependsOn: [] - timeoutInSeconds: 600 - syncIntervalInSeconds: 600 - validation: 'none' - prune: true + { + namespace: 'flux-system-helm' + scope: 'cluster' + gitRepository: { + repositoryRef: { + branch: 'main' + } + sshKnownHosts: '' + syncIntervalInSeconds: 300 + timeoutInSeconds: 180 + url: 'https://github.com/Azure/gitops-flux2-kustomize-helm-mt' } - apps: { - path: './apps/staging' - dependsOn: [ - 'infra' - ] - timeoutInSeconds: 600 - syncIntervalInSeconds: 600 - retryIntervalInSeconds: 120 - prune: true + kustomizations: { + infra: { + path: './infrastructure' + dependsOn: [] + timeoutInSeconds: 600 + syncIntervalInSeconds: 600 + validation: 'none' + prune: true + } + apps: { + path: './apps/staging' + dependsOn: [ + 'infra' + ] + timeoutInSeconds: 600 + syncIntervalInSeconds: 600 + retryIntervalInSeconds: 120 + prune: true + } } } - } - ] + ] + } } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/container-service/managed-cluster/tests/e2e/defaults/main.test.bicep b/avm/res/container-service/managed-cluster/tests/e2e/defaults/main.test.bicep index b212dcf8f8..fbeddb2b7e 100644 --- a/avm/res/container-service/managed-cluster/tests/e2e/defaults/main.test.bicep +++ b/avm/res/container-service/managed-cluster/tests/e2e/defaults/main.test.bicep @@ -32,22 +32,24 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { } @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 - managedIdentities: { - systemAssigned: true - } - primaryAgentPoolProfile: [ - { - name: 'systempool' - count: 1 - vmSize: 'Standard_DS2_v2' - mode: 'System' +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 + managedIdentities: { + systemAssigned: true } - ] + primaryAgentPoolProfile: [ + { + name: 'systempool' + count: 1 + vmSize: 'Standard_DS2_v2' + mode: 'System' + } + ] + } } -}] +] diff --git a/avm/res/container-service/managed-cluster/tests/e2e/kubenet/dependencies.bicep b/avm/res/container-service/managed-cluster/tests/e2e/kubenet/dependencies.bicep index bcd58414ee..e564f5c4b6 100644 --- a/avm/res/container-service/managed-cluster/tests/e2e/kubenet/dependencies.bicep +++ b/avm/res/container-service/managed-cluster/tests/e2e/kubenet/dependencies.bicep @@ -8,13 +8,13 @@ param managedIdentityName string param dnsZoneName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' = { - name: dnsZoneName - location: 'global' + name: dnsZoneName + location: 'global' } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/container-service/managed-cluster/tests/e2e/kubenet/main.test.bicep b/avm/res/container-service/managed-cluster/tests/e2e/kubenet/main.test.bicep index ce9e1930c8..5b2adb181b 100644 --- a/avm/res/container-service/managed-cluster/tests/e2e/kubenet/main.test.bicep +++ b/avm/res/container-service/managed-cluster/tests/e2e/kubenet/main.test.bicep @@ -60,124 +60,129 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - primaryAgentPoolProfile: [ - { - availabilityZones: [ - '3' - ] - count: 1 - enableAutoScaling: true - maxCount: 3 - maxPods: 30 - minCount: 1 - mode: 'System' - name: 'systempool' - osDiskSizeGB: 0 - osType: 'Linux' - serviceCidr: '' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' - } - ] - agentPools: [ - { - availabilityZones: [ - '3' - ] - count: 2 - enableAutoScaling: true - maxCount: 3 - maxPods: 30 - minCount: 1 - minPods: 2 - mode: 'User' - name: 'userpool1' - nodeLabels: {} - nodeTaints: [ - 'CriticalAddonsOnly=true:NoSchedule' - ] - osDiskSizeGB: 128 - osType: 'Linux' - scaleSetEvictionPolicy: 'Delete' - scaleSetPriority: 'Regular' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' - } - { - availabilityZones: [ - '3' - ] - count: 2 - enableAutoScaling: true - maxCount: 3 - maxPods: 30 - minCount: 1 - minPods: 2 - mode: 'User' - name: 'userpool2' - nodeLabels: {} - nodeTaints: [ - 'CriticalAddonsOnly=true:NoSchedule' - ] - osDiskSizeGB: 128 - osType: 'Linux' - scaleSetEvictionPolicy: 'Delete' - scaleSetPriority: 'Regular' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' - } - ] - networkPlugin: 'kubenet' - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } +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 + primaryAgentPoolProfile: [ + { + availabilityZones: [ + '3' + ] + count: 1 + enableAutoScaling: true + maxCount: 3 + maxPods: 30 + minCount: 1 + mode: 'System' + name: 'systempool' + osDiskSizeGB: 0 + osType: 'Linux' + serviceCidr: '' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + } + ] + agentPools: [ + { + availabilityZones: [ + '3' + ] + count: 2 + enableAutoScaling: true + maxCount: 3 + maxPods: 30 + minCount: 1 + minPods: 2 + mode: 'User' + name: 'userpool1' + nodeLabels: {} + nodeTaints: [ + 'CriticalAddonsOnly=true:NoSchedule' + ] + osDiskSizeGB: 128 + osType: 'Linux' + scaleSetEvictionPolicy: 'Delete' + scaleSetPriority: 'Regular' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + } + { + availabilityZones: [ + '3' + ] + count: 2 + enableAutoScaling: true + maxCount: 3 + maxPods: 30 + minCount: 1 + minPods: 2 + mode: 'User' + name: 'userpool2' + nodeLabels: {} + nodeTaints: [ + 'CriticalAddonsOnly=true:NoSchedule' + ] + osDiskSizeGB: 128 + osType: 'Linux' + scaleSetEvictionPolicy: 'Delete' + scaleSetPriority: 'Regular' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + } + ] + networkPlugin: 'kubenet' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + 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' + } + ] + managedIdentities: { + userAssignedResourcesIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] - 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' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - managedIdentities: { - userAssignedResourcesIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/container-service/managed-cluster/tests/e2e/priv/dependencies.bicep b/avm/res/container-service/managed-cluster/tests/e2e/priv/dependencies.bicep index b74bb113ac..eab20c41e4 100644 --- a/avm/res/container-service/managed-cluster/tests/e2e/priv/dependencies.bicep +++ b/avm/res/container-service/managed-cluster/tests/e2e/priv/dependencies.bicep @@ -59,7 +59,10 @@ resource msiVnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04- scope: virtualNetwork properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') // Network Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4d97b98b-1d4f-4787-a291-c67834d212e7' + ) // Network Contributor principalType: 'ServicePrincipal' } } @@ -69,7 +72,10 @@ resource msiPrivDnsZoneRoleAssignment 'Microsoft.Authorization/roleAssignments@2 scope: privateDnsZone properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') // Private DNS Zone Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b12aa53e-6015-4669-85d0-8515ebb3ae7f' + ) // Private DNS Zone Contributor principalType: 'ServicePrincipal' } } diff --git a/avm/res/container-service/managed-cluster/tests/e2e/priv/main.test.bicep b/avm/res/container-service/managed-cluster/tests/e2e/priv/main.test.bicep index 57372d1425..4c6b264529 100644 --- a/avm/res/container-service/managed-cluster/tests/e2e/priv/main.test.bicep +++ b/avm/res/container-service/managed-cluster/tests/e2e/priv/main.test.bicep @@ -47,94 +47,96 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - enablePrivateCluster: true - primaryAgentPoolProfile: [ - { - availabilityZones: [ - '3' - ] - count: 1 - enableAutoScaling: true - maxCount: 3 - maxPods: 30 - minCount: 1 - mode: 'System' - name: 'systempool' - osDiskSizeGB: 0 - osType: 'Linux' - serviceCidr: '' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' - vnetSubnetID: '${nestedDependencies.outputs.vNetResourceId}/subnets/defaultSubnet' - } - ] - agentPools: [ - { - availabilityZones: [ - '3' - ] - count: 2 - enableAutoScaling: true - maxCount: 3 - maxPods: 30 - minCount: 1 - minPods: 2 - mode: 'User' - name: 'userpool1' - nodeLabels: {} - nodeTaints: [ - 'CriticalAddonsOnly=true:NoSchedule' - ] - osDiskSizeGB: 128 - osType: 'Linux' - scaleSetEvictionPolicy: 'Delete' - scaleSetPriority: 'Regular' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' - vnetSubnetID: '${nestedDependencies.outputs.vNetResourceId}/subnets/defaultSubnet' - } - { - availabilityZones: [ - '3' - ] - count: 2 - enableAutoScaling: true - maxCount: 3 - maxPods: 30 - minCount: 1 - minPods: 2 - mode: 'User' - name: 'userpool2' - nodeLabels: {} - nodeTaints: [ - 'CriticalAddonsOnly=true:NoSchedule' +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 + enablePrivateCluster: true + primaryAgentPoolProfile: [ + { + availabilityZones: [ + '3' + ] + count: 1 + enableAutoScaling: true + maxCount: 3 + maxPods: 30 + minCount: 1 + mode: 'System' + name: 'systempool' + osDiskSizeGB: 0 + osType: 'Linux' + serviceCidr: '' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + vnetSubnetID: '${nestedDependencies.outputs.vNetResourceId}/subnets/defaultSubnet' + } + ] + agentPools: [ + { + availabilityZones: [ + '3' + ] + count: 2 + enableAutoScaling: true + maxCount: 3 + maxPods: 30 + minCount: 1 + minPods: 2 + mode: 'User' + name: 'userpool1' + nodeLabels: {} + nodeTaints: [ + 'CriticalAddonsOnly=true:NoSchedule' + ] + osDiskSizeGB: 128 + osType: 'Linux' + scaleSetEvictionPolicy: 'Delete' + scaleSetPriority: 'Regular' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + vnetSubnetID: '${nestedDependencies.outputs.vNetResourceId}/subnets/defaultSubnet' + } + { + availabilityZones: [ + '3' + ] + count: 2 + enableAutoScaling: true + maxCount: 3 + maxPods: 30 + minCount: 1 + minPods: 2 + mode: 'User' + name: 'userpool2' + nodeLabels: {} + nodeTaints: [ + 'CriticalAddonsOnly=true:NoSchedule' + ] + osDiskSizeGB: 128 + osType: 'Linux' + scaleSetEvictionPolicy: 'Delete' + scaleSetPriority: 'Regular' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + } + ] + networkPlugin: 'azure' + skuTier: 'Standard' + dnsServiceIP: '10.10.200.10' + serviceCidr: '10.10.200.0/24' + privateDNSZone: nestedDependencies.outputs.privateDnsZoneResourceId + managedIdentities: { + userAssignedResourcesIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] - osDiskSizeGB: 128 - osType: 'Linux' - scaleSetEvictionPolicy: 'Delete' - scaleSetPriority: 'Regular' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' } - ] - networkPlugin: 'azure' - skuTier: 'Standard' - dnsServiceIP: '10.10.200.10' - serviceCidr: '10.10.200.0/24' - privateDNSZone: nestedDependencies.outputs.privateDnsZoneResourceId - managedIdentities: { - userAssignedResourcesIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/container-service/managed-cluster/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/container-service/managed-cluster/tests/e2e/waf-aligned/dependencies.bicep index b74bb113ac..eab20c41e4 100644 --- a/avm/res/container-service/managed-cluster/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/container-service/managed-cluster/tests/e2e/waf-aligned/dependencies.bicep @@ -59,7 +59,10 @@ resource msiVnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04- scope: virtualNetwork properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') // Network Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4d97b98b-1d4f-4787-a291-c67834d212e7' + ) // Network Contributor principalType: 'ServicePrincipal' } } @@ -69,7 +72,10 @@ resource msiPrivDnsZoneRoleAssignment 'Microsoft.Authorization/roleAssignments@2 scope: privateDnsZone properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') // Private DNS Zone Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b12aa53e-6015-4669-85d0-8515ebb3ae7f' + ) // Private DNS Zone Contributor principalType: 'ServicePrincipal' } } diff --git a/avm/res/container-service/managed-cluster/tests/e2e/waf-aligned/main.test.bicep b/avm/res/container-service/managed-cluster/tests/e2e/waf-aligned/main.test.bicep index 98b0174d2d..0c67fcdcb0 100644 --- a/avm/res/container-service/managed-cluster/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/container-service/managed-cluster/tests/e2e/waf-aligned/main.test.bicep @@ -63,136 +63,138 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - enablePrivateCluster: true - primaryAgentPoolProfile: [ - { - availabilityZones: [ - '3' - ] - count: 3 - enableAutoScaling: true - maxCount: 3 - maxPods: 50 - minCount: 1 - mode: 'System' - name: 'systempool' - osDiskSizeGB: 0 - osType: 'Linux' - serviceCidr: '' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' - vnetSubnetID: '${nestedDependencies.outputs.vNetResourceId}/subnets/defaultSubnet' - } - ] - agentPools: [ - { - availabilityZones: [ - '3' - ] - count: 2 - enableAutoScaling: true - maxCount: 3 - maxPods: 50 - minCount: 1 - minPods: 2 - mode: 'User' - name: 'userpool1' - nodeLabels: {} - nodeTaints: [ - 'CriticalAddonsOnly=true:NoSchedule' - ] - osDiskType: 'Ephemeral' - osDiskSizeGB: 60 - osType: 'Linux' - scaleSetEvictionPolicy: 'Delete' - scaleSetPriority: 'Regular' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' - vnetSubnetID: '${nestedDependencies.outputs.vNetResourceId}/subnets/defaultSubnet' - } - { - availabilityZones: [ - '3' - ] - count: 2 - enableAutoScaling: true - maxCount: 3 - maxPods: 50 - minCount: 1 - minPods: 2 - mode: 'User' - name: 'userpool2' - nodeLabels: {} - nodeTaints: [ - 'CriticalAddonsOnly=true:NoSchedule' +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 + enablePrivateCluster: true + primaryAgentPoolProfile: [ + { + availabilityZones: [ + '3' + ] + count: 3 + enableAutoScaling: true + maxCount: 3 + maxPods: 50 + minCount: 1 + mode: 'System' + name: 'systempool' + osDiskSizeGB: 0 + osType: 'Linux' + serviceCidr: '' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + vnetSubnetID: '${nestedDependencies.outputs.vNetResourceId}/subnets/defaultSubnet' + } + ] + agentPools: [ + { + availabilityZones: [ + '3' + ] + count: 2 + enableAutoScaling: true + maxCount: 3 + maxPods: 50 + minCount: 1 + minPods: 2 + mode: 'User' + name: 'userpool1' + nodeLabels: {} + nodeTaints: [ + 'CriticalAddonsOnly=true:NoSchedule' + ] + osDiskType: 'Ephemeral' + osDiskSizeGB: 60 + osType: 'Linux' + scaleSetEvictionPolicy: 'Delete' + scaleSetPriority: 'Regular' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + vnetSubnetID: '${nestedDependencies.outputs.vNetResourceId}/subnets/defaultSubnet' + } + { + availabilityZones: [ + '3' + ] + count: 2 + enableAutoScaling: true + maxCount: 3 + maxPods: 50 + minCount: 1 + minPods: 2 + mode: 'User' + name: 'userpool2' + nodeLabels: {} + nodeTaints: [ + 'CriticalAddonsOnly=true:NoSchedule' + ] + osDiskType: 'Ephemeral' + osDiskSizeGB: 60 + osType: 'Linux' + scaleSetEvictionPolicy: 'Delete' + scaleSetPriority: 'Regular' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_DS2_v2' + } + ] + autoUpgradeProfileUpgradeChannel: 'stable' + networkPlugin: 'azure' + networkPolicy: 'azure' + skuTier: 'Standard' + dnsServiceIP: '10.10.200.10' + serviceCidr: '10.10.200.0/24' + omsAgentEnabled: true + monitoringWorkspaceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + disableLocalAccounts: true + enableAzureDefender: true + diagnosticSettings: [ + { + name: 'customSetting' + logCategoriesAndGroups: [ + { + category: 'kube-apiserver' + } + { + category: 'kube-controller-manager' + } + { + category: 'kube-scheduler' + } + { + category: 'cluster-autoscaler' + } + ] + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + privateDNSZone: nestedDependencies.outputs.privateDnsZoneResourceId + managedIdentities: { + userAssignedResourcesIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] - osDiskType: 'Ephemeral' - osDiskSizeGB: 60 - osType: 'Linux' - scaleSetEvictionPolicy: 'Delete' - scaleSetPriority: 'Regular' - type: 'VirtualMachineScaleSets' - vmSize: 'Standard_DS2_v2' } - ] - autoUpgradeProfileUpgradeChannel: 'stable' - networkPlugin: 'azure' - networkPolicy: 'azure' - skuTier: 'Standard' - dnsServiceIP: '10.10.200.10' - serviceCidr: '10.10.200.0/24' - omsAgentEnabled: true - monitoringWorkspaceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - disableLocalAccounts: true - enableAzureDefender: true - diagnosticSettings: [ - { - name: 'customSetting' - logCategoriesAndGroups: [ - { - category: 'kube-apiserver' - } - { - category: 'kube-controller-manager' - } - { - category: 'kube-scheduler' - } - { - category: 'cluster-autoscaler' - } - ] - metricCategories: [ - { - category: 'AllMetrics' - } - ] - 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' } - ] - privateDNSZone: nestedDependencies.outputs.privateDnsZoneResourceId - managedIdentities: { - userAssignedResourcesIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] 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 052a79bdb4..4590e10872 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.25.53.49325", - "templateHash": "3601741933922377880" + "version": "0.26.54.24096", + "templateHash": "11424915933898928003" }, "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.bicep b/avm/res/data-protection/backup-vault/main.bicep index 48648bcf2b..3c8a00201d 100644 --- a/avm/res/data-protection/backup-vault/main.bicep +++ b/avm/res/data-protection/backup-vault/main.bicep @@ -55,38 +55,56 @@ param securitySettings object = {} @description('Optional. Feature settings for the backup vault.') param featureSettings object = {} -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? 'SystemAssigned' : null -} : null +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) ? 'SystemAssigned' : null + } + : null var builtInRoleNames = { - 'Backup Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b') - 'Backup Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324') - 'Backup Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a795c7a0-d4a2-40c1-ae25-d81f01202912') + 'Backup Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '5e467623-bb1f-42f4-a55d-6e525e11384b' + ) + 'Backup Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '00c29273-979b-4161-815c-10b084fb9324' + ) + 'Backup Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a795c7a0-d4a2-40c1-ae25-d81f01202912' + ) 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') + '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.dataprotection-backupvault.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.dataprotection-backupvault.${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 backupVault 'Microsoft.DataProtection/backupVaults@2023-05-01' = { name: name @@ -110,37 +128,48 @@ resource backupVault 'Microsoft.DataProtection/backupVaults@2023-05-01' = { } } -module backupVault_backupPolicies 'backup-policy/main.bicep' = [for (backupPolicy, index) in backupPolicies: { - name: '${uniqueString(deployment().name, location)}-BV-BackupPolicy-${index}' - params: { - backupVaultName: backupVault.name - name: backupPolicy.name - properties: backupPolicy.properties +module backupVault_backupPolicies 'backup-policy/main.bicep' = [ + for (backupPolicy, index) in backupPolicies: { + name: '${uniqueString(deployment().name, location)}-BV-BackupPolicy-${index}' + params: { + backupVaultName: backupVault.name + name: backupPolicy.name + properties: backupPolicy.properties + } } -}] - -resource backupVault_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.' +] + +resource backupVault_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: backupVault } - scope: backupVault -} -resource backupVault_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(backupVault.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 +resource backupVault_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(backupVault.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: backupVault } - scope: backupVault -}] +] @description('The resource ID of the backup vault.') output resourceId string = backupVault.id diff --git a/avm/res/data-protection/backup-vault/main.json b/avm/res/data-protection/backup-vault/main.json index c43d9cb3c2..47ec72bf63 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.25.53.49325", - "templateHash": "11297894401927654762" + "version": "0.26.54.24096", + "templateHash": "17999944940585257784" }, "name": "Data Protection Backup Vaults", "description": "This module deploys a Data Protection Backup Vault.", @@ -344,8 +344,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3601741933922377880" + "version": "0.26.54.24096", + "templateHash": "11424915933898928003" }, "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/tests/e2e/defaults/main.test.bicep b/avm/res/data-protection/backup-vault/tests/e2e/defaults/main.test.bicep index c908151dba..9021d7db82 100644 --- a/avm/res/data-protection/backup-vault/tests/e2e/defaults/main.test.bicep +++ b/avm/res/data-protection/backup-vault/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/data-protection/backup-vault/tests/e2e/max/dependencies.bicep b/avm/res/data-protection/backup-vault/tests/e2e/max/dependencies.bicep index 0f0755a6f4..0b7f226c1a 100644 --- a/avm/res/data-protection/backup-vault/tests/e2e/max/dependencies.bicep +++ b/avm/res/data-protection/backup-vault/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/data-protection/backup-vault/tests/e2e/max/main.test.bicep b/avm/res/data-protection/backup-vault/tests/e2e/max/main.test.bicep index fb264e4ff2..dea4591b1c 100644 --- a/avm/res/data-protection/backup-vault/tests/e2e/max/main.test.bicep +++ b/avm/res/data-protection/backup-vault/tests/e2e/max/main.test.bicep @@ -45,106 +45,111 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - 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' +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 + 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' + } + ] + azureMonitorAlertSettingsAlertsForAllJobFailures: 'Disabled' + managedIdentities: { + systemAssigned: true } - ] - azureMonitorAlertSettingsAlertsForAllJobFailures: 'Disabled' - managedIdentities: { - systemAssigned: true - } - backupPolicies: [ - { - name: 'DefaultPolicy' - properties: { - datasourceTypes: [ - 'Microsoft.Compute/disks' - ] - objectType: 'BackupPolicy' - policyRules: [ - { - backupParameters: { - backupType: 'Incremental' - objectType: 'AzureBackupParams' - } - dataStore: { - dataStoreType: 'OperationalStore' - objectType: 'DataStoreInfoBase' - } - name: 'BackupDaily' - objectType: 'AzureBackupRule' - trigger: { - objectType: 'ScheduleBasedTriggerContext' - schedule: { - repeatingTimeIntervals: [ - 'R/2022-05-31T23:30:00+01:00/P1D' + backupPolicies: [ + { + name: 'DefaultPolicy' + properties: { + datasourceTypes: [ + 'Microsoft.Compute/disks' + ] + objectType: 'BackupPolicy' + policyRules: [ + { + backupParameters: { + backupType: 'Incremental' + objectType: 'AzureBackupParams' + } + dataStore: { + dataStoreType: 'OperationalStore' + objectType: 'DataStoreInfoBase' + } + name: 'BackupDaily' + objectType: 'AzureBackupRule' + trigger: { + objectType: 'ScheduleBasedTriggerContext' + schedule: { + repeatingTimeIntervals: [ + 'R/2022-05-31T23:30:00+01:00/P1D' + ] + timeZone: 'W. Europe Standard Time' + } + taggingCriteria: [ + { + isDefault: true + taggingPriority: 99 + tagInfo: { + id: 'Default_' + tagName: 'Default' + } + } ] - timeZone: 'W. Europe Standard Time' } - taggingCriteria: [ + } + { + isDefault: true + lifecycles: [ { - isDefault: true - taggingPriority: 99 - tagInfo: { - id: 'Default_' - tagName: 'Default' + deleteAfter: { + duration: 'P7D' + objectType: 'AbsoluteDeleteOption' + } + sourceDataStore: { + dataStoreType: 'OperationalStore' + objectType: 'DataStoreInfoBase' } + targetDataStoreCopySettings: [] } ] + name: 'Default' + objectType: 'AzureRetentionRule' } - } - { - isDefault: true - lifecycles: [ - { - deleteAfter: { - duration: 'P7D' - objectType: 'AbsoluteDeleteOption' - } - sourceDataStore: { - dataStoreType: 'OperationalStore' - objectType: 'DataStoreInfoBase' - } - targetDataStoreCopySettings: [] - } - ] - name: 'Default' - objectType: 'AzureRetentionRule' - } - ] + ] + } } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/data-protection/backup-vault/tests/e2e/waf-aligned/main.test.bicep b/avm/res/data-protection/backup-vault/tests/e2e/waf-aligned/main.test.bicep index 1bc01850e2..fd6fdf9a58 100644 --- a/avm/res/data-protection/backup-vault/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/data-protection/backup-vault/tests/e2e/waf-aligned/main.test.bicep @@ -36,86 +36,88 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - azureMonitorAlertSettingsAlertsForAllJobFailures: 'Disabled' - managedIdentities: { - systemAssigned: true - } - backupPolicies: [ - { - name: 'DefaultPolicy' - properties: { - datasourceTypes: [ - 'Microsoft.Compute/disks' - ] - objectType: 'BackupPolicy' - policyRules: [ - { - backupParameters: { - backupType: 'Incremental' - objectType: 'AzureBackupParams' - } - dataStore: { - dataStoreType: 'OperationalStore' - objectType: 'DataStoreInfoBase' - } - name: 'BackupDaily' - objectType: 'AzureBackupRule' - trigger: { - objectType: 'ScheduleBasedTriggerContext' - schedule: { - repeatingTimeIntervals: [ - 'R/2022-05-31T23:30:00+01:00/P1D' +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 + azureMonitorAlertSettingsAlertsForAllJobFailures: 'Disabled' + managedIdentities: { + systemAssigned: true + } + backupPolicies: [ + { + name: 'DefaultPolicy' + properties: { + datasourceTypes: [ + 'Microsoft.Compute/disks' + ] + objectType: 'BackupPolicy' + policyRules: [ + { + backupParameters: { + backupType: 'Incremental' + objectType: 'AzureBackupParams' + } + dataStore: { + dataStoreType: 'OperationalStore' + objectType: 'DataStoreInfoBase' + } + name: 'BackupDaily' + objectType: 'AzureBackupRule' + trigger: { + objectType: 'ScheduleBasedTriggerContext' + schedule: { + repeatingTimeIntervals: [ + 'R/2022-05-31T23:30:00+01:00/P1D' + ] + timeZone: 'W. Europe Standard Time' + } + taggingCriteria: [ + { + isDefault: true + taggingPriority: 99 + tagInfo: { + id: 'Default_' + tagName: 'Default' + } + } ] - timeZone: 'W. Europe Standard Time' } - taggingCriteria: [ + } + { + isDefault: true + lifecycles: [ { - isDefault: true - taggingPriority: 99 - tagInfo: { - id: 'Default_' - tagName: 'Default' + deleteAfter: { + duration: 'P7D' + objectType: 'AbsoluteDeleteOption' + } + sourceDataStore: { + dataStoreType: 'OperationalStore' + objectType: 'DataStoreInfoBase' } + targetDataStoreCopySettings: [] } ] + name: 'Default' + objectType: 'AzureRetentionRule' } - } - { - isDefault: true - lifecycles: [ - { - deleteAfter: { - duration: 'P7D' - objectType: 'AbsoluteDeleteOption' - } - sourceDataStore: { - dataStoreType: 'OperationalStore' - objectType: 'DataStoreInfoBase' - } - targetDataStoreCopySettings: [] - } - ] - name: 'Default' - objectType: 'AzureRetentionRule' - } - ] + ] + } } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] 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 5480bf8dab..e4df947daa 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.25.53.49325", - "templateHash": "9797360516324373554" + "version": "0.26.54.24096", + "templateHash": "2817201491275445304" }, "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 96c3f0eeda..77895b3ecb 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.25.53.49325", - "templateHash": "1786501395002693358" + "version": "0.26.54.24096", + "templateHash": "9734848552595709363" }, "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 c4ec0e06bc..70bdf3643c 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.25.53.49325", - "templateHash": "1600222376229916804" + "version": "0.26.54.24096", + "templateHash": "2931317814738693960" }, "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 9d0bb2c610..a0e0389dd2 100644 --- a/avm/res/db-for-my-sql/flexible-server/main.bicep +++ b/avm/res/db-for-my-sql/flexible-server/main.bicep @@ -162,67 +162,101 @@ param diagnosticSettings diagnosticSettingType @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: !empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: !empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'MySQL Backup And Export Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd18ad5f3-1baf-4119-b49b-d944edb1f9d0') + 'MySQL Backup And Export Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd18ad5f3-1baf-4119-b49b-d944edb1f9d0' + ) 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') + '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.dbformysql-flexibleserver.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.dbformysql-flexibleserver.${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 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 cMKGeoKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = if (!empty(customerManagedKeyGeo.?keyVaultResourceId)) { - name: last(split((customerManagedKeyGeo.?keyVaultResourceId ?? 'dummyVault'), '/')) - scope: resourceGroup(split((customerManagedKeyGeo.?keyVaultResourceId ?? '//'), '/')[2], split((customerManagedKeyGeo.?keyVaultResourceId ?? '////'), '/')[4]) +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 cMKKey 'keys@2023-02-01' existing = if (!empty(customerManagedKeyGeo.?keyVaultResourceId) && !empty(customerManagedKeyGeo.?keyName)) { - name: customerManagedKeyGeo.?keyName ?? 'dummyKey' +resource cMKGeoKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = + if (!empty(customerManagedKeyGeo.?keyVaultResourceId)) { + name: last(split((customerManagedKeyGeo.?keyVaultResourceId ?? 'dummyVault'), '/')) + scope: resourceGroup( + split((customerManagedKeyGeo.?keyVaultResourceId ?? '//'), '/')[2], + split((customerManagedKeyGeo.?keyVaultResourceId ?? '////'), '/')[4] + ) + + resource cMKKey 'keys@2023-02-01' existing = + if (!empty(customerManagedKeyGeo.?keyVaultResourceId) && !empty(customerManagedKeyGeo.?keyName)) { + name: customerManagedKeyGeo.?keyName ?? 'dummyKey' + } } -} -resource cMKGeoUserAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = if (!empty(customerManagedKeyGeo.?userAssignedIdentityResourceId)) { - name: last(split(customerManagedKeyGeo.?userAssignedIdentityResourceId ?? 'dummyMsi', '/')) - scope: resourceGroup(split((customerManagedKeyGeo.?userAssignedIdentityResourceId ?? '//'), '/')[2], split((customerManagedKeyGeo.?userAssignedIdentityResourceId ?? '////'), '/')[4]) -} +resource cMKGeoUserAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = + if (!empty(customerManagedKeyGeo.?userAssignedIdentityResourceId)) { + name: last(split(customerManagedKeyGeo.?userAssignedIdentityResourceId ?? 'dummyMsi', '/')) + scope: resourceGroup( + split((customerManagedKeyGeo.?userAssignedIdentityResourceId ?? '//'), '/')[2], + split((customerManagedKeyGeo.?userAssignedIdentityResourceId ?? '////'), '/')[4] + ) + } resource flexibleServer 'Microsoft.DBforMySQL/flexibleServers@2022-09-30-preview' = { name: name @@ -242,27 +276,39 @@ resource flexibleServer 'Microsoft.DBforMySQL/flexibleServers@2022-09-30-preview geoRedundantBackup: geoRedundantBackup } createMode: createMode - dataEncryption: !empty(customerManagedKey) ? { - type: 'AzureKeyVault' - geoBackupKeyURI: geoRedundantBackup == 'Enabled' ? (!empty(customerManagedKeyGeo.?keyVersion ?? '') ? '${cMKGeoKeyVault::cMKKey.properties.keyUri}/${customerManagedKeyGeo!.keyVersion}' : cMKGeoKeyVault::cMKKey.properties.keyUriWithVersion) : null - geoBackupUserAssignedIdentityId: geoRedundantBackup == 'Enabled' ? cMKGeoUserAssignedIdentity.id : null - primaryKeyURI: !empty(customerManagedKey.?keyVersion ?? '') ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.keyVersion}' : cMKKeyVault::cMKKey.properties.keyUriWithVersion - primaryUserAssignedIdentityId: cMKUserAssignedIdentity.id - } : null + dataEncryption: !empty(customerManagedKey) + ? { + type: 'AzureKeyVault' + geoBackupKeyURI: geoRedundantBackup == 'Enabled' + ? (!empty(customerManagedKeyGeo.?keyVersion ?? '') + ? '${cMKGeoKeyVault::cMKKey.properties.keyUri}/${customerManagedKeyGeo!.keyVersion}' + : cMKGeoKeyVault::cMKKey.properties.keyUriWithVersion) + : null + geoBackupUserAssignedIdentityId: geoRedundantBackup == 'Enabled' ? cMKGeoUserAssignedIdentity.id : null + primaryKeyURI: !empty(customerManagedKey.?keyVersion ?? '') + ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.keyVersion}' + : cMKKeyVault::cMKKey.properties.keyUriWithVersion + primaryUserAssignedIdentityId: cMKUserAssignedIdentity.id + } + : null highAvailability: { mode: highAvailability standbyAvailabilityZone: highAvailability == 'SameZone' ? availabilityZone : null } - maintenanceWindow: !empty(maintenanceWindow) ? { - customWindow: maintenanceWindow.customWindow - dayOfWeek: maintenanceWindow.customWindow == 'Enabled' ? maintenanceWindow.dayOfWeek : 0 - startHour: maintenanceWindow.customWindow == 'Enabled' ? maintenanceWindow.startHour : 0 - startMinute: maintenanceWindow.customWindow == 'Enabled' ? maintenanceWindow.startMinute : 0 - } : null - network: !empty(delegatedSubnetResourceId) && empty(firewallRules) ? { - delegatedSubnetResourceId: delegatedSubnetResourceId - privateDnsZoneResourceId: privateDnsZoneResourceId - } : null + maintenanceWindow: !empty(maintenanceWindow) + ? { + customWindow: maintenanceWindow.customWindow + dayOfWeek: maintenanceWindow.customWindow == 'Enabled' ? maintenanceWindow.dayOfWeek : 0 + startHour: maintenanceWindow.customWindow == 'Enabled' ? maintenanceWindow.startHour : 0 + startMinute: maintenanceWindow.customWindow == 'Enabled' ? maintenanceWindow.startMinute : 0 + } + : null + network: !empty(delegatedSubnetResourceId) && empty(firewallRules) + ? { + delegatedSubnetResourceId: delegatedSubnetResourceId + privateDnsZoneResourceId: privateDnsZoneResourceId + } + : null replicationRole: replicationRole restorePointInTime: restorePointInTime sourceServerResourceId: !empty(sourceServerResourceId) ? sourceServerResourceId : null @@ -276,82 +322,103 @@ resource flexibleServer 'Microsoft.DBforMySQL/flexibleServers@2022-09-30-preview } } -resource flexibleServer_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.' +resource flexibleServer_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: flexibleServer } - scope: flexibleServer -} -resource flexibleServer_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(flexibleServer.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 +resource flexibleServer_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(flexibleServer.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: flexibleServer } - scope: flexibleServer -}] - -module flexibleServer_databases 'database/main.bicep' = [for (database, index) in databases: { - name: '${uniqueString(deployment().name, location)}-MySQL-DB-${index}' - params: { - name: database.name - flexibleServerName: flexibleServer.name - collation: contains(database, 'collation') ? database.collation : '' - charset: contains(database, 'charset') ? database.charset : '' +] + +module flexibleServer_databases 'database/main.bicep' = [ + for (database, index) in databases: { + name: '${uniqueString(deployment().name, location)}-MySQL-DB-${index}' + params: { + name: database.name + flexibleServerName: flexibleServer.name + collation: contains(database, 'collation') ? database.collation : '' + charset: contains(database, 'charset') ? database.charset : '' + } } -}] - -module flexibleServer_firewallRules 'firewall-rule/main.bicep' = [for (firewallRule, index) in firewallRules: { - name: '${uniqueString(deployment().name, location)}-MySQL-FirewallRules-${index}' - params: { - name: firewallRule.name - flexibleServerName: flexibleServer.name - startIpAddress: firewallRule.startIpAddress - endIpAddress: firewallRule.endIpAddress +] + +module flexibleServer_firewallRules 'firewall-rule/main.bicep' = [ + for (firewallRule, index) in firewallRules: { + name: '${uniqueString(deployment().name, location)}-MySQL-FirewallRules-${index}' + params: { + name: firewallRule.name + flexibleServerName: flexibleServer.name + startIpAddress: firewallRule.startIpAddress + endIpAddress: firewallRule.endIpAddress + } } -}] - -module flexibleServer_administrators 'administrator/main.bicep' = [for (administrator, index) in administrators: { - name: '${uniqueString(deployment().name, location)}-MySQL-Administrators-${index}' - params: { - flexibleServerName: flexibleServer.name - login: administrator.login - sid: administrator.sid - identityResourceId: administrator.identityResourceId - tenantId: contains(administrator, 'tenantId') ? administrator.tenantId : tenant().tenantId +] + +module flexibleServer_administrators 'administrator/main.bicep' = [ + for (administrator, index) in administrators: { + name: '${uniqueString(deployment().name, location)}-MySQL-Administrators-${index}' + params: { + flexibleServerName: flexibleServer.name + login: administrator.login + sid: administrator.sid + identityResourceId: administrator.identityResourceId + tenantId: contains(administrator, 'tenantId') ? administrator.tenantId : tenant().tenantId + } } -}] - -resource flexibleServer_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 - 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 +] + +resource flexibleServer_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 + 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 + } + scope: flexibleServer } - scope: flexibleServer -}] +] @description('The name of the deployed MySQL Flexible server.') output name string = flexibleServer.name diff --git a/avm/res/db-for-my-sql/flexible-server/tests/e2e/defaults/main.test.bicep b/avm/res/db-for-my-sql/flexible-server/tests/e2e/defaults/main.test.bicep index d13a62288a..8412371c66 100644 --- a/avm/res/db-for-my-sql/flexible-server/tests/e2e/defaults/main.test.bicep +++ b/avm/res/db-for-my-sql/flexible-server/tests/e2e/defaults/main.test.bicep @@ -40,15 +40,17 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { // ============== // @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 - administratorLogin: 'adminUserName' - administratorLoginPassword: password - skuName: 'Standard_B1ms' - tier: 'Burstable' +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 + administratorLogin: 'adminUserName' + administratorLoginPassword: password + skuName: 'Standard_B1ms' + tier: 'Burstable' + } } -}] +] diff --git a/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/dependencies1.bicep b/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/dependencies1.bicep index c1ed5dfa4c..4c1716bb23 100644 --- a/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/dependencies1.bicep +++ b/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/dependencies1.bicep @@ -8,38 +8,41 @@ param managedIdentityName string param pairedRegionScriptName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${location}-${managedIdentity.id}-Reader-RoleAssignment') - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') // Reader - principalType: 'ServicePrincipal' - } + name: guid('msi-${location}-${managedIdentity.id}-Reader-RoleAssignment') + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) // Reader + principalType: 'ServicePrincipal' + } } resource getPairedRegionScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: pairedRegionScriptName - location: location - kind: 'AzurePowerShell' - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - azPowerShellVersion: '8.0' - retentionInterval: 'P1D' - arguments: '-Location \\"${location}\\"' - scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Get-PairedRegion.ps1') + name: pairedRegionScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} } - dependsOn: [ - roleAssignment - ] + } + properties: { + azPowerShellVersion: '8.0' + retentionInterval: 'P1D' + arguments: '-Location \\"${location}\\"' + scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Get-PairedRegion.ps1') + } + dependsOn: [ + roleAssignment + ] } @description('The name of the paired region.') diff --git a/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/dependencies2.bicep b/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/dependencies2.bicep index 258d087ade..0077f627ce 100644 --- a/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/dependencies2.bicep +++ b/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/dependencies2.bicep @@ -17,85 +17,91 @@ param geoBackupManagedIdentityName string param geoBackupLocation string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } resource keyVault 'Microsoft.KeyVault/vaults@2023-02-01' = { - name: keyVaultName - location: location - properties: { - sku: { - family: 'A' - name: 'standard' - } - tenantId: tenant().tenantId - enablePurgeProtection: true - softDeleteRetentionInDays: 90 - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: true - accessPolicies: [] + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' } - - resource key 'keys@2023-02-01' = { - name: 'keyEncryptionKey' - properties: { - kty: 'RSA' - } + tenantId: tenant().tenantId + enablePurgeProtection: true + softDeleteRetentionInDays: 90 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2023-02-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' - } + 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 geoBackupManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: geoBackupManagedIdentityName - location: geoBackupLocation + name: geoBackupManagedIdentityName + location: geoBackupLocation } resource geoBackupKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' = { - name: geoBackupKeyVaultName - location: geoBackupLocation - properties: { - sku: { - family: 'A' - name: 'standard' - } - tenantId: tenant().tenantId - enablePurgeProtection: true - softDeleteRetentionInDays: 90 - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: true - accessPolicies: [] + name: geoBackupKeyVaultName + location: geoBackupLocation + properties: { + sku: { + family: 'A' + name: 'standard' } - - resource key 'keys@2023-02-01' = { - name: 'keyEncryptionKey' - properties: { - kty: 'RSA' - } + tenantId: tenant().tenantId + enablePurgeProtection: true + softDeleteRetentionInDays: 90 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2023-02-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' } + } } resource geoBackupKeyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${geoBackupKeyVault::key.id}-${geoBackupLocation}-${geoBackupManagedIdentity.id}-Key-Reader-RoleAssignment') - scope: geoBackupKeyVault::key - properties: { - principalId: geoBackupManagedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User - principalType: 'ServicePrincipal' - } + name: guid('msi-${geoBackupKeyVault::key.id}-${geoBackupLocation}-${geoBackupManagedIdentity.id}-Key-Reader-RoleAssignment') + scope: geoBackupKeyVault::key + properties: { + principalId: geoBackupManagedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User + principalType: 'ServicePrincipal' + } } @description('The resource ID of the created Managed Identity.') diff --git a/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/main.test.bicep b/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/main.test.bicep index 032e6b1e20..09db4d5368 100644 --- a/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/main.test.bicep +++ b/avm/res/db-for-my-sql/flexible-server/tests/e2e/max/main.test.bicep @@ -82,113 +82,117 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies1.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies1.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies1.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'MySQL Flexible Server' - serverName: '${namePrefix}${serviceShort}001' - } - administratorLogin: 'adminUserName' - administratorLoginPassword: password - skuName: 'Standard_D2ads_v5' - tier: 'GeneralPurpose' - storageAutoIoScaling: 'Enabled' - storageSizeGB: 64 - storageIOPS: 400 - backupRetentionDays: 20 - availabilityZone: '1' - databases: [ - { - - name: 'testdb1' +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' } - { - name: 'testdb2' - charset: 'ascii' - collation: 'ascii_general_ci' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies1.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies1.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) + principalId: nestedDependencies1.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'MySQL Flexible Server' + serverName: '${namePrefix}${serviceShort}001' } - ] - firewallRules: [ - { - endIpAddress: '0.0.0.0' - name: 'AllowAllWindowsAzureIps' - startIpAddress: '0.0.0.0' + administratorLogin: 'adminUserName' + administratorLoginPassword: password + skuName: 'Standard_D2ads_v5' + tier: 'GeneralPurpose' + storageAutoIoScaling: 'Enabled' + storageSizeGB: 64 + storageIOPS: 400 + backupRetentionDays: 20 + availabilityZone: '1' + databases: [ + { + name: 'testdb1' + } + { + name: 'testdb2' + charset: 'ascii' + collation: 'ascii_general_ci' + } + ] + firewallRules: [ + { + endIpAddress: '0.0.0.0' + name: 'AllowAllWindowsAzureIps' + startIpAddress: '0.0.0.0' + } + { + endIpAddress: '10.10.10.10' + name: 'test-rule1' + startIpAddress: '10.10.10.1' + } + { + endIpAddress: '100.100.100.10' + name: 'test-rule2' + startIpAddress: '100.100.100.1' + } + ] + highAvailability: 'SameZone' + storageAutoGrow: 'Enabled' + version: '8.0.21' + customerManagedKey: { + keyName: nestedDependencies2.outputs.keyName + keyVaultResourceId: nestedDependencies2.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies2.outputs.managedIdentityResourceId } - { - endIpAddress: '10.10.10.10' - name: 'test-rule1' - startIpAddress: '10.10.10.1' + geoRedundantBackup: 'Enabled' + customerManagedKeyGeo: { + keyName: nestedDependencies2.outputs.geoBackupKeyName + keyVaultResourceId: nestedDependencies2.outputs.geoBackupKeyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies2.outputs.geoBackupManagedIdentityResourceId } - { - endIpAddress: '100.100.100.10' - name: 'test-rule2' - startIpAddress: '100.100.100.1' + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies2.outputs.managedIdentityResourceId + nestedDependencies2.outputs.geoBackupManagedIdentityResourceId + ] } - ] - highAvailability: 'SameZone' - storageAutoGrow: 'Enabled' - version: '8.0.21' - customerManagedKey: { - keyName: nestedDependencies2.outputs.keyName - keyVaultResourceId: nestedDependencies2.outputs.keyVaultResourceId - userAssignedIdentityResourceId: nestedDependencies2.outputs.managedIdentityResourceId - } - geoRedundantBackup: 'Enabled' - customerManagedKeyGeo: { - keyName: nestedDependencies2.outputs.geoBackupKeyName - keyVaultResourceId: nestedDependencies2.outputs.geoBackupKeyVaultResourceId - userAssignedIdentityResourceId: nestedDependencies2.outputs.geoBackupManagedIdentityResourceId - } - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies2.outputs.managedIdentityResourceId - nestedDependencies2.outputs.geoBackupManagedIdentityResourceId + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } ] } - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } + dependsOn: [ + nestedDependencies1 + nestedDependencies2 + diagnosticDependencies ] } - dependsOn: [ - nestedDependencies1 - nestedDependencies2 - diagnosticDependencies - ] -}] +] diff --git a/avm/res/db-for-my-sql/flexible-server/tests/e2e/private/main.test.bicep b/avm/res/db-for-my-sql/flexible-server/tests/e2e/private/main.test.bicep index 9d8ab419ec..4966686565 100644 --- a/avm/res/db-for-my-sql/flexible-server/tests/e2e/private/main.test.bicep +++ b/avm/res/db-for-my-sql/flexible-server/tests/e2e/private/main.test.bicep @@ -50,44 +50,45 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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: resourceGroup.location - administratorLogin: 'adminUserName' - administratorLoginPassword: password - skuName: 'Standard_D2ds_v4' - tier: 'GeneralPurpose' - delegatedSubnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId - storageAutoIoScaling: 'Enabled' - storageSizeGB: 64 - storageIOPS: 400 - backupRetentionDays: 10 - databases: [ - { - - name: 'testdb1' +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: resourceGroup.location + administratorLogin: 'adminUserName' + administratorLoginPassword: password + skuName: 'Standard_D2ds_v4' + tier: 'GeneralPurpose' + delegatedSubnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + storageAutoIoScaling: 'Enabled' + storageSizeGB: 64 + storageIOPS: 400 + backupRetentionDays: 10 + databases: [ + { + name: 'testdb1' + } + ] + highAvailability: 'SameZone' + storageAutoGrow: 'Enabled' + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] } - ] - highAvailability: 'SameZone' - storageAutoGrow: 'Enabled' - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId + administrators: [ + { + identityResourceId: nestedDependencies.outputs.managedIdentityResourceId + login: nestedDependencies.outputs.managedIdentityName + sid: nestedDependencies.outputs.managedIdentityPrincipalId + } ] } - administrators: [ - { - identityResourceId: nestedDependencies.outputs.managedIdentityResourceId - login: nestedDependencies.outputs.managedIdentityName - sid: nestedDependencies.outputs.managedIdentityPrincipalId - } + dependsOn: [ + nestedDependencies ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/db-for-my-sql/flexible-server/tests/e2e/waf-aligned/main.test.bicep b/avm/res/db-for-my-sql/flexible-server/tests/e2e/waf-aligned/main.test.bicep index 0db1445062..9b2301311f 100644 --- a/avm/res/db-for-my-sql/flexible-server/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/db-for-my-sql/flexible-server/tests/e2e/waf-aligned/main.test.bicep @@ -42,24 +42,26 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - administratorLogin: 'adminUserName' - administratorLoginPassword: password - skuName: 'Standard_B1ms' - tier: 'Burstable' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + administratorLogin: 'adminUserName' + administratorLoginPassword: password + skuName: 'Standard_B1ms' + tier: 'Burstable' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] 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 4c1e49e061..f4a72730ab 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.25.53.49325", - "templateHash": "14998758936357296642" + "version": "0.26.54.24096", + "templateHash": "4962117704341008645" }, "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 c7a1671955..7bc951c35a 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.25.53.49325", - "templateHash": "13489282175455188314" + "version": "0.26.54.24096", + "templateHash": "15593908401685608166" }, "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 d671937490..94e7c5dda2 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.25.53.49325", - "templateHash": "12415562574078248070" + "version": "0.26.54.24096", + "templateHash": "9123565269712158909" }, "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 d92c543ae2..a72ec6a432 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.25.53.49325", - "templateHash": "12878552829645985725" + "version": "0.26.54.24096", + "templateHash": "4295272529604037098" }, "name": "DBforPostgreSQL Flexible Server Firewall Rules", "description": "This module deploys a DBforPostgreSQL Flexible Server Firewall Rule.", diff --git a/avm/res/desktop-virtualization/application-group/application/main.json b/avm/res/desktop-virtualization/application-group/application/main.json index c5394ba356..c2a2d880fb 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.25.53.49325", - "templateHash": "1502648604355228279" + "version": "0.26.54.24096", + "templateHash": "11159515031632739969" }, "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 78c890153c..8ab27b64b1 100644 --- a/avm/res/desktop-virtualization/application-group/main.bicep +++ b/avm/res/desktop-virtualization/application-group/main.bicep @@ -68,23 +68,24 @@ var builtInRoleNames = { 'Managed Applications Reader': '/providers/Microsoft.Authorization/roleDefinitions/b9331d33-8a36-4f8c-b097-4f54124fdb44' } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.desktopvirtualization-appgroup.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.desktopvirtualization-appgroup.${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 appGroup_hostpool 'Microsoft.DesktopVirtualization/hostPools@2022-09-09' existing = { name: hostpoolName @@ -102,62 +103,77 @@ resource appGroup 'Microsoft.DesktopVirtualization/applicationGroups@2023-09-05' } } -module appGroup_applications 'application/main.bicep' = [for (application, index) in applications: { - name: '${uniqueString(deployment().name, location)}-AppGroup-App-${index}' - params: { - name: application.name - applicationGroupName: appGroup.name - description: contains(application, 'description') ? application.description : '' - friendlyName: contains(application, 'friendlyName') ? application.friendlyName : appGroup.name - filePath: application.filePath - commandLineSetting: contains(application, 'commandLineSetting') ? application.commandLineSetting : 'DoNotAllow' - commandLineArguments: contains(application, 'commandLineArguments') ? application.commandLineArguments : '' - showInPortal: contains(application, 'showInPortal') ? application.showInPortal : false - iconPath: contains(application, 'iconPath') ? application.iconPath : application.filePath - iconIndex: contains(application, 'iconIndex') ? application.iconIndex : 0 +module appGroup_applications 'application/main.bicep' = [ + for (application, index) in applications: { + name: '${uniqueString(deployment().name, location)}-AppGroup-App-${index}' + params: { + name: application.name + applicationGroupName: appGroup.name + description: contains(application, 'description') ? application.description : '' + friendlyName: contains(application, 'friendlyName') ? application.friendlyName : appGroup.name + filePath: application.filePath + commandLineSetting: contains(application, 'commandLineSetting') ? application.commandLineSetting : 'DoNotAllow' + commandLineArguments: contains(application, 'commandLineArguments') ? application.commandLineArguments : '' + showInPortal: contains(application, 'showInPortal') ? application.showInPortal : false + iconPath: contains(application, 'iconPath') ? application.iconPath : application.filePath + iconIndex: contains(application, 'iconIndex') ? application.iconIndex : 0 + } } -}] - -resource appGroup_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.' +] + +resource appGroup_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: appGroup } - scope: appGroup -} -resource appGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(appGroup.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 +resource appGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(appGroup.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: appGroup } - scope: appGroup -}] - -resource appGroup_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 +] + +resource appGroup_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: appGroup } - scope: appGroup -}] +] @sys.description('The resource ID of the scaling plan.') output resourceId string = appGroup.id diff --git a/avm/res/desktop-virtualization/application-group/main.json b/avm/res/desktop-virtualization/application-group/main.json index d2eeb102b7..53714466f4 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.25.53.49325", - "templateHash": "16737123607848283739" + "version": "0.26.54.24096", + "templateHash": "11461831707158104939" }, "name": "Azure Virtual Desktop Application Group", "description": "This module deploys an Azure Virtual Desktop Application Group.", @@ -459,8 +459,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "1502648604355228279" + "version": "0.26.54.24096", + "templateHash": "11159515031632739969" }, "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/tests/e2e/defaults/main.test.bicep b/avm/res/desktop-virtualization/application-group/tests/e2e/defaults/main.test.bicep index 3f081725bf..bb93aa44a4 100644 --- a/avm/res/desktop-virtualization/application-group/tests/e2e/defaults/main.test.bicep +++ b/avm/res/desktop-virtualization/application-group/tests/e2e/defaults/main.test.bicep @@ -42,16 +42,18 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - applicationGroupType: 'Desktop' - hostpoolName: nestedDependencies.outputs.hostPoolName +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 + applicationGroupType: 'Desktop' + hostpoolName: nestedDependencies.outputs.hostPoolName + } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/desktop-virtualization/application-group/tests/e2e/max/main.test.bicep b/avm/res/desktop-virtualization/application-group/tests/e2e/max/main.test.bicep index 0b0141930b..6085203f7a 100644 --- a/avm/res/desktop-virtualization/application-group/tests/e2e/max/main.test.bicep +++ b/avm/res/desktop-virtualization/application-group/tests/e2e/max/main.test.bicep @@ -58,76 +58,81 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - applicationGroupType: 'RemoteApp' - applications: [ - { - commandLineArguments: '' - commandLineSetting: 'DoNotAllow' - description: 'Notepad by ARM template' - filePath: 'C:\\Windows\\System32\\notepad.exe' - friendlyName: 'Notepad' - iconIndex: 0 - iconPath: 'C:\\Windows\\System32\\notepad.exe' - name: 'notepad' - showInPortal: true +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 + applicationGroupType: 'RemoteApp' + applications: [ + { + commandLineArguments: '' + commandLineSetting: 'DoNotAllow' + description: 'Notepad by ARM template' + filePath: 'C:\\Windows\\System32\\notepad.exe' + friendlyName: 'Notepad' + iconIndex: 0 + iconPath: 'C:\\Windows\\System32\\notepad.exe' + name: 'notepad' + showInPortal: true + } + { + filePath: 'C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe' + friendlyName: 'Wordpad' + name: 'wordpad' + } + ] + description: 'myDescription' + hostpoolName: nestedDependencies.outputs.hostPoolName + diagnosticSettings: [ + { + name: 'customSetting' + logCategoriesAndGroups: [ + { + categoryGroup: 'allLogs' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - filePath: 'C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe' - friendlyName: 'Wordpad' - name: 'wordpad' - } - ] - description: 'myDescription' - hostpoolName: nestedDependencies.outputs.hostPoolName - 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' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - 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' - } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/desktop-virtualization/application-group/tests/e2e/waf-aligned/main.test.bicep b/avm/res/desktop-virtualization/application-group/tests/e2e/waf-aligned/main.test.bicep index c29e628c1d..17d4eb2d40 100644 --- a/avm/res/desktop-virtualization/application-group/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/desktop-virtualization/application-group/tests/e2e/waf-aligned/main.test.bicep @@ -57,29 +57,31 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - applicationGroupType: 'Desktop' - hostpoolName: nestedDependencies.outputs.hostPoolName - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + applicationGroupType: 'Desktop' + hostpoolName: nestedDependencies.outputs.hostPoolName + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + tags: { + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - tags: { - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/desktop-virtualization/host-pool/main.bicep b/avm/res/desktop-virtualization/host-pool/main.bicep index d173f8e6f0..4c2492ea35 100644 --- a/avm/res/desktop-virtualization/host-pool/main.bicep +++ b/avm/res/desktop-virtualization/host-pool/main.bicep @@ -147,23 +147,27 @@ var builtInRoleNames = { '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 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 @@ -196,88 +200,109 @@ resource hostPool 'Microsoft.DesktopVirtualization/hostPools@2023-09-05' = { } } -module hostPool_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-HostPool-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(hostPool.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' - privateLinkServiceConnections: [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(hostPool.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' - properties: { - privateLinkServiceId: hostPool.id - groupIds: [ - privateEndpoint.?service ?? 'connection' - ] +module hostPool_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-HostPool-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(hostPool.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' + privateLinkServiceConnections: [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(hostPool.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' + properties: { + privateLinkServiceId: hostPool.id + groupIds: [ + privateEndpoint.?service ?? 'connection' + ] + } } - } - ] - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(hostPool.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' - properties: { - privateLinkServiceId: hostPool.id - groupIds: [ - privateEndpoint.?service ?? 'connection' + ] + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(hostPool.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' + properties: { + privateLinkServiceId: hostPool.id + groupIds: [ + privateEndpoint.?service ?? 'connection' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - subnetResourceId: privateEndpoint.subnetResourceId - location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: privateEndpoint.?lock ?? lock - enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds - roleAssignments: privateEndpoint.?roleAssignments - tags: privateEndpoint.?tags ?? tags - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + subnetResourceId: privateEndpoint.subnetResourceId + location: privateEndpoint.?location ?? reference( + split(privateEndpoint.subnetResourceId, '/subnets/')[0], + '2020-06-01', + 'Full' + ).location + lock: privateEndpoint.?lock ?? lock + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + 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.' +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 } - 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 +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 } - 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 +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 } - scope: hostPool -}] +] @sys.description('The resource ID of the host pool.') output resourceId string = hostPool.id diff --git a/avm/res/desktop-virtualization/host-pool/main.json b/avm/res/desktop-virtualization/host-pool/main.json index 698856fcc8..61a90f36c2 100644 --- a/avm/res/desktop-virtualization/host-pool/main.json +++ b/avm/res/desktop-virtualization/host-pool/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17476152824582806077" + "version": "0.26.54.24096", + "templateHash": "10100380447618545512" }, "name": "Azure Virtual Desktop Host Pool", "description": "This module deploys an Azure Virtual Desktop Host Pool", 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 index bda485891a..ca82949ae4 100644 --- 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 @@ -133,7 +133,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/desktop-virtualization/scaling-plan/main.bicep b/avm/res/desktop-virtualization/scaling-plan/main.bicep index 8f822e0e06..d16e592f20 100644 --- a/avm/res/desktop-virtualization/scaling-plan/main.bicep +++ b/avm/res/desktop-virtualization/scaling-plan/main.bicep @@ -66,23 +66,24 @@ var builtInRoleNames = { 'Desktop Virtualization Workspace Reader': '/providers/Microsoft.Authorization/roleDefinitions/0fa44ee9-7a7d-466b-9bb2-2bf446b1204d' } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.desktopvirtualization-scalingplan.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.desktopvirtualization-scalingplan.${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 scalingPlan 'Microsoft.DesktopVirtualization/scalingPlans@2022-09-09' = { name: name @@ -99,46 +100,59 @@ resource scalingPlan 'Microsoft.DesktopVirtualization/scalingPlans@2022-09-09' = } } -resource scalingPlan_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.' +resource scalingPlan_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: scalingPlan } - scope: scalingPlan -} -resource scalingPlan_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(scalingPlan.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 +resource scalingPlan_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(scalingPlan.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: scalingPlan } - scope: scalingPlan -}] - -resource scalingPlan_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 +] + +resource scalingPlan_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: scalingPlan } - scope: scalingPlan -}] +] @sys.description('The resource ID of the Scaling Plan.') output resourceId string = scalingPlan.id diff --git a/avm/res/desktop-virtualization/scaling-plan/main.json b/avm/res/desktop-virtualization/scaling-plan/main.json index f9f1af28c7..93bd78240d 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.25.53.49325", - "templateHash": "18153655960792051130" + "version": "0.26.54.24096", + "templateHash": "9815061252044383943" }, "name": "Azure Virtual Desktop Scaling Plan", "description": "This module deploys an Azure Virtual Desktop Scaling Plan.", diff --git a/avm/res/desktop-virtualization/scaling-plan/tests/e2e/defaults/main.test.bicep b/avm/res/desktop-virtualization/scaling-plan/tests/e2e/defaults/main.test.bicep index 1b45a81aec..532bc90df8 100644 --- a/avm/res/desktop-virtualization/scaling-plan/tests/e2e/defaults/main.test.bicep +++ b/avm/res/desktop-virtualization/scaling-plan/tests/e2e/defaults/main.test.bicep @@ -33,11 +33,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/scaling-plan/tests/e2e/max/main.test.bicep b/avm/res/desktop-virtualization/scaling-plan/tests/e2e/max/main.test.bicep index 9a3224e186..a39813e0ff 100644 --- a/avm/res/desktop-virtualization/scaling-plan/tests/e2e/max/main.test.bicep +++ b/avm/res/desktop-virtualization/scaling-plan/tests/e2e/max/main.test.bicep @@ -57,167 +57,172 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - friendlyName: 'friendlyName' - description: 'myDescription' - schedules: [ - { - daysOfWeek: [ - 'Monday' - 'Wednesday' - 'Thursday' - 'Friday' - ] - name: 'WeekdaySchedule' - offPeakLoadBalancingAlgorithm: 'DepthFirst' - offPeakStartTime: { - hour: 20 - minute: 0 - } - peakLoadBalancingAlgorithm: 'DepthFirst' - peakStartTime: { - hour: 9 - minute: 0 - } - rampDownCapacityThresholdPct: 90 - rampDownForceLogoffUsers: true - rampDownLoadBalancingAlgorithm: 'DepthFirst' - rampDownMinimumHostsPct: 0 - rampDownNotificationMessage: 'You will be logged off in 30 min. Make sure to save your work.' - rampDownStartTime: { - hour: 18 - minute: 0 - } - rampDownStopHostsWhen: 'ZeroActiveSessions' - rampDownWaitTimeMinutes: 30 - rampUpCapacityThresholdPct: 80 - rampUpLoadBalancingAlgorithm: 'BreadthFirst' - rampUpMinimumHostsPct: 20 - rampUpStartTime: { - hour: 7 - minute: 0 +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 + friendlyName: 'friendlyName' + description: 'myDescription' + schedules: [ + { + daysOfWeek: [ + 'Monday' + 'Wednesday' + 'Thursday' + 'Friday' + ] + name: 'WeekdaySchedule' + offPeakLoadBalancingAlgorithm: 'DepthFirst' + offPeakStartTime: { + hour: 20 + minute: 0 + } + peakLoadBalancingAlgorithm: 'DepthFirst' + peakStartTime: { + hour: 9 + minute: 0 + } + rampDownCapacityThresholdPct: 90 + rampDownForceLogoffUsers: true + rampDownLoadBalancingAlgorithm: 'DepthFirst' + rampDownMinimumHostsPct: 0 + rampDownNotificationMessage: 'You will be logged off in 30 min. Make sure to save your work.' + rampDownStartTime: { + hour: 18 + minute: 0 + } + rampDownStopHostsWhen: 'ZeroActiveSessions' + rampDownWaitTimeMinutes: 30 + rampUpCapacityThresholdPct: 80 + rampUpLoadBalancingAlgorithm: 'BreadthFirst' + rampUpMinimumHostsPct: 20 + rampUpStartTime: { + hour: 7 + minute: 0 + } } - } - { - daysOfWeek: [ - 'Tuesday' - ] - name: 'weekdaysSchedule-agent-updates' - offPeakLoadBalancingAlgorithm: 'DepthFirst' - offPeakStartTime: { - hour: 20 - minute: 0 + { + daysOfWeek: [ + 'Tuesday' + ] + name: 'weekdaysSchedule-agent-updates' + offPeakLoadBalancingAlgorithm: 'DepthFirst' + offPeakStartTime: { + hour: 20 + minute: 0 + } + peakLoadBalancingAlgorithm: 'DepthFirst' + peakStartTime: { + hour: 9 + minute: 0 + } + rampDownCapacityThresholdPct: 90 + rampDownForceLogoffUsers: true + rampDownLoadBalancingAlgorithm: 'DepthFirst' + rampDownMinimumHostsPct: 0 + rampDownNotificationMessage: 'You will be logged off in 30 min. Make sure to save your work.' + rampDownStartTime: { + hour: 19 + minute: 0 + } + rampDownStopHostsWhen: 'ZeroActiveSessions' + rampDownWaitTimeMinutes: 30 + rampUpCapacityThresholdPct: 80 + rampUpLoadBalancingAlgorithm: 'BreadthFirst' + rampUpMinimumHostsPct: 20 + rampUpStartTime: { + hour: 7 + minute: 0 + } } - peakLoadBalancingAlgorithm: 'DepthFirst' - peakStartTime: { - hour: 9 - minute: 0 + { + daysOfWeek: [ + 'Saturday' + 'Sunday' + ] + name: 'WeekendSchedule' + offPeakLoadBalancingAlgorithm: 'DepthFirst' + offPeakStartTime: { + hour: 18 + minute: 0 + } + peakLoadBalancingAlgorithm: 'DepthFirst' + peakStartTime: { + hour: 10 + minute: 0 + } + rampDownCapacityThresholdPct: 90 + rampDownForceLogoffUsers: true + rampDownLoadBalancingAlgorithm: 'DepthFirst' + rampDownMinimumHostsPct: 0 + rampDownNotificationMessage: 'You will be logged off in 30 min. Make sure to save your work.' + rampDownStartTime: { + hour: 16 + minute: 0 + } + rampDownStopHostsWhen: 'ZeroActiveSessions' + rampDownWaitTimeMinutes: 30 + rampUpCapacityThresholdPct: 90 + rampUpLoadBalancingAlgorithm: 'DepthFirst' + rampUpMinimumHostsPct: 0 + rampUpStartTime: { + hour: 9 + minute: 0 + } } - rampDownCapacityThresholdPct: 90 - rampDownForceLogoffUsers: true - rampDownLoadBalancingAlgorithm: 'DepthFirst' - rampDownMinimumHostsPct: 0 - rampDownNotificationMessage: 'You will be logged off in 30 min. Make sure to save your work.' - rampDownStartTime: { - hour: 19 - minute: 0 + ] + hostPoolReferences: [ + { + hostPoolArmPath: nestedDependencies.outputs.hostPoolId + scalingPlanEnabled: true } - rampDownStopHostsWhen: 'ZeroActiveSessions' - rampDownWaitTimeMinutes: 30 - rampUpCapacityThresholdPct: 80 - rampUpLoadBalancingAlgorithm: 'BreadthFirst' - rampUpMinimumHostsPct: 20 - rampUpStartTime: { - hour: 7 - minute: 0 + ] + diagnosticSettings: [ + { + name: 'customSetting' + logCategoriesAndGroups: [ + { + categoryGroup: 'allLogs' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - daysOfWeek: [ - 'Saturday' - 'Sunday' - ] - name: 'WeekendSchedule' - offPeakLoadBalancingAlgorithm: 'DepthFirst' - offPeakStartTime: { - hour: 18 - minute: 0 - } - peakLoadBalancingAlgorithm: 'DepthFirst' - peakStartTime: { - hour: 10 - minute: 0 + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - rampDownCapacityThresholdPct: 90 - rampDownForceLogoffUsers: true - rampDownLoadBalancingAlgorithm: 'DepthFirst' - rampDownMinimumHostsPct: 0 - rampDownNotificationMessage: 'You will be logged off in 30 min. Make sure to save your work.' - rampDownStartTime: { - hour: 16 - minute: 0 + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - rampDownStopHostsWhen: 'ZeroActiveSessions' - rampDownWaitTimeMinutes: 30 - rampUpCapacityThresholdPct: 90 - rampUpLoadBalancingAlgorithm: 'DepthFirst' - rampUpMinimumHostsPct: 0 - rampUpStartTime: { - hour: 9 - minute: 0 + { + 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' } - ] - hostPoolReferences: [ - { - hostPoolArmPath: nestedDependencies.outputs.hostPoolId - scalingPlanEnabled: true - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - logCategoriesAndGroups: [ - { - categoryGroup: 'allLogs' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - 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/desktop-virtualization/scaling-plan/tests/e2e/waf-aligned/main.test.bicep b/avm/res/desktop-virtualization/scaling-plan/tests/e2e/waf-aligned/main.test.bicep index 6d8d79a130..8e0f7bf7bc 100644 --- a/avm/res/desktop-virtualization/scaling-plan/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/desktop-virtualization/scaling-plan/tests/e2e/waf-aligned/main.test.bicep @@ -48,26 +48,28 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - friendlyName: 'myFriendlyName' - location: resourceLocation - description: 'myDescription' - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}002' + friendlyName: 'myFriendlyName' + location: resourceLocation + description: 'myDescription' + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/desktop-virtualization/workspace/main.bicep b/avm/res/desktop-virtualization/workspace/main.bicep index b696e0baca..06136befd9 100644 --- a/avm/res/desktop-virtualization/workspace/main.bicep +++ b/avm/res/desktop-virtualization/workspace/main.bicep @@ -60,23 +60,27 @@ var builtInRoleNames = { '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 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 @@ -90,89 +94,108 @@ resource workspace 'Microsoft.DesktopVirtualization/workspaces@2022-10-14-previe } } -module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Workspace-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' - privateLinkServiceConnections: [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' - properties: { - privateLinkServiceId: workspace.id - groupIds: [ - privateEndpoint.?service ?? 'connection' - ] +module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Workspace-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' + privateLinkServiceConnections: [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' + properties: { + privateLinkServiceId: workspace.id + groupIds: [ + privateEndpoint.?service ?? 'connection' + ] + } } - } - ] - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' - properties: { - privateLinkServiceId: workspace.id - groupIds: [ - privateEndpoint.?service ?? 'connection' + ] + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'connection'}-${index}' + properties: { + privateLinkServiceId: workspace.id + groupIds: [ + privateEndpoint.?service ?? 'connection' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - subnetResourceId: privateEndpoint.subnetResourceId - location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: privateEndpoint.?lock ?? lock - enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds - roleAssignments: privateEndpoint.?roleAssignments - tags: privateEndpoint.?tags ?? tags - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + subnetResourceId: privateEndpoint.subnetResourceId + location: privateEndpoint.?location ?? reference( + split(privateEndpoint.subnetResourceId, '/subnets/')[0], + '2020-06-01', + 'Full' + ).location + lock: privateEndpoint.?lock ?? lock + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + 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.' +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 } - 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 +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 } - 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 +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 } - scope: workspace -}] +] @sys.description('The resource ID of the workspace.') output resourceId string = workspace.id diff --git a/avm/res/desktop-virtualization/workspace/main.json b/avm/res/desktop-virtualization/workspace/main.json index 504dc0dc06..fafa2032d3 100644 --- a/avm/res/desktop-virtualization/workspace/main.json +++ b/avm/res/desktop-virtualization/workspace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "1061929067377896447" + "version": "0.26.54.24096", + "templateHash": "15344364678225245703" }, "name": "Workspace", "description": "This module deploys an Azure Virtual Desktop Workspace.", 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 index 4fe2615c0e..f990891507 100644 --- a/avm/res/desktop-virtualization/workspace/tests/e2e/defaults/main.test.bicep +++ b/avm/res/desktop-virtualization/workspace/tests/e2e/defaults/main.test.bicep @@ -33,11 +33,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/main.test.bicep b/avm/res/desktop-virtualization/workspace/tests/e2e/max/main.test.bicep index e81a1febd0..4ba1325da5 100644 --- a/avm/res/desktop-virtualization/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/desktop-virtualization/workspace/tests/e2e/max/main.test.bicep @@ -58,128 +58,133 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' +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' } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - 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' } - ] - ipConfigurations: [ - { - name: 'myIPconfig-feed1' - properties: { - groupId: 'feed' - memberName: 'web-r0' - privateIPAddress: '10.0.0.10' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - } - { - name: 'myIPconfig-feed2' - properties: { - groupId: 'feed' - memberName: 'web-r1' - privateIPAddress: '10.0.0.13' + ] + ipConfigurations: [ + { + name: 'myIPconfig-feed1' + properties: { + groupId: 'feed' + memberName: 'web-r0' + privateIPAddress: '10.0.0.10' + } } - } - ] - 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' + { + name: 'myIPconfig-feed2' + properties: { + groupId: 'feed' + memberName: 'web-r1' + privateIPAddress: '10.0.0.13' + } + } + ] + customDnsConfigs: [] } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + { + 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' } - ] - ipConfigurations: [ - { - name: 'myIPconfig-global' - properties: { - groupId: 'global' - memberName: 'web' - privateIPAddress: '10.0.0.11' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - } - ] - customDnsConfigs: [] + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] 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 index 1103178216..0d560ab307 100644 --- 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 @@ -48,27 +48,29 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 +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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + diagnosticDependencies + ] } - dependsOn: [ - diagnosticDependencies - ] -}] +] diff --git a/avm/res/dev-test-lab/lab/artifactsource/main.json b/avm/res/dev-test-lab/lab/artifactsource/main.json index f1effe1d6d..be320c82ec 100644 --- a/avm/res/dev-test-lab/lab/artifactsource/main.json +++ b/avm/res/dev-test-lab/lab/artifactsource/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15843038393934364114" + "version": "0.26.54.24096", + "templateHash": "11935479410507680738" }, "name": "DevTest Lab Artifact Sources", "description": "This module deploys a DevTest Lab Artifact Source.\n\nAn artifact source allows you to create custom artifacts for the VMs in the lab, or use Azure Resource Manager templates to create a custom test environment. You must add a private Git repository for the artifacts or Resource Manager templates that your team creates. The repository can be hosted on GitHub or on Azure DevOps Services.", diff --git a/avm/res/dev-test-lab/lab/cost/main.json b/avm/res/dev-test-lab/lab/cost/main.json index 594f4bf22a..725ab01ee8 100644 --- a/avm/res/dev-test-lab/lab/cost/main.json +++ b/avm/res/dev-test-lab/lab/cost/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "65674909664804563" + "version": "0.26.54.24096", + "templateHash": "11267524415855336246" }, "name": "DevTest Lab Costs", "description": "This module deploys a DevTest Lab Cost.\n\nManage lab costs by setting a spending target that can be viewed in the Monthly Estimated Cost Trend chart. DevTest Labs can send a notification when spending reaches the specified target threshold.", diff --git a/avm/res/dev-test-lab/lab/main.bicep b/avm/res/dev-test-lab/lab/main.bicep index fb53d16685..58763e05dd 100644 --- a/avm/res/dev-test-lab/lab/main.bicep +++ b/avm/res/dev-test-lab/lab/main.bicep @@ -114,43 +114,67 @@ param costs object = {} @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: !empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned' - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : any(null) +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: !empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned' + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : any(null) -var formattedManagementIdentities = !empty(managementIdentitiesResourceIds) ? reduce(map((managementIdentitiesResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) : {} // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } +var formattedManagementIdentities = !empty(managementIdentitiesResourceIds) + ? reduce(map((managementIdentitiesResourceIds ?? []), (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') - 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64') + 'DevTest Labs User': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '76283e04-6283-4c54-8f91-bcf1374a3c64' + ) 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': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') - 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c') + 'Resource Policy Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '36243c78-bf99-498c-9df9-86d9f8d28608' + ) + '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' + ) + 'Virtual Machine Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '9980e02c-c2be-4d73-94e8-173b1dc7cf3c' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.devtestlab-lab.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.devtestlab-lab.${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 lab 'Microsoft.DevTestLab/labs@2018-10-15-preview' = { name: name @@ -179,128 +203,176 @@ resource lab 'Microsoft.DevTestLab/labs@2018-10-15-preview' = { } } -resource lab_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.' +resource lab_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: lab } - scope: lab -} -module lab_virtualNetworks 'virtualnetwork/main.bicep' = [for (virtualNetwork, index) in virtualnetworks: { - name: '${uniqueString(deployment().name, location)}-Lab-VirtualNetwork-${index}' - params: { - labName: lab.name - name: virtualNetwork.name - tags: virtualNetwork.?tags ?? tags - externalProviderResourceId: virtualNetwork.externalProviderResourceId - description: contains(virtualNetwork, 'description') ? virtualNetwork.description : '' - allowedSubnets: contains(virtualNetwork, 'allowedSubnets') ? virtualNetwork.allowedSubnets : [] - subnetOverrides: contains(virtualNetwork, 'subnetOverrides') ? virtualNetwork.subnetOverrides : [] +module lab_virtualNetworks 'virtualnetwork/main.bicep' = [ + for (virtualNetwork, index) in virtualnetworks: { + name: '${uniqueString(deployment().name, location)}-Lab-VirtualNetwork-${index}' + params: { + labName: lab.name + name: virtualNetwork.name + tags: virtualNetwork.?tags ?? tags + externalProviderResourceId: virtualNetwork.externalProviderResourceId + description: contains(virtualNetwork, 'description') ? virtualNetwork.description : '' + allowedSubnets: contains(virtualNetwork, 'allowedSubnets') ? virtualNetwork.allowedSubnets : [] + subnetOverrides: contains(virtualNetwork, 'subnetOverrides') ? virtualNetwork.subnetOverrides : [] + } } -}] - -module lab_policies 'policyset/policy/main.bicep' = [for (policy, index) in policies: { - name: '${uniqueString(deployment().name, location)}-Lab-PolicySets-Policy-${index}' - params: { - labName: lab.name - name: policy.name - - description: contains(policy, 'description') ? policy.description : '' - evaluatorType: policy.evaluatorType - factData: contains(policy, 'factData') ? policy.factData : '' - factName: policy.factName - status: contains(policy, 'status') ? policy.status : 'Enabled' - threshold: policy.threshold +] + +module lab_policies 'policyset/policy/main.bicep' = [ + for (policy, index) in policies: { + name: '${uniqueString(deployment().name, location)}-Lab-PolicySets-Policy-${index}' + params: { + labName: lab.name + name: policy.name + + description: contains(policy, 'description') ? policy.description : '' + evaluatorType: policy.evaluatorType + factData: contains(policy, 'factData') ? policy.factData : '' + factName: policy.factName + status: contains(policy, 'status') ? policy.status : 'Enabled' + threshold: policy.threshold + } } -}] - -module lab_schedules 'schedule/main.bicep' = [for (schedule, index) in schedules: { - name: '${uniqueString(deployment().name, location)}-Lab-Schedules-${index}' - params: { - labName: lab.name - name: schedule.name - tags: schedule.?tags ?? tags - taskType: schedule.taskType - dailyRecurrence: contains(schedule, 'dailyRecurrence') ? schedule.dailyRecurrence : {} - hourlyRecurrence: contains(schedule, 'hourlyRecurrence') ? schedule.hourlyRecurrence : {} - weeklyRecurrence: contains(schedule, 'weeklyRecurrence') ? schedule.weeklyRecurrence : {} - status: contains(schedule, 'status') ? schedule.status : 'Enabled' - targetResourceId: contains(schedule, 'targetResourceId') ? schedule.targetResourceId : '' - timeZoneId: contains(schedule, 'timeZoneId') ? schedule.timeZoneId : 'Pacific Standard time' - notificationSettingsStatus: contains(schedule, 'notificationSettingsStatus') ? schedule.notificationSettingsStatus : 'Disabled' - notificationSettingsTimeInMinutes: contains(schedule, 'notificationSettingsTimeInMinutes') ? schedule.notificationSettingsTimeInMinutes : 30 +] + +module lab_schedules 'schedule/main.bicep' = [ + for (schedule, index) in schedules: { + name: '${uniqueString(deployment().name, location)}-Lab-Schedules-${index}' + params: { + labName: lab.name + name: schedule.name + tags: schedule.?tags ?? tags + taskType: schedule.taskType + dailyRecurrence: contains(schedule, 'dailyRecurrence') ? schedule.dailyRecurrence : {} + hourlyRecurrence: contains(schedule, 'hourlyRecurrence') ? schedule.hourlyRecurrence : {} + weeklyRecurrence: contains(schedule, 'weeklyRecurrence') ? schedule.weeklyRecurrence : {} + status: contains(schedule, 'status') ? schedule.status : 'Enabled' + targetResourceId: contains(schedule, 'targetResourceId') ? schedule.targetResourceId : '' + timeZoneId: contains(schedule, 'timeZoneId') ? schedule.timeZoneId : 'Pacific Standard time' + notificationSettingsStatus: contains(schedule, 'notificationSettingsStatus') + ? schedule.notificationSettingsStatus + : 'Disabled' + notificationSettingsTimeInMinutes: contains(schedule, 'notificationSettingsTimeInMinutes') + ? schedule.notificationSettingsTimeInMinutes + : 30 + } } -}] - -module lab_notificationChannels 'notificationchannel/main.bicep' = [for (notificationChannel, index) in notificationchannels: { - name: '${uniqueString(deployment().name, location)}-Lab-NotificationChannels-${index}' - params: { - labName: lab.name - name: notificationChannel.name - tags: notificationChannel.?tags ?? tags - description: contains(notificationChannel, 'description') ? notificationChannel.description : '' - events: notificationChannel.events - emailRecipient: contains(notificationChannel, 'emailRecipient') ? notificationChannel.emailRecipient : '' - webHookUrl: contains(notificationChannel, 'webhookUrl') ? notificationChannel.webhookUrl : '' - notificationLocale: contains(notificationChannel, 'notificationLocale') ? notificationChannel.notificationLocale : 'en' +] + +module lab_notificationChannels 'notificationchannel/main.bicep' = [ + for (notificationChannel, index) in notificationchannels: { + name: '${uniqueString(deployment().name, location)}-Lab-NotificationChannels-${index}' + params: { + labName: lab.name + name: notificationChannel.name + tags: notificationChannel.?tags ?? tags + description: contains(notificationChannel, 'description') ? notificationChannel.description : '' + events: notificationChannel.events + emailRecipient: contains(notificationChannel, 'emailRecipient') ? notificationChannel.emailRecipient : '' + webHookUrl: contains(notificationChannel, 'webhookUrl') ? notificationChannel.webhookUrl : '' + notificationLocale: contains(notificationChannel, 'notificationLocale') + ? notificationChannel.notificationLocale + : 'en' + } } -}] - -module lab_artifactSources 'artifactsource/main.bicep' = [for (artifactSource, index) in artifactsources: { - name: '${uniqueString(deployment().name, location)}-Lab-ArtifactSources-${index}' - params: { - labName: lab.name - name: artifactSource.name - tags: artifactSource.?tags ?? tags - displayName: contains(artifactSource, 'displayName') ? artifactSource.displayName : artifactSource.name - branchRef: contains(artifactSource, 'branchRef') ? artifactSource.branchRef : '' - folderPath: contains(artifactSource, 'folderPath') ? artifactSource.folderPath : '' - armTemplateFolderPath: contains(artifactSource, 'armTemplateFolderPath') ? artifactSource.armTemplateFolderPath : '' - sourceType: contains(artifactSource, 'sourceType') ? artifactSource.sourceType : '' - status: contains(artifactSource, 'status') ? artifactSource.status : 'Enabled' - uri: artifactSource.uri +] + +module lab_artifactSources 'artifactsource/main.bicep' = [ + for (artifactSource, index) in artifactsources: { + name: '${uniqueString(deployment().name, location)}-Lab-ArtifactSources-${index}' + params: { + labName: lab.name + name: artifactSource.name + tags: artifactSource.?tags ?? tags + displayName: contains(artifactSource, 'displayName') ? artifactSource.displayName : artifactSource.name + branchRef: contains(artifactSource, 'branchRef') ? artifactSource.branchRef : '' + folderPath: contains(artifactSource, 'folderPath') ? artifactSource.folderPath : '' + armTemplateFolderPath: contains(artifactSource, 'armTemplateFolderPath') + ? artifactSource.armTemplateFolderPath + : '' + sourceType: contains(artifactSource, 'sourceType') ? artifactSource.sourceType : '' + status: contains(artifactSource, 'status') ? artifactSource.status : 'Enabled' + uri: artifactSource.uri + } } -}] - -module lab_costs 'cost/main.bicep' = if (!empty(costs)) { - name: '${uniqueString(deployment().name, location)}-Lab-Costs' - params: { - labName: lab.name - tags: costs.?tags ?? tags - currencyCode: contains(costs, 'currencyCode') ? costs.currencyCode : 'USD' - cycleType: costs.cycleType - cycleStartDateTime: contains(costs, 'cycleStartDateTime') ? costs.cycleStartDateTime : '' - cycleEndDateTime: contains(costs, 'cycleEndDateTime') ? costs.cycleEndDateTime : '' - status: contains(costs, 'status') ? costs.status : 'Enabled' - target: contains(costs, 'target') ? costs.target : 0 - thresholdValue25DisplayOnChart: contains(costs, 'thresholdValue25DisplayOnChart') ? costs.thresholdValue25DisplayOnChart : 'Disabled' - thresholdValue25SendNotificationWhenExceeded: contains(costs, 'thresholdValue25SendNotificationWhenExceeded') ? costs.thresholdValue25SendNotificationWhenExceeded : 'Disabled' - thresholdValue50DisplayOnChart: contains(costs, 'thresholdValue50DisplayOnChart') ? costs.thresholdValue50DisplayOnChart : 'Disabled' - thresholdValue50SendNotificationWhenExceeded: contains(costs, 'thresholdValue50SendNotificationWhenExceeded') ? costs.thresholdValue50SendNotificationWhenExceeded : 'Disabled' - thresholdValue75DisplayOnChart: contains(costs, 'thresholdValue75DisplayOnChart') ? costs.thresholdValue75DisplayOnChart : 'Disabled' - thresholdValue75SendNotificationWhenExceeded: contains(costs, 'thresholdValue75SendNotificationWhenExceeded') ? costs.thresholdValue75SendNotificationWhenExceeded : 'Disabled' - thresholdValue100DisplayOnChart: contains(costs, 'thresholdValue100DisplayOnChart') ? costs.thresholdValue100DisplayOnChart : 'Disabled' - thresholdValue100SendNotificationWhenExceeded: contains(costs, 'thresholdValue100SendNotificationWhenExceeded') ? costs.thresholdValue100SendNotificationWhenExceeded : 'Disabled' - thresholdValue125DisplayOnChart: contains(costs, 'thresholdValue125DisplayOnChart') ? costs.thresholdValue125DisplayOnChart : 'Disabled' - thresholdValue125SendNotificationWhenExceeded: contains(costs, 'thresholdValue125SendNotificationWhenExceeded') ? costs.thresholdValue125SendNotificationWhenExceeded : 'Disabled' +] + +module lab_costs 'cost/main.bicep' = + if (!empty(costs)) { + name: '${uniqueString(deployment().name, location)}-Lab-Costs' + params: { + labName: lab.name + tags: costs.?tags ?? tags + currencyCode: contains(costs, 'currencyCode') ? costs.currencyCode : 'USD' + cycleType: costs.cycleType + cycleStartDateTime: contains(costs, 'cycleStartDateTime') ? costs.cycleStartDateTime : '' + cycleEndDateTime: contains(costs, 'cycleEndDateTime') ? costs.cycleEndDateTime : '' + status: contains(costs, 'status') ? costs.status : 'Enabled' + target: contains(costs, 'target') ? costs.target : 0 + thresholdValue25DisplayOnChart: contains(costs, 'thresholdValue25DisplayOnChart') + ? costs.thresholdValue25DisplayOnChart + : 'Disabled' + thresholdValue25SendNotificationWhenExceeded: contains(costs, 'thresholdValue25SendNotificationWhenExceeded') + ? costs.thresholdValue25SendNotificationWhenExceeded + : 'Disabled' + thresholdValue50DisplayOnChart: contains(costs, 'thresholdValue50DisplayOnChart') + ? costs.thresholdValue50DisplayOnChart + : 'Disabled' + thresholdValue50SendNotificationWhenExceeded: contains(costs, 'thresholdValue50SendNotificationWhenExceeded') + ? costs.thresholdValue50SendNotificationWhenExceeded + : 'Disabled' + thresholdValue75DisplayOnChart: contains(costs, 'thresholdValue75DisplayOnChart') + ? costs.thresholdValue75DisplayOnChart + : 'Disabled' + thresholdValue75SendNotificationWhenExceeded: contains(costs, 'thresholdValue75SendNotificationWhenExceeded') + ? costs.thresholdValue75SendNotificationWhenExceeded + : 'Disabled' + thresholdValue100DisplayOnChart: contains(costs, 'thresholdValue100DisplayOnChart') + ? costs.thresholdValue100DisplayOnChart + : 'Disabled' + thresholdValue100SendNotificationWhenExceeded: contains(costs, 'thresholdValue100SendNotificationWhenExceeded') + ? costs.thresholdValue100SendNotificationWhenExceeded + : 'Disabled' + thresholdValue125DisplayOnChart: contains(costs, 'thresholdValue125DisplayOnChart') + ? costs.thresholdValue125DisplayOnChart + : 'Disabled' + thresholdValue125SendNotificationWhenExceeded: contains(costs, 'thresholdValue125SendNotificationWhenExceeded') + ? costs.thresholdValue125SendNotificationWhenExceeded + : 'Disabled' + } } -} -resource lab_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(lab.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 +resource lab_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(lab.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: lab } - scope: lab -}] +] @description('The unique identifier for the lab. Used to track tags that the lab applies to each resource that it creates.') output uniqueIdentifier string = lab.properties.uniqueIdentifier diff --git a/avm/res/dev-test-lab/lab/main.json b/avm/res/dev-test-lab/lab/main.json index cf21fa30b3..8fff71a8e5 100644 --- a/avm/res/dev-test-lab/lab/main.json +++ b/avm/res/dev-test-lab/lab/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7675513612588492913" + "version": "0.26.54.24096", + "templateHash": "7819268743072339084" }, "name": "DevTest Labs", "description": "This module deploys a DevTest Lab.", @@ -486,8 +486,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "418188724139628409" + "version": "0.26.54.24096", + "templateHash": "6899804233871456970" }, "name": "DevTest Lab Virtual Networks", "description": "This module deploys a DevTest Lab Virtual Network.\n\nLab virtual machines must be deployed into a virtual network. This resource type allows configuring the virtual network and subnet settings used for the lab virtual machines.", @@ -632,8 +632,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16570135700722429091" + "version": "0.26.54.24096", + "templateHash": "486340638220018026" }, "name": "DevTest Lab Policy Sets Policies", "description": "This module deploys a DevTest Lab Policy Sets Policy.\n\nDevTest lab policies are used to modify the lab settings such as only allowing certain VM Size SKUs, marketplace image types, number of VMs allowed per user and other settings.", @@ -798,8 +798,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "96187176657838206" + "version": "0.26.54.24096", + "templateHash": "5684619798703415484" }, "name": "DevTest Lab Schedules", "description": "This module deploys a DevTest Lab Schedule.\n\nLab schedules are used to modify the settings for auto-shutdown, auto-start for lab virtual machines.", @@ -998,8 +998,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "18438352233682084029" + "version": "0.26.54.24096", + "templateHash": "1696945877581040577" }, "name": "DevTest Lab Notification Channels", "description": "This module deploys a DevTest Lab Notification Channel.\n\nNotification channels are used by the schedule resource type in order to send notifications or events to email addresses and/or webhooks.", @@ -1158,8 +1158,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15843038393934364114" + "version": "0.26.54.24096", + "templateHash": "11935479410507680738" }, "name": "DevTest Lab Artifact Sources", "description": "This module deploys a DevTest Lab Artifact Source.\n\nAn artifact source allows you to create custom artifacts for the VMs in the lab, or use Azure Resource Manager templates to create a custom test environment. You must add a private Git repository for the artifacts or Resource Manager templates that your team creates. The repository can be hosted on GitHub or on Azure DevOps Services.", @@ -1350,8 +1350,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "65674909664804563" + "version": "0.26.54.24096", + "templateHash": "11267524415855336246" }, "name": "DevTest Lab Costs", "description": "This module deploys a DevTest Lab Cost.\n\nManage lab costs by setting a spending target that can be viewed in the Monthly Estimated Cost Trend chart. DevTest Labs can send a notification when spending reaches the specified target threshold.", diff --git a/avm/res/dev-test-lab/lab/notificationchannel/main.json b/avm/res/dev-test-lab/lab/notificationchannel/main.json index 8310fa785d..8d69509f11 100644 --- a/avm/res/dev-test-lab/lab/notificationchannel/main.json +++ b/avm/res/dev-test-lab/lab/notificationchannel/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "18438352233682084029" + "version": "0.26.54.24096", + "templateHash": "1696945877581040577" }, "name": "DevTest Lab Notification Channels", "description": "This module deploys a DevTest Lab Notification Channel.\n\nNotification channels are used by the schedule resource type in order to send notifications or events to email addresses and/or webhooks.", diff --git a/avm/res/dev-test-lab/lab/policyset/policy/main.json b/avm/res/dev-test-lab/lab/policyset/policy/main.json index 42085fd964..6da1dd875f 100644 --- a/avm/res/dev-test-lab/lab/policyset/policy/main.json +++ b/avm/res/dev-test-lab/lab/policyset/policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16570135700722429091" + "version": "0.26.54.24096", + "templateHash": "486340638220018026" }, "name": "DevTest Lab Policy Sets Policies", "description": "This module deploys a DevTest Lab Policy Sets Policy.\n\nDevTest lab policies are used to modify the lab settings such as only allowing certain VM Size SKUs, marketplace image types, number of VMs allowed per user and other settings.", diff --git a/avm/res/dev-test-lab/lab/schedule/main.bicep b/avm/res/dev-test-lab/lab/schedule/main.bicep index e3ae7dcd60..c71be08e40 100644 --- a/avm/res/dev-test-lab/lab/schedule/main.bicep +++ b/avm/res/dev-test-lab/lab/schedule/main.bicep @@ -72,10 +72,12 @@ resource schedule 'Microsoft.DevTestLab/labs/schedules@2018-09-15' = { status: status targetResourceId: !empty(targetResourceId) ? targetResourceId : null timeZoneId: timeZoneId - notificationSettings: notificationSettingsStatus == 'Enabled' ? { - status: notificationSettingsStatus - timeInMinutes: notificationSettingsTimeInMinutes - } : {} + notificationSettings: notificationSettingsStatus == 'Enabled' + ? { + status: notificationSettingsStatus + timeInMinutes: notificationSettingsTimeInMinutes + } + : {} } } diff --git a/avm/res/dev-test-lab/lab/schedule/main.json b/avm/res/dev-test-lab/lab/schedule/main.json index 859cb7f806..be1257f81e 100644 --- a/avm/res/dev-test-lab/lab/schedule/main.json +++ b/avm/res/dev-test-lab/lab/schedule/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "96187176657838206" + "version": "0.26.54.24096", + "templateHash": "5684619798703415484" }, "name": "DevTest Lab Schedules", "description": "This module deploys a DevTest Lab Schedule.\n\nLab schedules are used to modify the settings for auto-shutdown, auto-start for lab virtual machines.", diff --git a/avm/res/dev-test-lab/lab/tests/e2e/defaults/main.test.bicep b/avm/res/dev-test-lab/lab/tests/e2e/defaults/main.test.bicep index 92ab727db0..429a4ed306 100644 --- a/avm/res/dev-test-lab/lab/tests/e2e/defaults/main.test.bicep +++ b/avm/res/dev-test-lab/lab/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/dev-test-lab/lab/tests/e2e/max/dependencies.bicep b/avm/res/dev-test-lab/lab/tests/e2e/max/dependencies.bicep index 10d28c8ae6..376758c41c 100644 --- a/avm/res/dev-test-lab/lab/tests/e2e/max/dependencies.bicep +++ b/avm/res/dev-test-lab/lab/tests/e2e/max/dependencies.bicep @@ -71,7 +71,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: keyVault properties: { principalId: diskEncryptionSet.identity.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6') // Key Vault Crypto Service Encryption User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'e147488a-f6f5-4113-8e2d-b22465e65bf6' + ) // Key Vault Crypto Service Encryption User principalType: 'ServicePrincipal' } } diff --git a/avm/res/dev-test-lab/lab/tests/e2e/max/main.test.bicep b/avm/res/dev-test-lab/lab/tests/e2e/max/main.test.bicep index 3f6526a8cd..898647489d 100644 --- a/avm/res/dev-test-lab/lab/tests/e2e/max/main.test.bicep +++ b/avm/res/dev-test-lab/lab/tests/e2e/max/main.test.bicep @@ -53,242 +53,247 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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: resourceGroup.location - 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' +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: resourceGroup.location + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'DevTest Lab' - labName: '${namePrefix}${serviceShort}001' - } - announcement: { - enabled: 'Enabled' - expirationDate: '2028-12-30T13:00:00.000Z' - markdown: 'DevTest Lab announcement text.
New line. It also supports Markdown' - title: 'DevTest announcement title' - } - environmentPermission: 'Contributor' - extendedProperties: { - RdpConnectionType: '7' - } - labStorageType: 'Premium' - artifactsStorageAccount: nestedDependencies.outputs.storageAccountResourceId - premiumDataDisks: 'Enabled' - support: { - enabled: 'Enabled' - markdown: 'DevTest Lab support text.
New line. It also supports Markdown' - } - 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' + } ] - } - managementIdentitiesResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - vmCreationResourceGroupId: resourceGroup.id - browserConnect: 'Enabled' - disableAutoUpgradeCseMinorVersion: true - isolateLabResources: 'Enabled' - encryptionType: 'EncryptionAtRestWithCustomerKey' - encryptionDiskEncryptionSetId: nestedDependencies.outputs.diskEncryptionSetResourceId - virtualnetworks: [ - { - name: nestedDependencies.outputs.virtualNetworkName - externalProviderResourceId: nestedDependencies.outputs.virtualNetworkResourceId - description: 'lab virtual network description' - allowedSubnets: [ - { - labSubnetName: nestedDependencies.outputs.subnetName - resourceId: nestedDependencies.outputs.subnetResourceId - allowPublicIp: 'Allow' - } - ] - subnetOverrides: [ - { - labSubnetName: nestedDependencies.outputs.subnetName - resourceId: nestedDependencies.outputs.subnetResourceId - useInVmCreationPermission: 'Allow' - usePublicIpAddressPermission: 'Allow' - sharedPublicIpAddressConfiguration: { - allowedPorts: [ - { - transportProtocol: 'Tcp' - backendPort: 3389 - } - { - transportProtocol: 'Tcp' - backendPort: 22 - } - ] - } - } - ] - } - ] - policies: [ - { - name: nestedDependencies.outputs.subnetName - evaluatorType: 'MaxValuePolicy' - factData: nestedDependencies.outputs.subnetResourceId - factName: 'UserOwnedLabVmCountInSubnet' - threshold: '1' - } - { - name: 'MaxVmsAllowedPerUser' - evaluatorType: 'MaxValuePolicy' - factName: 'UserOwnedLabVmCount' - threshold: '2' - } - { - name: 'MaxPremiumVmsAllowedPerUser' - evaluatorType: 'MaxValuePolicy' - factName: 'UserOwnedLabPremiumVmCount' - status: 'Disabled' - threshold: '1' - } - { - name: 'MaxVmsAllowedPerLab' - evaluatorType: 'MaxValuePolicy' - factName: 'LabVmCount' - threshold: '3' - } - { - name: 'MaxPremiumVmsAllowedPerLab' - evaluatorType: 'MaxValuePolicy' - factName: 'LabPremiumVmCount' - threshold: '2' - } - { - name: 'AllowedVmSizesInLab' - evaluatorType: 'AllowedValuesPolicy' - factData: '' - factName: 'LabVmSize' - threshold: ' ${string('["Basic_A0","Basic_A1"]')}' - status: 'Enabled' + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'DevTest Lab' + labName: '${namePrefix}${serviceShort}001' } - { - name: 'ScheduleEditPermission' - evaluatorType: 'AllowedValuesPolicy' - factName: 'ScheduleEditPermission' - threshold: ' ${string('["None","Modify"]')}' + announcement: { + enabled: 'Enabled' + expirationDate: '2028-12-30T13:00:00.000Z' + markdown: 'DevTest Lab announcement text.
New line. It also supports Markdown' + title: 'DevTest announcement title' } - { - name: 'GalleryImage' - evaluatorType: 'AllowedValuesPolicy' - factName: 'GalleryImage' - threshold: ' ${string('["{\\"offer\\":\\"WindowsServer\\",\\"publisher\\":\\"MicrosoftWindowsServer\\",\\"sku\\":\\"2019-Datacenter-smalldisk\\",\\"osType\\":\\"Windows\\",\\"version\\":\\"latest\\"}","{\\"offer\\":\\"WindowsServer\\",\\"publisher\\":\\"MicrosoftWindowsServer\\",\\"sku\\":\\"2022-datacenter-smalldisk\\",\\"osType\\":\\"Windows\\",\\"version\\":\\"latest\\"}"]')}' + environmentPermission: 'Contributor' + extendedProperties: { + RdpConnectionType: '7' } - { - name: 'EnvironmentTemplate' - description: 'Public Environment Policy' - evaluatorType: 'AllowedValuesPolicy' - factName: 'EnvironmentTemplate' - threshold: ' ${string('[""]')}' + labStorageType: 'Premium' + artifactsStorageAccount: nestedDependencies.outputs.storageAccountResourceId + premiumDataDisks: 'Enabled' + support: { + enabled: 'Enabled' + markdown: 'DevTest Lab support text.
New line. It also supports Markdown' } - ] - schedules: [ - { - name: 'LabVmsShutdown' - taskType: 'LabVmsShutdownTask' - status: 'Enabled' - timeZoneId: 'AUS Eastern Standard Time' - dailyRecurrence: { - time: '0000' - } - notificationSettingsStatus: 'Enabled' - notificationSettingsTimeInMinutes: 30 + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] } - { - name: 'LabVmAutoStart' - taskType: 'LabVmsStartupTask' - status: 'Enabled' - timeZoneId: 'AUS Eastern Standard Time' - weeklyRecurrence: { - time: '0700' - weekdays: [ - 'Monday' - 'Tuesday' - 'Wednesday' - 'Thursday' - 'Friday' + managementIdentitiesResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + vmCreationResourceGroupId: resourceGroup.id + browserConnect: 'Enabled' + disableAutoUpgradeCseMinorVersion: true + isolateLabResources: 'Enabled' + encryptionType: 'EncryptionAtRestWithCustomerKey' + encryptionDiskEncryptionSetId: nestedDependencies.outputs.diskEncryptionSetResourceId + virtualnetworks: [ + { + name: nestedDependencies.outputs.virtualNetworkName + externalProviderResourceId: nestedDependencies.outputs.virtualNetworkResourceId + description: 'lab virtual network description' + allowedSubnets: [ + { + labSubnetName: nestedDependencies.outputs.subnetName + resourceId: nestedDependencies.outputs.subnetResourceId + allowPublicIp: 'Allow' + } + ] + subnetOverrides: [ + { + labSubnetName: nestedDependencies.outputs.subnetName + resourceId: nestedDependencies.outputs.subnetResourceId + useInVmCreationPermission: 'Allow' + usePublicIpAddressPermission: 'Allow' + sharedPublicIpAddressConfiguration: { + allowedPorts: [ + { + transportProtocol: 'Tcp' + backendPort: 3389 + } + { + transportProtocol: 'Tcp' + backendPort: 22 + } + ] + } + } ] } - } - ] - notificationchannels: [ - { - name: 'autoShutdown' - description: 'Integration configured for auto-shutdown' - events: [ - { - eventName: 'AutoShutdown' + ] + policies: [ + { + name: nestedDependencies.outputs.subnetName + evaluatorType: 'MaxValuePolicy' + factData: nestedDependencies.outputs.subnetResourceId + factName: 'UserOwnedLabVmCountInSubnet' + threshold: '1' + } + { + name: 'MaxVmsAllowedPerUser' + evaluatorType: 'MaxValuePolicy' + factName: 'UserOwnedLabVmCount' + threshold: '2' + } + { + name: 'MaxPremiumVmsAllowedPerUser' + evaluatorType: 'MaxValuePolicy' + factName: 'UserOwnedLabPremiumVmCount' + status: 'Disabled' + threshold: '1' + } + { + name: 'MaxVmsAllowedPerLab' + evaluatorType: 'MaxValuePolicy' + factName: 'LabVmCount' + threshold: '3' + } + { + name: 'MaxPremiumVmsAllowedPerLab' + evaluatorType: 'MaxValuePolicy' + factName: 'LabPremiumVmCount' + threshold: '2' + } + { + name: 'AllowedVmSizesInLab' + evaluatorType: 'AllowedValuesPolicy' + factData: '' + factName: 'LabVmSize' + threshold: ' ${string('["Basic_A0","Basic_A1"]')}' + status: 'Enabled' + } + { + name: 'ScheduleEditPermission' + evaluatorType: 'AllowedValuesPolicy' + factName: 'ScheduleEditPermission' + threshold: ' ${string('["None","Modify"]')}' + } + { + name: 'GalleryImage' + evaluatorType: 'AllowedValuesPolicy' + factName: 'GalleryImage' + threshold: ' ${string('["{\\"offer\\":\\"WindowsServer\\",\\"publisher\\":\\"MicrosoftWindowsServer\\",\\"sku\\":\\"2019-Datacenter-smalldisk\\",\\"osType\\":\\"Windows\\",\\"version\\":\\"latest\\"}","{\\"offer\\":\\"WindowsServer\\",\\"publisher\\":\\"MicrosoftWindowsServer\\",\\"sku\\":\\"2022-datacenter-smalldisk\\",\\"osType\\":\\"Windows\\",\\"version\\":\\"latest\\"}"]')}' + } + { + name: 'EnvironmentTemplate' + description: 'Public Environment Policy' + evaluatorType: 'AllowedValuesPolicy' + factName: 'EnvironmentTemplate' + threshold: ' ${string('[""]')}' + } + ] + schedules: [ + { + name: 'LabVmsShutdown' + taskType: 'LabVmsShutdownTask' + status: 'Enabled' + timeZoneId: 'AUS Eastern Standard Time' + dailyRecurrence: { + time: '0000' } - ] - emailRecipient: 'mail@contosodtlmail.com' - webHookUrl: 'https://webhook.contosotest.com' - notificationLocale: 'en' - } - { - name: 'costThreshold' - events: [ - { - eventName: 'Cost' + notificationSettingsStatus: 'Enabled' + notificationSettingsTimeInMinutes: 30 + } + { + name: 'LabVmAutoStart' + taskType: 'LabVmsStartupTask' + status: 'Enabled' + timeZoneId: 'AUS Eastern Standard Time' + weeklyRecurrence: { + time: '0700' + weekdays: [ + 'Monday' + 'Tuesday' + 'Wednesday' + 'Thursday' + 'Friday' + ] } - ] - webHookUrl: 'https://webhook.contosotest.com' - } - ] - artifactsources: [ - { - name: 'Public Repo' - displayName: 'Public Artifact Repo' - status: 'Disabled' - uri: 'https://github.com/Azure/azure-devtestlab.git' - sourceType: 'GitHub' - branchRef: 'master' - folderPath: '/Artifacts' - } - { - name: 'Public Environment Repo' - displayName: 'Public Environment Repo' - status: 'Disabled' - uri: 'https://github.com/Azure/azure-devtestlab.git' - sourceType: 'GitHub' - branchRef: 'master' - armTemplateFolderPath: '/Environments' + } + ] + notificationchannels: [ + { + name: 'autoShutdown' + description: 'Integration configured for auto-shutdown' + events: [ + { + eventName: 'AutoShutdown' + } + ] + emailRecipient: 'mail@contosodtlmail.com' + webHookUrl: 'https://webhook.contosotest.com' + notificationLocale: 'en' + } + { + name: 'costThreshold' + events: [ + { + eventName: 'Cost' + } + ] + webHookUrl: 'https://webhook.contosotest.com' + } + ] + artifactsources: [ + { + name: 'Public Repo' + displayName: 'Public Artifact Repo' + status: 'Disabled' + uri: 'https://github.com/Azure/azure-devtestlab.git' + sourceType: 'GitHub' + branchRef: 'master' + folderPath: '/Artifacts' + } + { + name: 'Public Environment Repo' + displayName: 'Public Environment Repo' + status: 'Disabled' + uri: 'https://github.com/Azure/azure-devtestlab.git' + sourceType: 'GitHub' + branchRef: 'master' + armTemplateFolderPath: '/Environments' + } + ] + costs: { + status: 'Enabled' + cycleType: 'CalendarMonth' + target: 450 + thresholdValue100DisplayOnChart: 'Enabled' + thresholdValue100SendNotificationWhenExceeded: 'Enabled' } - ] - costs: { - status: 'Enabled' - cycleType: 'CalendarMonth' - target: 450 - thresholdValue100DisplayOnChart: 'Enabled' - thresholdValue100SendNotificationWhenExceeded: 'Enabled' } } -}] +] diff --git a/avm/res/dev-test-lab/lab/tests/e2e/waf-aligned/main.test.bicep b/avm/res/dev-test-lab/lab/tests/e2e/waf-aligned/main.test.bicep index e7af1bbad9..3ecf9f9e52 100644 --- a/avm/res/dev-test-lab/lab/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/dev-test-lab/lab/tests/e2e/waf-aligned/main.test.bicep @@ -46,16 +46,18 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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: resourceGroup.location - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'DevTest Lab' - labName: '${namePrefix}${serviceShort}001' +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: resourceGroup.location + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'DevTest Lab' + labName: '${namePrefix}${serviceShort}001' + } } } -}] +] diff --git a/avm/res/dev-test-lab/lab/virtualnetwork/main.json b/avm/res/dev-test-lab/lab/virtualnetwork/main.json index 4af584e570..7e9745af75 100644 --- a/avm/res/dev-test-lab/lab/virtualnetwork/main.json +++ b/avm/res/dev-test-lab/lab/virtualnetwork/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "418188724139628409" + "version": "0.26.54.24096", + "templateHash": "6899804233871456970" }, "name": "DevTest Lab Virtual Networks", "description": "This module deploys a DevTest Lab Virtual Network.\n\nLab virtual machines must be deployed into a virtual network. This resource type allows configuring the virtual network and subnet settings used for the lab virtual machines.", diff --git a/avm/res/event-grid/domain/main.bicep b/avm/res/event-grid/domain/main.bicep index 2b02292287..6c5936bf8c 100644 --- a/avm/res/event-grid/domain/main.bicep +++ b/avm/res/event-grid/domain/main.bicep @@ -52,42 +52,72 @@ param managedIdentities managedIdentitiesType @description('Optional. Allow only Azure AD authentication. Should be enabled for security reasons.') param disableLocalAuth bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'EventGrid Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1e241071-0855-49ea-94dc-649edcd759de') - 'EventGrid Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7') - 'EventGrid EventSubscription Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '428e0ff0-5e57-4d9c-a221-2c70d0e0a443') - 'EventGrid EventSubscription Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2414bbcf-6497-4faf-8c65-045460748405') + 'EventGrid Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1e241071-0855-49ea-94dc-649edcd759de' + ) + 'EventGrid Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd5a91429-5739-47e2-a06b-3470a27159e7' + ) + 'EventGrid EventSubscription Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '428e0ff0-5e57-4d9c-a221-2c70d0e0a443' + ) + 'EventGrid EventSubscription Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2414bbcf-6497-4faf-8c65-045460748405' + ) 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') + '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: take('46d3xbcp.res.eventgrid-domain.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: take( + '46d3xbcp.res.eventgrid-domain.${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 domain 'Microsoft.EventGrid/domains@2023-06-01-preview' = { name: name @@ -95,7 +125,9 @@ resource domain 'Microsoft.EventGrid/domains@2023-06-01-preview' = { tags: tags identity: identity properties: { - publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) : (!empty(privateEndpoints) && empty(inboundIpRules) ? 'Disabled' : null) + publicNetworkAccess: !empty(publicNetworkAccess) + ? any(publicNetworkAccess) + : (!empty(privateEndpoints) && empty(inboundIpRules) ? 'Disabled' : null) inboundIpRules: !empty(inboundIpRules) ? inboundIpRules : null autoCreateTopicWithFirstSubscription: autoCreateTopicWithFirstSubscription autoDeleteTopicWithLastSubscription: autoDeleteTopicWithLastSubscription @@ -103,101 +135,126 @@ resource domain 'Microsoft.EventGrid/domains@2023-06-01-preview' = { } } -module domain_topics 'topic/main.bicep' = [for (topic, index) in (topics ?? []): { - name: '${uniqueString(deployment().name, location)}-topics-${index}' - params: { - domainName: domain.name - name: topic +module domain_topics 'topic/main.bicep' = [ + for (topic, index) in (topics ?? []): { + name: '${uniqueString(deployment().name, location)}-topics-${index}' + params: { + domainName: domain.name + name: topic + } } -}] +] -resource domain_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.' +resource domain_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: domain } - scope: domain -} -resource domain_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 - 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 +resource domain_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 + 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 + } + scope: domain } - scope: domain -}] - -module domain_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Domain-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(domain.id, '/'))}-${privateEndpoint.?service ?? 'domain'}-${index}' - privateLinkServiceConnections: [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(domain.id, '/'))}-${privateEndpoint.?service ?? 'domain'}-${index}' - properties: { - privateLinkServiceId: domain.id - groupIds: [ - privateEndpoint.?service ?? 'domain' - ] +] + +module domain_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Domain-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(domain.id, '/'))}-${privateEndpoint.?service ?? 'domain'}-${index}' + privateLinkServiceConnections: [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(domain.id, '/'))}-${privateEndpoint.?service ?? 'domain'}-${index}' + properties: { + privateLinkServiceId: domain.id + groupIds: [ + privateEndpoint.?service ?? 'domain' + ] + } } - } - ] - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(domain.id, '/'))}-${privateEndpoint.?service ?? 'domain'}-${index}' - properties: { - privateLinkServiceId: domain.id - groupIds: [ - privateEndpoint.?service ?? 'domain' + ] + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(domain.id, '/'))}-${privateEndpoint.?service ?? 'domain'}-${index}' + properties: { + privateLinkServiceId: domain.id + groupIds: [ + privateEndpoint.?service ?? 'domain' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - subnetResourceId: privateEndpoint.subnetResourceId - location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: privateEndpoint.?lock ?? lock - enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds - roleAssignments: privateEndpoint.?roleAssignments - tags: privateEndpoint.?tags ?? tags - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + subnetResourceId: privateEndpoint.subnetResourceId + location: privateEndpoint.?location ?? reference( + split(privateEndpoint.subnetResourceId, '/subnets/')[0], + '2020-06-01', + 'Full' + ).location + lock: privateEndpoint.?lock ?? lock + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource domain_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(domain.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 +resource domain_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(domain.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: domain } - scope: domain -}] +] @description('The name of the event grid domain.') output name string = domain.name diff --git a/avm/res/event-grid/domain/main.json b/avm/res/event-grid/domain/main.json index 287a5989c6..06df4dfe5e 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.25.53.49325", - "templateHash": "7406933903897002331" + "version": "0.26.54.24096", + "templateHash": "5443849158463047514" }, "name": "Event Grid Domains", "description": "This module deploys an Event Grid Domain.", @@ -692,8 +692,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3346602576302560002" + "version": "0.26.54.24096", + "templateHash": "11448955001407567896" }, "name": "Event Grid Domain Topics", "description": "This module deploys an Event Grid Domain Topic.", diff --git a/avm/res/event-grid/domain/tests/e2e/defaults/main.test.bicep b/avm/res/event-grid/domain/tests/e2e/defaults/main.test.bicep index f60f9071a1..4ef73b4322 100644 --- a/avm/res/event-grid/domain/tests/e2e/defaults/main.test.bicep +++ b/avm/res/event-grid/domain/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/event-grid/domain/tests/e2e/max/main.test.bicep b/avm/res/event-grid/domain/tests/e2e/max/main.test.bicep index 8e80b695fd..eb86e5c6ea 100644 --- a/avm/res/event-grid/domain/tests/e2e/max/main.test.bicep +++ b/avm/res/event-grid/domain/tests/e2e/max/main.test.bicep @@ -60,83 +60,88 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - inboundIpRules: [ - { - action: 'Allow' - ipMask: '40.74.28.0/23' - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } + ] + inboundIpRules: [ + { + action: 'Allow' + ipMask: '40.74.28.0/23' + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - 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 + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + topics: [ + '${namePrefix}-topic-${serviceShort}001' + ] } - topics: [ - '${namePrefix}-topic-${serviceShort}001' + dependsOn: [ + nestedDependencies + diagnosticDependencies ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/event-grid/domain/tests/e2e/waf-aligned/main.test.bicep b/avm/res/event-grid/domain/tests/e2e/waf-aligned/main.test.bicep index 17923ede99..6f5ed2bdbd 100644 --- a/avm/res/event-grid/domain/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/event-grid/domain/tests/e2e/waf-aligned/main.test.bicep @@ -59,56 +59,58 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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 - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + inboundIpRules: [] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - inboundIpRules: [] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'domain' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'domain' + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + topics: [ + '${namePrefix}-topic-${serviceShort}001' + ] } - topics: [ - '${namePrefix}-topic-${serviceShort}001' + dependsOn: [ + nestedDependencies + diagnosticDependencies ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/event-grid/domain/topic/main.json b/avm/res/event-grid/domain/topic/main.json index 2d26a76f82..c9e6632c2e 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.25.53.49325", - "templateHash": "3346602576302560002" + "version": "0.26.54.24096", + "templateHash": "11448955001407567896" }, "name": "Event Grid Domain Topics", "description": "This module deploys an Event Grid Domain Topic.", diff --git a/avm/res/event-grid/namespace/ca-certificate/main.json b/avm/res/event-grid/namespace/ca-certificate/main.json index 16e7ad0345..47fa8d0ce2 100644 --- a/avm/res/event-grid/namespace/ca-certificate/main.json +++ b/avm/res/event-grid/namespace/ca-certificate/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "13620127830367721222" + "version": "0.26.54.24096", + "templateHash": "1062917273000341959" }, "name": "Eventgrid Namespace CA Certificates", "description": "This module deploys an Eventgrid Namespace CA Certificate.", diff --git a/avm/res/event-grid/namespace/client-group/main.json b/avm/res/event-grid/namespace/client-group/main.json index 125c0311f0..5e393fa85d 100644 --- a/avm/res/event-grid/namespace/client-group/main.json +++ b/avm/res/event-grid/namespace/client-group/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10781129401411225399" + "version": "0.26.54.24096", + "templateHash": "7182498673501513186" }, "name": "Eventgrid Namespace Client Groups", "description": "This module deploys an Eventgrid Namespace Client Group.", diff --git a/avm/res/event-grid/namespace/client/main.bicep b/avm/res/event-grid/namespace/client/main.bicep index f327199c31..044864b850 100644 --- a/avm/res/event-grid/namespace/client/main.bicep +++ b/avm/res/event-grid/namespace/client/main.bicep @@ -17,14 +17,13 @@ param description string? param authenticationName string? @sys.allowed([ - 'DnsMatchesAuthenticationName' - 'EmailMatchesAuthenticationName' - 'IpMatchesAuthenticationName' - 'SubjectMatchesAuthenticationName' - 'ThumbprintMatch' - 'UriMatchesAuthenticationName' - ] -) + 'DnsMatchesAuthenticationName' + 'EmailMatchesAuthenticationName' + 'IpMatchesAuthenticationName' + 'SubjectMatchesAuthenticationName' + 'ThumbprintMatch' + 'UriMatchesAuthenticationName' +]) @sys.description('Optional. The validation scheme used to authenticate the client.') param clientCertificateAuthenticationValidationSchema string = 'SubjectMatchesAuthenticationName' @@ -54,7 +53,9 @@ resource client 'Microsoft.EventGrid/namespaces/clients@2023-12-15-preview' = { attributes: attributes clientCertificateAuthentication: { validationScheme: clientCertificateAuthenticationValidationSchema - allowedThumbprints: clientCertificateAuthenticationValidationSchema == 'ThumbprintMatch' ? clientCertificateAuthenticationAllowedThumbprints : null + allowedThumbprints: clientCertificateAuthenticationValidationSchema == 'ThumbprintMatch' + ? clientCertificateAuthenticationAllowedThumbprints + : null } state: state } diff --git a/avm/res/event-grid/namespace/client/main.json b/avm/res/event-grid/namespace/client/main.json index 0e0d7c7227..26f45c3c04 100644 --- a/avm/res/event-grid/namespace/client/main.json +++ b/avm/res/event-grid/namespace/client/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10531114495322688171" + "version": "0.26.54.24096", + "templateHash": "11296609826875033958" }, "name": "Eventgrid Namespace Clients", "description": "This module deploys an Eventgrid Namespace Client.", diff --git a/avm/res/event-grid/namespace/main.bicep b/avm/res/event-grid/namespace/main.bicep index d2b2581705..247475ff32 100644 --- a/avm/res/event-grid/namespace/main.bicep +++ b/avm/res/event-grid/namespace/main.bicep @@ -99,50 +99,89 @@ param topicSpaces array? @description('Optional. All namespace Permission Bindings to create. Used only when MQTT broker is enabled (\'topicSpacesState\' is set to \'Enabled\').') param permissionBindings array? -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - 'Azure Resource Notifications System Topics Subscriber': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0b962ed2-6d56-471c-bd5f-3477d83a7ba4') + 'Azure Resource Notifications System Topics Subscriber': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0b962ed2-6d56-471c-bd5f-3477d83a7ba4' + ) Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'EventGrid Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1e241071-0855-49ea-94dc-649edcd759de') - 'EventGrid Data Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1d8c3fe3-8864-474b-8749-01e3783e8157') - 'EventGrid Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '78cbd9e7-9798-4e2e-9b5a-547d9ebb31fb') - 'EventGrid Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7') - 'EventGrid EventSubscription Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '428e0ff0-5e57-4d9c-a221-2c70d0e0a443') - 'EventGrid EventSubscription Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2414bbcf-6497-4faf-8c65-045460748405') - 'EventGrid TopicSpaces Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a12b0b94-b317-4dcd-84a8-502ce99884c6') - 'EventGrid TopicSpaces Subscriber': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4b0f2fd7-60b4-4eca-896f-4435034f8bf5') + 'EventGrid Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1e241071-0855-49ea-94dc-649edcd759de' + ) + 'EventGrid Data Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1d8c3fe3-8864-474b-8749-01e3783e8157' + ) + 'EventGrid Data Receiver': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '78cbd9e7-9798-4e2e-9b5a-547d9ebb31fb' + ) + 'EventGrid Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd5a91429-5739-47e2-a06b-3470a27159e7' + ) + 'EventGrid EventSubscription Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '428e0ff0-5e57-4d9c-a221-2c70d0e0a443' + ) + 'EventGrid EventSubscription Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2414bbcf-6497-4faf-8c65-045460748405' + ) + 'EventGrid TopicSpaces Publisher': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a12b0b94-b317-4dcd-84a8-502ce99884c6' + ) + 'EventGrid TopicSpaces Subscriber': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4b0f2fd7-60b4-4eca-896f-4435034f8bf5' + ) Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) } // ============== // // Resources // // ============== // -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.eventgrid-namespace.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.eventgrid-namespace.${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 namespace 'Microsoft.EventGrid/namespaces@2023-12-15-preview' = { name: name @@ -151,183 +190,231 @@ resource namespace 'Microsoft.EventGrid/namespaces@2023-12-15-preview' = { identity: identity properties: { isZoneRedundant: isZoneRedundant - publicNetworkAccess: !empty(publicNetworkAccess) ? publicNetworkAccess : (!empty(privateEndpoints) ? 'Disabled' : 'Enabled') + publicNetworkAccess: !empty(publicNetworkAccess) + ? publicNetworkAccess + : (!empty(privateEndpoints) ? 'Disabled' : 'Enabled') inboundIpRules: inboundIpRules - topicSpacesConfiguration: topicSpacesState == 'Enabled' ? { - state: topicSpacesState - clientAuthentication: !empty(alternativeAuthenticationNameSources) ? { - alternativeAuthenticationNameSources: alternativeAuthenticationNameSources - } : null - maximumSessionExpiryInHours: maximumSessionExpiryInHours - maximumClientSessionsPerAuthenticationName: maximumClientSessionsPerAuthenticationName - routeTopicResourceId: routeTopicResourceId - routingEnrichments: !empty(routeTopicResourceId) ? routingEnrichments : null - routingIdentityInfo: !empty(routeTopicResourceId) && !startsWith(routeTopicResourceId ?? '', '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.EventGrid/namespaces/${name}/topics/') ? routingIdentityInfo : null // Use routingIdentityInfo only if the topic is not in the same namespace - } : null + topicSpacesConfiguration: topicSpacesState == 'Enabled' + ? { + state: topicSpacesState + clientAuthentication: !empty(alternativeAuthenticationNameSources) + ? { + alternativeAuthenticationNameSources: alternativeAuthenticationNameSources + } + : null + maximumSessionExpiryInHours: maximumSessionExpiryInHours + maximumClientSessionsPerAuthenticationName: maximumClientSessionsPerAuthenticationName + routeTopicResourceId: routeTopicResourceId + routingEnrichments: !empty(routeTopicResourceId) ? routingEnrichments : null + routingIdentityInfo: !empty(routeTopicResourceId) && !startsWith( + routeTopicResourceId ?? '', + '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.EventGrid/namespaces/${name}/topics/' + ) + ? routingIdentityInfo + : null // Use routingIdentityInfo only if the topic is not in the same namespace + } + : null } } -resource namespace_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.' +resource namespace_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: namespace } - scope: namespace -} -resource namespace_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 - 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 +resource namespace_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 + 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 + } + scope: namespace } - scope: namespace -}] - -module namespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-namespace-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(namespace.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(namespace.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' - properties: { - privateLinkServiceId: namespace.id - groupIds: [ - privateEndpoint.?service ?? 'topic' +] + +module namespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-namespace-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(namespace.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(namespace.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' + properties: { + privateLinkServiceId: namespace.id + groupIds: [ + privateEndpoint.?service ?? 'topic' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(namespace.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' - properties: { - privateLinkServiceId: namespace.id - groupIds: [ - privateEndpoint.?service ?? 'topic' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(namespace.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' + properties: { + privateLinkServiceId: namespace.id + groupIds: [ + privateEndpoint.?service ?? 'topic' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource namespace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(namespace.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 +resource namespace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(namespace.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: namespace } - scope: namespace -}] - -module namespace_topics 'topic/main.bicep' = [for (topic, index) in (topics ?? []): { - name: '${uniqueString(deployment().name, location)}-Namespace-Topic-${index}' - params: { - name: topic.name - namespaceName: namespace.name - eventRetentionInDays: topic.?eventRetentionInDays - inputSchema: topic.?inputSchema - publisherType: topic.?publisherType - roleAssignments: topic.?roleAssignments - eventSubscriptions: topic.?eventSubscriptions +] + +module namespace_topics 'topic/main.bicep' = [ + for (topic, index) in (topics ?? []): { + name: '${uniqueString(deployment().name, location)}-Namespace-Topic-${index}' + params: { + name: topic.name + namespaceName: namespace.name + eventRetentionInDays: topic.?eventRetentionInDays + inputSchema: topic.?inputSchema + publisherType: topic.?publisherType + roleAssignments: topic.?roleAssignments + eventSubscriptions: topic.?eventSubscriptions + } } -}] - -module namespace_caCertificates 'ca-certificate/main.bicep' = [for (caCertificate, index) in (caCertificates ?? []): if (topicSpacesState == 'Enabled') { - name: '${uniqueString(deployment().name, location)}-Namespace-caCertificate-${index}' - params: { - name: caCertificate.name - namespaceName: namespace.name - description: caCertificate.?description - encodedCertificate: caCertificate.encodedCertificate +] + +module namespace_caCertificates 'ca-certificate/main.bicep' = [ + for (caCertificate, index) in (caCertificates ?? []): if (topicSpacesState == 'Enabled') { + name: '${uniqueString(deployment().name, location)}-Namespace-caCertificate-${index}' + params: { + name: caCertificate.name + namespaceName: namespace.name + description: caCertificate.?description + encodedCertificate: caCertificate.encodedCertificate + } } -}] - -module namespace_clients 'client/main.bicep' = [for (client, index) in (clients ?? []): if (topicSpacesState == 'Enabled') { - name: '${uniqueString(deployment().name, location)}-Namespace-Client-${index}' - params: { - name: client.name - namespaceName: namespace.name - authenticationName: client.?authenticationName - description: client.?description - clientCertificateAuthenticationValidationSchema: client.?clientCertificateAuthenticationValidationSchema - clientCertificateAuthenticationAllowedThumbprints: client.?clientCertificateAuthenticationAllowedThumbprints - attributes: client.?attributes - state: client.?state +] + +module namespace_clients 'client/main.bicep' = [ + for (client, index) in (clients ?? []): if (topicSpacesState == 'Enabled') { + name: '${uniqueString(deployment().name, location)}-Namespace-Client-${index}' + params: { + name: client.name + namespaceName: namespace.name + authenticationName: client.?authenticationName + description: client.?description + clientCertificateAuthenticationValidationSchema: client.?clientCertificateAuthenticationValidationSchema + clientCertificateAuthenticationAllowedThumbprints: client.?clientCertificateAuthenticationAllowedThumbprints + attributes: client.?attributes + state: client.?state + } } -}] - -module namespace_clientGroups 'client-group/main.bicep' = [for (clientGroup, index) in (clientGroups ?? []): if (topicSpacesState == 'Enabled') { - name: '${uniqueString(deployment().name, location)}-Namespace-clientGroup-${index}' - params: { - name: clientGroup.name - namespaceName: namespace.name - query: clientGroup.query - description: clientGroup.?description +] + +module namespace_clientGroups 'client-group/main.bicep' = [ + for (clientGroup, index) in (clientGroups ?? []): if (topicSpacesState == 'Enabled') { + name: '${uniqueString(deployment().name, location)}-Namespace-clientGroup-${index}' + params: { + name: clientGroup.name + namespaceName: namespace.name + query: clientGroup.query + description: clientGroup.?description + } } -}] - -module namespace_topicSpaces 'topic-space/main.bicep' = [for (topicSpaces, index) in (topicSpaces ?? []): if (topicSpacesState == 'Enabled') { - name: '${uniqueString(deployment().name, location)}-Namespace-topicSpace-${index}' - params: { - name: topicSpaces.name - namespaceName: namespace.name - description: topicSpaces.?description - topicTemplates: topicSpaces.topicTemplates - roleAssignments: topicSpaces.?roleAssignments +] + +module namespace_topicSpaces 'topic-space/main.bicep' = [ + for (topicSpaces, index) in (topicSpaces ?? []): if (topicSpacesState == 'Enabled') { + name: '${uniqueString(deployment().name, location)}-Namespace-topicSpace-${index}' + params: { + name: topicSpaces.name + namespaceName: namespace.name + description: topicSpaces.?description + topicTemplates: topicSpaces.topicTemplates + roleAssignments: topicSpaces.?roleAssignments + } } -}] - -module namespace_permissionBindings 'permission-binding/main.bicep' = [for (permissionBinding, index) in (permissionBindings ?? []): if (topicSpacesState == 'Enabled') { - name: '${uniqueString(deployment().name, location)}-Namespace-permissionBinding-${index}' - params: { - name: permissionBinding.name - namespaceName: namespace.name - description: permissionBinding.?description - clientGroupName: permissionBinding.clientGroupName - topicSpaceName: permissionBinding.topicSpaceName - permission: permissionBinding.permission +] + +module namespace_permissionBindings 'permission-binding/main.bicep' = [ + for (permissionBinding, index) in (permissionBindings ?? []): if (topicSpacesState == 'Enabled') { + name: '${uniqueString(deployment().name, location)}-Namespace-permissionBinding-${index}' + params: { + name: permissionBinding.name + namespaceName: namespace.name + description: permissionBinding.?description + clientGroupName: permissionBinding.clientGroupName + topicSpaceName: permissionBinding.topicSpaceName + permission: permissionBinding.permission + } + dependsOn: [ + namespace_clientGroups + namespace_topicSpaces + ] } - dependsOn: [ - namespace_clientGroups - namespace_topicSpaces - ] -}] +] // ============ // // Outputs // @@ -349,7 +436,9 @@ output resourceGroupName string = resourceGroup().name output systemAssignedMIPrincipalId string = namespace.?identity.?principalId ?? '' @sys.description('The Resources IDs of the EventGrid Namespace Topics.') -output topicResourceIds array = [for index in range(0, length(topics ?? [])): namespace_topics[index].outputs.resourceId] +output topicResourceIds array = [ + for index in range(0, length(topics ?? [])): namespace_topics[index].outputs.resourceId +] // ================ // // Definitions // diff --git a/avm/res/event-grid/namespace/main.json b/avm/res/event-grid/namespace/main.json index 61a0e2a060..e472645f36 100644 --- a/avm/res/event-grid/namespace/main.json +++ b/avm/res/event-grid/namespace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6122431651057596356" + "version": "0.26.54.24096", + "templateHash": "15037334455961343668" }, "name": "Event Grid Namespaces", "description": "This module deploys an Event Grid Namespace.", @@ -1458,8 +1458,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2836208779363789051" + "version": "0.26.54.24096", + "templateHash": "4459336414537252998" }, "name": "Eventgrid Namespace Topics", "description": "This module deploys an Eventgrid Namespace Topic.", @@ -1730,8 +1730,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "13130499975324434363" + "version": "0.26.54.24096", + "templateHash": "18248314164362964337" }, "name": "Event Subscriptions", "description": "This module deploys an Event Subscription.", @@ -2016,8 +2016,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "13620127830367721222" + "version": "0.26.54.24096", + "templateHash": "1062917273000341959" }, "name": "Eventgrid Namespace CA Certificates", "description": "This module deploys an Eventgrid Namespace CA Certificate.", @@ -2146,8 +2146,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10531114495322688171" + "version": "0.26.54.24096", + "templateHash": "11296609826875033958" }, "name": "Eventgrid Namespace Clients", "description": "This module deploys an Eventgrid Namespace Client.", @@ -2312,8 +2312,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10781129401411225399" + "version": "0.26.54.24096", + "templateHash": "7182498673501513186" }, "name": "Eventgrid Namespace Client Groups", "description": "This module deploys an Eventgrid Namespace Client Group.", @@ -2433,8 +2433,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6548696237893842735" + "version": "0.26.54.24096", + "templateHash": "4931718668767892926" }, "name": "Eventgrid Namespace Topic Spaces", "description": "This module deploys an Eventgrid Namespace Topic Space.", @@ -2671,8 +2671,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "5622068529761827218" + "version": "0.26.54.24096", + "templateHash": "353917243244046230" }, "name": "Eventgrid Namespace Permissions Bindings", "description": "This module deploys an Eventgrid Namespace Permission Binding.", diff --git a/avm/res/event-grid/namespace/permission-binding/main.json b/avm/res/event-grid/namespace/permission-binding/main.json index 066199c338..2c4f60f516 100644 --- a/avm/res/event-grid/namespace/permission-binding/main.json +++ b/avm/res/event-grid/namespace/permission-binding/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "5622068529761827218" + "version": "0.26.54.24096", + "templateHash": "353917243244046230" }, "name": "Eventgrid Namespace Permissions Bindings", "description": "This module deploys an Eventgrid Namespace Permission Binding.", diff --git a/avm/res/event-grid/namespace/tests/e2e/defaults/main.test.bicep b/avm/res/event-grid/namespace/tests/e2e/defaults/main.test.bicep index b616ea7110..49bb45bff3 100644 --- a/avm/res/event-grid/namespace/tests/e2e/defaults/main.test.bicep +++ b/avm/res/event-grid/namespace/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/event-grid/namespace/tests/e2e/max/dependencies.bicep b/avm/res/event-grid/namespace/tests/e2e/max/dependencies.bicep index f2d9cb0e70..6ee87f960d 100644 --- a/avm/res/event-grid/namespace/tests/e2e/max/dependencies.bicep +++ b/avm/res/event-grid/namespace/tests/e2e/max/dependencies.bicep @@ -74,7 +74,10 @@ resource eventHubNamespaceRbacAssignment 'Microsoft.Authorization/roleAssignment name: guid(managedIdentity.id, 'evhrbacAssignment') scope: eventHubNamespace properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975') // Azure Event Hubs Data Sender + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2b629674-e913-4c01-ae53-ef4638d8f975' + ) // Azure Event Hubs Data Sender principalId: managedIdentity.properties.principalId principalType: 'ServicePrincipal' } diff --git a/avm/res/event-grid/namespace/tests/e2e/max/main.test.bicep b/avm/res/event-grid/namespace/tests/e2e/max/main.test.bicep index 69d432f2a6..bc7f73489c 100644 --- a/avm/res/event-grid/namespace/tests/e2e/max/main.test.bicep +++ b/avm/res/event-grid/namespace/tests/e2e/max/main.test.bicep @@ -62,183 +62,194 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId +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 + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] } - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - 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' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + } + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - topics: [ - { - name: 'topic1' - eventRetentionInDays: 7 - eventSubscriptions: [ - { - name: 'subscription1' - 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' - } - ] - deliveryConfiguration: { - deliveryMode: 'Queue' - queue: { - receiveLockDurationInSeconds: 60 - maxDeliveryCount: 10 - eventTimeToLive: 'P7D' + topics: [ + { + name: 'topic1' + eventRetentionInDays: 7 + eventSubscriptions: [ + { + name: 'subscription1' + 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' + } + ] + deliveryConfiguration: { + deliveryMode: 'Queue' + queue: { + receiveLockDurationInSeconds: 60 + maxDeliveryCount: 10 + eventTimeToLive: 'P7D' + } } } - } - { - name: 'subscription2' - deliveryConfiguration: { - deliveryMode: 'Push' - push: { - maxDeliveryCount: 10 - eventTimeToLive: 'P7D' - deliveryWithResourceIdentity: { - identity: { - type: 'UserAssigned' - userAssignedIdentity: nestedDependencies.outputs.managedIdentityResourceId - } - destination: { - endpointType: 'EventHub' - properties: { - resourceId: nestedDependencies.outputs.eventHubResourceId - deliveryAttributeMappings: [ - { - properties: { - value: 'staticVaule' - isSecret: false + { + name: 'subscription2' + deliveryConfiguration: { + deliveryMode: 'Push' + push: { + maxDeliveryCount: 10 + eventTimeToLive: 'P7D' + deliveryWithResourceIdentity: { + identity: { + type: 'UserAssigned' + userAssignedIdentity: nestedDependencies.outputs.managedIdentityResourceId + } + destination: { + endpointType: 'EventHub' + properties: { + resourceId: nestedDependencies.outputs.eventHubResourceId + deliveryAttributeMappings: [ + { + properties: { + value: 'staticVaule' + isSecret: false + } + name: 'StaticHeader1' + type: 'Static' } - name: 'StaticHeader1' - type: 'Static' - } - { - properties: { - sourceField: 'id' + { + properties: { + sourceField: 'id' + } + name: 'DynamicHeader1' + type: 'Dynamic' } - name: 'DynamicHeader1' - type: 'Dynamic' - } - { - properties: { - value: 'Hidden' - isSecret: true + { + properties: { + value: 'Hidden' + isSecret: true + } + name: 'StaticSecretHeader1' + type: 'Static' } - name: 'StaticSecretHeader1' - type: 'Static' - } - ] + ] + } } } } } } + ] + } + { + name: 'topic2' + 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' + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - } - { - name: 'topic2' - 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' - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' } - } - ] + ] + } } -}] +] diff --git a/avm/res/event-grid/namespace/tests/e2e/mqttct/dependencies.bicep b/avm/res/event-grid/namespace/tests/e2e/mqttct/dependencies.bicep index d3c4a66d2a..0edd63c133 100644 --- a/avm/res/event-grid/namespace/tests/e2e/mqttct/dependencies.bicep +++ b/avm/res/event-grid/namespace/tests/e2e/mqttct/dependencies.bicep @@ -25,7 +25,10 @@ resource eventGridTopicRbacAssignment 'Microsoft.Authorization/roleAssignments@2 name: guid(managedIdentity.id, 'evgtRbacAssignment') scope: eventGridTopic properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7') // EventGrid Data Sender + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd5a91429-5739-47e2-a06b-3470a27159e7' + ) // EventGrid Data Sender principalId: managedIdentity.properties.principalId principalType: 'ServicePrincipal' } diff --git a/avm/res/event-grid/namespace/tests/e2e/mqttct/main.test.bicep b/avm/res/event-grid/namespace/tests/e2e/mqttct/main.test.bicep index 382a608544..79830836b6 100644 --- a/avm/res/event-grid/namespace/tests/e2e/mqttct/main.test.bicep +++ b/avm/res/event-grid/namespace/tests/e2e/mqttct/main.test.bicep @@ -46,149 +46,154 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - topics: [ - { - name: 'topic1' +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 + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] } - ] - topicSpacesState: 'Enabled' - maximumClientSessionsPerAuthenticationName: 5 - maximumSessionExpiryInHours: 2 - routeTopicResourceId: nestedDependencies.outputs.eventGridTopicResourceId - routingIdentityInfo: { - type: 'UserAssigned' - userAssignedIdentity: nestedDependencies.outputs.managedIdentityResourceId - } - routingEnrichments: { - static: [ + topics: [ { - key: 'static1' - value: 'value1' - valueType: 'String' - } - { - key: 'static2' - value: 'value2' - valueType: 'String' - } - ] - dynamic: [ - { - key: 'dynamic1' - value: '\${client.authenticationName}' + name: 'topic1' } ] - } - alternativeAuthenticationNameSources: [ - 'ClientCertificateEmail' - 'ClientCertificateUri' - ] - // caCertificates: [ - // { - // name: 'exampleCert' - // encodedCertificate: ''' - // ''' - // } - // ] - clients: [ - { - name: 'client1' - authenticationName: 'client2auth' - description: 'this is client2' - clientCertificateAuthenticationValidationSchema: 'ThumbprintMatch' - clientCertificateAuthenticationAllowedThumbprints: [ - '1111111111111111111111111111111111111111' - '2222222222222222222222222222222222222222' - ] - state: 'Enabled' - attributes: { - room: '345' - floor: 12 - deviceTypes: [ - 'Fan' - 'Light' - ] - } - } - { - name: 'client2' - clientCertificateAuthenticationValidationSchema: 'ThumbprintMatch' - clientCertificateAuthenticationAllowedThumbprints: [ - '3333333333333333333333333333333333333333' - ] - } - { - name: 'client3' - } - { - name: 'client4' - clientCertificateAuthenticationValidationSchema: 'IpMatchesAuthenticationName' - } - ] - clientGroups: [ - { - name: 'group1' - query: 'attributes.keyName IN [\'a\', \'b\', \'c\']' - description: 'this is group1' - } - ] - topicSpaces: [ - { - name: 'topicSpace1' - topicTemplates: [ - 'devices/foo/bar' - 'devices/topic1/+' - ] + topicSpacesState: 'Enabled' + maximumClientSessionsPerAuthenticationName: 5 + maximumSessionExpiryInHours: 2 + routeTopicResourceId: nestedDependencies.outputs.eventGridTopicResourceId + routingIdentityInfo: { + type: 'UserAssigned' + userAssignedIdentity: nestedDependencies.outputs.managedIdentityResourceId } - { - name: 'topicSpace2' - topicTemplates: [ - 'devices/topic1/+' - ] - roleAssignments: [ + routingEnrichments: { + static: [ { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + key: 'static1' + value: 'value1' + valueType: 'String' } { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + key: 'static2' + value: 'value2' + valueType: 'String' } + ] + dynamic: [ { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + key: 'dynamic1' + value: '\${client.authenticationName}' } ] } - ] - permissionBindings: [ - { - name: 'bindiing1' - description: 'this is binding1' - clientGroupName: 'group1' - topicSpaceName: 'topicSpace1' - permission: 'Publisher' - } - { - name: 'bindiing2' - clientGroupName: 'group1' - topicSpaceName: 'topicSpace2' - permission: 'Subscriber' - } - ] + alternativeAuthenticationNameSources: [ + 'ClientCertificateEmail' + 'ClientCertificateUri' + ] + // caCertificates: [ + // { + // name: 'exampleCert' + // encodedCertificate: ''' + // ''' + // } + // ] + clients: [ + { + name: 'client1' + authenticationName: 'client2auth' + description: 'this is client2' + clientCertificateAuthenticationValidationSchema: 'ThumbprintMatch' + clientCertificateAuthenticationAllowedThumbprints: [ + '1111111111111111111111111111111111111111' + '2222222222222222222222222222222222222222' + ] + state: 'Enabled' + attributes: { + room: '345' + floor: 12 + deviceTypes: [ + 'Fan' + 'Light' + ] + } + } + { + name: 'client2' + clientCertificateAuthenticationValidationSchema: 'ThumbprintMatch' + clientCertificateAuthenticationAllowedThumbprints: [ + '3333333333333333333333333333333333333333' + ] + } + { + name: 'client3' + } + { + name: 'client4' + clientCertificateAuthenticationValidationSchema: 'IpMatchesAuthenticationName' + } + ] + clientGroups: [ + { + name: 'group1' + query: 'attributes.keyName IN [\'a\', \'b\', \'c\']' + description: 'this is group1' + } + ] + topicSpaces: [ + { + name: 'topicSpace1' + topicTemplates: [ + 'devices/foo/bar' + 'devices/topic1/+' + ] + } + { + name: 'topicSpace2' + topicTemplates: [ + 'devices/topic1/+' + ] + 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' + } + ] + } + ] + permissionBindings: [ + { + name: 'bindiing1' + description: 'this is binding1' + clientGroupName: 'group1' + topicSpaceName: 'topicSpace1' + permission: 'Publisher' + } + { + name: 'bindiing2' + clientGroupName: 'group1' + topicSpaceName: 'topicSpace2' + permission: 'Subscriber' + } + ] + } } -}] +] diff --git a/avm/res/event-grid/namespace/tests/e2e/mqttnt/main.test.bicep b/avm/res/event-grid/namespace/tests/e2e/mqttnt/main.test.bicep index 40265c3ba5..e2a8332ca0 100644 --- a/avm/res/event-grid/namespace/tests/e2e/mqttnt/main.test.bicep +++ b/avm/res/event-grid/namespace/tests/e2e/mqttnt/main.test.bicep @@ -47,149 +47,154 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - topics: [ - { - name: 'topic1' +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 + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] } - ] - topicSpacesState: 'Enabled' - maximumClientSessionsPerAuthenticationName: 5 - maximumSessionExpiryInHours: 2 - routeTopicResourceId: nestedDependencies.outputs.eventGridNameSpaceTopicResourceId - routingIdentityInfo: { - type: 'UserAssigned' - userAssignedIdentity: nestedDependencies.outputs.managedIdentityResourceId - } - routingEnrichments: { - static: [ + topics: [ { - key: 'static1' - value: 'value1' - valueType: 'String' - } - { - key: 'static2' - value: 'value2' - valueType: 'String' - } - ] - dynamic: [ - { - key: 'dynamic1' - value: '\${client.authenticationName}' + name: 'topic1' } ] - } - alternativeAuthenticationNameSources: [ - 'ClientCertificateEmail' - 'ClientCertificateUri' - ] - // caCertificates: [ - // { - // name: 'exampleCert' - // encodedCertificate: ''' - // ''' - // } - // ] - clients: [ - { - name: 'client1' - authenticationName: 'client2auth' - description: 'this is client2' - clientCertificateAuthenticationValidationSchema: 'ThumbprintMatch' - clientCertificateAuthenticationAllowedThumbprints: [ - '1111111111111111111111111111111111111111' - '2222222222222222222222222222222222222222' - ] - state: 'Enabled' - attributes: { - room: '345' - floor: 12 - deviceTypes: [ - 'Fan' - 'Light' - ] - } - } - { - name: 'client2' - clientCertificateAuthenticationValidationSchema: 'ThumbprintMatch' - clientCertificateAuthenticationAllowedThumbprints: [ - '3333333333333333333333333333333333333333' - ] - } - { - name: 'client3' - } - { - name: 'client4' - clientCertificateAuthenticationValidationSchema: 'IpMatchesAuthenticationName' - } - ] - clientGroups: [ - { - name: 'group1' - query: 'attributes.keyName IN [\'a\', \'b\', \'c\']' - description: 'this is group1' - } - ] - topicSpaces: [ - { - name: 'topicSpace1' - topicTemplates: [ - 'devices/foo/bar' - 'devices/topic1/+' - ] + topicSpacesState: 'Enabled' + maximumClientSessionsPerAuthenticationName: 5 + maximumSessionExpiryInHours: 2 + routeTopicResourceId: nestedDependencies.outputs.eventGridNameSpaceTopicResourceId + routingIdentityInfo: { + type: 'UserAssigned' + userAssignedIdentity: nestedDependencies.outputs.managedIdentityResourceId } - { - name: 'topicSpace2' - topicTemplates: [ - 'devices/topic1/+' - ] - roleAssignments: [ + routingEnrichments: { + static: [ { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + key: 'static1' + value: 'value1' + valueType: 'String' } { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + key: 'static2' + value: 'value2' + valueType: 'String' } + ] + dynamic: [ { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + key: 'dynamic1' + value: '\${client.authenticationName}' } ] } - ] - permissionBindings: [ - { - name: 'bindiing1' - description: 'this is binding1' - clientGroupName: 'group1' - topicSpaceName: 'topicSpace1' - permission: 'Publisher' - } - { - name: 'bindiing2' - clientGroupName: 'group1' - topicSpaceName: 'topicSpace2' - permission: 'Subscriber' - } - ] + alternativeAuthenticationNameSources: [ + 'ClientCertificateEmail' + 'ClientCertificateUri' + ] + // caCertificates: [ + // { + // name: 'exampleCert' + // encodedCertificate: ''' + // ''' + // } + // ] + clients: [ + { + name: 'client1' + authenticationName: 'client2auth' + description: 'this is client2' + clientCertificateAuthenticationValidationSchema: 'ThumbprintMatch' + clientCertificateAuthenticationAllowedThumbprints: [ + '1111111111111111111111111111111111111111' + '2222222222222222222222222222222222222222' + ] + state: 'Enabled' + attributes: { + room: '345' + floor: 12 + deviceTypes: [ + 'Fan' + 'Light' + ] + } + } + { + name: 'client2' + clientCertificateAuthenticationValidationSchema: 'ThumbprintMatch' + clientCertificateAuthenticationAllowedThumbprints: [ + '3333333333333333333333333333333333333333' + ] + } + { + name: 'client3' + } + { + name: 'client4' + clientCertificateAuthenticationValidationSchema: 'IpMatchesAuthenticationName' + } + ] + clientGroups: [ + { + name: 'group1' + query: 'attributes.keyName IN [\'a\', \'b\', \'c\']' + description: 'this is group1' + } + ] + topicSpaces: [ + { + name: 'topicSpace1' + topicTemplates: [ + 'devices/foo/bar' + 'devices/topic1/+' + ] + } + { + name: 'topicSpace2' + topicTemplates: [ + 'devices/topic1/+' + ] + 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' + } + ] + } + ] + permissionBindings: [ + { + name: 'bindiing1' + description: 'this is binding1' + clientGroupName: 'group1' + topicSpaceName: 'topicSpace1' + permission: 'Publisher' + } + { + name: 'bindiing2' + clientGroupName: 'group1' + topicSpaceName: 'topicSpace2' + permission: 'Subscriber' + } + ] + } } -}] +] diff --git a/avm/res/event-grid/namespace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/event-grid/namespace/tests/e2e/waf-aligned/main.test.bicep index 62eef80089..a7f5df77a0 100644 --- a/avm/res/event-grid/namespace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/event-grid/namespace/tests/e2e/waf-aligned/main.test.bicep @@ -60,60 +60,65 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } + ] + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + } + ] + 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' } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } - ] - 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/event-grid/namespace/topic-space/main.bicep b/avm/res/event-grid/namespace/topic-space/main.bicep index f3e9e4e149..23cec86c04 100644 --- a/avm/res/event-grid/namespace/topic-space/main.bicep +++ b/avm/res/event-grid/namespace/topic-space/main.bicep @@ -19,19 +19,49 @@ param topicTemplates array param roleAssignments roleAssignmentType var builtInRoleNames = { - 'Azure Resource Notifications System Topics Subscriber': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0b962ed2-6d56-471c-bd5f-3477d83a7ba4') + 'Azure Resource Notifications System Topics Subscriber': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0b962ed2-6d56-471c-bd5f-3477d83a7ba4' + ) Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'EventGrid Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1e241071-0855-49ea-94dc-649edcd759de') - 'EventGrid Data Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1d8c3fe3-8864-474b-8749-01e3783e8157') - 'EventGrid Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '78cbd9e7-9798-4e2e-9b5a-547d9ebb31fb') - 'EventGrid Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7') - 'EventGrid EventSubscription Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '428e0ff0-5e57-4d9c-a221-2c70d0e0a443') - 'EventGrid EventSubscription Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2414bbcf-6497-4faf-8c65-045460748405') - 'EventGrid TopicSpaces Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a12b0b94-b317-4dcd-84a8-502ce99884c6') - 'EventGrid TopicSpaces Subscriber': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4b0f2fd7-60b4-4eca-896f-4435034f8bf5') + 'EventGrid Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1e241071-0855-49ea-94dc-649edcd759de' + ) + 'EventGrid Data Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1d8c3fe3-8864-474b-8749-01e3783e8157' + ) + 'EventGrid Data Receiver': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '78cbd9e7-9798-4e2e-9b5a-547d9ebb31fb' + ) + 'EventGrid Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd5a91429-5739-47e2-a06b-3470a27159e7' + ) + 'EventGrid EventSubscription Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '428e0ff0-5e57-4d9c-a221-2c70d0e0a443' + ) + 'EventGrid EventSubscription Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2414bbcf-6497-4faf-8c65-045460748405' + ) + 'EventGrid TopicSpaces Publisher': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a12b0b94-b317-4dcd-84a8-502ce99884c6' + ) + 'EventGrid TopicSpaces Subscriber': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4b0f2fd7-60b4-4eca-896f-4435034f8bf5' + ) Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) } // ============== // @@ -51,19 +81,25 @@ resource topicSpace 'Microsoft.EventGrid/namespaces/topicSpaces@2023-12-15-previ } } -resource topic_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(topicSpace.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 +resource topic_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(topicSpace.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: topicSpace } - scope: topicSpace -}] +] // ============ // // Outputs // diff --git a/avm/res/event-grid/namespace/topic-space/main.json b/avm/res/event-grid/namespace/topic-space/main.json index f094351427..c0b7cff6d7 100644 --- a/avm/res/event-grid/namespace/topic-space/main.json +++ b/avm/res/event-grid/namespace/topic-space/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6548696237893842735" + "version": "0.26.54.24096", + "templateHash": "4931718668767892926" }, "name": "Eventgrid Namespace Topic Spaces", "description": "This module deploys an Eventgrid Namespace Topic Space.", diff --git a/avm/res/event-grid/namespace/topic/event-subscription/main.bicep b/avm/res/event-grid/namespace/topic/event-subscription/main.bicep index f8d8c63bfc..553032cc47 100644 --- a/avm/res/event-grid/namespace/topic/event-subscription/main.bicep +++ b/avm/res/event-grid/namespace/topic/event-subscription/main.bicep @@ -24,19 +24,49 @@ param filtersConfiguration object? param roleAssignments roleAssignmentType var builtInRoleNames = { - 'Azure Resource Notifications System Topics Subscriber': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0b962ed2-6d56-471c-bd5f-3477d83a7ba4') + 'Azure Resource Notifications System Topics Subscriber': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0b962ed2-6d56-471c-bd5f-3477d83a7ba4' + ) Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'EventGrid Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1e241071-0855-49ea-94dc-649edcd759de') - 'EventGrid Data Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1d8c3fe3-8864-474b-8749-01e3783e8157') - 'EventGrid Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '78cbd9e7-9798-4e2e-9b5a-547d9ebb31fb') - 'EventGrid Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7') - 'EventGrid EventSubscription Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '428e0ff0-5e57-4d9c-a221-2c70d0e0a443') - 'EventGrid EventSubscription Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2414bbcf-6497-4faf-8c65-045460748405') - 'EventGrid TopicSpaces Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a12b0b94-b317-4dcd-84a8-502ce99884c6') - 'EventGrid TopicSpaces Subscriber': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4b0f2fd7-60b4-4eca-896f-4435034f8bf5') + 'EventGrid Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1e241071-0855-49ea-94dc-649edcd759de' + ) + 'EventGrid Data Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1d8c3fe3-8864-474b-8749-01e3783e8157' + ) + 'EventGrid Data Receiver': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '78cbd9e7-9798-4e2e-9b5a-547d9ebb31fb' + ) + 'EventGrid Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd5a91429-5739-47e2-a06b-3470a27159e7' + ) + 'EventGrid EventSubscription Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '428e0ff0-5e57-4d9c-a221-2c70d0e0a443' + ) + 'EventGrid EventSubscription Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2414bbcf-6497-4faf-8c65-045460748405' + ) + 'EventGrid TopicSpaces Publisher': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a12b0b94-b317-4dcd-84a8-502ce99884c6' + ) + 'EventGrid TopicSpaces Subscriber': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4b0f2fd7-60b4-4eca-896f-4435034f8bf5' + ) Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) } // ============== // @@ -61,19 +91,25 @@ resource eventSubscription 'Microsoft.EventGrid/namespaces/topics/eventSubscript } } -resource eventSubscription_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(eventSubscription.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 +resource eventSubscription_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(eventSubscription.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: eventSubscription } - scope: eventSubscription -}] +] // ============ // // Outputs // diff --git a/avm/res/event-grid/namespace/topic/event-subscription/main.json b/avm/res/event-grid/namespace/topic/event-subscription/main.json index 6895d512f1..e2c0296a00 100644 --- a/avm/res/event-grid/namespace/topic/event-subscription/main.json +++ b/avm/res/event-grid/namespace/topic/event-subscription/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "13130499975324434363" + "version": "0.26.54.24096", + "templateHash": "18248314164362964337" }, "name": "Event Subscriptions", "description": "This module deploys an Event Subscription.", diff --git a/avm/res/event-grid/namespace/topic/main.bicep b/avm/res/event-grid/namespace/topic/main.bicep index 9bc8a5fe64..6f9e29f534 100644 --- a/avm/res/event-grid/namespace/topic/main.bicep +++ b/avm/res/event-grid/namespace/topic/main.bicep @@ -29,19 +29,49 @@ param publisherType string = 'Custom' param eventSubscriptions array? var builtInRoleNames = { - 'Azure Resource Notifications System Topics Subscriber': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0b962ed2-6d56-471c-bd5f-3477d83a7ba4') + 'Azure Resource Notifications System Topics Subscriber': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0b962ed2-6d56-471c-bd5f-3477d83a7ba4' + ) Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'EventGrid Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1e241071-0855-49ea-94dc-649edcd759de') - 'EventGrid Data Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1d8c3fe3-8864-474b-8749-01e3783e8157') - 'EventGrid Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '78cbd9e7-9798-4e2e-9b5a-547d9ebb31fb') - 'EventGrid Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7') - 'EventGrid EventSubscription Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '428e0ff0-5e57-4d9c-a221-2c70d0e0a443') - 'EventGrid EventSubscription Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2414bbcf-6497-4faf-8c65-045460748405') - 'EventGrid TopicSpaces Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a12b0b94-b317-4dcd-84a8-502ce99884c6') - 'EventGrid TopicSpaces Subscriber': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4b0f2fd7-60b4-4eca-896f-4435034f8bf5') + 'EventGrid Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1e241071-0855-49ea-94dc-649edcd759de' + ) + 'EventGrid Data Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1d8c3fe3-8864-474b-8749-01e3783e8157' + ) + 'EventGrid Data Receiver': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '78cbd9e7-9798-4e2e-9b5a-547d9ebb31fb' + ) + 'EventGrid Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd5a91429-5739-47e2-a06b-3470a27159e7' + ) + 'EventGrid EventSubscription Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '428e0ff0-5e57-4d9c-a221-2c70d0e0a443' + ) + 'EventGrid EventSubscription Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2414bbcf-6497-4faf-8c65-045460748405' + ) + 'EventGrid TopicSpaces Publisher': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a12b0b94-b317-4dcd-84a8-502ce99884c6' + ) + 'EventGrid TopicSpaces Subscriber': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4b0f2fd7-60b4-4eca-896f-4435034f8bf5' + ) Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) } // ============== // @@ -62,41 +92,52 @@ resource topic 'Microsoft.EventGrid/namespaces/topics@2023-12-15-preview' = { } } -resource topic_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.' +resource topic_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: topic } - scope: topic -} -resource topic_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(topic.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 +resource topic_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(topic.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: topic } - scope: topic -}] - -module topic_eventSubscriptions 'event-subscription/main.bicep' = [for (eventSubscription, index) in (eventSubscriptions ?? []): { - name: '${uniqueString(deployment().name, topic.name)}-Topic-EventSubscription-${index}' - params: { - name: eventSubscription.name - namespaceName: namespace.name - topicName: topic.name - deliveryConfiguration: eventSubscription.?deliveryConfiguration - eventDeliverySchema: eventSubscription.?eventDeliverySchema - filtersConfiguration: eventSubscription.?filtersConfiguration - roleAssignments: eventSubscription.?roleAssignments +] + +module topic_eventSubscriptions 'event-subscription/main.bicep' = [ + for (eventSubscription, index) in (eventSubscriptions ?? []): { + name: '${uniqueString(deployment().name, topic.name)}-Topic-EventSubscription-${index}' + params: { + name: eventSubscription.name + namespaceName: namespace.name + topicName: topic.name + deliveryConfiguration: eventSubscription.?deliveryConfiguration + eventDeliverySchema: eventSubscription.?eventDeliverySchema + filtersConfiguration: eventSubscription.?filtersConfiguration + roleAssignments: eventSubscription.?roleAssignments + } } -}] +] // ============ // // Outputs // diff --git a/avm/res/event-grid/namespace/topic/main.json b/avm/res/event-grid/namespace/topic/main.json index 60a89a526b..0249d1ea0e 100644 --- a/avm/res/event-grid/namespace/topic/main.json +++ b/avm/res/event-grid/namespace/topic/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2836208779363789051" + "version": "0.26.54.24096", + "templateHash": "4459336414537252998" }, "name": "Eventgrid Namespace Topics", "description": "This module deploys an Eventgrid Namespace Topic.", @@ -277,8 +277,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "13130499975324434363" + "version": "0.26.54.24096", + "templateHash": "18248314164362964337" }, "name": "Event Subscriptions", "description": "This module deploys an Event Subscription.", diff --git a/avm/res/event-grid/system-topic/event-subscription/main.bicep b/avm/res/event-grid/system-topic/event-subscription/main.bicep index c4390be179..0dde5e9ed3 100644 --- a/avm/res/event-grid/system-topic/event-subscription/main.bicep +++ b/avm/res/event-grid/system-topic/event-subscription/main.bicep @@ -21,14 +21,12 @@ param deliveryWithResourceIdentity object = {} param destination object @description('Optional. The event delivery schema for the event subscription.') -@allowed( - [ - 'CloudEventSchemaV1_0' - 'CustomInputSchema' - 'EventGridSchema' - 'EventGridEvent' - ] -) +@allowed([ + 'CloudEventSchemaV1_0' + 'CustomInputSchema' + 'EventGridSchema' + 'EventGridEvent' +]) param eventDeliverySchema string = 'EventGridSchema' @description('Optional. The expiration time for the event subscription. Format is ISO-8601 (yyyy-MM-ddTHH:mm:ssZ).') 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 bd8f0faa07..16c30b2cc1 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.25.53.49325", - "templateHash": "5245070501778317327" + "version": "0.26.54.24096", + "templateHash": "10785513325752294615" }, "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 4224e2fb28..8595d6fa1d 100644 --- a/avm/res/event-grid/system-topic/main.bicep +++ b/avm/res/event-grid/system-topic/main.bicep @@ -35,42 +35,72 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'EventGrid Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1e241071-0855-49ea-94dc-649edcd759de') - 'EventGrid Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7') - 'EventGrid EventSubscription Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '428e0ff0-5e57-4d9c-a221-2c70d0e0a443') - 'EventGrid EventSubscription Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2414bbcf-6497-4faf-8c65-045460748405') + 'EventGrid Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1e241071-0855-49ea-94dc-649edcd759de' + ) + 'EventGrid Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd5a91429-5739-47e2-a06b-3470a27159e7' + ) + 'EventGrid EventSubscription Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '428e0ff0-5e57-4d9c-a221-2c70d0e0a443' + ) + 'EventGrid EventSubscription Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2414bbcf-6497-4faf-8c65-045460748405' + ) 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') + '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: take('46d3xbcp.res.eventgrid-systemtopic.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: take( + '46d3xbcp.res.eventgrid-systemtopic.${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 systemTopic 'Microsoft.EventGrid/systemTopics@2021-12-01' = { name: name @@ -84,68 +114,93 @@ resource systemTopic 'Microsoft.EventGrid/systemTopics@2021-12-01' = { } // Event subscriptions -module systemTopics_eventSubscriptions 'event-subscription/main.bicep' = [for (eventSubscription, index) in eventSubscriptions: { - name: '${uniqueString(deployment().name, location)}-EventGrid-SystemTopics-EventSubscriptions-${index}' - params: { - destination: eventSubscription.destination - systemTopicName: systemTopic.name - name: eventSubscription.name - deadLetterDestination: contains(eventSubscription, 'deadLetterDestination') ? eventSubscription.deadLetterDestination : {} - deadLetterWithResourceIdentity: contains(eventSubscription, 'deadLetterWithResourceIdentity') ? eventSubscription.deadLetterWithResourceIdentity : {} - deliveryWithResourceIdentity: contains(eventSubscription, 'deliveryWithResourceIdentity') ? eventSubscription.deliveryWithResourceIdentity : {} - eventDeliverySchema: contains(eventSubscription, 'eventDeliverySchema') ? eventSubscription.eventDeliverySchema : 'EventGridSchema' - expirationTimeUtc: contains(eventSubscription, 'expirationTimeUtc') ? eventSubscription.expirationTimeUtc : '' - filter: contains(eventSubscription, 'filter') ? eventSubscription.filter : {} - labels: contains(eventSubscription, 'labels') ? eventSubscription.labels : [] - retryPolicy: contains(eventSubscription, 'retryPolicy') ? eventSubscription.retryPolicy : {} +module systemTopics_eventSubscriptions 'event-subscription/main.bicep' = [ + for (eventSubscription, index) in eventSubscriptions: { + name: '${uniqueString(deployment().name, location)}-EventGrid-SystemTopics-EventSubscriptions-${index}' + params: { + destination: eventSubscription.destination + systemTopicName: systemTopic.name + name: eventSubscription.name + deadLetterDestination: contains(eventSubscription, 'deadLetterDestination') + ? eventSubscription.deadLetterDestination + : {} + deadLetterWithResourceIdentity: contains(eventSubscription, 'deadLetterWithResourceIdentity') + ? eventSubscription.deadLetterWithResourceIdentity + : {} + deliveryWithResourceIdentity: contains(eventSubscription, 'deliveryWithResourceIdentity') + ? eventSubscription.deliveryWithResourceIdentity + : {} + eventDeliverySchema: contains(eventSubscription, 'eventDeliverySchema') + ? eventSubscription.eventDeliverySchema + : 'EventGridSchema' + expirationTimeUtc: contains(eventSubscription, 'expirationTimeUtc') ? eventSubscription.expirationTimeUtc : '' + filter: contains(eventSubscription, 'filter') ? eventSubscription.filter : {} + labels: contains(eventSubscription, 'labels') ? eventSubscription.labels : [] + retryPolicy: contains(eventSubscription, 'retryPolicy') ? eventSubscription.retryPolicy : {} + } } -}] - -resource systemTopic_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.' +] + +resource systemTopic_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: systemTopic } - scope: systemTopic -} -resource systemTopic_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 - 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 +resource systemTopic_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 + 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 + } + scope: systemTopic } - scope: systemTopic -}] - -resource systemTopic_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(systemTopic.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 +] + +resource systemTopic_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(systemTopic.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: systemTopic } - scope: systemTopic -}] +] @description('The name of the event grid system topic.') output name string = systemTopic.name diff --git a/avm/res/event-grid/system-topic/main.json b/avm/res/event-grid/system-topic/main.json index 2844dda4b8..67bfb016c7 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.25.53.49325", - "templateHash": "8773071401179464366" + "version": "0.26.54.24096", + "templateHash": "6398074442417781494" }, "name": "Event Grid System Topics", "description": "This module deploys an Event Grid System Topic.", @@ -483,8 +483,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "5245070501778317327" + "version": "0.26.54.24096", + "templateHash": "10785513325752294615" }, "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/tests/e2e/defaults/dependencies.bicep b/avm/res/event-grid/system-topic/tests/e2e/defaults/dependencies.bicep index 61ebc54d90..04ef3b2647 100644 --- a/avm/res/event-grid/system-topic/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/event-grid/system-topic/tests/e2e/defaults/dependencies.bicep @@ -5,12 +5,12 @@ param location string = resourceGroup().location param storageAccountName string resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = { - name: storageAccountName - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' } @description('The resource ID of the created Storage Account.') diff --git a/avm/res/event-grid/system-topic/tests/e2e/defaults/main.test.bicep b/avm/res/event-grid/system-topic/tests/e2e/defaults/main.test.bicep index a5121372c9..122e408292 100644 --- a/avm/res/event-grid/system-topic/tests/e2e/defaults/main.test.bicep +++ b/avm/res/event-grid/system-topic/tests/e2e/defaults/main.test.bicep @@ -59,13 +59,15 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - source: nestedDependencies.outputs.storageAccountResourceId - topicType: 'Microsoft.Storage.StorageAccounts' - location: resourceLocation +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + source: nestedDependencies.outputs.storageAccountResourceId + topicType: 'Microsoft.Storage.StorageAccounts' + location: resourceLocation + } } -}] +] diff --git a/avm/res/event-grid/system-topic/tests/e2e/max/dependencies.bicep b/avm/res/event-grid/system-topic/tests/e2e/max/dependencies.bicep index 9b192272d4..ddb6369cc0 100644 --- a/avm/res/event-grid/system-topic/tests/e2e/max/dependencies.bicep +++ b/avm/res/event-grid/system-topic/tests/e2e/max/dependencies.bicep @@ -11,25 +11,25 @@ param storageAccountName string param storageQueueName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = { - name: storageAccountName - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' - - resource queueService 'queueServices@2022-09-01' = { - name: 'default' - - resource queue 'queues@2022-09-01' = { - name: storageQueueName - } + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + + resource queueService 'queueServices@2022-09-01' = { + name: 'default' + + resource queue 'queues@2022-09-01' = { + name: storageQueueName } + } } @description('The name of the created Storage Account Queue.') diff --git a/avm/res/event-grid/system-topic/tests/e2e/max/main.test.bicep b/avm/res/event-grid/system-topic/tests/e2e/max/main.test.bicep index fc6bf1aef4..c239434df1 100644 --- a/avm/res/event-grid/system-topic/tests/e2e/max/main.test.bicep +++ b/avm/res/event-grid/system-topic/tests/e2e/max/main.test.bicep @@ -60,77 +60,84 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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' - source: nestedDependencies.outputs.storageAccountResourceId - topicType: 'Microsoft.Storage.StorageAccounts' - location: resourceLocation - eventSubscriptions: [ { - name: '${namePrefix}${serviceShort}001' - expirationTimeUtc: '2099-01-01T11:00:21.715Z' - filter: { - isSubjectCaseSensitive: false - enableAdvancedFilteringOnArrays: true - } - retryPolicy: { - maxDeliveryAttempts: 10 - eventTimeToLive: '120' - } - eventDeliverySchema: 'CloudEventSchemaV1_0' - destination: { - endpointType: 'StorageQueue' - properties: { - resourceId: nestedDependencies.outputs.storageAccountResourceId - queueMessageTimeToLiveInSeconds: 86400 - queueName: nestedDependencies.outputs.queueName +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + source: nestedDependencies.outputs.storageAccountResourceId + topicType: 'Microsoft.Storage.StorageAccounts' + location: resourceLocation + eventSubscriptions: [ + { + name: '${namePrefix}${serviceShort}001' + expirationTimeUtc: '2099-01-01T11:00:21.715Z' + filter: { + isSubjectCaseSensitive: false + enableAdvancedFilteringOnArrays: true } - } - } ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' + retryPolicy: { + maxDeliveryAttempts: 10 + eventTimeToLive: '120' } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - managedIdentities: { - systemAssigned: true - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + eventDeliverySchema: 'CloudEventSchemaV1_0' + destination: { + endpointType: 'StorageQueue' + properties: { + resourceId: nestedDependencies.outputs.storageAccountResourceId + queueMessageTimeToLiveInSeconds: 86400 + queueName: nestedDependencies.outputs.queueName + } + } + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + managedIdentities: { + systemAssigned: true } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/event-grid/system-topic/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/event-grid/system-topic/tests/e2e/waf-aligned/dependencies.bicep index d53fdbeaa6..8de4272d56 100644 --- a/avm/res/event-grid/system-topic/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/event-grid/system-topic/tests/e2e/waf-aligned/dependencies.bicep @@ -8,20 +8,20 @@ param storageAccountName string param storageQueueName string resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = { - name: storageAccountName - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' - resource queueService 'queueServices@2022-09-01' = { - name: 'default' + resource queueService 'queueServices@2022-09-01' = { + name: 'default' - resource queue 'queues@2022-09-01' = { - name: storageQueueName - } + resource queue 'queues@2022-09-01' = { + name: storageQueueName } + } } @description('The name of the created Storage Account Queue.') diff --git a/avm/res/event-grid/system-topic/tests/e2e/waf-aligned/main.test.bicep b/avm/res/event-grid/system-topic/tests/e2e/waf-aligned/main.test.bicep index 1fd7a058c0..27154e7191 100644 --- a/avm/res/event-grid/system-topic/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/event-grid/system-topic/tests/e2e/waf-aligned/main.test.bicep @@ -60,57 +60,61 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - source: nestedDependencies.outputs.storageAccountResourceId - topicType: 'Microsoft.Storage.StorageAccounts' - location: resourceLocation - eventSubscriptions: [ { - name: '${namePrefix}${serviceShort}001' - expirationTimeUtc: '2099-01-01T11:00:21.715Z' - filter: { - isSubjectCaseSensitive: false - enableAdvancedFilteringOnArrays: true - } - retryPolicy: { - maxDeliveryAttempts: 10 - eventTimeToLive: '120' - } - eventDeliverySchema: 'CloudEventSchemaV1_0' - destination: { - endpointType: 'StorageQueue' - properties: { - resourceId: nestedDependencies.outputs.storageAccountResourceId - queueMessageTimeToLiveInSeconds: 86400 - queueName: nestedDependencies.outputs.queueName +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + source: nestedDependencies.outputs.storageAccountResourceId + topicType: 'Microsoft.Storage.StorageAccounts' + location: resourceLocation + eventSubscriptions: [ + { + name: '${namePrefix}${serviceShort}001' + expirationTimeUtc: '2099-01-01T11:00:21.715Z' + filter: { + isSubjectCaseSensitive: false + enableAdvancedFilteringOnArrays: true } - } - } ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' + retryPolicy: { + maxDeliveryAttempts: 10 + eventTimeToLive: '120' } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + eventDeliverySchema: 'CloudEventSchemaV1_0' + destination: { + endpointType: 'StorageQueue' + properties: { + resourceId: nestedDependencies.outputs.storageAccountResourceId + queueMessageTimeToLiveInSeconds: 86400 + queueName: nestedDependencies.outputs.queueName + } + } + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/event-grid/topic/event-subscription/main.bicep b/avm/res/event-grid/topic/event-subscription/main.bicep index 478e271988..2fa42cb4fa 100644 --- a/avm/res/event-grid/topic/event-subscription/main.bicep +++ b/avm/res/event-grid/topic/event-subscription/main.bicep @@ -21,14 +21,12 @@ param deliveryWithResourceIdentity object = {} param destination object @description('Optional. The event delivery schema for the event subscription.') -@allowed( - [ - 'CloudEventSchemaV1_0' - 'CustomInputSchema' - 'EventGridSchema' - 'EventGridEvent' - ] -) +@allowed([ + 'CloudEventSchemaV1_0' + 'CustomInputSchema' + 'EventGridSchema' + 'EventGridEvent' +]) param eventDeliverySchema string = 'EventGridSchema' @description('Optional. The expiration time for the event subscription. Format is ISO-8601 (yyyy-MM-ddTHH:mm:ssZ).') @@ -54,7 +52,7 @@ resource eventSubscription 'Microsoft.EventGrid/topics/eventSubscriptions@2022-0 deadLetterDestination: !empty(deadLetterDestination) ? deadLetterDestination : null deadLetterWithResourceIdentity: !empty(deadLetterWithResourceIdentity) ? deadLetterWithResourceIdentity : null deliveryWithResourceIdentity: !empty(deliveryWithResourceIdentity) ? deliveryWithResourceIdentity : null - destination: empty(deliveryWithResourceIdentity) ? destination: null + destination: empty(deliveryWithResourceIdentity) ? destination : null eventDeliverySchema: eventDeliverySchema expirationTimeUtc: !empty(expirationTimeUtc) ? expirationTimeUtc : '' filter: !empty(filter) ? filter : {} diff --git a/avm/res/event-grid/topic/event-subscription/main.json b/avm/res/event-grid/topic/event-subscription/main.json index c73adf1ab6..4ffd84afa9 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.25.53.49325", - "templateHash": "12495597102731978024" + "version": "0.26.54.24096", + "templateHash": "12645668843865460856" }, "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 be24002758..1d5d5ddee2 100644 --- a/avm/res/event-grid/topic/main.bicep +++ b/avm/res/event-grid/topic/main.bicep @@ -46,42 +46,72 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'EventGrid Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1e241071-0855-49ea-94dc-649edcd759de') - 'EventGrid Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7') - 'EventGrid EventSubscription Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '428e0ff0-5e57-4d9c-a221-2c70d0e0a443') - 'EventGrid EventSubscription Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2414bbcf-6497-4faf-8c65-045460748405') + 'EventGrid Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1e241071-0855-49ea-94dc-649edcd759de' + ) + 'EventGrid Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'd5a91429-5739-47e2-a06b-3470a27159e7' + ) + 'EventGrid EventSubscription Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '428e0ff0-5e57-4d9c-a221-2c70d0e0a443' + ) + 'EventGrid EventSubscription Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2414bbcf-6497-4faf-8c65-045460748405' + ) 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') + '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: take('46d3xbcp.res.eventgrid-topic.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: take( + '46d3xbcp.res.eventgrid-topic.${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 topic 'Microsoft.EventGrid/topics@2021-06-01-preview' = { name: name @@ -89,117 +119,152 @@ resource topic 'Microsoft.EventGrid/topics@2021-06-01-preview' = { identity: identity tags: tags properties: { - publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) : (!empty(privateEndpoints) && empty(inboundIpRules) ? 'Disabled' : null) + publicNetworkAccess: !empty(publicNetworkAccess) + ? any(publicNetworkAccess) + : (!empty(privateEndpoints) && empty(inboundIpRules) ? 'Disabled' : null) inboundIpRules: (empty(inboundIpRules) ? null : inboundIpRules) disableLocalAuth: disableLocalAuth } } // Event subscriptions -module topics_eventSubscriptions 'event-subscription/main.bicep' = [for (eventSubscription, index) in eventSubscriptions: { - name: '${uniqueString(deployment().name, location)}-EventGrid-Topics-EventSubscriptions-${index}' - params: { - destination: eventSubscription.destination - topicName: topic.name - name: eventSubscription.name - deadLetterDestination: contains(eventSubscriptions, 'deadLetterDestination') ? eventSubscription.deadLetterDestination : {} - deadLetterWithResourceIdentity: contains(eventSubscriptions, 'deadLetterWithResourceIdentity') ? eventSubscription.deadLetterWithResourceIdentity : {} - deliveryWithResourceIdentity: contains(eventSubscriptions, 'deliveryWithResourceIdentity') ? eventSubscription.deliveryWithResourceIdentity : {} - eventDeliverySchema: contains(eventSubscriptions, 'eventDeliverySchema') ? eventSubscription.eventDeliverySchema : 'EventGridSchema' - expirationTimeUtc: contains(eventSubscriptions, 'expirationTimeUtc') ? eventSubscription.expirationTimeUtc : '' - filter: contains(eventSubscriptions, 'filter') ? eventSubscription.filter : {} - labels: contains(eventSubscriptions, 'labels') ? eventSubscription.labels : [] - retryPolicy: contains(eventSubscriptions, 'retryPolicy') ? eventSubscription.retryPolicy : {} +module topics_eventSubscriptions 'event-subscription/main.bicep' = [ + for (eventSubscription, index) in eventSubscriptions: { + name: '${uniqueString(deployment().name, location)}-EventGrid-Topics-EventSubscriptions-${index}' + params: { + destination: eventSubscription.destination + topicName: topic.name + name: eventSubscription.name + deadLetterDestination: contains(eventSubscriptions, 'deadLetterDestination') + ? eventSubscription.deadLetterDestination + : {} + deadLetterWithResourceIdentity: contains(eventSubscriptions, 'deadLetterWithResourceIdentity') + ? eventSubscription.deadLetterWithResourceIdentity + : {} + deliveryWithResourceIdentity: contains(eventSubscriptions, 'deliveryWithResourceIdentity') + ? eventSubscription.deliveryWithResourceIdentity + : {} + eventDeliverySchema: contains(eventSubscriptions, 'eventDeliverySchema') + ? eventSubscription.eventDeliverySchema + : 'EventGridSchema' + expirationTimeUtc: contains(eventSubscriptions, 'expirationTimeUtc') ? eventSubscription.expirationTimeUtc : '' + filter: contains(eventSubscriptions, 'filter') ? eventSubscription.filter : {} + labels: contains(eventSubscriptions, 'labels') ? eventSubscription.labels : [] + retryPolicy: contains(eventSubscriptions, 'retryPolicy') ? eventSubscription.retryPolicy : {} + } } -}] +] -resource topic_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.' +resource topic_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: topic } - scope: topic -} -resource topic_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 - 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 +resource topic_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 + 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 + } + scope: topic } - scope: topic -}] - -module topic_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Topic-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(topic.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' - privateLinkServiceConnections: [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(topic.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' - properties: { - privateLinkServiceId: topic.id - groupIds: [ - privateEndpoint.?service ?? 'topic' - ] +] + +module topic_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Topic-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(topic.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' + privateLinkServiceConnections: [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(topic.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' + properties: { + privateLinkServiceId: topic.id + groupIds: [ + privateEndpoint.?service ?? 'topic' + ] + } } - } - ] - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(topic.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' - properties: { - privateLinkServiceId: topic.id - groupIds: [ - privateEndpoint.?service ?? 'topic' + ] + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(topic.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' + properties: { + privateLinkServiceId: topic.id + groupIds: [ + privateEndpoint.?service ?? 'topic' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - subnetResourceId: privateEndpoint.subnetResourceId - location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: privateEndpoint.?lock ?? lock - enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds - roleAssignments: privateEndpoint.?roleAssignments - tags: privateEndpoint.?tags ?? tags - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + subnetResourceId: privateEndpoint.subnetResourceId + location: privateEndpoint.?location ?? reference( + split(privateEndpoint.subnetResourceId, '/subnets/')[0], + '2020-06-01', + 'Full' + ).location + lock: privateEndpoint.?lock ?? lock + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource topic_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(topic.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 +resource topic_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(topic.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: topic } - scope: topic -}] +] @description('The name of the event grid topic.') output name string = topic.name diff --git a/avm/res/event-grid/topic/main.json b/avm/res/event-grid/topic/main.json index bd6faed608..2dd96899c8 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.25.53.49325", - "templateHash": "17945416734412715410" + "version": "0.26.54.24096", + "templateHash": "1380486990057725745" }, "name": "Event Grid Topics", "description": "This module deploys an Event Grid Topic.", @@ -687,8 +687,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12495597102731978024" + "version": "0.26.54.24096", + "templateHash": "12645668843865460856" }, "name": "EventGrid Topic Event Subscriptions", "description": "This module deploys an Event Grid Topic Event Subscription.", diff --git a/avm/res/event-grid/topic/tests/e2e/defaults/main.test.bicep b/avm/res/event-grid/topic/tests/e2e/defaults/main.test.bicep index daa75b91f2..e93dd24fb1 100644 --- a/avm/res/event-grid/topic/tests/e2e/defaults/main.test.bicep +++ b/avm/res/event-grid/topic/tests/e2e/defaults/main.test.bicep @@ -35,11 +35,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-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 +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/event-grid/topic/tests/e2e/max/main.test.bicep b/avm/res/event-grid/topic/tests/e2e/max/main.test.bicep index 755f0a4793..6c4015fec7 100644 --- a/avm/res/event-grid/topic/tests/e2e/max/main.test.bicep +++ b/avm/res/event-grid/topic/tests/e2e/max/main.test.bicep @@ -62,113 +62,123 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - eventSubscriptions: [ { - name: '${namePrefix}${serviceShort}001' - expirationTimeUtc: '2099-01-01T11:00:21.715Z' - filter: { - isSubjectCaseSensitive: false - enableAdvancedFilteringOnArrays: true +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 + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - retryPolicy: { - maxDeliveryAttempts: 10 - eventTimeToLive: '120' - } - eventDeliverySchema: 'CloudEventSchemaV1_0' - destination: { - endpointType: 'StorageQueue' - properties: { - resourceId: nestedDependencies.outputs.storageAccountResourceId - queueMessageTimeToLiveInSeconds: 86400 - queueName: nestedDependencies.outputs.queueName + ] + eventSubscriptions: [ + { + name: '${namePrefix}${serviceShort}001' + expirationTimeUtc: '2099-01-01T11:00:21.715Z' + filter: { + isSubjectCaseSensitive: false + enableAdvancedFilteringOnArrays: true } - } - } ] - inboundIpRules: [ - { - action: 'Allow' - ipMask: '40.74.28.0/23' - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + retryPolicy: { + maxDeliveryAttempts: 10 + eventTimeToLive: '120' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + eventDeliverySchema: 'CloudEventSchemaV1_0' + destination: { + endpointType: 'StorageQueue' + properties: { + resourceId: nestedDependencies.outputs.storageAccountResourceId + queueMessageTimeToLiveInSeconds: 86400 + queueName: nestedDependencies.outputs.queueName + } } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + ] + inboundIpRules: [ + { + action: 'Allow' + ipMask: '40.74.28.0/23' + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - 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 + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + 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' + } + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/event-grid/topic/tests/e2e/waf-aligned/main.test.bicep b/avm/res/event-grid/topic/tests/e2e/waf-aligned/main.test.bicep index e053ff5149..aec73401ac 100644 --- a/avm/res/event-grid/topic/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/event-grid/topic/tests/e2e/waf-aligned/main.test.bicep @@ -62,74 +62,78 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - eventSubscriptions: [ { - name: '${namePrefix}${serviceShort}001' - expirationTimeUtc: '2099-01-01T11:00:21.715Z' - filter: { - isSubjectCaseSensitive: false - enableAdvancedFilteringOnArrays: true - } - retryPolicy: { - maxDeliveryAttempts: 10 - eventTimeToLive: '120' +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 + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - eventDeliverySchema: 'CloudEventSchemaV1_0' - destination: { - endpointType: 'StorageQueue' - properties: { - resourceId: nestedDependencies.outputs.storageAccountResourceId - queueMessageTimeToLiveInSeconds: 86400 - queueName: nestedDependencies.outputs.queueName + ] + eventSubscriptions: [ + { + name: '${namePrefix}${serviceShort}001' + expirationTimeUtc: '2099-01-01T11:00:21.715Z' + filter: { + isSubjectCaseSensitive: false + enableAdvancedFilteringOnArrays: true + } + retryPolicy: { + maxDeliveryAttempts: 10 + eventTimeToLive: '120' + } + eventDeliverySchema: 'CloudEventSchemaV1_0' + destination: { + endpointType: 'StorageQueue' + properties: { + resourceId: nestedDependencies.outputs.storageAccountResourceId + queueMessageTimeToLiveInSeconds: 86400 + queueName: nestedDependencies.outputs.queueName + } } } - } ] - inboundIpRules: [] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'topic' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + ] + inboundIpRules: [] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'topic' + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/event-hub/namespace/authorization-rule/main.json b/avm/res/event-hub/namespace/authorization-rule/main.json index 6516efc5ac..1e2ad1c42c 100644 --- a/avm/res/event-hub/namespace/authorization-rule/main.json +++ b/avm/res/event-hub/namespace/authorization-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10638309014943371587" + "version": "0.26.54.24096", + "templateHash": "15327912662565121564" }, "name": "Event Hub Namespace Authorization Rule", "description": "This module deploys an Event Hub Namespace Authorization Rule.", diff --git a/avm/res/event-hub/namespace/disaster-recovery-config/main.json b/avm/res/event-hub/namespace/disaster-recovery-config/main.json index 5e57cbee56..ea59892550 100644 --- a/avm/res/event-hub/namespace/disaster-recovery-config/main.json +++ b/avm/res/event-hub/namespace/disaster-recovery-config/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14933577565840576961" + "version": "0.26.54.24096", + "templateHash": "11732013494690054024" }, "name": "Event Hub Namespace Disaster Recovery Configs", "description": "This module deploys an Event Hub Namespace Disaster Recovery Config.", diff --git a/avm/res/event-hub/namespace/eventhub/authorization-rule/main.json b/avm/res/event-hub/namespace/eventhub/authorization-rule/main.json index 9b5e8a5edc..ecbc4d54d5 100644 --- a/avm/res/event-hub/namespace/eventhub/authorization-rule/main.json +++ b/avm/res/event-hub/namespace/eventhub/authorization-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16757979367783376523" + "version": "0.26.54.24096", + "templateHash": "15301134976738274567" }, "name": "Event Hub Namespace Event Hub Authorization Rules", "description": "This module deploys an Event Hub Namespace Event Hub Authorization Rule.", diff --git a/avm/res/event-hub/namespace/eventhub/consumergroup/main.json b/avm/res/event-hub/namespace/eventhub/consumergroup/main.json index cd74392666..4e7f41aaf5 100644 --- a/avm/res/event-hub/namespace/eventhub/consumergroup/main.json +++ b/avm/res/event-hub/namespace/eventhub/consumergroup/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "697710281814211564" + "version": "0.26.54.24096", + "templateHash": "7757490711276971084" }, "name": "Event Hub Namespace Event Hub Consumer Groups", "description": "This module deploys an Event Hub Namespace Event Hub Consumer Group.", diff --git a/avm/res/event-hub/namespace/eventhub/main.bicep b/avm/res/event-hub/namespace/eventhub/main.bicep index 1cb2cbbf4d..199459adca 100644 --- a/avm/res/event-hub/namespace/eventhub/main.bicep +++ b/avm/res/event-hub/namespace/eventhub/main.bicep @@ -115,8 +115,12 @@ var eventHubProperties = { status: status retentionDescription: { cleanupPolicy: retentionDescriptionCleanupPolicy - retentionTimeInHours: retentionDescriptionCleanupPolicy == 'Delete' ? retentionDescriptionRetentionTimeInHours : null - tombstoneRetentionTimeInHours: retentionDescriptionCleanupPolicy == 'Compact' ? retentionDescriptionTombstoneRetentionTimeInHours : null + retentionTimeInHours: retentionDescriptionCleanupPolicy == 'Delete' + ? retentionDescriptionRetentionTimeInHours + : null + tombstoneRetentionTimeInHours: retentionDescriptionCleanupPolicy == 'Compact' + ? retentionDescriptionTombstoneRetentionTimeInHours + : null } } @@ -139,14 +143,29 @@ var eventHubPropertiesCapture = { } var builtInRoleNames = { - 'Azure Event Hubs Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec') - 'Azure Event Hubs Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde') - 'Azure Event Hubs Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975') + 'Azure Event Hubs Data Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f526a384-b230-433a-b45c-95f59c4a2dec' + ) + 'Azure Event Hubs Data Receiver': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde' + ) + 'Azure Event Hubs Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2b629674-e913-4c01-ae53-ef4638d8f975' + ) 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') + '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 namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { @@ -159,48 +178,61 @@ resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2022-10-01-preview' = properties: captureDescriptionEnabled ? union(eventHubProperties, eventHubPropertiesCapture) : eventHubProperties } -resource eventHub_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.' +resource eventHub_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: eventHub } - scope: eventHub -} -module eventHub_consumergroups 'consumergroup/main.bicep' = [for (consumerGroup, index) in consumergroups: { - name: '${deployment().name}-ConsumerGroup-${index}' - params: { - namespaceName: namespaceName - eventHubName: eventHub.name - name: consumerGroup.name - userMetadata: contains(consumerGroup, 'userMetadata') ? consumerGroup.userMetadata : '' +module eventHub_consumergroups 'consumergroup/main.bicep' = [ + for (consumerGroup, index) in consumergroups: { + name: '${deployment().name}-ConsumerGroup-${index}' + params: { + namespaceName: namespaceName + eventHubName: eventHub.name + name: consumerGroup.name + userMetadata: contains(consumerGroup, 'userMetadata') ? consumerGroup.userMetadata : '' + } } -}] - -module eventHub_authorizationRules 'authorization-rule/main.bicep' = [for (authorizationRule, index) in authorizationRules: { - name: '${deployment().name}-AuthRule-${index}' - params: { - namespaceName: namespaceName - eventHubName: eventHub.name - name: authorizationRule.name - rights: contains(authorizationRule, 'rights') ? authorizationRule.rights : [] +] + +module eventHub_authorizationRules 'authorization-rule/main.bicep' = [ + for (authorizationRule, index) in authorizationRules: { + name: '${deployment().name}-AuthRule-${index}' + params: { + namespaceName: namespaceName + eventHubName: eventHub.name + name: authorizationRule.name + rights: contains(authorizationRule, 'rights') ? authorizationRule.rights : [] + } } -}] - -resource eventHub_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(eventHub.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 +] + +resource eventHub_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(eventHub.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: eventHub } - scope: eventHub -}] +] @description('The name of the event hub.') output name string = eventHub.name diff --git a/avm/res/event-hub/namespace/eventhub/main.json b/avm/res/event-hub/namespace/eventhub/main.json index 57543ef237..d152f71273 100644 --- a/avm/res/event-hub/namespace/eventhub/main.json +++ b/avm/res/event-hub/namespace/eventhub/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8657514846937945810" + "version": "0.26.54.24096", + "templateHash": "14538170733088329405" }, "name": "Event Hub Namespace Event Hubs", "description": "This module deploys an Event Hub Namespace Event Hub.", @@ -416,8 +416,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "697710281814211564" + "version": "0.26.54.24096", + "templateHash": "7757490711276971084" }, "name": "Event Hub Namespace Event Hub Consumer Groups", "description": "This module deploys an Event Hub Namespace Event Hub Consumer Group.", @@ -520,8 +520,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16757979367783376523" + "version": "0.26.54.24096", + "templateHash": "15301134976738274567" }, "name": "Event Hub Namespace Event Hub Authorization Rules", "description": "This module deploys an Event Hub Namespace Event Hub Authorization Rule.", diff --git a/avm/res/event-hub/namespace/main.bicep b/avm/res/event-hub/namespace/main.bicep index ace3641cec..a6cda2cc83 100644 --- a/avm/res/event-hub/namespace/main.bicep +++ b/avm/res/event-hub/namespace/main.bicep @@ -106,55 +106,88 @@ param disasterRecoveryConfig object = {} var maximumThroughputUnitsVar = !isAutoInflateEnabled ? 0 : maximumThroughputUnits -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned, UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned, UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - 'Azure Event Hubs Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec') - 'Azure Event Hubs Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde') - 'Azure Event Hubs Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975') + 'Azure Event Hubs Data Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f526a384-b230-433a-b45c-95f59c4a2dec' + ) + 'Azure Event Hubs Data Receiver': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde' + ) + 'Azure Event Hubs Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2b629674-e913-4c01-ae53-ef4638d8f975' + ) 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') + '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 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 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 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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.eventhub-namespace.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.eventhub-namespace.${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 eventHubNamespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' = { name: name @@ -168,182 +201,260 @@ resource eventHubNamespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' = } properties: { disableLocalAuth: disableLocalAuth - encryption: !empty(customerManagedKey) ? { - keySource: 'Microsoft.KeyVault' - keyVaultProperties: [ - { - identity: !empty(customerManagedKey.?userAssignedIdentityResourceId) ? { - userAssignedIdentity: cMKUserAssignedIdentity.id - } : null - keyName: customerManagedKey!.keyName - keyVaultUri: cMKKeyVault.properties.vaultUri - keyVersion: !empty(customerManagedKey.?keyVersion ?? '') ? customerManagedKey!.keyVersion : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) + encryption: !empty(customerManagedKey) + ? { + keySource: 'Microsoft.KeyVault' + keyVaultProperties: [ + { + identity: !empty(customerManagedKey.?userAssignedIdentityResourceId) + ? { + userAssignedIdentity: cMKUserAssignedIdentity.id + } + : null + keyName: customerManagedKey!.keyName + keyVaultUri: cMKKeyVault.properties.vaultUri + keyVersion: !empty(customerManagedKey.?keyVersion ?? '') + ? customerManagedKey!.keyVersion + : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) + } + ] + requireInfrastructureEncryption: requireInfrastructureEncryption } - ] - requireInfrastructureEncryption: requireInfrastructureEncryption - } : null + : null isAutoInflateEnabled: isAutoInflateEnabled kafkaEnabled: kafkaEnabled maximumThroughputUnits: maximumThroughputUnitsVar minimumTlsVersion: minimumTlsVersion - publicNetworkAccess: contains(networkRuleSets, 'publicNetworkAccess') ? networkRuleSets.publicNetworkAccess : (!empty(privateEndpoints) && empty(networkRuleSets) ? 'Disabled' : publicNetworkAccess) + publicNetworkAccess: contains(networkRuleSets, 'publicNetworkAccess') + ? networkRuleSets.publicNetworkAccess + : (!empty(privateEndpoints) && empty(networkRuleSets) ? 'Disabled' : publicNetworkAccess) zoneRedundant: zoneRedundant } } -module eventHubNamespace_authorizationRules 'authorization-rule/main.bicep' = [for (authorizationRule, index) in authorizationRules: { - name: '${uniqueString(deployment().name, location)}-EvhbNamespace-AuthRule-${index}' - params: { - namespaceName: eventHubNamespace.name - name: authorizationRule.name - rights: contains(authorizationRule, 'rights') ? authorizationRule.rights : [] +module eventHubNamespace_authorizationRules 'authorization-rule/main.bicep' = [ + for (authorizationRule, index) in authorizationRules: { + name: '${uniqueString(deployment().name, location)}-EvhbNamespace-AuthRule-${index}' + params: { + namespaceName: eventHubNamespace.name + name: authorizationRule.name + rights: contains(authorizationRule, 'rights') ? authorizationRule.rights : [] + } } -}] - -module eventHubNamespace_disasterRecoveryConfig 'disaster-recovery-config/main.bicep' = if (!empty(disasterRecoveryConfig)) { - name: '${uniqueString(deployment().name, location)}-EvhbNamespace-DisRecConfig' - params: { - namespaceName: eventHubNamespace.name - name: disasterRecoveryConfig.name - partnerNamespaceId: contains(disasterRecoveryConfig, 'partnerNamespaceId') ? disasterRecoveryConfig.partnerNamespaceId : '' +] + +module eventHubNamespace_disasterRecoveryConfig 'disaster-recovery-config/main.bicep' = + if (!empty(disasterRecoveryConfig)) { + name: '${uniqueString(deployment().name, location)}-EvhbNamespace-DisRecConfig' + params: { + namespaceName: eventHubNamespace.name + name: disasterRecoveryConfig.name + partnerNamespaceId: contains(disasterRecoveryConfig, 'partnerNamespaceId') + ? disasterRecoveryConfig.partnerNamespaceId + : '' + } } -} -module eventHubNamespace_eventhubs 'eventhub/main.bicep' = [for (eventHub, index) in eventhubs: { - name: '${uniqueString(deployment().name, location)}-EvhbNamespace-EventHub-${index}' - params: { - namespaceName: eventHubNamespace.name - name: eventHub.name - authorizationRules: contains(eventHub, 'authorizationRules') ? eventHub.authorizationRules : [ - { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] - } - ] - captureDescriptionDestinationArchiveNameFormat: contains(eventHub, 'captureDescriptionDestinationArchiveNameFormat') ? eventHub.captureDescriptionDestinationArchiveNameFormat : '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' - captureDescriptionDestinationBlobContainer: contains(eventHub, 'captureDescriptionDestinationBlobContainer') ? eventHub.captureDescriptionDestinationBlobContainer : '' - captureDescriptionDestinationName: contains(eventHub, 'captureDescriptionDestinationName') ? eventHub.captureDescriptionDestinationName : 'EventHubArchive.AzureBlockBlob' - captureDescriptionDestinationStorageAccountResourceId: contains(eventHub, 'captureDescriptionDestinationStorageAccountResourceId') ? eventHub.captureDescriptionDestinationStorageAccountResourceId : '' - captureDescriptionEnabled: contains(eventHub, 'captureDescriptionEnabled') ? eventHub.captureDescriptionEnabled : false - captureDescriptionEncoding: contains(eventHub, 'captureDescriptionEncoding') ? eventHub.captureDescriptionEncoding : 'Avro' - captureDescriptionIntervalInSeconds: contains(eventHub, 'captureDescriptionIntervalInSeconds') ? eventHub.captureDescriptionIntervalInSeconds : 300 - captureDescriptionSizeLimitInBytes: contains(eventHub, 'captureDescriptionSizeLimitInBytes') ? eventHub.captureDescriptionSizeLimitInBytes : 314572800 - captureDescriptionSkipEmptyArchives: contains(eventHub, 'captureDescriptionSkipEmptyArchives') ? eventHub.captureDescriptionSkipEmptyArchives : false - consumergroups: contains(eventHub, 'consumergroups') ? eventHub.consumergroups : [] - lock: eventHub.?lock ?? lock - messageRetentionInDays: contains(eventHub, 'messageRetentionInDays') ? eventHub.messageRetentionInDays : 1 - partitionCount: contains(eventHub, 'partitionCount') ? eventHub.partitionCount : 2 - roleAssignments: contains(eventHub, 'roleAssignments') ? eventHub.roleAssignments : [] - status: contains(eventHub, 'status') ? eventHub.status : 'Active' - retentionDescriptionCleanupPolicy: contains(eventHub, 'retentionDescriptionCleanupPolicy') ? eventHub.retentionDescriptionCleanupPolicy : 'Delete' - retentionDescriptionRetentionTimeInHours: contains(eventHub, 'retentionDescriptionRetentionTimeInHours') ? eventHub.retentionDescriptionRetentionTimeInHours : 1 - retentionDescriptionTombstoneRetentionTimeInHours: contains(eventHub, 'retentionDescriptionTombstoneRetentionTimeInHours') ? eventHub.retentionDescriptionTombstoneRetentionTimeInHours : 1 +module eventHubNamespace_eventhubs 'eventhub/main.bicep' = [ + for (eventHub, index) in eventhubs: { + name: '${uniqueString(deployment().name, location)}-EvhbNamespace-EventHub-${index}' + params: { + namespaceName: eventHubNamespace.name + name: eventHub.name + authorizationRules: contains(eventHub, 'authorizationRules') + ? eventHub.authorizationRules + : [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + ] + captureDescriptionDestinationArchiveNameFormat: contains( + eventHub, + 'captureDescriptionDestinationArchiveNameFormat' + ) + ? eventHub.captureDescriptionDestinationArchiveNameFormat + : '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' + captureDescriptionDestinationBlobContainer: contains(eventHub, 'captureDescriptionDestinationBlobContainer') + ? eventHub.captureDescriptionDestinationBlobContainer + : '' + captureDescriptionDestinationName: contains(eventHub, 'captureDescriptionDestinationName') + ? eventHub.captureDescriptionDestinationName + : 'EventHubArchive.AzureBlockBlob' + captureDescriptionDestinationStorageAccountResourceId: contains( + eventHub, + 'captureDescriptionDestinationStorageAccountResourceId' + ) + ? eventHub.captureDescriptionDestinationStorageAccountResourceId + : '' + captureDescriptionEnabled: contains(eventHub, 'captureDescriptionEnabled') + ? eventHub.captureDescriptionEnabled + : false + captureDescriptionEncoding: contains(eventHub, 'captureDescriptionEncoding') + ? eventHub.captureDescriptionEncoding + : 'Avro' + captureDescriptionIntervalInSeconds: contains(eventHub, 'captureDescriptionIntervalInSeconds') + ? eventHub.captureDescriptionIntervalInSeconds + : 300 + captureDescriptionSizeLimitInBytes: contains(eventHub, 'captureDescriptionSizeLimitInBytes') + ? eventHub.captureDescriptionSizeLimitInBytes + : 314572800 + captureDescriptionSkipEmptyArchives: contains(eventHub, 'captureDescriptionSkipEmptyArchives') + ? eventHub.captureDescriptionSkipEmptyArchives + : false + consumergroups: contains(eventHub, 'consumergroups') ? eventHub.consumergroups : [] + lock: eventHub.?lock ?? lock + messageRetentionInDays: contains(eventHub, 'messageRetentionInDays') ? eventHub.messageRetentionInDays : 1 + partitionCount: contains(eventHub, 'partitionCount') ? eventHub.partitionCount : 2 + roleAssignments: contains(eventHub, 'roleAssignments') ? eventHub.roleAssignments : [] + status: contains(eventHub, 'status') ? eventHub.status : 'Active' + retentionDescriptionCleanupPolicy: contains(eventHub, 'retentionDescriptionCleanupPolicy') + ? eventHub.retentionDescriptionCleanupPolicy + : 'Delete' + retentionDescriptionRetentionTimeInHours: contains(eventHub, 'retentionDescriptionRetentionTimeInHours') + ? eventHub.retentionDescriptionRetentionTimeInHours + : 1 + retentionDescriptionTombstoneRetentionTimeInHours: contains( + eventHub, + 'retentionDescriptionTombstoneRetentionTimeInHours' + ) + ? eventHub.retentionDescriptionTombstoneRetentionTimeInHours + : 1 + } } -}] - -module eventHubNamespace_networkRuleSet 'network-rule-set/main.bicep' = if (!empty(networkRuleSets) || !empty(privateEndpoints)) { - name: '${uniqueString(deployment().name, location)}-EvhbNamespace-NetworkRuleSet' - params: { - namespaceName: eventHubNamespace.name - publicNetworkAccess: contains(networkRuleSets, 'publicNetworkAccess') ? networkRuleSets.publicNetworkAccess : (!empty(privateEndpoints) && empty(networkRuleSets) ? 'Disabled' : 'Enabled') - defaultAction: contains(networkRuleSets, 'defaultAction') ? networkRuleSets.defaultAction : 'Allow' - trustedServiceAccessEnabled: networkRuleSets.?trustedServiceAccessEnabled - ipRules: contains(networkRuleSets, 'ipRules') ? networkRuleSets.ipRules : [] - virtualNetworkRules: contains(networkRuleSets, 'virtualNetworkRules') ? networkRuleSets.virtualNetworkRules : [] +] + +module eventHubNamespace_networkRuleSet 'network-rule-set/main.bicep' = + if (!empty(networkRuleSets) || !empty(privateEndpoints)) { + name: '${uniqueString(deployment().name, location)}-EvhbNamespace-NetworkRuleSet' + params: { + namespaceName: eventHubNamespace.name + publicNetworkAccess: contains(networkRuleSets, 'publicNetworkAccess') + ? networkRuleSets.publicNetworkAccess + : (!empty(privateEndpoints) && empty(networkRuleSets) ? 'Disabled' : 'Enabled') + defaultAction: contains(networkRuleSets, 'defaultAction') ? networkRuleSets.defaultAction : 'Allow' + trustedServiceAccessEnabled: networkRuleSets.?trustedServiceAccessEnabled + ipRules: contains(networkRuleSets, 'ipRules') ? networkRuleSets.ipRules : [] + virtualNetworkRules: contains(networkRuleSets, 'virtualNetworkRules') ? networkRuleSets.virtualNetworkRules : [] + } } -} -module eventHubNamespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-EventHubNamespace-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' - properties: { - privateLinkServiceId: eventHubNamespace.id - groupIds: [ - privateEndpoint.?service ?? 'namespace' +module eventHubNamespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-EventHubNamespace-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + properties: { + privateLinkServiceId: eventHubNamespace.id + groupIds: [ + privateEndpoint.?service ?? 'namespace' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' - properties: { - privateLinkServiceId: eventHubNamespace.id - groupIds: [ - privateEndpoint.?service ?? 'namespace' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + properties: { + privateLinkServiceId: eventHubNamespace.id + groupIds: [ + privateEndpoint.?service ?? 'namespace' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource eventHubNamespace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(eventHubNamespace.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 +resource eventHubNamespace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(eventHubNamespace.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: eventHubNamespace } - scope: eventHubNamespace -}] +] -resource eventHubNamespace_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.' +resource eventHubNamespace_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: eventHubNamespace } - scope: eventHubNamespace -} -resource eventHubNamespace_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 - 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 +resource eventHubNamespace_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 + 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 + } + scope: eventHubNamespace } - scope: eventHubNamespace -}] +] @description('The name of the eventspace.') output name string = eventHubNamespace.name @@ -361,7 +472,9 @@ output systemAssignedMIPrincipalId string = eventHubNamespace.?identity.?princip output location string = eventHubNamespace.location @description('The Resources IDs of the EventHubs within this eventspace.') -output eventHubResourceIds array = [for index in range(0, length(eventhubs ?? [])): eventHubNamespace_eventhubs[index].outputs.resourceId] +output eventHubResourceIds array = [ + for index in range(0, length(eventhubs ?? [])): eventHubNamespace_eventhubs[index].outputs.resourceId +] // =============== // // Definitions // diff --git a/avm/res/event-hub/namespace/main.json b/avm/res/event-hub/namespace/main.json index fa65131a62..95d0847f8a 100644 --- a/avm/res/event-hub/namespace/main.json +++ b/avm/res/event-hub/namespace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11007166139796021582" + "version": "0.26.54.24096", + "templateHash": "5884251970985873966" }, "name": "Event Hub Namespaces", "description": "This module deploys an Event Hub Namespace.", @@ -854,8 +854,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10638309014943371587" + "version": "0.26.54.24096", + "templateHash": "15327912662565121564" }, "name": "Event Hub Namespace Authorization Rule", "description": "This module deploys an Event Hub Namespace Authorization Rule.", @@ -951,8 +951,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14933577565840576961" + "version": "0.26.54.24096", + "templateHash": "11732013494690054024" }, "name": "Event Hub Namespace Disaster Recovery Configs", "description": "This module deploys an Event Hub Namespace Disaster Recovery Config.", @@ -1067,8 +1067,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8657514846937945810" + "version": "0.26.54.24096", + "templateHash": "14538170733088329405" }, "name": "Event Hub Namespace Event Hubs", "description": "This module deploys an Event Hub Namespace Event Hub.", @@ -1478,8 +1478,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "697710281814211564" + "version": "0.26.54.24096", + "templateHash": "7757490711276971084" }, "name": "Event Hub Namespace Event Hub Consumer Groups", "description": "This module deploys an Event Hub Namespace Event Hub Consumer Group.", @@ -1582,8 +1582,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16757979367783376523" + "version": "0.26.54.24096", + "templateHash": "15301134976738274567" }, "name": "Event Hub Namespace Event Hub Authorization Rules", "description": "This module deploys an Event Hub Namespace Event Hub Authorization Rule.", @@ -1718,8 +1718,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11239292624069957748" + "version": "0.26.54.24096", + "templateHash": "3984181780336367181" }, "name": "Event Hub Namespace Network Rule Sets", "description": "This module deploys an Event Hub Namespace Network Rule Set.", diff --git a/avm/res/event-hub/namespace/network-rule-set/main.bicep b/avm/res/event-hub/namespace/network-rule-set/main.bicep index 925095ca39..382e1a8e3e 100644 --- a/avm/res/event-hub/namespace/network-rule-set/main.bicep +++ b/avm/res/event-hub/namespace/network-rule-set/main.bicep @@ -29,14 +29,20 @@ param virtualNetworkRules array = [] param ipRules array = [] @description('Optional. The name of the network ruleset.') - param networkRuleSetName string = 'default' +param networkRuleSetName string = 'default' -var networkRules = [for (virtualNetworkRule, index) in virtualNetworkRules: { - ignoreMissingVnetServiceEndpoint: contains(virtualNetworkRule, 'ignoreMissingVnetServiceEndpoint') ? virtualNetworkRule.ignoreMissingVnetServiceEndpoint : null - subnet: contains(virtualNetworkRule, 'subnetResourceId') ? { - id: virtualNetworkRule.subnetResourceId - } : null -}] +var networkRules = [ + for (virtualNetworkRule, index) in virtualNetworkRules: { + ignoreMissingVnetServiceEndpoint: contains(virtualNetworkRule, 'ignoreMissingVnetServiceEndpoint') + ? virtualNetworkRule.ignoreMissingVnetServiceEndpoint + : null + subnet: contains(virtualNetworkRule, 'subnetResourceId') + ? { + id: virtualNetworkRule.subnetResourceId + } + : null + } +] resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { name: namespaceName @@ -47,7 +53,9 @@ resource networkRuleSet 'Microsoft.EventHub/namespaces/networkRuleSets@2022-10-0 parent: namespace properties: { publicNetworkAccess: publicNetworkAccess - defaultAction: publicNetworkAccess == 'Disabled' ? null : (!empty(ipRules) || !empty(virtualNetworkRules) ? 'Deny' : defaultAction) + defaultAction: publicNetworkAccess == 'Disabled' + ? null + : (!empty(ipRules) || !empty(virtualNetworkRules) ? 'Deny' : defaultAction) trustedServiceAccessEnabled: trustedServiceAccessEnabled ipRules: publicNetworkAccess == 'Disabled' ? null : ipRules virtualNetworkRules: publicNetworkAccess == 'Disabled' ? null : networkRules diff --git a/avm/res/event-hub/namespace/network-rule-set/main.json b/avm/res/event-hub/namespace/network-rule-set/main.json index 923c335e93..2a82bd5fc8 100644 --- a/avm/res/event-hub/namespace/network-rule-set/main.json +++ b/avm/res/event-hub/namespace/network-rule-set/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11239292624069957748" + "version": "0.26.54.24096", + "templateHash": "3984181780336367181" }, "name": "Event Hub Namespace Network Rule Sets", "description": "This module deploys an Event Hub Namespace Network Rule Set.", diff --git a/avm/res/event-hub/namespace/tests/e2e/defaults/main.test.bicep b/avm/res/event-hub/namespace/tests/e2e/defaults/main.test.bicep index b6a55d3ace..1e04339dfb 100644 --- a/avm/res/event-hub/namespace/tests/e2e/defaults/main.test.bicep +++ b/avm/res/event-hub/namespace/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/event-hub/namespace/tests/e2e/encr/dependencies.bicep b/avm/res/event-hub/namespace/tests/e2e/encr/dependencies.bicep index dab158fd15..6c4085b1e5 100644 --- a/avm/res/event-hub/namespace/tests/e2e/encr/dependencies.bicep +++ b/avm/res/event-hub/namespace/tests/e2e/encr/dependencies.bicep @@ -69,7 +69,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { properties: { principalId: managedIdentity.properties.principalId // Key Vault Crypto User - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) principalType: 'ServicePrincipal' } } diff --git a/avm/res/event-hub/namespace/tests/e2e/encr/main.test.bicep b/avm/res/event-hub/namespace/tests/e2e/encr/main.test.bicep index d4296b83d8..ae8a447877 100644 --- a/avm/res/event-hub/namespace/tests/e2e/encr/main.test.bicep +++ b/avm/res/event-hub/namespace/tests/e2e/encr/main.test.bicep @@ -3,7 +3,6 @@ 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 // // ========== // diff --git a/avm/res/event-hub/namespace/tests/e2e/max/main.test.bicep b/avm/res/event-hub/namespace/tests/e2e/max/main.test.bicep index 4433a3e1a0..b4f2b5c6c3 100644 --- a/avm/res/event-hub/namespace/tests/e2e/max/main.test.bicep +++ b/avm/res/event-hub/namespace/tests/e2e/max/main.test.bicep @@ -59,178 +59,183 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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 - zoneRedundant: true - skuName: 'Standard' - skuCapacity: 2 - authorizationRules: [ - { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] - } - { - name: 'SendListenAccess' - rights: [ - 'Listen' - 'Send' - ] - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - eventhubs: [ - { - name: '${namePrefix}-az-evh-x-001' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] +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 + zoneRedundant: true + skuName: 'Standard' + skuCapacity: 2 + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + eventhubs: [ + { + name: '${namePrefix}-az-evh-x-001' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + } + { + name: '${namePrefix}-az-evh-x-002' + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + captureDescriptionDestinationArchiveNameFormat: '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' + captureDescriptionDestinationBlobContainer: 'eventhub' + captureDescriptionDestinationName: 'EventHubArchive.AzureBlockBlob' + captureDescriptionDestinationStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + captureDescriptionEnabled: true + captureDescriptionEncoding: 'Avro' + captureDescriptionIntervalInSeconds: 300 + captureDescriptionSizeLimitInBytes: 314572800 + captureDescriptionSkipEmptyArchives: true + consumergroups: [ + { + name: 'custom' + userMetadata: 'customMetadata' + } + ] + messageRetentionInDays: 1 + partitionCount: 2 + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + status: 'Active' + retentionDescriptionCleanupPolicy: 'Delete' + retentionDescriptionRetentionTimeInHours: 3 + } + { + name: '${namePrefix}-az-evh-x-003' + retentionDescriptionCleanupPolicy: 'Compact' + retentionDescriptionTombstoneRetentionTimeInHours: 24 + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - name: '${namePrefix}-az-evh-x-002' - authorizationRules: [ + networkRuleSets: { + defaultAction: 'Deny' + ipRules: [ { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] - } - { - name: 'SendListenAccess' - rights: [ - 'Listen' - 'Send' - ] + action: 'Allow' + ipMask: '10.10.10.10' } ] - captureDescriptionDestinationArchiveNameFormat: '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' - captureDescriptionDestinationBlobContainer: 'eventhub' - captureDescriptionDestinationName: 'EventHubArchive.AzureBlockBlob' - captureDescriptionDestinationStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - captureDescriptionEnabled: true - captureDescriptionEncoding: 'Avro' - captureDescriptionIntervalInSeconds: 300 - captureDescriptionSizeLimitInBytes: 314572800 - captureDescriptionSkipEmptyArchives: true - consumergroups: [ + trustedServiceAccessEnabled: false + publicNetworkAccess: 'Disabled' + virtualNetworkRules: [ { - name: 'custom' - userMetadata: 'customMetadata' + ignoreMissingVnetServiceEndpoint: true + subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] - messageRetentionInDays: 1 - partitionCount: 2 - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - status: 'Active' - retentionDescriptionCleanupPolicy: 'Delete' - retentionDescriptionRetentionTimeInHours: 3 - } - { - name: '${namePrefix}-az-evh-x-003' - retentionDescriptionCleanupPolicy: 'Compact' - retentionDescriptionTombstoneRetentionTimeInHours: 24 } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - networkRuleSets: { - defaultAction: 'Deny' - ipRules: [ + privateEndpoints: [ { - action: 'Allow' - ipMask: '10.10.10.10' + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'namespace' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } ] - trustedServiceAccessEnabled: false - publicNetworkAccess: 'Disabled' - virtualNetworkRules: [ + roleAssignments: [ { - ignoreMissingVnetServiceEndpoint: true - subnetResourceId: nestedDependencies.outputs.subnetResourceId + 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 + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] - service: 'namespace' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - ] - 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' } - ] - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + kafkaEnabled: true + disableLocalAuth: true + isAutoInflateEnabled: true + minimumTlsVersion: '1.2' + maximumThroughputUnits: 4 + publicNetworkAccess: 'Disabled' } - kafkaEnabled: true - disableLocalAuth: true - isAutoInflateEnabled: true - minimumTlsVersion: '1.2' - maximumThroughputUnits: 4 - publicNetworkAccess: 'Disabled' } -}] +] diff --git a/avm/res/event-hub/namespace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/event-hub/namespace/tests/e2e/waf-aligned/main.test.bicep index 607e156738..cf65bb6f5e 100644 --- a/avm/res/event-hub/namespace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/event-hub/namespace/tests/e2e/waf-aligned/main.test.bicep @@ -58,135 +58,137 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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 - zoneRedundant: true - skuName: 'Standard' - skuCapacity: 2 - authorizationRules: [ - { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] - } - { - name: 'SendListenAccess' - rights: [ - 'Listen' - 'Send' - ] - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - eventhubs: [ - { - name: '${namePrefix}-az-evh-x-001' - } - { - name: '${namePrefix}-az-evh-x-002' - authorizationRules: [ - { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] - } +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 + zoneRedundant: true + skuName: 'Standard' + skuCapacity: 2 + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + eventhubs: [ + { + name: '${namePrefix}-az-evh-x-001' + } + { + name: '${namePrefix}-az-evh-x-002' + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + captureDescriptionDestinationArchiveNameFormat: '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' + captureDescriptionDestinationBlobContainer: 'eventhub' + captureDescriptionDestinationName: 'EventHubArchive.AzureBlockBlob' + captureDescriptionDestinationStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + captureDescriptionEnabled: true + captureDescriptionEncoding: 'Avro' + captureDescriptionIntervalInSeconds: 300 + captureDescriptionSizeLimitInBytes: 314572800 + captureDescriptionSkipEmptyArchives: true + consumergroups: [ + { + name: 'custom' + userMetadata: 'customMetadata' + } + ] + messageRetentionInDays: 1 + partitionCount: 2 + status: 'Active' + retentionDescriptionCleanupPolicy: 'Delete' + retentionDescriptionRetentionTimeInHours: 3 + } + { + name: '${namePrefix}-az-evh-x-003' + retentionDescriptionCleanupPolicy: 'Compact' + retentionDescriptionTombstoneRetentionTimeInHours: 24 + } + ] + networkRuleSets: { + defaultAction: 'Deny' + ipRules: [ { - name: 'SendListenAccess' - rights: [ - 'Listen' - 'Send' - ] + action: 'Allow' + ipMask: '10.10.10.10' } ] - captureDescriptionDestinationArchiveNameFormat: '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' - captureDescriptionDestinationBlobContainer: 'eventhub' - captureDescriptionDestinationName: 'EventHubArchive.AzureBlockBlob' - captureDescriptionDestinationStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - captureDescriptionEnabled: true - captureDescriptionEncoding: 'Avro' - captureDescriptionIntervalInSeconds: 300 - captureDescriptionSizeLimitInBytes: 314572800 - captureDescriptionSkipEmptyArchives: true - consumergroups: [ + trustedServiceAccessEnabled: false + virtualNetworkRules: [ { - name: 'custom' - userMetadata: 'customMetadata' + ignoreMissingVnetServiceEndpoint: true + subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] - messageRetentionInDays: 1 - partitionCount: 2 - status: 'Active' - retentionDescriptionCleanupPolicy: 'Delete' - retentionDescriptionRetentionTimeInHours: 3 - } - { - name: '${namePrefix}-az-evh-x-003' - retentionDescriptionCleanupPolicy: 'Compact' - retentionDescriptionTombstoneRetentionTimeInHours: 24 } - ] - networkRuleSets: { - defaultAction: 'Deny' - ipRules: [ - { - action: 'Allow' - ipMask: '10.10.10.10' - } - ] - trustedServiceAccessEnabled: false - virtualNetworkRules: [ + privateEndpoints: [ { - ignoreMissingVnetServiceEndpoint: true + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } ] - } - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } + kafkaEnabled: true + disableLocalAuth: true + isAutoInflateEnabled: true + minimumTlsVersion: '1.2' + maximumThroughputUnits: 4 + publicNetworkAccess: 'Disabled' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - kafkaEnabled: true - disableLocalAuth: true - isAutoInflateEnabled: true - minimumTlsVersion: '1.2' - maximumThroughputUnits: 4 - publicNetworkAccess: 'Disabled' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/health-bot/health-bot/main.bicep b/avm/res/health-bot/health-bot/main.bicep index 646bd61273..cbf4ac9fb9 100644 --- a/avm/res/health-bot/health-bot/main.bicep +++ b/avm/res/health-bot/health-bot/main.bicep @@ -31,38 +31,51 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: !empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: !empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : 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') - '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') + '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.healthbot-healthbot.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.healthbot-healthbot.${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 healthBot 'Microsoft.HealthBot/healthBots@2022-08-08' = { name: name @@ -75,28 +88,37 @@ resource healthBot 'Microsoft.HealthBot/healthBots@2022-08-08' = { properties: {} } -resource healthBot_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.' +resource healthBot_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: healthBot } - scope: healthBot -} -resource healthBot_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(healthBot.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 +resource healthBot_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(healthBot.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: healthBot } - scope: healthBot -}] +] @description('The resource group the health bot was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/health-bot/health-bot/main.json b/avm/res/health-bot/health-bot/main.json index 6f8d59ab81..acc6bacc25 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.25.53.49325", - "templateHash": "13278518763850368052" + "version": "0.26.54.24096", + "templateHash": "13957265537042927127" }, "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 8b458aca57..767ab4af97 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 @@ -36,12 +36,14 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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: resourceGroup.location - sku: 'F0' +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: resourceGroup.location + sku: 'F0' + } } -}] +] diff --git a/avm/res/health-bot/health-bot/tests/e2e/max/dependencies.bicep b/avm/res/health-bot/health-bot/tests/e2e/max/dependencies.bicep index 539240be2b..ad4e2ec09a 100644 --- a/avm/res/health-bot/health-bot/tests/e2e/max/dependencies.bicep +++ b/avm/res/health-bot/health-bot/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The resource ID of the created Managed Identity.') 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 173d84268b..bb00e40d5f 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 @@ -45,46 +45,51 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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: resourceGroup.location - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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: resourceGroup.location + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + sku: 'F0' + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - sku: 'F0' - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] 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 ca8e64a199..f559c16801 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 @@ -36,21 +36,23 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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: resourceGroup.location - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' +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: resourceGroup.location + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + sku: 'F0' } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - sku: 'F0' } -}] +] diff --git a/avm/res/insights/action-group/main.bicep b/avm/res/insights/action-group/main.bicep index 8f4dfc69e5..89ad05f0ba 100644 --- a/avm/res/insights/action-group/main.bicep +++ b/avm/res/insights/action-group/main.bicep @@ -57,27 +57,34 @@ 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') + '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.insights-actiongroup.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.insights-actiongroup.${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 actionGroup 'Microsoft.Insights/actionGroups@2023-01-01' = { name: name @@ -99,19 +106,25 @@ resource actionGroup 'Microsoft.Insights/actionGroups@2023-01-01' = { } } -resource actionGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(actionGroup.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 +resource actionGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(actionGroup.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: actionGroup } - scope: actionGroup -}] +] @description('The resource group the action group was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/insights/action-group/main.json b/avm/res/insights/action-group/main.json index db92f1556e..baa6e6af1e 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.25.53.49325", - "templateHash": "452819506402297284" + "version": "0.26.54.24096", + "templateHash": "3572364605280930173" }, "name": "Action Groups", "description": "This module deploys an Action Group.", diff --git a/avm/res/insights/action-group/tests/e2e/defaults/main.test.bicep b/avm/res/insights/action-group/tests/e2e/defaults/main.test.bicep index 6091b16997..9f0d06aa1f 100644 --- a/avm/res/insights/action-group/tests/e2e/defaults/main.test.bicep +++ b/avm/res/insights/action-group/tests/e2e/defaults/main.test.bicep @@ -36,12 +36,14 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - groupShortName: 'ag${serviceShort}001' +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' + groupShortName: 'ag${serviceShort}001' + } } -}] +] diff --git a/avm/res/insights/action-group/tests/e2e/max/dependencies.bicep b/avm/res/insights/action-group/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/insights/action-group/tests/e2e/max/dependencies.bicep +++ b/avm/res/insights/action-group/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/insights/action-group/tests/e2e/max/main.test.bicep b/avm/res/insights/action-group/tests/e2e/max/main.test.bicep index a11a34591d..3a06f69507 100644 --- a/avm/res/insights/action-group/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/action-group/tests/e2e/max/main.test.bicep @@ -45,53 +45,58 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - groupShortName: 'ag${serviceShort}001' - emailReceivers: [ - { - emailAddress: 'test.user@testcompany.com' - name: 'TestUser_-EmailAction-' - useCommonAlertSchema: true - } - { - emailAddress: 'test.user2@testcompany.com' - name: 'TestUser2' - useCommonAlertSchema: true - } - ] - 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' - } - ] - smsReceivers: [ - { - countryCode: '1' - name: 'TestUser_-SMSAction-' - phoneNumber: '2345678901' +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' + groupShortName: 'ag${serviceShort}001' + emailReceivers: [ + { + emailAddress: 'test.user@testcompany.com' + name: 'TestUser_-EmailAction-' + useCommonAlertSchema: true + } + { + emailAddress: 'test.user2@testcompany.com' + name: 'TestUser2' + useCommonAlertSchema: true + } + ] + 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' + } + ] + smsReceivers: [ + { + countryCode: '1' + name: 'TestUser_-SMSAction-' + phoneNumber: '2345678901' + } + ] + 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/insights/action-group/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/insights/action-group/tests/e2e/waf-aligned/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/insights/action-group/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/insights/action-group/tests/e2e/waf-aligned/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/insights/action-group/tests/e2e/waf-aligned/main.test.bicep b/avm/res/insights/action-group/tests/e2e/waf-aligned/main.test.bicep index 68492a4ecb..e2195df6ee 100644 --- a/avm/res/insights/action-group/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/insights/action-group/tests/e2e/waf-aligned/main.test.bicep @@ -45,17 +45,19 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - groupShortName: 'ag${serviceShort}001' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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' + groupShortName: 'ag${serviceShort}001' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/insights/activity-log-alert/main.bicep b/avm/res/insights/activity-log-alert/main.bicep index 231f56fca7..559309346a 100644 --- a/avm/res/insights/activity-log-alert/main.bicep +++ b/avm/res/insights/activity-log-alert/main.bicep @@ -34,36 +34,45 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var actionGroups = [for action in actions: { - actionGroupId: contains(action, 'actionGroupId') ? action.actionGroupId : action - webhookProperties: contains(action, 'webhookProperties') ? action.webhookProperties : null -}] +var actionGroups = [ + for action in actions: { + actionGroupId: contains(action, 'actionGroupId') ? action.actionGroupId : action + webhookProperties: contains(action, 'webhookProperties') ? action.webhookProperties : 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') - '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') + '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.insights-activitylogalert.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.insights-activitylogalert.${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 activityLogAlert 'Microsoft.Insights/activityLogAlerts@2020-10-01' = { name: name @@ -82,19 +91,25 @@ resource activityLogAlert 'Microsoft.Insights/activityLogAlerts@2020-10-01' = { } } -resource activityLogAlert_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(activityLogAlert.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 +resource activityLogAlert_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(activityLogAlert.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: activityLogAlert } - scope: activityLogAlert -}] +] @description('The name of the activity log alert.') output name string = activityLogAlert.name diff --git a/avm/res/insights/activity-log-alert/main.json b/avm/res/insights/activity-log-alert/main.json index 567c3f6c42..e7904d72d1 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.25.53.49325", - "templateHash": "11885081769153040344" + "version": "0.26.54.24096", + "templateHash": "4555927328226234726" }, "name": "Activity Log Alerts", "description": "This module deploys an Activity Log Alert.", diff --git a/avm/res/insights/activity-log-alert/tests/e2e/defaults/main.test.bicep b/avm/res/insights/activity-log-alert/tests/e2e/defaults/main.test.bicep index 3de3c2af28..5b099760e2 100644 --- a/avm/res/insights/activity-log-alert/tests/e2e/defaults/main.test.bicep +++ b/avm/res/insights/activity-log-alert/tests/e2e/defaults/main.test.bicep @@ -36,41 +36,43 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - conditions: [ - { - field: 'category' - equals: 'ServiceHealth' - } - { - anyOf: [ - { - field: 'properties.incidentType' - equals: 'Incident' - } - { - field: 'properties.incidentType' - equals: 'Maintenance' - } - ] - } - { - field: 'properties.impactedServices[*].ServiceName' - containsAny: [ - 'Storage' - ] - } - { - field: 'properties.impactedServices[*].ImpactedRegions[*].RegionName' - containsAny: [ - 'West Europe' - ] - } - ] +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' + conditions: [ + { + field: 'category' + equals: 'ServiceHealth' + } + { + anyOf: [ + { + field: 'properties.incidentType' + equals: 'Incident' + } + { + field: 'properties.incidentType' + equals: 'Maintenance' + } + ] + } + { + field: 'properties.impactedServices[*].ServiceName' + containsAny: [ + 'Storage' + ] + } + { + field: 'properties.impactedServices[*].ImpactedRegions[*].RegionName' + containsAny: [ + 'West Europe' + ] + } + ] + } } -}] +] diff --git a/avm/res/insights/activity-log-alert/tests/e2e/max/main.test.bicep b/avm/res/insights/activity-log-alert/tests/e2e/max/main.test.bicep index 796fb3756e..dd3bb2c84b 100644 --- a/avm/res/insights/activity-log-alert/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/activity-log-alert/tests/e2e/max/main.test.bicep @@ -46,73 +46,78 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - conditions: [ - { - field: 'category' - equals: 'ServiceHealth' - } - { - anyOf: [ - { - field: 'properties.incidentType' - equals: 'Incident' - } - { - field: 'properties.incidentType' - equals: 'Maintenance' - } - ] - } - { - field: 'properties.impactedServices[*].ServiceName' - containsAny: [ - 'Action Groups' - 'Activity Logs & Alerts' - ] - } - { - field: 'properties.impactedServices[*].ImpactedRegions[*].RegionName' - containsAny: [ - 'West Europe' - 'Global' - ] - } - ] - actions: [ - { - actionGroupId: nestedDependencies.outputs.actionGroupResourceId - } - ] - 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' +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' + conditions: [ + { + field: 'category' + equals: 'ServiceHealth' + } + { + anyOf: [ + { + field: 'properties.incidentType' + equals: 'Incident' + } + { + field: 'properties.incidentType' + equals: 'Maintenance' + } + ] + } + { + field: 'properties.impactedServices[*].ServiceName' + containsAny: [ + 'Action Groups' + 'Activity Logs & Alerts' + ] + } + { + field: 'properties.impactedServices[*].ImpactedRegions[*].RegionName' + containsAny: [ + 'West Europe' + 'Global' + ] + } + ] + actions: [ + { + actionGroupId: nestedDependencies.outputs.actionGroupResourceId + } + ] + 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' + } + ] + scopes: [ + subscription().id + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - scopes: [ - subscription().id - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/insights/activity-log-alert/tests/e2e/waf-aligned/main.test.bicep b/avm/res/insights/activity-log-alert/tests/e2e/waf-aligned/main.test.bicep index 7af69a877b..e86926d0b7 100644 --- a/avm/res/insights/activity-log-alert/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/insights/activity-log-alert/tests/e2e/waf-aligned/main.test.bicep @@ -44,56 +44,58 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - conditions: [ - { - field: 'category' - equals: 'ServiceHealth' - } - { - anyOf: [ - { - field: 'properties.incidentType' - equals: 'Incident' - } - { - field: 'properties.incidentType' - equals: 'Maintenance' - } - ] - } - { - field: 'properties.impactedServices[*].ServiceName' - containsAny: [ - 'Action Groups' - 'Activity Logs & Alerts' - ] - } - { - field: 'properties.impactedServices[*].ImpactedRegions[*].RegionName' - containsAny: [ - 'West Europe' - 'Global' - ] - } - ] - actions: [ - { - actionGroupId: nestedDependencies.outputs.actionGroupResourceId +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' + conditions: [ + { + field: 'category' + equals: 'ServiceHealth' + } + { + anyOf: [ + { + field: 'properties.incidentType' + equals: 'Incident' + } + { + field: 'properties.incidentType' + equals: 'Maintenance' + } + ] + } + { + field: 'properties.impactedServices[*].ServiceName' + containsAny: [ + 'Action Groups' + 'Activity Logs & Alerts' + ] + } + { + field: 'properties.impactedServices[*].ImpactedRegions[*].RegionName' + containsAny: [ + 'West Europe' + 'Global' + ] + } + ] + actions: [ + { + actionGroupId: nestedDependencies.outputs.actionGroupResourceId + } + ] + scopes: [ + subscription().id + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - scopes: [ - subscription().id - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/insights/component/linkedStorageAccounts/main.json b/avm/res/insights/component/linkedStorageAccounts/main.json index 853cdbcf3a..13b7ff86e1 100644 --- a/avm/res/insights/component/linkedStorageAccounts/main.json +++ b/avm/res/insights/component/linkedStorageAccounts/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15515506165880058222" + "version": "0.26.54.24096", + "templateHash": "10843790724446601865" }, "name": "Application Insights Linked Storage Account", "description": "This component deploys an Application Insights Linked Storage Account.", diff --git a/avm/res/insights/component/main.bicep b/avm/res/insights/component/main.bicep index 26504d0676..fe78cec221 100644 --- a/avm/res/insights/component/main.bicep +++ b/avm/res/insights/component/main.bicep @@ -82,27 +82,34 @@ 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') + '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.insights-component.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.insights-component.${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 appInsights 'Microsoft.Insights/components@2020-02-02' = { name: name @@ -122,50 +129,63 @@ 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 +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: { - 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 +resource appInsights_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(appInsights.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: appInsights } - scope: appInsights -}] - -resource appInsights_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 - 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 +] + +resource appInsights_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 + 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 + } + scope: appInsights } - scope: appInsights -}] +] @description('The name of the application insights component.') output name string = appInsights.name diff --git a/avm/res/insights/component/main.json b/avm/res/insights/component/main.json index a479a84010..2cfb14e258 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.25.53.49325", - "templateHash": "2927135998555920691" + "version": "0.26.54.24096", + "templateHash": "6536051249599059447" }, "name": "Application Insights", "description": "This component deploys an Application Insights instance.", @@ -478,8 +478,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15515506165880058222" + "version": "0.26.54.24096", + "templateHash": "10843790724446601865" }, "name": "Application Insights Linked Storage Account", "description": "This component deploys an Application Insights Linked Storage Account.", diff --git a/avm/res/insights/component/tests/e2e/defaults/dependencies.bicep b/avm/res/insights/component/tests/e2e/defaults/dependencies.bicep index cc24476629..63e7a207db 100644 --- a/avm/res/insights/component/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/insights/component/tests/e2e/defaults/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param logAnalyticsWorkspaceName string resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location } @description('The resource ID of the created Log Analytics Workspace.') 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 1f587dd740..899534b33a 100644 --- a/avm/res/insights/component/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/component/tests/e2e/max/main.test.bicep @@ -96,7 +96,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/insights/component/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/insights/component/tests/e2e/waf-aligned/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/insights/component/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/insights/component/tests/e2e/waf-aligned/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/insights/data-collection-endpoint/main.bicep b/avm/res/insights/data-collection-endpoint/main.bicep index cffa96ea8c..7e8ca0fbab 100644 --- a/avm/res/insights/data-collection-endpoint/main.bicep +++ b/avm/res/insights/data-collection-endpoint/main.bicep @@ -42,31 +42,38 @@ 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') + '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' + ) } // =============== // // Deployments // // =============== // -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.insights-datacollectionendpoint.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.insights-datacollectionendpoint.${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 dataCollectionEndpoint 'Microsoft.Insights/dataCollectionEndpoints@2021-04-01' = { kind: kind @@ -80,28 +87,37 @@ resource dataCollectionEndpoint 'Microsoft.Insights/dataCollectionEndpoints@2021 } } -resource dataCollectionEndpoint_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.' +resource dataCollectionEndpoint_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: dataCollectionEndpoint } - scope: dataCollectionEndpoint -} -resource dataCollectionEndpoint_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(dataCollectionEndpoint.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 +resource dataCollectionEndpoint_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(dataCollectionEndpoint.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: dataCollectionEndpoint } - scope: dataCollectionEndpoint -}] +] // =========== // // Outputs // diff --git a/avm/res/insights/data-collection-endpoint/main.json b/avm/res/insights/data-collection-endpoint/main.json index 01c4550922..acdabe202e 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.25.53.49325", - "templateHash": "2640603462631612916" + "version": "0.26.54.24096", + "templateHash": "3365574102168324158" }, "name": "Data Collection Endpoints", "description": "This module deploys a Data Collection Endpoint.", diff --git a/avm/res/insights/data-collection-endpoint/tests/e2e/defaults/main.test.bicep b/avm/res/insights/data-collection-endpoint/tests/e2e/defaults/main.test.bicep index 88c90cd91c..cdf5ac6d3a 100644 --- a/avm/res/insights/data-collection-endpoint/tests/e2e/defaults/main.test.bicep +++ b/avm/res/insights/data-collection-endpoint/tests/e2e/defaults/main.test.bicep @@ -35,11 +35,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/insights/data-collection-endpoint/tests/e2e/max/main.test.bicep b/avm/res/insights/data-collection-endpoint/tests/e2e/max/main.test.bicep index f1247259b2..2089ac4f21 100644 --- a/avm/res/insights/data-collection-endpoint/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/data-collection-endpoint/tests/e2e/max/main.test.bicep @@ -44,39 +44,44 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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: 'Enabled' - kind: 'Windows' - 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' +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: 'Enabled' + kind: 'Windows' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' + resourceType: 'Data Collection Rules' + kind: 'Windows' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'Data Collection Rules' - kind: 'Windows' } } -}] +] diff --git a/avm/res/insights/data-collection-endpoint/tests/e2e/waf-aligned/main.test.bicep b/avm/res/insights/data-collection-endpoint/tests/e2e/waf-aligned/main.test.bicep index 4766a05468..e421f1282a 100644 --- a/avm/res/insights/data-collection-endpoint/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/insights/data-collection-endpoint/tests/e2e/waf-aligned/main.test.bicep @@ -35,18 +35,20 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - kind: 'Windows' - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'Data Collection Rules' +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' kind: 'Windows' + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Data Collection Rules' + kind: 'Windows' + } } } -}] +] diff --git a/avm/res/insights/data-collection-rule/main.bicep b/avm/res/insights/data-collection-rule/main.bicep index 1195de6abd..a7dacba601 100644 --- a/avm/res/insights/data-collection-rule/main.bicep +++ b/avm/res/insights/data-collection-rule/main.bicep @@ -57,27 +57,34 @@ 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') + '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.insights-datacollectionrule.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.insights-datacollectionrule.${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 dataCollectionRule 'Microsoft.Insights/dataCollectionRules@2021-09-01-preview' = { kind: kind @@ -94,28 +101,37 @@ resource dataCollectionRule 'Microsoft.Insights/dataCollectionRules@2021-09-01-p } } -resource dataCollectionRule_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.' +resource dataCollectionRule_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: dataCollectionRule } - scope: dataCollectionRule -} -resource dataCollectionRule_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(dataCollectionRule.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 +resource dataCollectionRule_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(dataCollectionRule.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: dataCollectionRule } - scope: dataCollectionRule -}] +] // =========== // // Outputs // diff --git a/avm/res/insights/data-collection-rule/main.json b/avm/res/insights/data-collection-rule/main.json index b076b6e1de..e029f11464 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.25.53.49325", - "templateHash": "11839102114188195603" + "version": "0.26.54.24096", + "templateHash": "7431041910788264170" }, "name": "Data Collection Rules", "description": "This module deploys a Data Collection Rule.", diff --git a/avm/res/insights/data-collection-rule/tests/e2e/customadv/dependencies.bicep b/avm/res/insights/data-collection-rule/tests/e2e/customadv/dependencies.bicep index dc07e5f605..35ea4ba120 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/customadv/dependencies.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/customadv/dependencies.bicep @@ -8,54 +8,54 @@ param dataCollectionEndpointName string param logAnalyticsWorkspaceName string resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location - resource customTableAdvanced 'tables@2022-10-01' = { + resource customTableAdvanced 'tables@2022-10-01' = { + name: 'CustomTableAdvanced_CL' + properties: { + schema: { name: 'CustomTableAdvanced_CL' - properties: { - schema: { - name: 'CustomTableAdvanced_CL' - columns: [ - { - name: 'TimeGenerated' - type: 'DateTime' - } - { - name: 'EventTime' - type: 'DateTime' - } - { - name: 'EventLevel' - type: 'String' - } - { - name: 'EventCode' - type: 'Int' - } - { - name: 'Message' - type: 'String' - } - { - name: 'RawData' - type: 'String' - } - ] - } - } + columns: [ + { + name: 'TimeGenerated' + type: 'DateTime' + } + { + name: 'EventTime' + type: 'DateTime' + } + { + name: 'EventLevel' + type: 'String' + } + { + name: 'EventCode' + type: 'Int' + } + { + name: 'Message' + type: 'String' + } + { + name: 'RawData' + type: 'String' + } + ] + } } + } } resource dataCollectionEndpoint 'Microsoft.Insights/dataCollectionEndpoints@2021-04-01' = { - kind: 'Windows' - location: location - name: dataCollectionEndpointName - properties: { - networkAcls: { - publicNetworkAccess: 'Enabled' - } + kind: 'Windows' + location: location + name: dataCollectionEndpointName + properties: { + networkAcls: { + publicNetworkAccess: 'Enabled' } + } } @description('The resource ID of the created Log Analytics Workspace.') diff --git a/avm/res/insights/data-collection-rule/tests/e2e/customadv/main.test.bicep b/avm/res/insights/data-collection-rule/tests/e2e/customadv/main.test.bicep index ded0c6e219..6eb2366a0b 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/customadv/main.test.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/customadv/main.test.bicep @@ -45,89 +45,91 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - dataCollectionEndpointId: nestedDependencies.outputs.dataCollectionEndpointResourceId - description: 'Collecting custom text logs with ingestion-time transformation to columns. Expected format of a log line (comma separated values): ",,,", for example: "2023-01-25T20:15:05Z,ERROR,404,Page not found"' - dataFlows: [ - { - streams: [ - 'Custom-CustomTableAdvanced_CL' - ] - destinations: [ - nestedDependencies.outputs.logAnalyticsWorkspaceName - ] - transformKql: 'source | extend LogFields = split(RawData, ",") | extend EventTime = todatetime(LogFields[0]) | extend EventLevel = tostring(LogFields[1]) | extend EventCode = toint(LogFields[2]) | extend Message = tostring(LogFields[3]) | project TimeGenerated, EventTime, EventLevel, EventCode, Message' - outputStream: 'Custom-CustomTableAdvanced_CL' - } - ] - dataSources: { - logFiles: [ +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 + dataCollectionEndpointId: nestedDependencies.outputs.dataCollectionEndpointResourceId + description: 'Collecting custom text logs with ingestion-time transformation to columns. Expected format of a log line (comma separated values): ",,,", for example: "2023-01-25T20:15:05Z,ERROR,404,Page not found"' + dataFlows: [ { - name: 'CustomTableAdvanced_CL' - samplingFrequencyInSeconds: 60 streams: [ 'Custom-CustomTableAdvanced_CL' ] - filePatterns: [ - 'C:\\TestLogsAdvanced\\TestLog*.log' + destinations: [ + nestedDependencies.outputs.logAnalyticsWorkspaceName ] - format: 'text' - settings: { - text: { - recordStartTimestampFormat: 'ISO 8601' - } - } - } - ] - } - destinations: { - logAnalytics: [ - { - workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - name: nestedDependencies.outputs.logAnalyticsWorkspaceName + transformKql: 'source | extend LogFields = split(RawData, ",") | extend EventTime = todatetime(LogFields[0]) | extend EventLevel = tostring(LogFields[1]) | extend EventCode = toint(LogFields[2]) | extend Message = tostring(LogFields[3]) | project TimeGenerated, EventTime, EventLevel, EventCode, Message' + outputStream: 'Custom-CustomTableAdvanced_CL' } ] - } - streamDeclarations: { - 'Custom-CustomTableAdvanced_CL': { - columns: [ + dataSources: { + logFiles: [ { - name: 'TimeGenerated' - type: 'datetime' - } - { - name: 'EventTime' - type: 'datetime' - } - { - name: 'EventLevel' - type: 'string' - } - { - name: 'EventCode' - type: 'int' - } - { - name: 'Message' - type: 'string' + name: 'CustomTableAdvanced_CL' + samplingFrequencyInSeconds: 60 + streams: [ + 'Custom-CustomTableAdvanced_CL' + ] + filePatterns: [ + 'C:\\TestLogsAdvanced\\TestLog*.log' + ] + format: 'text' + settings: { + text: { + recordStartTimestampFormat: 'ISO 8601' + } + } } + ] + } + destinations: { + logAnalytics: [ { - name: 'RawData' - type: 'string' + workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + name: nestedDependencies.outputs.logAnalyticsWorkspaceName } ] } - } - kind: 'Windows' - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'Data Collection Rules' + streamDeclarations: { + 'Custom-CustomTableAdvanced_CL': { + columns: [ + { + name: 'TimeGenerated' + type: 'datetime' + } + { + name: 'EventTime' + type: 'datetime' + } + { + name: 'EventLevel' + type: 'string' + } + { + name: 'EventCode' + type: 'int' + } + { + name: 'Message' + type: 'string' + } + { + name: 'RawData' + type: 'string' + } + ] + } + } kind: 'Windows' + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Data Collection Rules' + kind: 'Windows' + } } } -}] +] diff --git a/avm/res/insights/data-collection-rule/tests/e2e/custombasic/dependencies.bicep b/avm/res/insights/data-collection-rule/tests/e2e/custombasic/dependencies.bicep index 4afb136cb6..0412e61164 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/custombasic/dependencies.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/custombasic/dependencies.bicep @@ -8,38 +8,38 @@ param dataCollectionEndpointName string param logAnalyticsWorkspaceName string resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location - resource customTableBasic 'tables@2022-10-01' = { + resource customTableBasic 'tables@2022-10-01' = { + name: 'CustomTableBasic_CL' + properties: { + schema: { name: 'CustomTableBasic_CL' - properties: { - schema: { - name: 'CustomTableBasic_CL' - columns: [ - { - name: 'TimeGenerated' - type: 'DateTime' - } - { - name: 'RawData' - type: 'String' - } - ] - } - } + columns: [ + { + name: 'TimeGenerated' + type: 'DateTime' + } + { + name: 'RawData' + type: 'String' + } + ] + } } + } } resource dataCollectionEndpoint 'Microsoft.Insights/dataCollectionEndpoints@2021-04-01' = { - kind: 'Windows' - location: location - name: dataCollectionEndpointName - properties: { - networkAcls: { - publicNetworkAccess: 'Enabled' - } + kind: 'Windows' + location: location + name: dataCollectionEndpointName + properties: { + networkAcls: { + publicNetworkAccess: 'Enabled' } + } } @description('The resource ID of the created Log Analytics Workspace.') diff --git a/avm/res/insights/data-collection-rule/tests/e2e/custombasic/main.test.bicep b/avm/res/insights/data-collection-rule/tests/e2e/custombasic/main.test.bicep index 3fa5aac564..cf1e2a9b3c 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/custombasic/main.test.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/custombasic/main.test.bicep @@ -45,73 +45,75 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - dataCollectionEndpointId: nestedDependencies.outputs.dataCollectionEndpointResourceId - description: 'Collecting custom text logs without ingestion-time transformation.' - dataFlows: [ - { - streams: [ - 'Custom-CustomTableBasic_CL' - ] - destinations: [ - nestedDependencies.outputs.logAnalyticsWorkspaceName - ] - transformKql: 'source' - outputStream: 'Custom-CustomTableBasic_CL' - } - ] - dataSources: { - logFiles: [ +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 + dataCollectionEndpointId: nestedDependencies.outputs.dataCollectionEndpointResourceId + description: 'Collecting custom text logs without ingestion-time transformation.' + dataFlows: [ { - name: 'CustomTableBasic_CL' - samplingFrequencyInSeconds: 60 streams: [ 'Custom-CustomTableBasic_CL' ] - filePatterns: [ - 'C:\\TestLogsBasic\\TestLog*.log' + destinations: [ + nestedDependencies.outputs.logAnalyticsWorkspaceName ] - format: 'text' - settings: { - text: { - recordStartTimestampFormat: 'ISO 8601' - } - } - } - ] - } - destinations: { - logAnalytics: [ - { - workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - name: nestedDependencies.outputs.logAnalyticsWorkspaceName + transformKql: 'source' + outputStream: 'Custom-CustomTableBasic_CL' } ] - } - streamDeclarations: { - 'Custom-CustomTableBasic_CL': { - columns: [ + dataSources: { + logFiles: [ { - name: 'TimeGenerated' - type: 'datetime' + name: 'CustomTableBasic_CL' + samplingFrequencyInSeconds: 60 + streams: [ + 'Custom-CustomTableBasic_CL' + ] + filePatterns: [ + 'C:\\TestLogsBasic\\TestLog*.log' + ] + format: 'text' + settings: { + text: { + recordStartTimestampFormat: 'ISO 8601' + } + } } + ] + } + destinations: { + logAnalytics: [ { - name: 'RawData' - type: 'string' + workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + name: nestedDependencies.outputs.logAnalyticsWorkspaceName } ] } - } - kind: 'Windows' - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'Data Collection Rules' + streamDeclarations: { + 'Custom-CustomTableBasic_CL': { + columns: [ + { + name: 'TimeGenerated' + type: 'datetime' + } + { + name: 'RawData' + type: 'string' + } + ] + } + } kind: 'Windows' + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Data Collection Rules' + kind: 'Windows' + } } } -}] +] diff --git a/avm/res/insights/data-collection-rule/tests/e2e/customiis/dependencies.bicep b/avm/res/insights/data-collection-rule/tests/e2e/customiis/dependencies.bicep index 0a3bc96cfe..b12b662cc7 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/customiis/dependencies.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/customiis/dependencies.bicep @@ -8,19 +8,19 @@ param dataCollectionEndpointName string param logAnalyticsWorkspaceName string resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location } resource dataCollectionEndpoint 'Microsoft.Insights/dataCollectionEndpoints@2021-04-01' = { - kind: 'Windows' - location: location - name: dataCollectionEndpointName - properties: { - networkAcls: { - publicNetworkAccess: 'Enabled' - } + kind: 'Windows' + location: location + name: dataCollectionEndpointName + properties: { + networkAcls: { + publicNetworkAccess: 'Enabled' } + } } @description('The resource ID of the created Log Analytics Workspace.') diff --git a/avm/res/insights/data-collection-rule/tests/e2e/customiis/main.test.bicep b/avm/res/insights/data-collection-rule/tests/e2e/customiis/main.test.bicep index 4c8af81827..fa08fbf64c 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/customiis/main.test.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/customiis/main.test.bicep @@ -45,52 +45,54 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - dataCollectionEndpointId: nestedDependencies.outputs.dataCollectionEndpointResourceId - description: 'Collecting IIS logs.' - dataFlows: [ - { - streams: [ - 'Microsoft-W3CIISLog' - ] - destinations: [ - nestedDependencies.outputs.logAnalyticsWorkspaceName - ] - transformKql: 'source' - outputStream: 'Microsoft-W3CIISLog' - } - ] - dataSources: { - iisLogs: [ +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 + dataCollectionEndpointId: nestedDependencies.outputs.dataCollectionEndpointResourceId + description: 'Collecting IIS logs.' + dataFlows: [ { - name: 'iisLogsDataSource' streams: [ 'Microsoft-W3CIISLog' ] - logDirectories: [ - 'C:\\inetpub\\logs\\LogFiles\\W3SVC1' + destinations: [ + nestedDependencies.outputs.logAnalyticsWorkspaceName ] + transformKql: 'source' + outputStream: 'Microsoft-W3CIISLog' } ] - } - destinations: { - logAnalytics: [ - { - workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - name: nestedDependencies.outputs.logAnalyticsWorkspaceName - } - ] - } - kind: 'Windows' - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'Data Collection Rules' + dataSources: { + iisLogs: [ + { + name: 'iisLogsDataSource' + streams: [ + 'Microsoft-W3CIISLog' + ] + logDirectories: [ + 'C:\\inetpub\\logs\\LogFiles\\W3SVC1' + ] + } + ] + } + destinations: { + logAnalytics: [ + { + workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + name: nestedDependencies.outputs.logAnalyticsWorkspaceName + } + ] + } kind: 'Windows' + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Data Collection Rules' + kind: 'Windows' + } } } -}] +] diff --git a/avm/res/insights/data-collection-rule/tests/e2e/defaults/main.test.bicep b/avm/res/insights/data-collection-rule/tests/e2e/defaults/main.test.bicep index fc46e9ec99..8a9070c88e 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/defaults/main.test.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/defaults/main.test.bicep @@ -35,50 +35,52 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - dataSources: { - performanceCounters: [ +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 + dataSources: { + performanceCounters: [ + { + name: 'perfCounterDataSource60' + samplingFrequencyInSeconds: 60 + streams: [ + 'Microsoft-InsightsMetrics' + ] + counterSpecifiers: [ + '\\Processor Information(_Total)\\% Processor Time' + '\\Processor Information(_Total)\\% Privileged Time' + '\\Processor Information(_Total)\\% User Time' + '\\Processor Information(_Total)\\Processor Frequency' + '\\System\\Processes' + '\\Process(_Total)\\Thread Count' + '\\Process(_Total)\\Handle Count' + '\\System\\System Up Time' + '\\System\\Context Switches/sec' + '\\System\\Processor Queue Length' + ] + } + ] + } + destinations: { + azureMonitorMetrics: { + name: 'azureMonitorMetrics-default' + } + } + dataFlows: [ { - name: 'perfCounterDataSource60' - samplingFrequencyInSeconds: 60 streams: [ 'Microsoft-InsightsMetrics' ] - counterSpecifiers: [ - '\\Processor Information(_Total)\\% Processor Time' - '\\Processor Information(_Total)\\% Privileged Time' - '\\Processor Information(_Total)\\% User Time' - '\\Processor Information(_Total)\\Processor Frequency' - '\\System\\Processes' - '\\Process(_Total)\\Thread Count' - '\\Process(_Total)\\Handle Count' - '\\System\\System Up Time' - '\\System\\Context Switches/sec' - '\\System\\Processor Queue Length' + destinations: [ + 'azureMonitorMetrics-default' ] } ] + kind: 'Windows' } - destinations: { - azureMonitorMetrics: { - name: 'azureMonitorMetrics-default' - } - } - dataFlows: [ - { - streams: [ - 'Microsoft-InsightsMetrics' - ] - destinations: [ - 'azureMonitorMetrics-default' - ] - } - ] - kind: 'Windows' } -}] +] diff --git a/avm/res/insights/data-collection-rule/tests/e2e/linux/dependencies.bicep b/avm/res/insights/data-collection-rule/tests/e2e/linux/dependencies.bicep index 7d1119142f..c20b584c10 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/linux/dependencies.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/linux/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param logAnalyticsWorkspaceName string resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location } @description('The resource ID of the created Log Analytics Workspace.') diff --git a/avm/res/insights/data-collection-rule/tests/e2e/linux/main.test.bicep b/avm/res/insights/data-collection-rule/tests/e2e/linux/main.test.bicep index 8f8435b569..7ffc209efb 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/linux/main.test.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/linux/main.test.bicep @@ -44,166 +44,167 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - description: 'Collecting Linux-specific performance counters and Linux Syslog' - dataSources: { - performanceCounters: [ - { - name: 'perfCounterDataSource60' - samplingFrequencyInSeconds: 60 - streams: [ - 'Microsoft-InsightsMetrics' - ] - counterSpecifiers: [ - 'Processor(*)\\% Processor Time' - 'Processor(*)\\% Idle Time' - 'Processor(*)\\% User Time' - 'Processor(*)\\% Nice Time' - 'Processor(*)\\% Privileged Time' - 'Processor(*)\\% IO Wait Time' - 'Processor(*)\\% Interrupt Time' - 'Processor(*)\\% DPC Time' - 'Memory(*)\\Available MBytes Memory' - 'Memory(*)\\% Available Memory' - 'Memory(*)\\Used Memory MBytes' - 'Memory(*)\\% Used Memory' - 'Memory(*)\\Pages/sec' - 'Memory(*)\\Page Reads/sec' - 'Memory(*)\\Page Writes/sec' - 'Memory(*)\\Available MBytes Swap' - 'Memory(*)\\% Available Swap Space' - 'Memory(*)\\Used MBytes Swap Space' - 'Memory(*)\\% Used Swap Space' - 'Logical Disk(*)\\% Free Inodes' - 'Logical Disk(*)\\% Used Inodes' - 'Logical Disk(*)\\Free Megabytes' - 'Logical Disk(*)\\% Free Space' - 'Logical Disk(*)\\% Used Space' - 'Logical Disk(*)\\Logical Disk Bytes/sec' - 'Logical Disk(*)\\Disk Read Bytes/sec' - 'Logical Disk(*)\\Disk Write Bytes/sec' - 'Logical Disk(*)\\Disk Transfers/sec' - 'Logical Disk(*)\\Disk Reads/sec' - 'Logical Disk(*)\\Disk Writes/sec' - 'Network(*)\\Total Bytes Transmitted' - 'Network(*)\\Total Bytes Received' - 'Network(*)\\Total Bytes' - 'Network(*)\\Total Packets Transmitted' - 'Network(*)\\Total Packets Received' - 'Network(*)\\Total Rx Errors' - 'Network(*)\\Total Tx Errors' - 'Network(*)\\Total Collisions' - ] - } - ] - syslog: [ - { - name: 'sysLogsDataSource-debugLevel' - streams: [ - 'Microsoft-Syslog' - ] - facilityNames: [ - 'auth' - 'authpriv' - ] - logLevels: [ - 'Debug' - 'Info' - 'Notice' - 'Warning' - 'Error' - 'Critical' - 'Alert' - 'Emergency' - ] +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 + description: 'Collecting Linux-specific performance counters and Linux Syslog' + dataSources: { + performanceCounters: [ + { + name: 'perfCounterDataSource60' + samplingFrequencyInSeconds: 60 + streams: [ + 'Microsoft-InsightsMetrics' + ] + counterSpecifiers: [ + 'Processor(*)\\% Processor Time' + 'Processor(*)\\% Idle Time' + 'Processor(*)\\% User Time' + 'Processor(*)\\% Nice Time' + 'Processor(*)\\% Privileged Time' + 'Processor(*)\\% IO Wait Time' + 'Processor(*)\\% Interrupt Time' + 'Processor(*)\\% DPC Time' + 'Memory(*)\\Available MBytes Memory' + 'Memory(*)\\% Available Memory' + 'Memory(*)\\Used Memory MBytes' + 'Memory(*)\\% Used Memory' + 'Memory(*)\\Pages/sec' + 'Memory(*)\\Page Reads/sec' + 'Memory(*)\\Page Writes/sec' + 'Memory(*)\\Available MBytes Swap' + 'Memory(*)\\% Available Swap Space' + 'Memory(*)\\Used MBytes Swap Space' + 'Memory(*)\\% Used Swap Space' + 'Logical Disk(*)\\% Free Inodes' + 'Logical Disk(*)\\% Used Inodes' + 'Logical Disk(*)\\Free Megabytes' + 'Logical Disk(*)\\% Free Space' + 'Logical Disk(*)\\% Used Space' + 'Logical Disk(*)\\Logical Disk Bytes/sec' + 'Logical Disk(*)\\Disk Read Bytes/sec' + 'Logical Disk(*)\\Disk Write Bytes/sec' + 'Logical Disk(*)\\Disk Transfers/sec' + 'Logical Disk(*)\\Disk Reads/sec' + 'Logical Disk(*)\\Disk Writes/sec' + 'Network(*)\\Total Bytes Transmitted' + 'Network(*)\\Total Bytes Received' + 'Network(*)\\Total Bytes' + 'Network(*)\\Total Packets Transmitted' + 'Network(*)\\Total Packets Received' + 'Network(*)\\Total Rx Errors' + 'Network(*)\\Total Tx Errors' + 'Network(*)\\Total Collisions' + ] + } + ] + syslog: [ + { + name: 'sysLogsDataSource-debugLevel' + streams: [ + 'Microsoft-Syslog' + ] + facilityNames: [ + 'auth' + 'authpriv' + ] + logLevels: [ + 'Debug' + 'Info' + 'Notice' + 'Warning' + 'Error' + 'Critical' + 'Alert' + 'Emergency' + ] + } + { + name: 'sysLogsDataSource-warningLevel' + streams: [ + 'Microsoft-Syslog' + ] + facilityNames: [ + 'cron' + 'daemon' + 'mark' + 'kern' + 'local0' + ] + logLevels: [ + 'Warning' + 'Error' + 'Critical' + 'Alert' + 'Emergency' + ] + } + { + name: 'sysLogsDataSource-errLevel' + streams: [ + 'Microsoft-Syslog' + ] + facilityNames: [ + 'local1' + 'local2' + 'local3' + 'local4' + 'local5' + 'local6' + 'local7' + 'lpr' + 'mail' + 'news' + 'syslog' + ] + logLevels: [ + 'Error' + 'Critical' + 'Alert' + 'Emergency' + ] + } + ] + } + destinations: { + azureMonitorMetrics: { + name: 'azureMonitorMetrics-default' } + logAnalytics: [ + { + workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + name: nestedDependencies.outputs.logAnalyticsWorkspaceName + } + ] + } + dataFlows: [ { - name: 'sysLogsDataSource-warningLevel' streams: [ - 'Microsoft-Syslog' - ] - facilityNames: [ - 'cron' - 'daemon' - 'mark' - 'kern' - 'local0' + 'Microsoft-InsightsMetrics' ] - logLevels: [ - 'Warning' - 'Error' - 'Critical' - 'Alert' - 'Emergency' + destinations: [ + 'azureMonitorMetrics-default' ] } { - name: 'sysLogsDataSource-errLevel' streams: [ 'Microsoft-Syslog' ] - facilityNames: [ - 'local1' - 'local2' - 'local3' - 'local4' - 'local5' - 'local6' - 'local7' - 'lpr' - 'mail' - 'news' - 'syslog' - ] - logLevels: [ - 'Error' - 'Critical' - 'Alert' - 'Emergency' + destinations: [ + nestedDependencies.outputs.logAnalyticsWorkspaceName ] } ] - } - destinations: { - azureMonitorMetrics: { - name: 'azureMonitorMetrics-default' - } - logAnalytics: [ - { - workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - name: nestedDependencies.outputs.logAnalyticsWorkspaceName - } - ] - } - dataFlows: [ - { - streams: [ - 'Microsoft-InsightsMetrics' - ] - destinations: [ - 'azureMonitorMetrics-default' - ] - } - { - streams: [ - 'Microsoft-Syslog' - ] - destinations: [ - nestedDependencies.outputs.logAnalyticsWorkspaceName - ] - } - - ] - kind: 'Linux' - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'Data Collection Rules' kind: 'Linux' + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Data Collection Rules' + kind: 'Linux' + } } } -}] +] diff --git a/avm/res/insights/data-collection-rule/tests/e2e/max/dependencies.bicep b/avm/res/insights/data-collection-rule/tests/e2e/max/dependencies.bicep index f1804cde92..e7a3cd006b 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/max/dependencies.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/max/dependencies.bicep @@ -11,43 +11,43 @@ param logAnalyticsWorkspaceName string param managedIdentityName string resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location - resource customTableBasic 'tables@2022-10-01' = { + resource customTableBasic 'tables@2022-10-01' = { + name: 'CustomTableBasic_CL' + properties: { + schema: { name: 'CustomTableBasic_CL' - properties: { - schema: { - name: 'CustomTableBasic_CL' - columns: [ - { - name: 'TimeGenerated' - type: 'DateTime' - } - { - name: 'RawData' - type: 'String' - } - ] - } - } + columns: [ + { + name: 'TimeGenerated' + type: 'DateTime' + } + { + name: 'RawData' + type: 'String' + } + ] + } } + } } resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } resource dataCollectionEndpoint 'Microsoft.Insights/dataCollectionEndpoints@2021-04-01' = { - kind: 'Windows' - location: location - name: dataCollectionEndpointName - properties: { - networkAcls: { - publicNetworkAccess: 'Enabled' - } + kind: 'Windows' + location: location + name: dataCollectionEndpointName + properties: { + networkAcls: { + publicNetworkAccess: 'Enabled' } + } } @description('The resource ID of the created Log Analytics Workspace.') diff --git a/avm/res/insights/data-collection-rule/tests/e2e/max/main.test.bicep b/avm/res/insights/data-collection-rule/tests/e2e/max/main.test.bicep index 7bafac2eb6..cf81a64bfc 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/max/main.test.bicep @@ -46,94 +46,99 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - dataCollectionEndpointId: nestedDependencies.outputs.dataCollectionEndpointResourceId - description: 'Collecting custom text logs without ingestion-time transformation.' - dataFlows: [ - { - streams: [ - 'Custom-CustomTableBasic_CL' - ] - destinations: [ - nestedDependencies.outputs.logAnalyticsWorkspaceName - ] - transformKql: 'source' - outputStream: 'Custom-CustomTableBasic_CL' - } - ] - dataSources: { - logFiles: [ +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 + dataCollectionEndpointId: nestedDependencies.outputs.dataCollectionEndpointResourceId + description: 'Collecting custom text logs without ingestion-time transformation.' + dataFlows: [ { - name: 'CustomTableBasic_CL' - samplingFrequencyInSeconds: 60 streams: [ 'Custom-CustomTableBasic_CL' ] - filePatterns: [ - 'C:\\TestLogsBasic\\TestLog*.log' + destinations: [ + nestedDependencies.outputs.logAnalyticsWorkspaceName ] - format: 'text' - settings: { - text: { - recordStartTimestampFormat: 'ISO 8601' - } - } + transformKql: 'source' + outputStream: 'Custom-CustomTableBasic_CL' } ] - } - destinations: { - logAnalytics: [ - { - workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - name: nestedDependencies.outputs.logAnalyticsWorkspaceName - } - ] - } - streamDeclarations: { - 'Custom-CustomTableBasic_CL': { - columns: [ + dataSources: { + logFiles: [ { - name: 'TimeGenerated' - type: 'datetime' + name: 'CustomTableBasic_CL' + samplingFrequencyInSeconds: 60 + streams: [ + 'Custom-CustomTableBasic_CL' + ] + filePatterns: [ + 'C:\\TestLogsBasic\\TestLog*.log' + ] + format: 'text' + settings: { + text: { + recordStartTimestampFormat: 'ISO 8601' + } + } } + ] + } + destinations: { + logAnalytics: [ { - name: 'RawData' - type: 'string' + workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + name: nestedDependencies.outputs.logAnalyticsWorkspaceName } ] } - } - kind: 'Windows' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + streamDeclarations: { + 'Custom-CustomTableBasic_CL': { + columns: [ + { + name: 'TimeGenerated' + type: 'datetime' + } + { + name: 'RawData' + type: 'string' + } + ] + } } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + kind: 'Windows' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' + resourceType: 'Data Collection Rules' + kind: 'Windows' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'Data Collection Rules' - kind: 'Windows' } } -}] +] diff --git a/avm/res/insights/data-collection-rule/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/insights/data-collection-rule/tests/e2e/waf-aligned/dependencies.bicep index 7d1119142f..c20b584c10 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/waf-aligned/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param logAnalyticsWorkspaceName string resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location } @description('The resource ID of the created Log Analytics Workspace.') diff --git a/avm/res/insights/data-collection-rule/tests/e2e/waf-aligned/main.test.bicep b/avm/res/insights/data-collection-rule/tests/e2e/waf-aligned/main.test.bicep index 7c566cc632..c1b93f95b5 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/waf-aligned/main.test.bicep @@ -45,120 +45,121 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - description: 'Collecting Windows-specific performance counters and Windows Event Logs' - dataSources: { - performanceCounters: [ +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 + description: 'Collecting Windows-specific performance counters and Windows Event Logs' + dataSources: { + performanceCounters: [ + { + name: 'perfCounterDataSource60' + samplingFrequencyInSeconds: 60 + streams: [ + 'Microsoft-InsightsMetrics' + ] + counterSpecifiers: [ + '\\Processor Information(_Total)\\% Processor Time' + '\\Processor Information(_Total)\\% Privileged Time' + '\\Processor Information(_Total)\\% User Time' + '\\Processor Information(_Total)\\Processor Frequency' + '\\System\\Processes' + '\\Process(_Total)\\Thread Count' + '\\Process(_Total)\\Handle Count' + '\\System\\System Up Time' + '\\System\\Context Switches/sec' + '\\System\\Processor Queue Length' + '\\Memory\\% Committed Bytes In Use' + '\\Memory\\Available Bytes' + '\\Memory\\Committed Bytes' + '\\Memory\\Cache Bytes' + '\\Memory\\Pool Paged Bytes' + '\\Memory\\Pool Nonpaged Bytes' + '\\Memory\\Pages/sec' + '\\Memory\\Page Faults/sec' + '\\Process(_Total)\\Working Set' + '\\Process(_Total)\\Working Set - Private' + '\\LogicalDisk(_Total)\\% Disk Time' + '\\LogicalDisk(_Total)\\% Disk Read Time' + '\\LogicalDisk(_Total)\\% Disk Write Time' + '\\LogicalDisk(_Total)\\% Idle Time' + '\\LogicalDisk(_Total)\\Disk Bytes/sec' + '\\LogicalDisk(_Total)\\Disk Read Bytes/sec' + '\\LogicalDisk(_Total)\\Disk Write Bytes/sec' + '\\LogicalDisk(_Total)\\Disk Transfers/sec' + '\\LogicalDisk(_Total)\\Disk Reads/sec' + '\\LogicalDisk(_Total)\\Disk Writes/sec' + '\\LogicalDisk(_Total)\\Avg. Disk sec/Transfer' + '\\LogicalDisk(_Total)\\Avg. Disk sec/Read' + '\\LogicalDisk(_Total)\\Avg. Disk sec/Write' + '\\LogicalDisk(_Total)\\Avg. Disk Queue Length' + '\\LogicalDisk(_Total)\\Avg. Disk Read Queue Length' + '\\LogicalDisk(_Total)\\Avg. Disk Write Queue Length' + '\\LogicalDisk(_Total)\\% Free Space' + '\\LogicalDisk(_Total)\\Free Megabytes' + '\\Network Interface(*)\\Bytes Total/sec' + '\\Network Interface(*)\\Bytes Sent/sec' + '\\Network Interface(*)\\Bytes Received/sec' + '\\Network Interface(*)\\Packets/sec' + '\\Network Interface(*)\\Packets Sent/sec' + '\\Network Interface(*)\\Packets Received/sec' + '\\Network Interface(*)\\Packets Outbound Errors' + '\\Network Interface(*)\\Packets Received Errors' + ] + } + ] + windowsEventLogs: [ + { + name: 'eventLogsDataSource' + streams: [ + 'Microsoft-Event' + ] + xPathQueries: [ + 'Application!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]' + 'Security!*[System[(band(Keywords,13510798882111488))]]' + 'System!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]' + ] + } + ] + } + destinations: { + azureMonitorMetrics: { + name: 'azureMonitorMetrics-default' + } + logAnalytics: [ + { + workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + name: nestedDependencies.outputs.logAnalyticsWorkspaceName + } + ] + } + dataFlows: [ { - name: 'perfCounterDataSource60' - samplingFrequencyInSeconds: 60 streams: [ 'Microsoft-InsightsMetrics' ] - counterSpecifiers: [ - '\\Processor Information(_Total)\\% Processor Time' - '\\Processor Information(_Total)\\% Privileged Time' - '\\Processor Information(_Total)\\% User Time' - '\\Processor Information(_Total)\\Processor Frequency' - '\\System\\Processes' - '\\Process(_Total)\\Thread Count' - '\\Process(_Total)\\Handle Count' - '\\System\\System Up Time' - '\\System\\Context Switches/sec' - '\\System\\Processor Queue Length' - '\\Memory\\% Committed Bytes In Use' - '\\Memory\\Available Bytes' - '\\Memory\\Committed Bytes' - '\\Memory\\Cache Bytes' - '\\Memory\\Pool Paged Bytes' - '\\Memory\\Pool Nonpaged Bytes' - '\\Memory\\Pages/sec' - '\\Memory\\Page Faults/sec' - '\\Process(_Total)\\Working Set' - '\\Process(_Total)\\Working Set - Private' - '\\LogicalDisk(_Total)\\% Disk Time' - '\\LogicalDisk(_Total)\\% Disk Read Time' - '\\LogicalDisk(_Total)\\% Disk Write Time' - '\\LogicalDisk(_Total)\\% Idle Time' - '\\LogicalDisk(_Total)\\Disk Bytes/sec' - '\\LogicalDisk(_Total)\\Disk Read Bytes/sec' - '\\LogicalDisk(_Total)\\Disk Write Bytes/sec' - '\\LogicalDisk(_Total)\\Disk Transfers/sec' - '\\LogicalDisk(_Total)\\Disk Reads/sec' - '\\LogicalDisk(_Total)\\Disk Writes/sec' - '\\LogicalDisk(_Total)\\Avg. Disk sec/Transfer' - '\\LogicalDisk(_Total)\\Avg. Disk sec/Read' - '\\LogicalDisk(_Total)\\Avg. Disk sec/Write' - '\\LogicalDisk(_Total)\\Avg. Disk Queue Length' - '\\LogicalDisk(_Total)\\Avg. Disk Read Queue Length' - '\\LogicalDisk(_Total)\\Avg. Disk Write Queue Length' - '\\LogicalDisk(_Total)\\% Free Space' - '\\LogicalDisk(_Total)\\Free Megabytes' - '\\Network Interface(*)\\Bytes Total/sec' - '\\Network Interface(*)\\Bytes Sent/sec' - '\\Network Interface(*)\\Bytes Received/sec' - '\\Network Interface(*)\\Packets/sec' - '\\Network Interface(*)\\Packets Sent/sec' - '\\Network Interface(*)\\Packets Received/sec' - '\\Network Interface(*)\\Packets Outbound Errors' - '\\Network Interface(*)\\Packets Received Errors' + destinations: [ + 'azureMonitorMetrics-default' ] } - ] - windowsEventLogs: [ { - name: 'eventLogsDataSource' streams: [ 'Microsoft-Event' ] - xPathQueries: [ - 'Application!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]' - 'Security!*[System[(band(Keywords,13510798882111488))]]' - 'System!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]' + destinations: [ + nestedDependencies.outputs.logAnalyticsWorkspaceName ] } ] - } - destinations: { - azureMonitorMetrics: { - name: 'azureMonitorMetrics-default' - } - logAnalytics: [ - { - workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - name: nestedDependencies.outputs.logAnalyticsWorkspaceName - } - ] - } - dataFlows: [ - { - streams: [ - 'Microsoft-InsightsMetrics' - ] - destinations: [ - 'azureMonitorMetrics-default' - ] - } - { - streams: [ - 'Microsoft-Event' - ] - destinations: [ - nestedDependencies.outputs.logAnalyticsWorkspaceName - ] - } - - ] - kind: 'Windows' - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'Data Collection Rules' kind: 'Windows' + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Data Collection Rules' + kind: 'Windows' + } } } -}] +] diff --git a/avm/res/insights/data-collection-rule/tests/e2e/windows/dependencies.bicep b/avm/res/insights/data-collection-rule/tests/e2e/windows/dependencies.bicep index 7d1119142f..c20b584c10 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/windows/dependencies.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/windows/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param logAnalyticsWorkspaceName string resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location } @description('The resource ID of the created Log Analytics Workspace.') diff --git a/avm/res/insights/data-collection-rule/tests/e2e/windows/main.test.bicep b/avm/res/insights/data-collection-rule/tests/e2e/windows/main.test.bicep index 9bc58edc58..d5e29bfc40 100644 --- a/avm/res/insights/data-collection-rule/tests/e2e/windows/main.test.bicep +++ b/avm/res/insights/data-collection-rule/tests/e2e/windows/main.test.bicep @@ -44,120 +44,121 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - description: 'Collecting Windows-specific performance counters and Windows Event Logs' - dataSources: { - performanceCounters: [ +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 + description: 'Collecting Windows-specific performance counters and Windows Event Logs' + dataSources: { + performanceCounters: [ + { + name: 'perfCounterDataSource60' + samplingFrequencyInSeconds: 60 + streams: [ + 'Microsoft-InsightsMetrics' + ] + counterSpecifiers: [ + '\\Processor Information(_Total)\\% Processor Time' + '\\Processor Information(_Total)\\% Privileged Time' + '\\Processor Information(_Total)\\% User Time' + '\\Processor Information(_Total)\\Processor Frequency' + '\\System\\Processes' + '\\Process(_Total)\\Thread Count' + '\\Process(_Total)\\Handle Count' + '\\System\\System Up Time' + '\\System\\Context Switches/sec' + '\\System\\Processor Queue Length' + '\\Memory\\% Committed Bytes In Use' + '\\Memory\\Available Bytes' + '\\Memory\\Committed Bytes' + '\\Memory\\Cache Bytes' + '\\Memory\\Pool Paged Bytes' + '\\Memory\\Pool Nonpaged Bytes' + '\\Memory\\Pages/sec' + '\\Memory\\Page Faults/sec' + '\\Process(_Total)\\Working Set' + '\\Process(_Total)\\Working Set - Private' + '\\LogicalDisk(_Total)\\% Disk Time' + '\\LogicalDisk(_Total)\\% Disk Read Time' + '\\LogicalDisk(_Total)\\% Disk Write Time' + '\\LogicalDisk(_Total)\\% Idle Time' + '\\LogicalDisk(_Total)\\Disk Bytes/sec' + '\\LogicalDisk(_Total)\\Disk Read Bytes/sec' + '\\LogicalDisk(_Total)\\Disk Write Bytes/sec' + '\\LogicalDisk(_Total)\\Disk Transfers/sec' + '\\LogicalDisk(_Total)\\Disk Reads/sec' + '\\LogicalDisk(_Total)\\Disk Writes/sec' + '\\LogicalDisk(_Total)\\Avg. Disk sec/Transfer' + '\\LogicalDisk(_Total)\\Avg. Disk sec/Read' + '\\LogicalDisk(_Total)\\Avg. Disk sec/Write' + '\\LogicalDisk(_Total)\\Avg. Disk Queue Length' + '\\LogicalDisk(_Total)\\Avg. Disk Read Queue Length' + '\\LogicalDisk(_Total)\\Avg. Disk Write Queue Length' + '\\LogicalDisk(_Total)\\% Free Space' + '\\LogicalDisk(_Total)\\Free Megabytes' + '\\Network Interface(*)\\Bytes Total/sec' + '\\Network Interface(*)\\Bytes Sent/sec' + '\\Network Interface(*)\\Bytes Received/sec' + '\\Network Interface(*)\\Packets/sec' + '\\Network Interface(*)\\Packets Sent/sec' + '\\Network Interface(*)\\Packets Received/sec' + '\\Network Interface(*)\\Packets Outbound Errors' + '\\Network Interface(*)\\Packets Received Errors' + ] + } + ] + windowsEventLogs: [ + { + name: 'eventLogsDataSource' + streams: [ + 'Microsoft-Event' + ] + xPathQueries: [ + 'Application!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]' + 'Security!*[System[(band(Keywords,13510798882111488))]]' + 'System!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]' + ] + } + ] + } + destinations: { + azureMonitorMetrics: { + name: 'azureMonitorMetrics-default' + } + logAnalytics: [ + { + workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + name: nestedDependencies.outputs.logAnalyticsWorkspaceName + } + ] + } + dataFlows: [ { - name: 'perfCounterDataSource60' - samplingFrequencyInSeconds: 60 streams: [ 'Microsoft-InsightsMetrics' ] - counterSpecifiers: [ - '\\Processor Information(_Total)\\% Processor Time' - '\\Processor Information(_Total)\\% Privileged Time' - '\\Processor Information(_Total)\\% User Time' - '\\Processor Information(_Total)\\Processor Frequency' - '\\System\\Processes' - '\\Process(_Total)\\Thread Count' - '\\Process(_Total)\\Handle Count' - '\\System\\System Up Time' - '\\System\\Context Switches/sec' - '\\System\\Processor Queue Length' - '\\Memory\\% Committed Bytes In Use' - '\\Memory\\Available Bytes' - '\\Memory\\Committed Bytes' - '\\Memory\\Cache Bytes' - '\\Memory\\Pool Paged Bytes' - '\\Memory\\Pool Nonpaged Bytes' - '\\Memory\\Pages/sec' - '\\Memory\\Page Faults/sec' - '\\Process(_Total)\\Working Set' - '\\Process(_Total)\\Working Set - Private' - '\\LogicalDisk(_Total)\\% Disk Time' - '\\LogicalDisk(_Total)\\% Disk Read Time' - '\\LogicalDisk(_Total)\\% Disk Write Time' - '\\LogicalDisk(_Total)\\% Idle Time' - '\\LogicalDisk(_Total)\\Disk Bytes/sec' - '\\LogicalDisk(_Total)\\Disk Read Bytes/sec' - '\\LogicalDisk(_Total)\\Disk Write Bytes/sec' - '\\LogicalDisk(_Total)\\Disk Transfers/sec' - '\\LogicalDisk(_Total)\\Disk Reads/sec' - '\\LogicalDisk(_Total)\\Disk Writes/sec' - '\\LogicalDisk(_Total)\\Avg. Disk sec/Transfer' - '\\LogicalDisk(_Total)\\Avg. Disk sec/Read' - '\\LogicalDisk(_Total)\\Avg. Disk sec/Write' - '\\LogicalDisk(_Total)\\Avg. Disk Queue Length' - '\\LogicalDisk(_Total)\\Avg. Disk Read Queue Length' - '\\LogicalDisk(_Total)\\Avg. Disk Write Queue Length' - '\\LogicalDisk(_Total)\\% Free Space' - '\\LogicalDisk(_Total)\\Free Megabytes' - '\\Network Interface(*)\\Bytes Total/sec' - '\\Network Interface(*)\\Bytes Sent/sec' - '\\Network Interface(*)\\Bytes Received/sec' - '\\Network Interface(*)\\Packets/sec' - '\\Network Interface(*)\\Packets Sent/sec' - '\\Network Interface(*)\\Packets Received/sec' - '\\Network Interface(*)\\Packets Outbound Errors' - '\\Network Interface(*)\\Packets Received Errors' + destinations: [ + 'azureMonitorMetrics-default' ] } - ] - windowsEventLogs: [ { - name: 'eventLogsDataSource' streams: [ 'Microsoft-Event' ] - xPathQueries: [ - 'Application!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]' - 'Security!*[System[(band(Keywords,13510798882111488))]]' - 'System!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]' + destinations: [ + nestedDependencies.outputs.logAnalyticsWorkspaceName ] } ] - } - destinations: { - azureMonitorMetrics: { - name: 'azureMonitorMetrics-default' - } - logAnalytics: [ - { - workspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - name: nestedDependencies.outputs.logAnalyticsWorkspaceName - } - ] - } - dataFlows: [ - { - streams: [ - 'Microsoft-InsightsMetrics' - ] - destinations: [ - 'azureMonitorMetrics-default' - ] - } - { - streams: [ - 'Microsoft-Event' - ] - destinations: [ - nestedDependencies.outputs.logAnalyticsWorkspaceName - ] - } - - ] - kind: 'Windows' - tags: { - 'hidden-title': 'This is visible in the resource name' - resourceType: 'Data Collection Rules' kind: 'Windows' + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Data Collection Rules' + kind: 'Windows' + } } } -}] +] diff --git a/avm/res/insights/diagnostic-setting/main.bicep b/avm/res/insights/diagnostic-setting/main.bicep index c55623e60c..9f5a177338 100644 --- a/avm/res/insights/diagnostic-setting/main.bicep +++ b/avm/res/insights/diagnostic-setting/main.bicep @@ -44,24 +44,25 @@ param enableTelemetry bool = true @description('Optional. Location deployment metadata.') param location string = deployment().location -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.insights-diagnosticsetting.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.insights-diagnosticsetting.${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 diagnosticSetting 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = { name: name @@ -72,16 +73,20 @@ resource diagnosticSetting 'Microsoft.Insights/diagnosticSettings@2021-05-01-pre eventHubName: eventHubName logAnalyticsDestinationType: !empty(logAnalyticsDestinationType) ? logAnalyticsDestinationType : null marketplacePartnerId: marketplacePartnerResourceId - logs: [for group in (logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { - categoryGroup: group.?categoryGroup - category: group.?category - enabled: group.?enabled ?? true - }] - metrics: [for group in (metricCategories ?? [ { category: 'AllMetrics' } ]): { - category: group.category - enabled: group.?enabled ?? true - timeGrain: null - }] + logs: [ + for group in (logCategoriesAndGroups ?? [{ categoryGroup: 'allLogs' }]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + } + ] + metrics: [ + for group in (metricCategories ?? [{ category: 'AllMetrics' }]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + } + ] } } diff --git a/avm/res/insights/diagnostic-setting/main.json b/avm/res/insights/diagnostic-setting/main.json index abbf525d82..158031e200 100644 --- a/avm/res/insights/diagnostic-setting/main.json +++ b/avm/res/insights/diagnostic-setting/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "5117333214781202133" + "version": "0.26.54.24096", + "templateHash": "5981394739767783762" }, "name": "Diagnostic Settings (Activity Logs) for Azure Subscriptions", "description": "This module deploys a Subscription wide export of the Activity Log.", diff --git a/avm/res/insights/diagnostic-setting/tests/e2e/defaults/main.test.bicep b/avm/res/insights/diagnostic-setting/tests/e2e/defaults/main.test.bicep index 324cb36d18..41cd930d47 100644 --- a/avm/res/insights/diagnostic-setting/tests/e2e/defaults/main.test.bicep +++ b/avm/res/insights/diagnostic-setting/tests/e2e/defaults/main.test.bicep @@ -50,11 +50,13 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: '${namePrefix}${serviceShort}001' - location: resourceLocation - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } } -}] +] diff --git a/avm/res/insights/diagnostic-setting/tests/e2e/max/main.test.bicep b/avm/res/insights/diagnostic-setting/tests/e2e/max/main.test.bicep index 08aea32676..a8c6832848 100644 --- a/avm/res/insights/diagnostic-setting/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/diagnostic-setting/tests/e2e/max/main.test.bicep @@ -50,19 +50,21 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: '${namePrefix}${serviceShort}001' - location: resourceLocation - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } } -}] +] diff --git a/avm/res/insights/diagnostic-setting/tests/e2e/waf-aligned/main.test.bicep b/avm/res/insights/diagnostic-setting/tests/e2e/waf-aligned/main.test.bicep index 02a93b9eb2..eec20b3471 100644 --- a/avm/res/insights/diagnostic-setting/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/insights/diagnostic-setting/tests/e2e/waf-aligned/main.test.bicep @@ -50,19 +50,21 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: '${namePrefix}${serviceShort}001' - location: resourceLocation - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } } -}] +] diff --git a/avm/res/insights/metric-alert/main.bicep b/avm/res/insights/metric-alert/main.bicep index 04650703e9..9bd5b95162 100644 --- a/avm/res/insights/metric-alert/main.bicep +++ b/avm/res/insights/metric-alert/main.bicep @@ -84,36 +84,45 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var actionGroups = [for action in actions: { - actionGroupId: contains(action, 'actionGroupId') ? action.actionGroupId : action - webHookProperties: contains(action, 'webHookProperties') ? action.webHookProperties : null -}] +var actionGroups = [ + for action in actions: { + actionGroupId: contains(action, 'actionGroupId') ? action.actionGroupId : action + webHookProperties: contains(action, 'webHookProperties') ? action.webHookProperties : 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') - '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') + '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.insights-metricalert.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.insights-metricalert.${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 metricAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { name: name @@ -137,19 +146,25 @@ resource metricAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { } } -resource metricAlert_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(metricAlert.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 +resource metricAlert_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(metricAlert.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: metricAlert } - scope: metricAlert -}] +] @description('The resource group the metric alert was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/insights/metric-alert/main.json b/avm/res/insights/metric-alert/main.json index 2d3ca25563..c80ef0e731 100644 --- a/avm/res/insights/metric-alert/main.json +++ b/avm/res/insights/metric-alert/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3036524835571607907" + "version": "0.26.54.24096", + "templateHash": "7733798583122178659" }, "name": "Metric Alerts", "description": "This module deploys a Metric Alert.", diff --git a/avm/res/insights/metric-alert/tests/e2e/defaults/main.test.bicep b/avm/res/insights/metric-alert/tests/e2e/defaults/main.test.bicep index 1e5d69fa27..bf6a693cc3 100644 --- a/avm/res/insights/metric-alert/tests/e2e/defaults/main.test.bicep +++ b/avm/res/insights/metric-alert/tests/e2e/defaults/main.test.bicep @@ -36,24 +36,26 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - criterias: [ - { - criterionType: 'StaticThresholdCriterion' - metricName: 'Percentage CPU' - metricNamespace: 'microsoft.compute/virtualmachines' - name: 'HighCPU' - operator: 'GreaterThan' - threshold: '90' - timeAggregation: 'Average' - } - ] - targetResourceRegion: 'westeurope' - targetResourceType: 'microsoft.compute/virtualmachines' +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' + criterias: [ + { + criterionType: 'StaticThresholdCriterion' + metricName: 'Percentage CPU' + metricNamespace: 'microsoft.compute/virtualmachines' + name: 'HighCPU' + operator: 'GreaterThan' + threshold: '90' + timeAggregation: 'Average' + } + ] + targetResourceRegion: 'westeurope' + targetResourceType: 'microsoft.compute/virtualmachines' + } } -}] +] diff --git a/avm/res/insights/metric-alert/tests/e2e/max/dependencies.bicep b/avm/res/insights/metric-alert/tests/e2e/max/dependencies.bicep index eb23eca835..38c9636e26 100644 --- a/avm/res/insights/metric-alert/tests/e2e/max/dependencies.bicep +++ b/avm/res/insights/metric-alert/tests/e2e/max/dependencies.bicep @@ -8,18 +8,18 @@ param managedIdentityName string param actionGroupName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } resource actionGroup 'Microsoft.Insights/actionGroups@2022-06-01' = { - name: actionGroupName - location: 'global' + name: actionGroupName + location: 'global' - properties: { - enabled: true - groupShortName: substring(actionGroupName, 0, 11) - } + properties: { + enabled: true + groupShortName: substring(actionGroupName, 0, 11) + } } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/insights/metric-alert/tests/e2e/max/main.test.bicep b/avm/res/insights/metric-alert/tests/e2e/max/main.test.bicep index a6c15d2793..2d4de682aa 100644 --- a/avm/res/insights/metric-alert/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/metric-alert/tests/e2e/max/main.test.bicep @@ -46,51 +46,56 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - criterias: [ - { - criterionType: 'StaticThresholdCriterion' - metricName: 'Percentage CPU' - metricNamespace: 'microsoft.compute/virtualmachines' - name: 'HighCPU' - operator: 'GreaterThan' - threshold: '90' - timeAggregation: 'Average' - } - ] - actions: [ - nestedDependencies.outputs.actionGroupResourceId - ] - alertCriteriaType: 'Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria' - 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' +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' + criterias: [ + { + criterionType: 'StaticThresholdCriterion' + metricName: 'Percentage CPU' + metricNamespace: 'microsoft.compute/virtualmachines' + name: 'HighCPU' + operator: 'GreaterThan' + threshold: '90' + timeAggregation: 'Average' + } + ] + actions: [ + nestedDependencies.outputs.actionGroupResourceId + ] + alertCriteriaType: 'Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria' + 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' + } + ] + targetResourceRegion: 'westeurope' + targetResourceType: 'microsoft.compute/virtualmachines' + windowSize: 'PT15M' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - targetResourceRegion: 'westeurope' - targetResourceType: 'microsoft.compute/virtualmachines' - windowSize: 'PT15M' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/insights/metric-alert/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/insights/metric-alert/tests/e2e/waf-aligned/dependencies.bicep index 68a384092c..b332d7fdc1 100644 --- a/avm/res/insights/metric-alert/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/insights/metric-alert/tests/e2e/waf-aligned/dependencies.bicep @@ -2,13 +2,13 @@ param actionGroupName string resource actionGroup 'Microsoft.Insights/actionGroups@2022-06-01' = { - name: actionGroupName - location: 'global' + name: actionGroupName + location: 'global' - properties: { - enabled: true - groupShortName: substring(actionGroupName, 0, 11) - } + properties: { + enabled: true + groupShortName: substring(actionGroupName, 0, 11) + } } @description('The resource ID of the created Action Group.') diff --git a/avm/res/insights/metric-alert/tests/e2e/waf-aligned/main.test.bicep b/avm/res/insights/metric-alert/tests/e2e/waf-aligned/main.test.bicep index e12bab9638..3c6db678cb 100644 --- a/avm/res/insights/metric-alert/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/insights/metric-alert/tests/e2e/waf-aligned/main.test.bicep @@ -44,34 +44,36 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - criterias: [ - { - criterionType: 'StaticThresholdCriterion' - metricName: 'Percentage CPU' - metricNamespace: 'microsoft.compute/virtualmachines' - name: 'HighCPU' - operator: 'GreaterThan' - threshold: '90' - timeAggregation: 'Average' +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' + criterias: [ + { + criterionType: 'StaticThresholdCriterion' + metricName: 'Percentage CPU' + metricNamespace: 'microsoft.compute/virtualmachines' + name: 'HighCPU' + operator: 'GreaterThan' + threshold: '90' + timeAggregation: 'Average' + } + ] + actions: [ + nestedDependencies.outputs.actionGroupResourceId + ] + alertCriteriaType: 'Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria' + targetResourceRegion: 'westeurope' + targetResourceType: 'microsoft.compute/virtualmachines' + windowSize: 'PT15M' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - actions: [ - nestedDependencies.outputs.actionGroupResourceId - ] - alertCriteriaType: 'Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria' - targetResourceRegion: 'westeurope' - targetResourceType: 'microsoft.compute/virtualmachines' - windowSize: 'PT15M' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/insights/private-link-scope/main.bicep b/avm/res/insights/private-link-scope/main.bicep index 361702d546..e2c8e7f9d8 100644 --- a/avm/res/insights/private-link-scope/main.bicep +++ b/avm/res/insights/private-link-scope/main.bicep @@ -35,129 +35,184 @@ 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') + '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') + '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') + '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 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 ?? [] - } + 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 +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.' +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 } - scope: privateLinkScope -} -module privateLinkScope_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateLinkScope-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(privateLinkScope.id, '/'))}-${privateEndpoint.?service ?? 'azuremonitor'}-${index}' - privateLinkServiceConnections: [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(privateLinkScope.id, '/'))}-${privateEndpoint.?service ?? 'azuremonitor'}-${index}' - properties: { - privateLinkServiceId: privateLinkScope.id - groupIds: [ - privateEndpoint.?service ?? 'azuremonitor' - ] +module privateLinkScope_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateLinkScope-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(privateLinkScope.id, '/'))}-${privateEndpoint.?service ?? 'azuremonitor'}-${index}' + privateLinkServiceConnections: [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(privateLinkScope.id, '/'))}-${privateEndpoint.?service ?? 'azuremonitor'}-${index}' + properties: { + privateLinkServiceId: privateLinkScope.id + groupIds: [ + privateEndpoint.?service ?? 'azuremonitor' + ] + } } - } - ] - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(privateLinkScope.id, '/'))}-${privateEndpoint.?service ?? 'azuremonitor'}-${index}' - properties: { - privateLinkServiceId: privateLinkScope.id - groupIds: [ - privateEndpoint.?service ?? 'azuremonitor' + ] + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(privateLinkScope.id, '/'))}-${privateEndpoint.?service ?? 'azuremonitor'}-${index}' + properties: { + privateLinkServiceId: privateLinkScope.id + groupIds: [ + privateEndpoint.?service ?? 'azuremonitor' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - subnetResourceId: privateEndpoint.subnetResourceId - location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: privateEndpoint.?lock ?? lock - enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds - roleAssignments: privateEndpoint.?roleAssignments - tags: privateEndpoint.?tags ?? tags - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + subnetResourceId: privateEndpoint.subnetResourceId + location: privateEndpoint.?location ?? reference( + split(privateEndpoint.subnetResourceId, '/subnets/')[0], + '2020-06-01', + 'Full' + ).location + lock: privateEndpoint.?lock ?? lock + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + 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 +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 } - scope: privateLinkScope -}] +] @description('The name of the private link scope.') output name string = privateLinkScope.name diff --git a/avm/res/insights/private-link-scope/main.json b/avm/res/insights/private-link-scope/main.json index 479a4c9333..b7948504fb 100644 --- a/avm/res/insights/private-link-scope/main.json +++ b/avm/res/insights/private-link-scope/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "9103650402015462975" + "version": "0.26.54.24096", + "templateHash": "15663862403424377072" }, "name": "Azure Monitor Private Link Scopes", "description": "This module deploys an Azure Monitor Private Link Scope.", @@ -550,8 +550,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14997816805234479909" + "version": "0.26.54.24096", + "templateHash": "4916941705691599780" }, "name": "Private Link Scope Scoped Resources", "description": "This module deploys a Private Link Scope Scoped Resource.", diff --git a/avm/res/insights/private-link-scope/scoped-resource/main.json b/avm/res/insights/private-link-scope/scoped-resource/main.json index 1c0c1180af..f721ddb2d6 100644 --- a/avm/res/insights/private-link-scope/scoped-resource/main.json +++ b/avm/res/insights/private-link-scope/scoped-resource/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14997816805234479909" + "version": "0.26.54.24096", + "templateHash": "4916941705691599780" }, "name": "Private Link Scope Scoped Resources", "description": "This module deploys a Private Link Scope Scoped Resource.", 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 index 7b221cf51c..122e677443 100644 --- 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 @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' +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/main.test.bicep b/avm/res/insights/private-link-scope/tests/e2e/max/main.test.bicep index 30cc132bcc..5b2e9ec8d5 100644 --- 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 @@ -49,169 +49,174 @@ module nestedDependencies 'dependencies.bicep' = { 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: [ +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: [ { - ingestionAccessMode: 'PrivateOnly' - queryAccessMode: 'PrivateOnly' - privateEndpointConnectionName: 'thisisatest' + name: 'scoped1' + linkedResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId } ] - 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' + 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' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - } - { - name: 'globalinai' - properties: { - groupId: 'azuremonitor' - memberName: 'global.in.ai' - privateIPAddress: '10.0.0.12' + ] + ipConfigurations: [ + { + name: 'api' + properties: { + groupId: 'azuremonitor' + memberName: 'api' + privateIPAddress: '10.0.0.11' + } } - } - { - name: 'profiler' - properties: { - groupId: 'azuremonitor' - memberName: 'profiler' - privateIPAddress: '10.0.0.13' + { + name: 'globalinai' + properties: { + groupId: 'azuremonitor' + memberName: 'global.in.ai' + privateIPAddress: '10.0.0.12' + } } - } - { - name: 'live' - properties: { - groupId: 'azuremonitor' - memberName: 'live' - privateIPAddress: '10.0.0.14' + { + name: 'profiler' + properties: { + groupId: 'azuremonitor' + memberName: 'profiler' + privateIPAddress: '10.0.0.13' + } } - } - { - name: 'diagservicesquery' - properties: { - groupId: 'azuremonitor' - memberName: 'diagservicesquery' - privateIPAddress: '10.0.0.15' + { + name: 'live' + properties: { + groupId: 'azuremonitor' + memberName: 'live' + privateIPAddress: '10.0.0.14' + } } - } - { - name: 'snapshot' - properties: { - groupId: 'azuremonitor' - memberName: 'snapshot' - privateIPAddress: '10.0.0.16' + { + name: 'diagservicesquery' + properties: { + groupId: 'azuremonitor' + memberName: 'diagservicesquery' + privateIPAddress: '10.0.0.15' + } } - } - { - name: 'agentsolutionpackstore' - properties: { - groupId: 'azuremonitor' - memberName: 'agentsolutionpackstore' - privateIPAddress: '10.0.0.17' + { + name: 'snapshot' + properties: { + groupId: 'azuremonitor' + memberName: 'snapshot' + privateIPAddress: '10.0.0.16' + } } - } - { - name: 'dce-global' - properties: { - groupId: 'azuremonitor' - memberName: 'dce-global' - privateIPAddress: '10.0.0.18' + { + name: 'agentsolutionpackstore' + properties: { + groupId: 'azuremonitor' + memberName: 'agentsolutionpackstore' + privateIPAddress: '10.0.0.17' + } } - } - { - name: 'oms-${locationUpdated}' - properties: { - groupId: 'azuremonitor' - memberName: 'oms-${locationUpdated}' - privateIPAddress: '10.0.0.19' + { + name: 'dce-global' + properties: { + groupId: 'azuremonitor' + memberName: 'dce-global' + privateIPAddress: '10.0.0.18' + } } - } - { - name: 'ods-${locationUpdated}' - properties: { - groupId: 'azuremonitor' - memberName: 'ods-${locationUpdated}' - privateIPAddress: '10.0.0.20' + { + name: 'oms-${locationUpdated}' + properties: { + groupId: 'azuremonitor' + memberName: 'oms-${locationUpdated}' + privateIPAddress: '10.0.0.19' + } } - } - { - name: 'agent-${locationUpdated}' - properties: { - groupId: 'azuremonitor' - memberName: 'agent-${locationUpdated}' - privateIPAddress: '10.0.0.21' + { + name: 'ods-${locationUpdated}' + properties: { + groupId: 'azuremonitor' + memberName: 'ods-${locationUpdated}' + privateIPAddress: '10.0.0.20' + } } - } - ] - } - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + { + 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' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] 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 index 3dead88b70..c92cf66a1d 100644 --- 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 @@ -47,130 +47,132 @@ module nestedDependencies 'dependencies.bicep' = { 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' +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 } - ipConfigurations: [ - { - name: 'api' - properties: { - groupId: 'azuremonitor' - memberName: 'api' - privateIPAddress: '10.0.0.11' - } + ] + 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' } - { - name: 'globalinai' - properties: { - groupId: 'azuremonitor' - memberName: 'global.in.ai' - privateIPAddress: '10.0.0.12' + ipConfigurations: [ + { + name: 'api' + properties: { + groupId: 'azuremonitor' + memberName: 'api' + privateIPAddress: '10.0.0.11' + } } - } - { - name: 'profiler' - properties: { - groupId: 'azuremonitor' - memberName: 'profiler' - privateIPAddress: '10.0.0.13' + { + name: 'globalinai' + properties: { + groupId: 'azuremonitor' + memberName: 'global.in.ai' + privateIPAddress: '10.0.0.12' + } } - } - { - name: 'live' - properties: { - groupId: 'azuremonitor' - memberName: 'live' - privateIPAddress: '10.0.0.14' + { + name: 'profiler' + properties: { + groupId: 'azuremonitor' + memberName: 'profiler' + privateIPAddress: '10.0.0.13' + } } - } - { - name: 'diagservicesquery' - properties: { - groupId: 'azuremonitor' - memberName: 'diagservicesquery' - privateIPAddress: '10.0.0.15' + { + name: 'live' + properties: { + groupId: 'azuremonitor' + memberName: 'live' + privateIPAddress: '10.0.0.14' + } } - } - { - name: 'snapshot' - properties: { - groupId: 'azuremonitor' - memberName: 'snapshot' - privateIPAddress: '10.0.0.16' + { + name: 'diagservicesquery' + properties: { + groupId: 'azuremonitor' + memberName: 'diagservicesquery' + privateIPAddress: '10.0.0.15' + } } - } - { - name: 'agentsolutionpackstore' - properties: { - groupId: 'azuremonitor' - memberName: 'agentsolutionpackstore' - privateIPAddress: '10.0.0.17' + { + name: 'snapshot' + properties: { + groupId: 'azuremonitor' + memberName: 'snapshot' + privateIPAddress: '10.0.0.16' + } } - } - { - name: 'dce-global' - properties: { - groupId: 'azuremonitor' - memberName: 'dce-global' - privateIPAddress: '10.0.0.18' + { + name: 'agentsolutionpackstore' + properties: { + groupId: 'azuremonitor' + memberName: 'agentsolutionpackstore' + privateIPAddress: '10.0.0.17' + } } - } - { - name: 'oms-${locationUpdated}' - properties: { - groupId: 'azuremonitor' - memberName: 'oms-${locationUpdated}' - privateIPAddress: '10.0.0.19' + { + name: 'dce-global' + properties: { + groupId: 'azuremonitor' + memberName: 'dce-global' + privateIPAddress: '10.0.0.18' + } } - } - { - name: 'ods-${locationUpdated}' - properties: { - groupId: 'azuremonitor' - memberName: 'ods-${locationUpdated}' - privateIPAddress: '10.0.0.20' + { + name: 'oms-${locationUpdated}' + properties: { + groupId: 'azuremonitor' + memberName: 'oms-${locationUpdated}' + privateIPAddress: '10.0.0.19' + } } - } - { - name: 'agent-${locationUpdated}' - properties: { - groupId: 'azuremonitor' - memberName: 'agent-${locationUpdated}' - privateIPAddress: '10.0.0.21' + { + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/insights/scheduled-query-rule/main.bicep b/avm/res/insights/scheduled-query-rule/main.bicep index 5c51cfacae..bea4edc69f 100644 --- a/avm/res/insights/scheduled-query-rule/main.bicep +++ b/avm/res/insights/scheduled-query-rule/main.bicep @@ -74,27 +74,34 @@ 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') + '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.insights-scheduledqueryrule.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.insights-scheduledqueryrule.${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 queryRule 'Microsoft.Insights/scheduledQueryRules@2021-02-01-preview' = { name: name @@ -122,19 +129,25 @@ resource queryRule 'Microsoft.Insights/scheduledQueryRules@2021-02-01-preview' = } } -resource queryRule_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(queryRule.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 +resource queryRule_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(queryRule.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: queryRule } - scope: queryRule -}] +] @description('The Name of the created scheduled query rule.') output name string = queryRule.name diff --git a/avm/res/insights/scheduled-query-rule/main.json b/avm/res/insights/scheduled-query-rule/main.json index 0e84461043..3f5f174495 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.25.53.49325", - "templateHash": "17106717169874117365" + "version": "0.26.54.24096", + "templateHash": "11130634754232789940" }, "name": "Scheduled Query Rules", "description": "This module deploys a Scheduled Query Rule.", diff --git a/avm/res/insights/scheduled-query-rule/tests/e2e/defaults/dependencies.bicep b/avm/res/insights/scheduled-query-rule/tests/e2e/defaults/dependencies.bicep index cc24476629..63e7a207db 100644 --- a/avm/res/insights/scheduled-query-rule/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/insights/scheduled-query-rule/tests/e2e/defaults/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param logAnalyticsWorkspaceName string resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location } @description('The resource ID of the created Log Analytics Workspace.') diff --git a/avm/res/insights/scheduled-query-rule/tests/e2e/defaults/main.test.bicep b/avm/res/insights/scheduled-query-rule/tests/e2e/defaults/main.test.bicep index 3c3f88928d..90dbf0cbfd 100644 --- a/avm/res/insights/scheduled-query-rule/tests/e2e/defaults/main.test.bicep +++ b/avm/res/insights/scheduled-query-rule/tests/e2e/defaults/main.test.bicep @@ -45,43 +45,45 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - criterias: { - allOf: [ - { - dimensions: [ - { - name: 'Computer' - operator: 'Include' - values: [ - '*' - ] - } - { - name: 'InstanceName' - operator: 'Include' - values: [ - '*' - ] - } - ] - metricMeasureColumn: 'AggregatedValue' - operator: 'GreaterThan' - query: 'Perf | where ObjectName == "LogicalDisk" | where CounterName == "% Free Space" | where InstanceName <> "HarddiskVolume1" and InstanceName <> "_Total" | summarize AggregatedValue = min(CounterValue) by Computer, InstanceName, bin(TimeGenerated,5m)' - threshold: 0 - timeAggregation: 'Average' - } +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 + criterias: { + allOf: [ + { + dimensions: [ + { + name: 'Computer' + operator: 'Include' + values: [ + '*' + ] + } + { + name: 'InstanceName' + operator: 'Include' + values: [ + '*' + ] + } + ] + metricMeasureColumn: 'AggregatedValue' + operator: 'GreaterThan' + query: 'Perf | where ObjectName == "LogicalDisk" | where CounterName == "% Free Space" | where InstanceName <> "HarddiskVolume1" and InstanceName <> "_Total" | summarize AggregatedValue = min(CounterValue) by Computer, InstanceName, bin(TimeGenerated,5m)' + threshold: 0 + timeAggregation: 'Average' + } + ] + } + evaluationFrequency: 'PT5M' + scopes: [ + nestedDependencies.outputs.logAnalyticsWorkspaceResourceId ] + windowSize: 'PT5M' } - evaluationFrequency: 'PT5M' - scopes: [ - nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - ] - windowSize: 'PT5M' } -}] +] diff --git a/avm/res/insights/scheduled-query-rule/tests/e2e/max/dependencies.bicep b/avm/res/insights/scheduled-query-rule/tests/e2e/max/dependencies.bicep index 9e9a8f2510..c4b3188814 100644 --- a/avm/res/insights/scheduled-query-rule/tests/e2e/max/dependencies.bicep +++ b/avm/res/insights/scheduled-query-rule/tests/e2e/max/dependencies.bicep @@ -8,13 +8,13 @@ param managedIdentityName string param logAnalyticsWorkspaceName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/insights/scheduled-query-rule/tests/e2e/max/main.test.bicep b/avm/res/insights/scheduled-query-rule/tests/e2e/max/main.test.bicep index bf15311fd2..372e4cebd7 100644 --- a/avm/res/insights/scheduled-query-rule/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/scheduled-query-rule/tests/e2e/max/main.test.bicep @@ -46,69 +46,74 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - alertDescription: 'My sample Alert' - autoMitigate: false - criterias: { - allOf: [ +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 + alertDescription: 'My sample Alert' + autoMitigate: false + criterias: { + allOf: [ + { + dimensions: [ + { + name: 'Computer' + operator: 'Include' + values: [ + '*' + ] + } + { + name: 'InstanceName' + operator: 'Include' + values: [ + '*' + ] + } + ] + metricMeasureColumn: 'AggregatedValue' + operator: 'GreaterThan' + query: 'Perf | where ObjectName == "LogicalDisk" | where CounterName == "% Free Space" | where InstanceName <> "HarddiskVolume1" and InstanceName <> "_Total" | summarize AggregatedValue = min(CounterValue) by Computer, InstanceName, bin(TimeGenerated,5m)' + threshold: 0 + timeAggregation: 'Average' + } + ] + } + evaluationFrequency: 'PT5M' + queryTimeRange: 'PT5M' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } { - dimensions: [ - { - name: 'Computer' - operator: 'Include' - values: [ - '*' - ] - } - { - name: 'InstanceName' - operator: 'Include' - values: [ - '*' - ] - } - ] - metricMeasureColumn: 'AggregatedValue' - operator: 'GreaterThan' - query: 'Perf | where ObjectName == "LogicalDisk" | where CounterName == "% Free Space" | where InstanceName <> "HarddiskVolume1" and InstanceName <> "_Total" | summarize AggregatedValue = min(CounterValue) by Computer, InstanceName, bin(TimeGenerated,5m)' - threshold: 0 - timeAggregation: 'Average' + 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' } ] - } - evaluationFrequency: 'PT5M' - queryTimeRange: 'PT5M' - 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' + scopes: [ + nestedDependencies.outputs.logAnalyticsWorkspaceResourceId + ] + suppressForMinutes: 'PT5M' + windowSize: 'PT5M' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - scopes: [ - nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - ] - suppressForMinutes: 'PT5M' - windowSize: 'PT5M' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/insights/scheduled-query-rule/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/insights/scheduled-query-rule/tests/e2e/waf-aligned/dependencies.bicep index cc24476629..63e7a207db 100644 --- a/avm/res/insights/scheduled-query-rule/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/insights/scheduled-query-rule/tests/e2e/waf-aligned/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param logAnalyticsWorkspaceName string resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { - name: logAnalyticsWorkspaceName - location: location + name: logAnalyticsWorkspaceName + location: location } @description('The resource ID of the created Log Analytics Workspace.') diff --git a/avm/res/insights/scheduled-query-rule/tests/e2e/waf-aligned/main.test.bicep b/avm/res/insights/scheduled-query-rule/tests/e2e/waf-aligned/main.test.bicep index 9cc4ee9abb..911787cae6 100644 --- a/avm/res/insights/scheduled-query-rule/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/insights/scheduled-query-rule/tests/e2e/waf-aligned/main.test.bicep @@ -45,52 +45,54 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - alertDescription: 'My sample Alert' - autoMitigate: false - criterias: { - allOf: [ - { - dimensions: [ - { - name: 'Computer' - operator: 'Include' - values: [ - '*' - ] - } - { - name: 'InstanceName' - operator: 'Include' - values: [ - '*' - ] - } - ] - metricMeasureColumn: 'AggregatedValue' - operator: 'GreaterThan' - query: 'Perf | where ObjectName == "LogicalDisk" | where CounterName == "% Free Space" | where InstanceName <> "HarddiskVolume1" and InstanceName <> "_Total" | summarize AggregatedValue = min(CounterValue) by Computer, InstanceName, bin(TimeGenerated,5m)' - threshold: 0 - timeAggregation: 'Average' - } +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 + alertDescription: 'My sample Alert' + autoMitigate: false + criterias: { + allOf: [ + { + dimensions: [ + { + name: 'Computer' + operator: 'Include' + values: [ + '*' + ] + } + { + name: 'InstanceName' + operator: 'Include' + values: [ + '*' + ] + } + ] + metricMeasureColumn: 'AggregatedValue' + operator: 'GreaterThan' + query: 'Perf | where ObjectName == "LogicalDisk" | where CounterName == "% Free Space" | where InstanceName <> "HarddiskVolume1" and InstanceName <> "_Total" | summarize AggregatedValue = min(CounterValue) by Computer, InstanceName, bin(TimeGenerated,5m)' + threshold: 0 + timeAggregation: 'Average' + } + ] + } + evaluationFrequency: 'PT5M' + queryTimeRange: 'PT5M' + scopes: [ + nestedDependencies.outputs.logAnalyticsWorkspaceResourceId ] - } - evaluationFrequency: 'PT5M' - queryTimeRange: 'PT5M' - scopes: [ - nestedDependencies.outputs.logAnalyticsWorkspaceResourceId - ] - suppressForMinutes: 'PT5M' - windowSize: 'PT5M' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + suppressForMinutes: 'PT5M' + windowSize: 'PT5M' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/insights/webtest/main.bicep b/avm/res/insights/webtest/main.bicep index 1b788fd240..8bca15afd2 100644 --- a/avm/res/insights/webtest/main.bicep +++ b/avm/res/insights/webtest/main.bicep @@ -88,27 +88,34 @@ 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') + '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.insights-webtest.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.insights-webtest.${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 webtest 'Microsoft.Insights/webtests@2022-06-15' = { name: name @@ -130,28 +137,37 @@ resource webtest 'Microsoft.Insights/webtests@2022-06-15' = { } } -resource webtest_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.' +resource webtest_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: webtest } - scope: webtest -} -resource webtest_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(webtest.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 +resource webtest_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(webtest.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: webtest } - scope: webtest -}] +] @sys.description('The name of the webtest.') output name string = webtest.name diff --git a/avm/res/insights/webtest/main.json b/avm/res/insights/webtest/main.json index 246ccae4f5..fbf790faf9 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.25.53.49325", - "templateHash": "16473822871746404569" + "version": "0.26.54.24096", + "templateHash": "279019710662992731" }, "name": "Web Tests", "description": "This module deploys a Web Test.", diff --git a/avm/res/insights/webtest/tests/e2e/defaults/main.test.bicep b/avm/res/insights/webtest/tests/e2e/defaults/main.test.bicep index 2415c915c7..dc52027e62 100644 --- a/avm/res/insights/webtest/tests/e2e/defaults/main.test.bicep +++ b/avm/res/insights/webtest/tests/e2e/defaults/main.test.bicep @@ -46,17 +46,19 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - appInsightResourceId: nestedDependencies.outputs.appInsightResourceId - webTestName: 'wt${namePrefix}$${serviceShort}001' - request: { - RequestUrl: 'https://learn.microsoft.com/en-us/' - HttpVerb: 'GET' +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 + appInsightResourceId: nestedDependencies.outputs.appInsightResourceId + webTestName: 'wt${namePrefix}$${serviceShort}001' + request: { + RequestUrl: 'https://learn.microsoft.com/en-us/' + HttpVerb: 'GET' + } } } -}] +] diff --git a/avm/res/insights/webtest/tests/e2e/max/main.test.bicep b/avm/res/insights/webtest/tests/e2e/max/main.test.bicep index 55c279f0b1..351a8baa6e 100644 --- a/avm/res/insights/webtest/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/webtest/tests/e2e/max/main.test.bicep @@ -47,49 +47,54 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - appInsightResourceId: nestedDependencies.outputs.appInsightResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - webTestName: 'wt${namePrefix}$${serviceShort}001' - syntheticMonitorId: '${namePrefix}${serviceShort}001' - locations: [ - { - Id: 'emea-nl-ams-azr' - } - ] - request: { - RequestUrl: 'https://learn.microsoft.com/en-us/' - HttpVerb: 'GET' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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 + appInsightResourceId: nestedDependencies.outputs.appInsightResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + webTestName: 'wt${namePrefix}$${serviceShort}001' + syntheticMonitorId: '${namePrefix}${serviceShort}001' + locations: [ + { + Id: 'emea-nl-ams-azr' + } + ] + request: { + RequestUrl: 'https://learn.microsoft.com/en-us/' + HttpVerb: 'GET' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' } } -}] +] diff --git a/avm/res/insights/webtest/tests/e2e/waf-aligned/main.test.bicep b/avm/res/insights/webtest/tests/e2e/waf-aligned/main.test.bicep index bccb92e4f7..11a413e559 100644 --- a/avm/res/insights/webtest/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/insights/webtest/tests/e2e/waf-aligned/main.test.bicep @@ -46,26 +46,28 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - appInsightResourceId: nestedDependencies.outputs.appInsightResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - } - webTestName: 'wt${namePrefix}$${serviceShort}001' - syntheticMonitorId: '${namePrefix}${serviceShort}001' - locations: [ - { - Id: 'emea-nl-ams-azr' +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 + appInsightResourceId: nestedDependencies.outputs.appInsightResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + } + webTestName: 'wt${namePrefix}$${serviceShort}001' + syntheticMonitorId: '${namePrefix}${serviceShort}001' + locations: [ + { + Id: 'emea-nl-ams-azr' + } + ] + request: { + RequestUrl: 'https://learn.microsoft.com/en-us/' + HttpVerb: 'GET' } - ] - request: { - RequestUrl: 'https://learn.microsoft.com/en-us/' - HttpVerb: 'GET' } } -}] +] diff --git a/avm/res/kubernetes-configuration/extension/main.bicep b/avm/res/kubernetes-configuration/extension/main.bicep index 741d911002..68b991b60e 100644 --- a/avm/res/kubernetes-configuration/extension/main.bicep +++ b/avm/res/kubernetes-configuration/extension/main.bicep @@ -39,23 +39,24 @@ param version string? @description('Optional. A list of flux configuraitons.') param fluxConfigurations array? -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.kubernetesconfiguration-extension.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.kubernetesconfiguration-extension.${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 managedCluster 'Microsoft.ContainerService/managedClusters@2022-07-01' existing = { name: clusterName @@ -71,36 +72,42 @@ resource extension 'Microsoft.KubernetesConfiguration/extensions@2022-03-01' = { extensionType: extensionType releaseTrain: releaseTrain scope: { - cluster: !empty(releaseNamespace ?? '') ? { - releaseNamespace: releaseNamespace - } : null - namespace: !empty(targetNamespace ?? '') ? { - targetNamespace: targetNamespace - } : null + cluster: !empty(releaseNamespace ?? '') + ? { + releaseNamespace: releaseNamespace + } + : null + namespace: !empty(targetNamespace ?? '') + ? { + targetNamespace: targetNamespace + } + : null } version: version } } -module fluxConfiguration 'br/public:avm/res/kubernetes-configuration/flux-configuration:0.3.1' = [for (fluxConfiguration, index) in (fluxConfigurations ?? []): { - name: '${uniqueString(deployment().name, location)}-ManagedCluster-FluxConfiguration${index}' - params: { - enableTelemetry: fluxConfiguration.?enableTelemetry ?? enableTelemetry - clusterName: managedCluster.name - scope: fluxConfiguration.scope - namespace: fluxConfiguration.namespace - sourceKind: contains(fluxConfiguration, 'gitRepository') ? 'GitRepository' : 'Bucket' - name: fluxConfiguration.?name ?? toLower('${managedCluster.name}-fluxconfiguration${index}') - bucket: fluxConfiguration.?bucket - configurationProtectedSettings: fluxConfiguration.?configurationProtectedSettings - gitRepository: fluxConfiguration.?gitRepository - kustomizations: fluxConfiguration.kustomizations - suspend: fluxConfiguration.?suspend +module fluxConfiguration 'br/public:avm/res/kubernetes-configuration/flux-configuration:0.3.1' = [ + for (fluxConfiguration, index) in (fluxConfigurations ?? []): { + name: '${uniqueString(deployment().name, location)}-ManagedCluster-FluxConfiguration${index}' + params: { + enableTelemetry: fluxConfiguration.?enableTelemetry ?? enableTelemetry + clusterName: managedCluster.name + scope: fluxConfiguration.scope + namespace: fluxConfiguration.namespace + sourceKind: contains(fluxConfiguration, 'gitRepository') ? 'GitRepository' : 'Bucket' + name: fluxConfiguration.?name ?? toLower('${managedCluster.name}-fluxconfiguration${index}') + bucket: fluxConfiguration.?bucket + configurationProtectedSettings: fluxConfiguration.?configurationProtectedSettings + gitRepository: fluxConfiguration.?gitRepository + kustomizations: fluxConfiguration.kustomizations + suspend: fluxConfiguration.?suspend + } + dependsOn: [ + extension + ] } - dependsOn: [ - extension - ] -}] +] @description('The name of the extension.') output name string = extension.name diff --git a/avm/res/kubernetes-configuration/extension/main.json b/avm/res/kubernetes-configuration/extension/main.json index a79e84ead3..c85c779228 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.25.53.49325", - "templateHash": "7131693872347776073" + "version": "0.26.54.24096", + "templateHash": "18185878129921547282" }, "name": "Kubernetes Configuration Extensions", "description": "This module deploys a Kubernetes Configuration Extension.", diff --git a/avm/res/kubernetes-configuration/extension/tests/e2e/defaults/main.test.bicep b/avm/res/kubernetes-configuration/extension/tests/e2e/defaults/main.test.bicep index a71469af7c..b46932fa1c 100644 --- a/avm/res/kubernetes-configuration/extension/tests/e2e/defaults/main.test.bicep +++ b/avm/res/kubernetes-configuration/extension/tests/e2e/defaults/main.test.bicep @@ -45,18 +45,20 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - clusterName: nestedDependencies.outputs.clusterName - extensionType: 'microsoft.flux' - releaseNamespace: 'flux-system' - releaseTrain: 'Stable' +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 + clusterName: nestedDependencies.outputs.clusterName + extensionType: 'microsoft.flux' + releaseNamespace: 'flux-system' + releaseTrain: 'Stable' + } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/kubernetes-configuration/extension/tests/e2e/max/main.test.bicep b/avm/res/kubernetes-configuration/extension/tests/e2e/max/main.test.bicep index 1d299f95bd..835be36f07 100644 --- a/avm/res/kubernetes-configuration/extension/tests/e2e/max/main.test.bicep +++ b/avm/res/kubernetes-configuration/extension/tests/e2e/max/main.test.bicep @@ -46,47 +46,49 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - clusterName: nestedDependencies.outputs.clusterName - extensionType: 'microsoft.flux' - configurationSettings: { - 'image-automation-controller.enabled': 'false' - 'image-reflector-controller.enabled': 'false' - 'kustomize-controller.enabled': 'true' - 'notification-controller.enabled': 'false' - 'source-controller.enabled': 'true' - } - releaseNamespace: 'flux-system' - releaseTrain: 'Stable' - version: '0.5.2' - fluxConfigurations: [ - { - namespace: 'flux-system' - scope: 'cluster' - gitRepository: { - repositoryRef: { - branch: 'main' +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 + clusterName: nestedDependencies.outputs.clusterName + extensionType: 'microsoft.flux' + configurationSettings: { + 'image-automation-controller.enabled': 'false' + 'image-reflector-controller.enabled': 'false' + 'kustomize-controller.enabled': 'true' + 'notification-controller.enabled': 'false' + 'source-controller.enabled': 'true' + } + releaseNamespace: 'flux-system' + releaseTrain: 'Stable' + version: '0.5.2' + fluxConfigurations: [ + { + namespace: 'flux-system' + scope: 'cluster' + gitRepository: { + repositoryRef: { + branch: 'main' + } + sshKnownHosts: '' + syncIntervalInSeconds: 300 + timeoutInSeconds: 180 + url: 'https://github.com/mspnp/aks-baseline' } - sshKnownHosts: '' - syncIntervalInSeconds: 300 - timeoutInSeconds: 180 - url: 'https://github.com/mspnp/aks-baseline' - } - kustomizations: { - unified: { - path: './cluster-manifests' + kustomizations: { + unified: { + path: './cluster-manifests' + } } + suspend: false } - suspend: false - } + ] + } + dependsOn: [ + nestedDependencies ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/kubernetes-configuration/extension/tests/e2e/waf-aligned/main.test.bicep b/avm/res/kubernetes-configuration/extension/tests/e2e/waf-aligned/main.test.bicep index b9078ed104..b9fb8d1047 100644 --- a/avm/res/kubernetes-configuration/extension/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/kubernetes-configuration/extension/tests/e2e/waf-aligned/main.test.bicep @@ -46,47 +46,49 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - clusterName: nestedDependencies.outputs.clusterName - extensionType: 'microsoft.flux' - configurationSettings: { - 'image-automation-controller.enabled': 'false' - 'image-reflector-controller.enabled': 'false' - 'kustomize-controller.enabled': 'true' - 'notification-controller.enabled': 'false' - 'source-controller.enabled': 'true' - } - releaseNamespace: 'flux-system' - releaseTrain: 'Stable' - version: '0.5.2' - fluxConfigurations: [ - { - namespace: 'flux-system' - scope: 'cluster' - gitRepository: { - repositoryRef: { - branch: 'main' +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 + clusterName: nestedDependencies.outputs.clusterName + extensionType: 'microsoft.flux' + configurationSettings: { + 'image-automation-controller.enabled': 'false' + 'image-reflector-controller.enabled': 'false' + 'kustomize-controller.enabled': 'true' + 'notification-controller.enabled': 'false' + 'source-controller.enabled': 'true' + } + releaseNamespace: 'flux-system' + releaseTrain: 'Stable' + version: '0.5.2' + fluxConfigurations: [ + { + namespace: 'flux-system' + scope: 'cluster' + gitRepository: { + repositoryRef: { + branch: 'main' + } + sshKnownHosts: '' + syncIntervalInSeconds: 300 + timeoutInSeconds: 180 + url: 'https://github.com/mspnp/aks-baseline' } - sshKnownHosts: '' - syncIntervalInSeconds: 300 - timeoutInSeconds: 180 - url: 'https://github.com/mspnp/aks-baseline' - } - kustomizations: { - unified: { - path: './cluster-manifests' + kustomizations: { + unified: { + path: './cluster-manifests' + } } + suspend: false } - suspend: false - } + ] + } + dependsOn: [ + nestedDependencies ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/kubernetes-configuration/flux-configuration/main.bicep b/avm/res/kubernetes-configuration/flux-configuration/main.bicep index d20f80e3e8..902f352b66 100644 --- a/avm/res/kubernetes-configuration/flux-configuration/main.bicep +++ b/avm/res/kubernetes-configuration/flux-configuration/main.bicep @@ -47,23 +47,24 @@ param sourceKind string @description('Optional. Whether this configuration should suspend its reconciliation of its kustomizations and sources.') param suspend bool = false -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.kubernetesconfiguration-fluxconfig.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.kubernetesconfiguration-fluxconfig.${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 managedCluster 'Microsoft.ContainerService/managedClusters@2022-07-01' existing = { name: clusterName diff --git a/avm/res/kubernetes-configuration/flux-configuration/main.json b/avm/res/kubernetes-configuration/flux-configuration/main.json index 6cd90c53c6..531c562fa1 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.25.53.49325", - "templateHash": "17949418893063624330" + "version": "0.26.54.24096", + "templateHash": "5850792806507194652" }, "name": "Kubernetes Configuration Flux Configurations", "description": "This module deploys a Kubernetes Configuration Flux Configuration.", diff --git a/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/defaults/main.test.bicep b/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/defaults/main.test.bicep index d9f8504c7e..430f6d59a3 100644 --- a/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/defaults/main.test.bicep +++ b/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/defaults/main.test.bicep @@ -47,32 +47,34 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - clusterName: nestedDependencies.outputs.clusterName - namespace: 'flux-system' - scope: 'cluster' - sourceKind: 'GitRepository' - gitRepository: { - repositoryRef: { - branch: 'main' +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' + clusterName: nestedDependencies.outputs.clusterName + namespace: 'flux-system' + scope: 'cluster' + sourceKind: 'GitRepository' + gitRepository: { + repositoryRef: { + branch: 'main' + } + sshKnownHosts: '' + syncIntervalInSeconds: 300 + timeoutInSeconds: 180 + url: 'https://github.com/mspnp/aks-baseline' } - sshKnownHosts: '' - syncIntervalInSeconds: 300 - timeoutInSeconds: 180 - url: 'https://github.com/mspnp/aks-baseline' - } - kustomizations: { - unified: { - path: './cluster-manifests' + kustomizations: { + unified: { + path: './cluster-manifests' + } } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/max/main.test.bicep b/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/max/main.test.bicep index 10a9bbd4eb..0545b6e5c9 100644 --- a/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/max/main.test.bicep +++ b/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/max/main.test.bicep @@ -47,43 +47,45 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - clusterName: nestedDependencies.outputs.clusterName - namespace: 'flux-system' - scope: 'cluster' - sourceKind: 'GitRepository' - gitRepository: { - repositoryRef: { - branch: 'main' - } - sshKnownHosts: '' - syncIntervalInSeconds: 300 - timeoutInSeconds: 180 - url: 'https://github.com/mspnp/aks-baseline' - } - kustomizations: { - unified: { - dependsOn: [] - force: false - path: './cluster-manifests' - prune: true +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 + clusterName: nestedDependencies.outputs.clusterName + namespace: 'flux-system' + scope: 'cluster' + sourceKind: 'GitRepository' + gitRepository: { + repositoryRef: { + branch: 'main' + } + sshKnownHosts: '' syncIntervalInSeconds: 300 - timeoutInSeconds: 300 - postBuild: { - substitute: { - TEST_VAR1: 'foo' - TEST_VAR2: 'bar' + timeoutInSeconds: 180 + url: 'https://github.com/mspnp/aks-baseline' + } + kustomizations: { + unified: { + dependsOn: [] + force: false + path: './cluster-manifests' + prune: true + syncIntervalInSeconds: 300 + timeoutInSeconds: 300 + postBuild: { + substitute: { + TEST_VAR1: 'foo' + TEST_VAR2: 'bar' + } } } } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/waf-aligned/main.test.bicep b/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/waf-aligned/main.test.bicep index 148f5acfbd..10516046be 100644 --- a/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/waf-aligned/main.test.bicep @@ -47,37 +47,39 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - clusterName: nestedDependencies.outputs.clusterName - namespace: 'flux-system' - location: resourceLocation - scope: 'cluster' - sourceKind: 'GitRepository' - gitRepository: { - repositoryRef: { - branch: 'main' - } - sshKnownHosts: '' - syncIntervalInSeconds: 300 - timeoutInSeconds: 180 - url: 'https://github.com/mspnp/aks-baseline' - } - kustomizations: { - unified: { - dependsOn: [] - force: false - path: './cluster-manifests' - prune: true +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + clusterName: nestedDependencies.outputs.clusterName + namespace: 'flux-system' + location: resourceLocation + scope: 'cluster' + sourceKind: 'GitRepository' + gitRepository: { + repositoryRef: { + branch: 'main' + } + sshKnownHosts: '' syncIntervalInSeconds: 300 - timeoutInSeconds: 300 + timeoutInSeconds: 180 + url: 'https://github.com/mspnp/aks-baseline' + } + kustomizations: { + unified: { + dependsOn: [] + force: false + path: './cluster-manifests' + prune: true + syncIntervalInSeconds: 300 + timeoutInSeconds: 300 + } } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/machine-learning-services/workspace/compute/main.bicep b/avm/res/machine-learning-services/workspace/compute/main.bicep index e135ccbfef..70064ee383 100644 --- a/avm/res/machine-learning-services/workspace/compute/main.bicep +++ b/avm/res/machine-learning-services/workspace/compute/main.bicep @@ -71,12 +71,20 @@ param managedIdentities managedIdentitiesType // Variables // // ================// -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null // ============================= // // Existing resources references // @@ -90,27 +98,35 @@ resource machineLearningWorkspace 'Microsoft.MachineLearningServices/workspaces@ // Deployments // // ============ // -resource compute 'Microsoft.MachineLearningServices/workspaces/computes@2022-10-01' = if (deployCompute == true) { - name: name - location: location - tags: empty(resourceId) ? tags : any(null) - sku: empty(resourceId) ? { - name: sku - tier: sku - } : any(null) - parent: machineLearningWorkspace - identity: empty(resourceId) ? identity : any(null) - properties: union({ - description: description - disableLocalAuth: disableLocalAuth - computeType: computeType - }, (!empty(resourceId) ? { - resourceId: resourceId - } : { - computeLocation: computeLocation - properties: properties - })) -} +resource compute 'Microsoft.MachineLearningServices/workspaces/computes@2022-10-01' = + if (deployCompute == true) { + name: name + location: location + tags: empty(resourceId) ? tags : any(null) + sku: empty(resourceId) + ? { + name: sku + tier: sku + } + : any(null) + parent: machineLearningWorkspace + identity: empty(resourceId) ? identity : any(null) + properties: union( + { + description: description + disableLocalAuth: disableLocalAuth + computeType: computeType + }, + (!empty(resourceId) + ? { + resourceId: resourceId + } + : { + computeLocation: computeLocation + properties: properties + }) + ) + } // =========== // // Outputs // diff --git a/avm/res/machine-learning-services/workspace/compute/main.json b/avm/res/machine-learning-services/workspace/compute/main.json index ba90995b69..e1be6424e3 100644 --- a/avm/res/machine-learning-services/workspace/compute/main.json +++ b/avm/res/machine-learning-services/workspace/compute/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2960011886227478748" + "version": "0.26.54.24096", + "templateHash": "2355820538616279194" }, "name": "Machine Learning Services Workspaces Computes", "description": "This module deploys a Machine Learning Services Workspaces Compute.\n\nAttaching a compute is not idempotent and will fail in case you try to redeploy over an existing compute in AML (see parameter `deployCompute`).", diff --git a/avm/res/machine-learning-services/workspace/main.bicep b/avm/res/machine-learning-services/workspace/main.bicep index a60169b526..ece1f942f0 100644 --- a/avm/res/machine-learning-services/workspace/main.bicep +++ b/avm/res/machine-learning-services/workspace/main.bicep @@ -98,59 +98,95 @@ param publicNetworkAccess string? // Variables // // ================// -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null // ================// // Deployments // // ================// var builtInRoleNames = { - 'AzureML Compute Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e503ece1-11d0-4e8e-8e2c-7a6c3bf38815') - 'AzureML Data Scientist': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f6c7c914-8db3-469d-8ca1-694a8f32e121') - 'AzureML Metrics Writer (preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '635dd51f-9968-44d3-b7fb-6d9a6bd613ae') - 'AzureML Registry User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1823dd4f-9b8c-4ab6-ab4e-7397a3684615') + 'AzureML Compute Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'e503ece1-11d0-4e8e-8e2c-7a6c3bf38815' + ) + 'AzureML Data Scientist': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f6c7c914-8db3-469d-8ca1-694a8f32e121' + ) + 'AzureML Metrics Writer (preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '635dd51f-9968-44d3-b7fb-6d9a6bd613ae' + ) + 'AzureML Registry User': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1823dd4f-9b8c-4ab6-ab4e-7397a3684615' + ) 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') + '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.machinelearningservices-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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.machinelearningservices-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 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 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.MachineLearningServices/workspaces@2022-10-01' = { name: name @@ -173,137 +209,174 @@ resource workspace 'Microsoft.MachineLearningServices/workspaces@2022-10-01' = { allowPublicAccessWhenBehindVnet: allowPublicAccessWhenBehindVnet description: description discoveryUrl: discoveryUrl - encryption: !empty(customerManagedKey) ? { - status: 'Enabled' - identity: !empty(customerManagedKey.?userAssignedIdentityResourceId) ? { - userAssignedIdentity: cMKUserAssignedIdentity.id - } : null - keyVaultProperties: { - keyVaultArmId: cMKKeyVault.id - keyIdentifier: !empty(customerManagedKey.?keyVersion ?? '') ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.keyVersion}' : cMKKeyVault::cMKKey.properties.keyUriWithVersion - } - } : null + encryption: !empty(customerManagedKey) + ? { + status: 'Enabled' + identity: !empty(customerManagedKey.?userAssignedIdentityResourceId) + ? { + userAssignedIdentity: cMKUserAssignedIdentity.id + } + : null + keyVaultProperties: { + keyVaultArmId: cMKKeyVault.id + keyIdentifier: !empty(customerManagedKey.?keyVersion ?? '') + ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.keyVersion}' + : cMKKeyVault::cMKKey.properties.keyUriWithVersion + } + } + : null imageBuildCompute: imageBuildCompute primaryUserAssignedIdentity: primaryUserAssignedIdentity - publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) : (!empty(privateEndpoints) ? 'Disabled' : 'Enabled') + publicNetworkAccess: !empty(publicNetworkAccess) + ? any(publicNetworkAccess) + : (!empty(privateEndpoints) ? 'Disabled' : 'Enabled') serviceManagedResourcesSettings: serviceManagedResourcesSettings }, // Parameters only added if not empty - !empty(sharedPrivateLinkResources) ? { - sharedPrivateLinkResources: sharedPrivateLinkResources - } : {} + !empty(sharedPrivateLinkResources) + ? { + sharedPrivateLinkResources: sharedPrivateLinkResources + } + : {} ) } -module workspace_computes 'compute/main.bicep' = [for compute in (computes ?? []): { - name: '${workspace.name}-${compute.name}-compute' - params: { - machineLearningWorkspaceName: workspace.name - name: compute.name - location: compute.location - sku: compute.?sku - managedIdentities: compute.?managedIdentities - tags: compute.?tags - deployCompute: compute.?deployCompute - computeLocation: compute.?computeLocation - description: compute.?description - disableLocalAuth: compute.?disableLocalAuth - resourceId: compute.?resourceId - computeType: compute.computeType - properties: compute.?properties +module workspace_computes 'compute/main.bicep' = [ + for compute in (computes ?? []): { + name: '${workspace.name}-${compute.name}-compute' + params: { + machineLearningWorkspaceName: workspace.name + name: compute.name + location: compute.location + sku: compute.?sku + managedIdentities: compute.?managedIdentities + tags: compute.?tags + deployCompute: compute.?deployCompute + computeLocation: compute.?computeLocation + description: compute.?description + disableLocalAuth: compute.?disableLocalAuth + resourceId: compute.?resourceId + computeType: compute.computeType + properties: compute.?properties + } + dependsOn: [ + workspace_privateEndpoints + ] } - dependsOn: [ - workspace_privateEndpoints - ] -}] - -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.' +] + +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 } - 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 - 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 +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 + 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 + } + scope: workspace } - scope: workspace -}] - -module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-workspace-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'amlworkspace'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'amlworkspace'}-${index}' - properties: { - privateLinkServiceId: workspace.id - groupIds: [ - privateEndpoint.?service ?? 'amlworkspace' +] + +module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-workspace-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'amlworkspace'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'amlworkspace'}-${index}' + properties: { + privateLinkServiceId: workspace.id + groupIds: [ + privateEndpoint.?service ?? 'amlworkspace' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'amlworkspace'}-${index}' - properties: { - privateLinkServiceId: workspace.id - groupIds: [ - privateEndpoint.?service ?? 'amlworkspace' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? 'amlworkspace'}-${index}' + properties: { + privateLinkServiceId: workspace.id + groupIds: [ + privateEndpoint.?service ?? 'amlworkspace' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] - -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 +] + +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 } - scope: workspace -}] +] // ================// // Outputs // diff --git a/avm/res/machine-learning-services/workspace/main.json b/avm/res/machine-learning-services/workspace/main.json index 7af12d178a..d11a6904f5 100644 --- a/avm/res/machine-learning-services/workspace/main.json +++ b/avm/res/machine-learning-services/workspace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2153747383305102474" + "version": "0.26.54.24096", + "templateHash": "16054212084136992012" }, "name": "Machine Learning Services Workspaces", "description": "This module deploys a Machine Learning Services Workspace.", @@ -861,8 +861,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2960011886227478748" + "version": "0.26.54.24096", + "templateHash": "2355820538616279194" }, "name": "Machine Learning Services Workspaces Computes", "description": "This module deploys a Machine Learning Services Workspaces Compute.\n\nAttaching a compute is not idempotent and will fail in case you try to redeploy over an existing compute in AML (see parameter `deployCompute`).", diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/defaults/dependencies.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/defaults/dependencies.bicep index 950a61c9f9..6ddec13775 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/defaults/dependencies.bicep @@ -11,37 +11,37 @@ param applicationInsightsName string 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: null - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: true - accessPolicies: [] + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' } + tenantId: tenant().tenantId + enablePurgeProtection: null + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } } resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { - name: applicationInsightsName - location: location - kind: '' - properties: {} + name: applicationInsightsName + location: location + kind: '' + properties: {} } resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { - name: storageAccountName - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' } @description('The resource ID of the created Application Insights instance.') diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/defaults/main.test.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/defaults/main.test.bicep index 6641997985..94625f8a3d 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/defaults/main.test.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/defaults/main.test.bicep @@ -47,18 +47,20 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - associatedApplicationInsightsResourceId: nestedDependencies.outputs.applicationInsightsResourceId - associatedKeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - associatedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - sku: 'Basic' +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 + associatedApplicationInsightsResourceId: nestedDependencies.outputs.applicationInsightsResourceId + associatedKeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + associatedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + sku: 'Basic' + } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/encr/dependencies.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/encr/dependencies.bicep index ff1e354c49..4e41990054 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/encr/dependencies.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/encr/dependencies.bicep @@ -51,7 +51,10 @@ resource keyVaultServicePermissions 'Microsoft.Authorization/roleAssignments@202 scope: keyVault properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalType: 'ServicePrincipal' } } @@ -60,7 +63,10 @@ resource keyVaultDataPermissions 'Microsoft.Authorization/roleAssignments@2022-0 scope: keyVault::key properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User principalType: 'ServicePrincipal' } } diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/encr/main.test.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/encr/main.test.bicep index d133c23c22..909437d5c9 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/encr/main.test.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/encr/main.test.bicep @@ -52,30 +52,32 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - associatedApplicationInsightsResourceId: nestedDependencies.outputs.applicationInsightsResourceId - associatedKeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - associatedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - sku: 'Basic' - customerManagedKey: { - keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId - } - primaryUserAssignedIdentity: nestedDependencies.outputs.managedIdentityResourceId - managedIdentities: { - systemAssigned: false - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] +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 + associatedApplicationInsightsResourceId: nestedDependencies.outputs.applicationInsightsResourceId + associatedKeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + associatedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + sku: 'Basic' + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + } + primaryUserAssignedIdentity: nestedDependencies.outputs.managedIdentityResourceId + managedIdentities: { + systemAssigned: false + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/max/dependencies.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/max/dependencies.bicep index 4f7b46494d..2002a08799 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/max/dependencies.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/max/dependencies.bicep @@ -66,7 +66,10 @@ resource keyVaultServicePermissions 'Microsoft.Authorization/roleAssignments@202 scope: keyVault properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalType: 'ServicePrincipal' } } @@ -75,7 +78,10 @@ resource keyVaultDataPermissions 'Microsoft.Authorization/roleAssignments@2022-0 scope: keyVault properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483') // Key Vault Administrator + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '00482a5a-887f-4fb3-b363-3b7fe8e74483' + ) // Key Vault Administrator principalType: 'ServicePrincipal' } } diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/max/main.test.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/max/main.test.bicep index 6cfc6403a7..de85acc87e 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/max/main.test.bicep @@ -63,118 +63,123 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - associatedApplicationInsightsResourceId: nestedDependencies.outputs.applicationInsightsResourceId - associatedKeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - associatedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - sku: 'Premium' - computes: [ - { - computeLocation: resourceLocation - computeType: 'AmlCompute' - description: 'Default CPU Cluster' - disableLocalAuth: false - location: resourceLocation - name: 'DefaultCPU' - properties: { - enableNodePublicIp: true - isolatedNetwork: false - osType: 'Linux' - remoteLoginPortPublicAccess: 'Disabled' - scaleSettings: { - maxNodeCount: 3 - minNodeCount: 0 - nodeIdleTimeBeforeScaleDown: 'PT5M' +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 + associatedApplicationInsightsResourceId: nestedDependencies.outputs.applicationInsightsResourceId + associatedKeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + associatedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + sku: 'Premium' + computes: [ + { + computeLocation: resourceLocation + computeType: 'AmlCompute' + description: 'Default CPU Cluster' + disableLocalAuth: false + location: resourceLocation + name: 'DefaultCPU' + properties: { + enableNodePublicIp: true + isolatedNetwork: false + osType: 'Linux' + remoteLoginPortPublicAccess: 'Disabled' + scaleSettings: { + maxNodeCount: 3 + minNodeCount: 0 + nodeIdleTimeBeforeScaleDown: 'PT5M' + } + vmPriority: 'Dedicated' + vmSize: 'STANDARD_DS11_V2' + } + sku: 'Basic' + managedIdentities: { + systemAssigned: false + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] } - vmPriority: 'Dedicated' - vmSize: 'STANDARD_DS11_V2' } - sku: 'Basic' - managedIdentities: { - systemAssigned: false - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId + ] + description: 'The cake is a lie.' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } + ] + discoveryUrl: 'http://example.com' + imageBuildCompute: 'testcompute' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - description: 'The cake is a lie.' - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' + primaryUserAssignedIdentity: nestedDependencies.outputs.managedIdentityResourceId + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - discoveryUrl: 'http://example.com' - imageBuildCompute: 'testcompute' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - primaryUserAssignedIdentity: nestedDependencies.outputs.managedIdentityResourceId - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } - } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + } + ] + 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' + } + ] + managedIdentities: { + systemAssigned: false + 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' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - managedIdentities: { - systemAssigned: false - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/waf-aligned/dependencies.bicep index 4f7b46494d..2002a08799 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/waf-aligned/dependencies.bicep @@ -66,7 +66,10 @@ resource keyVaultServicePermissions 'Microsoft.Authorization/roleAssignments@202 scope: keyVault properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalType: 'ServicePrincipal' } } @@ -75,7 +78,10 @@ resource keyVaultDataPermissions 'Microsoft.Authorization/roleAssignments@2022-0 scope: keyVault properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483') // Key Vault Administrator + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '00482a5a-887f-4fb3-b363-3b7fe8e74483' + ) // Key Vault Administrator principalType: 'ServicePrincipal' } } diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/waf-aligned/main.test.bicep index 4a4ee2aafb..8835d7b037 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -63,45 +63,47 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - associatedApplicationInsightsResourceId: nestedDependencies.outputs.applicationInsightsResourceId - associatedKeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - associatedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - sku: 'Standard' - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + associatedApplicationInsightsResourceId: nestedDependencies.outputs.applicationInsightsResourceId + associatedKeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + associatedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + sku: 'Standard' + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/maintenance/maintenance-configuration/main.bicep b/avm/res/maintenance/maintenance-configuration/main.bicep index 0bd0fd9c37..729f65882d 100644 --- a/avm/res/maintenance/maintenance-configuration/main.bicep +++ b/avm/res/maintenance/maintenance-configuration/main.bicep @@ -63,28 +63,38 @@ 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') - 'Scheduled Patching Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cd08ab90-6b14-449c-ad9a-8f8e549482c6') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'Scheduled Patching Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'cd08ab90-6b14-449c-ad9a-8f8e549482c6' + ) + '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.maintenance-maintenanceconfiguration.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.maintenance-maintenanceconfiguration.${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 maintenanceConfiguration 'Microsoft.Maintenance/maintenanceConfigurations@2023-04-01' = { location: location @@ -100,28 +110,37 @@ resource maintenanceConfiguration 'Microsoft.Maintenance/maintenanceConfiguratio } } -resource maintenanceConfiguration_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.' +resource maintenanceConfiguration_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: maintenanceConfiguration } - scope: maintenanceConfiguration -} -resource maintenanceConfiguration_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(maintenanceConfiguration.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 +resource maintenanceConfiguration_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(maintenanceConfiguration.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: maintenanceConfiguration } - scope: maintenanceConfiguration -}] +] // =========== // // Outputs // diff --git a/avm/res/maintenance/maintenance-configuration/main.json b/avm/res/maintenance/maintenance-configuration/main.json index f06917ab55..f2d9aa1a6f 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.25.53.49325", - "templateHash": "16015110608585715401" + "version": "0.26.54.24096", + "templateHash": "1159826078324391802" }, "name": "Maintenance Configurations", "description": "This module deploys a Maintenance Configuration.", diff --git a/avm/res/maintenance/maintenance-configuration/tests/e2e/defaults/main.test.bicep b/avm/res/maintenance/maintenance-configuration/tests/e2e/defaults/main.test.bicep index 7eee9f0efe..8799ed5e45 100644 --- a/avm/res/maintenance/maintenance-configuration/tests/e2e/defaults/main.test.bicep +++ b/avm/res/maintenance/maintenance-configuration/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/maintenance/maintenance-configuration/tests/e2e/max/dependencies.bicep b/avm/res/maintenance/maintenance-configuration/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/maintenance/maintenance-configuration/tests/e2e/max/dependencies.bicep +++ b/avm/res/maintenance/maintenance-configuration/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/maintenance/maintenance-configuration/tests/e2e/max/main.test.bicep b/avm/res/maintenance/maintenance-configuration/tests/e2e/max/main.test.bicep index a6c8080465..c794755eb8 100644 --- a/avm/res/maintenance/maintenance-configuration/tests/e2e/max/main.test.bicep +++ b/avm/res/maintenance/maintenance-configuration/tests/e2e/max/main.test.bicep @@ -45,66 +45,71 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - extensionProperties: { - InGuestPatchMode: 'User' - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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 + extensionProperties: { + InGuestPatchMode: 'User' } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - 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' } - ] - maintenanceScope: 'InGuestPatch' - maintenanceWindow: { - duration: '03:00' - expirationDateTime: '9999-12-31 23:59:59' - recurEvery: 'Day' - startDateTime: '2022-12-31 13:00' - timeZone: 'W. Europe Standard Time' - } - namespace: '${serviceShort}ns' - visibility: 'Custom' - installPatches: { - linuxParameters: { - classificationsToInclude: null - packageNameMasksToExclude: null - packageNameMasksToInclude: null + 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' + } + ] + maintenanceScope: 'InGuestPatch' + maintenanceWindow: { + duration: '03:00' + expirationDateTime: '9999-12-31 23:59:59' + recurEvery: 'Day' + startDateTime: '2022-12-31 13:00' + timeZone: 'W. Europe Standard Time' } - rebootSetting: 'IfRequired' - windowsParameters: { - classificationsToInclude: [ - 'Critical' - 'Security' - ] - kbNumbersToExclude: null - kbNumbersToInclude: null + namespace: '${serviceShort}ns' + visibility: 'Custom' + installPatches: { + linuxParameters: { + classificationsToInclude: null + packageNameMasksToExclude: null + packageNameMasksToInclude: null + } + rebootSetting: 'IfRequired' + windowsParameters: { + classificationsToInclude: [ + 'Critical' + 'Security' + ] + kbNumbersToExclude: null + kbNumbersToInclude: null + } } } } -}] +] diff --git a/avm/res/maintenance/maintenance-configuration/tests/e2e/waf-aligned/main.test.bicep b/avm/res/maintenance/maintenance-configuration/tests/e2e/waf-aligned/main.test.bicep index 2eb217f971..a7ed09b649 100644 --- a/avm/res/maintenance/maintenance-configuration/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/maintenance/maintenance-configuration/tests/e2e/waf-aligned/main.test.bicep @@ -36,45 +36,47 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - extensionProperties: { - InGuestPatchMode: 'User' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - maintenanceScope: 'InGuestPatch' - maintenanceWindow: { - duration: '03:00' - expirationDateTime: '9999-12-31 23:59:59' - recurEvery: 'Day' - startDateTime: '2022-12-31 13:00' - timeZone: 'W. Europe Standard Time' - } - namespace: '${serviceShort}ns' - visibility: 'Custom' - installPatches: { - linuxParameters: { - classificationsToInclude: null - packageNameMasksToExclude: null - packageNameMasksToInclude: null +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 + extensionProperties: { + InGuestPatchMode: 'User' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + maintenanceScope: 'InGuestPatch' + maintenanceWindow: { + duration: '03:00' + expirationDateTime: '9999-12-31 23:59:59' + recurEvery: 'Day' + startDateTime: '2022-12-31 13:00' + timeZone: 'W. Europe Standard Time' } - rebootSetting: 'IfRequired' - windowsParameters: { - classificationsToInclude: [ - 'Critical' - 'Security' - ] - kbNumbersToExclude: null - kbNumbersToInclude: null + namespace: '${serviceShort}ns' + visibility: 'Custom' + installPatches: { + linuxParameters: { + classificationsToInclude: null + packageNameMasksToExclude: null + packageNameMasksToInclude: null + } + rebootSetting: 'IfRequired' + windowsParameters: { + classificationsToInclude: [ + 'Critical' + 'Security' + ] + kbNumbersToExclude: null + kbNumbersToInclude: null + } } } } -}] +] 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 41b27ff161..ea926bbb96 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.25.53.49325", - "templateHash": "15826270550299120709" + "version": "0.26.54.24096", + "templateHash": "4317497001099502136" }, "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.bicep b/avm/res/managed-identity/user-assigned-identity/main.bicep index 71ef19b973..a5ebb6e4cd 100644 --- a/avm/res/managed-identity/user-assigned-identity/main.bicep +++ b/avm/res/managed-identity/user-assigned-identity/main.bicep @@ -25,31 +25,44 @@ param enableTelemetry bool = true var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Managed Identity Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e40ec5ca-96e0-45a2-b4ff-59039f2c2b59') - 'Managed Identity Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f1a07417-d97a-45cb-824c-7a7467783830') + 'Managed Identity Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'e40ec5ca-96e0-45a2-b4ff-59039f2c2b59' + ) + 'Managed Identity Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f1a07417-d97a-45cb-824c-7a7467783830' + ) 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') + '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.managedidentity-userassignedidentity.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.managedidentity-userassignedidentity.${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 userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: name @@ -57,39 +70,50 @@ resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@ tags: tags } -resource userAssignedIdentity_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.' +resource userAssignedIdentity_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: userAssignedIdentity } - scope: userAssignedIdentity -} -module userAssignedIdentity_federatedIdentityCredentials 'federated-identity-credential/main.bicep' = [for (federatedIdentityCredential, index) in (federatedIdentityCredentials ?? []): { - name: '${uniqueString(deployment().name, location)}-UserMSI-FederatedIdentityCredential-${index}' - params: { - name: federatedIdentityCredential.name - userAssignedIdentityName: userAssignedIdentity.name - audiences: federatedIdentityCredential.audiences - issuer: federatedIdentityCredential.issuer - subject: federatedIdentityCredential.subject +module userAssignedIdentity_federatedIdentityCredentials 'federated-identity-credential/main.bicep' = [ + for (federatedIdentityCredential, index) in (federatedIdentityCredentials ?? []): { + name: '${uniqueString(deployment().name, location)}-UserMSI-FederatedIdentityCredential-${index}' + params: { + name: federatedIdentityCredential.name + userAssignedIdentityName: userAssignedIdentity.name + audiences: federatedIdentityCredential.audiences + issuer: federatedIdentityCredential.issuer + subject: federatedIdentityCredential.subject + } } -}] - -resource userAssignedIdentity_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(userAssignedIdentity.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 +] + +resource userAssignedIdentity_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(userAssignedIdentity.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: userAssignedIdentity } - scope: userAssignedIdentity -}] +] @description('The name of the user assigned identity.') output name string = userAssignedIdentity.name diff --git a/avm/res/managed-identity/user-assigned-identity/main.json b/avm/res/managed-identity/user-assigned-identity/main.json index 750eb2c5d0..7d006d7143 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.25.53.49325", - "templateHash": "11532993654681133775" + "version": "0.26.54.24096", + "templateHash": "8193140269981034553" }, "name": "User Assigned Identities", "description": "This module deploys a User Assigned Identity.", @@ -299,8 +299,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15826270550299120709" + "version": "0.26.54.24096", + "templateHash": "4317497001099502136" }, "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/tests/e2e/defaults/main.test.bicep b/avm/res/managed-identity/user-assigned-identity/tests/e2e/defaults/main.test.bicep index 97d58c24d0..627b394869 100644 --- a/avm/res/managed-identity/user-assigned-identity/tests/e2e/defaults/main.test.bicep +++ b/avm/res/managed-identity/user-assigned-identity/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/managed-identity/user-assigned-identity/tests/e2e/max/dependencies.bicep b/avm/res/managed-identity/user-assigned-identity/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/managed-identity/user-assigned-identity/tests/e2e/max/dependencies.bicep +++ b/avm/res/managed-identity/user-assigned-identity/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/managed-identity/user-assigned-identity/tests/e2e/max/main.test.bicep b/avm/res/managed-identity/user-assigned-identity/tests/e2e/max/main.test.bicep index 17ce769ad4..3d917bafd1 100644 --- a/avm/res/managed-identity/user-assigned-identity/tests/e2e/max/main.test.bicep +++ b/avm/res/managed-identity/user-assigned-identity/tests/e2e/max/main.test.bicep @@ -49,47 +49,52 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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: enforcedLocation - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - federatedIdentityCredentials: [ - { - name: 'test-fed-cred-${serviceShort}-001' - audiences: [ - 'api://AzureADTokenExchange' - ] - issuer: 'https://contoso.com/${subscription().tenantId}/${guid(deployment().name)}/' - subject: 'system:serviceaccount:default:workload-identity-sa' - } - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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: enforcedLocation + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + federatedIdentityCredentials: [ + { + name: 'test-fed-cred-${serviceShort}-001' + audiences: [ + 'api://AzureADTokenExchange' + ] + issuer: 'https://contoso.com/${subscription().tenantId}/${guid(deployment().name)}/' + subject: 'system:serviceaccount:default:workload-identity-sa' + } + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/managed-identity/user-assigned-identity/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/managed-identity/user-assigned-identity/tests/e2e/waf-aligned/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/managed-identity/user-assigned-identity/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/managed-identity/user-assigned-identity/tests/e2e/waf-aligned/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/managed-identity/user-assigned-identity/tests/e2e/waf-aligned/main.test.bicep b/avm/res/managed-identity/user-assigned-identity/tests/e2e/waf-aligned/main.test.bicep index 4d34dd01e5..2131970f5f 100644 --- a/avm/res/managed-identity/user-assigned-identity/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/managed-identity/user-assigned-identity/tests/e2e/waf-aligned/main.test.bicep @@ -40,30 +40,32 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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: enforcedLocation - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - federatedIdentityCredentials: [ - { - name: 'test-fed-cred-${serviceShort}-001' - audiences: [ - 'api://AzureADTokenExchange' - ] - issuer: 'https://contoso.com/${subscription().tenantId}/${guid(deployment().name)}/' - subject: 'system:serviceaccount:default:workload-identity-sa' +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: enforcedLocation + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + federatedIdentityCredentials: [ + { + name: 'test-fed-cred-${serviceShort}-001' + audiences: [ + 'api://AzureADTokenExchange' + ] + issuer: 'https://contoso.com/${subscription().tenantId}/${guid(deployment().name)}/' + subject: 'system:serviceaccount:default:workload-identity-sa' + } + ] + 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/management/management-group/main.bicep b/avm/res/management/management-group/main.bicep index 589fe375fa..563e3314f8 100644 --- a/avm/res/management/management-group/main.bicep +++ b/avm/res/management/management-group/main.bicep @@ -23,24 +23,25 @@ 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 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 @@ -52,11 +53,13 @@ resource managementGroup 'Microsoft.Management/managementGroups@2021-04-01' = { scope: tenant() properties: { displayName: displayName - details: !empty(parentId) ? { - parent: { - id: parentManagementGroup.id - } - } : null + details: !empty(parentId) + ? { + parent: { + id: parentManagementGroup.id + } + } + : null } } diff --git a/avm/res/management/management-group/main.json b/avm/res/management/management-group/main.json index 7fe3ed1d62..7457babe82 100644 --- a/avm/res/management/management-group/main.json +++ b/avm/res/management/management-group/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14104914545746658709" + "version": "0.26.54.24096", + "templateHash": "4075622511282134710" }, "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", 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 index cd24a798ff..f2c6516d82 100644 --- a/avm/res/management/management-group/tests/e2e/defaults/main.test.bicep +++ b/avm/res/management/management-group/tests/e2e/defaults/main.test.bicep @@ -21,10 +21,12 @@ param namePrefix string = '#_namePrefix_#' // ============== // @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 +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 index 38ef9faf72..c2ca358b8d 100644 --- a/avm/res/management/management-group/tests/e2e/max/main.test.bicep +++ b/avm/res/management/management-group/tests/e2e/max/main.test.bicep @@ -21,12 +21,14 @@ param namePrefix string = '#_namePrefix_#' // ============== // @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, '/')) +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 index a27ae728fa..aed91e35e6 100644 --- 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 @@ -21,12 +21,14 @@ param namePrefix string = '#_namePrefix_#' // ============== // @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, '/')) +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/network/application-security-group/main.bicep b/avm/res/network/application-security-group/main.bicep index 9ba811ed6c..f514b81a70 100644 --- a/avm/res/network/application-security-group/main.bicep +++ b/avm/res/network/application-security-group/main.bicep @@ -24,27 +24,34 @@ 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') + '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-applicationsecuritygroup.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-applicationsecuritygroup.${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 applicationSecurityGroup 'Microsoft.Network/applicationSecurityGroups@2023-04-01' = { name: name @@ -53,28 +60,37 @@ resource applicationSecurityGroup 'Microsoft.Network/applicationSecurityGroups@2 properties: {} } -resource applicationSecurityGroup_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.' +resource applicationSecurityGroup_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: applicationSecurityGroup } - scope: applicationSecurityGroup -} -resource applicationSecurityGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(applicationSecurityGroup.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 +resource applicationSecurityGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(applicationSecurityGroup.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: applicationSecurityGroup } - scope: applicationSecurityGroup -}] +] @description('The resource group the application security group was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/application-security-group/main.json b/avm/res/network/application-security-group/main.json index 02317ce977..60d6778939 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.25.53.49325", - "templateHash": "18328102101906578940" + "version": "0.26.54.24096", + "templateHash": "8902169234314141631" }, "name": "Application Security Groups (ASG)", "description": "This module deploys an Application Security Group (ASG).", diff --git a/avm/res/network/application-security-group/tests/e2e/defaults/main.test.bicep b/avm/res/network/application-security-group/tests/e2e/defaults/main.test.bicep index 3805501d29..1a8be9a7d2 100644 --- a/avm/res/network/application-security-group/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/application-security-group/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/application-security-group/tests/e2e/max/dependencies.bicep b/avm/res/network/application-security-group/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/network/application-security-group/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/application-security-group/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/network/application-security-group/tests/e2e/max/main.test.bicep b/avm/res/network/application-security-group/tests/e2e/max/main.test.bicep index ad4f14a855..773b0b4e2f 100644 --- a/avm/res/network/application-security-group/tests/e2e/max/main.test.bicep +++ b/avm/res/network/application-security-group/tests/e2e/max/main.test.bicep @@ -45,37 +45,42 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/network/application-security-group/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/application-security-group/tests/e2e/waf-aligned/main.test.bicep index 9743d1fe3b..ba74bf9828 100644 --- a/avm/res/network/application-security-group/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/application-security-group/tests/e2e/waf-aligned/main.test.bicep @@ -36,20 +36,22 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/network/azure-firewall/main.bicep b/avm/res/network/azure-firewall/main.bicep index f0edf1142c..08f4af0cc2 100644 --- a/avm/res/network/azure-firewall/main.bicep +++ b/avm/res/network/azure-firewall/main.bicep @@ -94,29 +94,41 @@ var isCreateDefaultManagementIP = empty(managementIPResourceID) && requiresManag // 2. Use new Public IP created in this module // 3. Do not use a Public IP if publicIPAddressObject is empty -var additionalPublicIpConfigurationsVar = [for ipConfiguration in additionalPublicIpConfigurations: { - name: ipConfiguration.name - properties: { - publicIPAddress: contains(ipConfiguration, 'publicIPAddressResourceId') ? { - id: ipConfiguration.publicIPAddressResourceId - } : null +var additionalPublicIpConfigurationsVar = [ + for ipConfiguration in additionalPublicIpConfigurations: { + name: ipConfiguration.name + properties: { + publicIPAddress: contains(ipConfiguration, 'publicIPAddressResourceId') + ? { + id: ipConfiguration.publicIPAddressResourceId + } + : null + } } -}] -var ipConfigurations = concat([ +] +var ipConfigurations = concat( + [ { name: !empty(publicIPResourceID) ? last(split(publicIPResourceID, '/')) : publicIPAddress.outputs.name - properties: union({ + properties: union( + { subnet: { id: '${virtualNetworkResourceId}/subnets/AzureFirewallSubnet' // The subnet name must be AzureFirewallSubnet } - }, (!empty(publicIPResourceID) || !empty(publicIPAddressObject)) ? { - //Use existing Public IP, new Public IP created in this module, or none if neither - publicIPAddress: { - id: !empty(publicIPResourceID) ? publicIPResourceID : publicIPAddress.outputs.resourceId - } - } : {}) + }, + (!empty(publicIPResourceID) || !empty(publicIPAddressObject)) + ? { + //Use existing Public IP, new Public IP created in this module, or none if neither + publicIPAddress: { + id: !empty(publicIPResourceID) ? publicIPResourceID : publicIPAddress.outputs.resourceId + } + } + : {} + ) } - ], additionalPublicIpConfigurationsVar) + ], + additionalPublicIpConfigurationsVar +) // ---------------------------------------------------------------------------- // Prep managementIPConfiguration object for different uses cases: @@ -125,16 +137,21 @@ var ipConfigurations = concat([ var managementIPConfiguration = { name: !empty(managementIPResourceID) ? last(split(managementIPResourceID, '/')) : managementIPAddress.outputs.name - properties: union({ + properties: union( + { subnet: { id: '${virtualNetworkResourceId}/subnets/AzureFirewallManagementSubnet' // The subnet name must be AzureFirewallManagementSubnet for a 'Basic' SKU tier firewall } - }, (!empty(publicIPResourceID) || !empty(managementIPAddressObject)) ? { - // Use existing Management Public IP, new Management Public IP created in this module, or none if neither - publicIPAddress: { - id: !empty(managementIPResourceID) ? managementIPResourceID : managementIPAddress.outputs.resourceId - } - } : {}) + }, + (!empty(publicIPResourceID) || !empty(managementIPAddressObject)) + ? { + // Use existing Management Public IP, new Management Public IP created in this module, or none if neither + publicIPAddress: { + id: !empty(managementIPResourceID) ? managementIPResourceID : managementIPAddress.outputs.resourceId + } + } + : {} + ) } // ---------------------------------------------------------------------------- @@ -142,143 +159,205 @@ 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') + '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-azurefirewall.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-azurefirewall.${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' + } } } } } -} -module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.2.1' = if (empty(publicIPResourceID) && azureSkuName == 'AZFW_VNet') { - name: '${uniqueString(deployment().name, location)}-Firewall-PIP' - params: { - name: publicIPAddressObject.name - publicIpPrefixResourceId: contains(publicIPAddressObject, 'publicIPPrefixResourceId') ? (!(empty(publicIPAddressObject.publicIPPrefixResourceId)) ? publicIPAddressObject.publicIPPrefixResourceId : '') : '' - publicIPAllocationMethod: contains(publicIPAddressObject, 'publicIPAllocationMethod') ? (!(empty(publicIPAddressObject.publicIPAllocationMethod)) ? publicIPAddressObject.publicIPAllocationMethod : 'Static') : 'Static' - skuName: contains(publicIPAddressObject, 'skuName') ? (!(empty(publicIPAddressObject.skuName)) ? publicIPAddressObject.skuName : 'Standard') : 'Standard' - skuTier: contains(publicIPAddressObject, 'skuTier') ? (!(empty(publicIPAddressObject.skuTier)) ? publicIPAddressObject.skuTier : 'Regional') : 'Regional' - roleAssignments: contains(publicIPAddressObject, 'roleAssignments') ? (!empty(publicIPAddressObject.roleAssignments) ? publicIPAddressObject.roleAssignments : []) : [] - diagnosticSettings: publicIPAddressObject.?diagnosticSettings - location: location - lock: lock - tags: publicIPAddressObject.?tags ?? tags - zones: zones - enableTelemetry: publicIPAddressObject.?enableTelemetry ?? enableTelemetry +module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.2.1' = + if (empty(publicIPResourceID) && azureSkuName == 'AZFW_VNet') { + name: '${uniqueString(deployment().name, location)}-Firewall-PIP' + params: { + name: publicIPAddressObject.name + publicIpPrefixResourceId: contains(publicIPAddressObject, 'publicIPPrefixResourceId') + ? (!(empty(publicIPAddressObject.publicIPPrefixResourceId)) + ? publicIPAddressObject.publicIPPrefixResourceId + : '') + : '' + publicIPAllocationMethod: contains(publicIPAddressObject, 'publicIPAllocationMethod') + ? (!(empty(publicIPAddressObject.publicIPAllocationMethod)) + ? publicIPAddressObject.publicIPAllocationMethod + : 'Static') + : 'Static' + skuName: contains(publicIPAddressObject, 'skuName') + ? (!(empty(publicIPAddressObject.skuName)) ? publicIPAddressObject.skuName : 'Standard') + : 'Standard' + skuTier: contains(publicIPAddressObject, 'skuTier') + ? (!(empty(publicIPAddressObject.skuTier)) ? publicIPAddressObject.skuTier : 'Regional') + : 'Regional' + roleAssignments: contains(publicIPAddressObject, 'roleAssignments') + ? (!empty(publicIPAddressObject.roleAssignments) ? publicIPAddressObject.roleAssignments : []) + : [] + diagnosticSettings: publicIPAddressObject.?diagnosticSettings + location: location + lock: lock + tags: publicIPAddressObject.?tags ?? tags + zones: zones + enableTelemetry: publicIPAddressObject.?enableTelemetry ?? enableTelemetry + } } -} // create a Management Public IP address if one is not provided and the flag is true -module managementIPAddress 'br/public:avm/res/network/public-ip-address:0.2.1' = if (isCreateDefaultManagementIP && azureSkuName == 'AZFW_VNet') { - name: '${uniqueString(deployment().name, location)}-Firewall-MIP' - params: { - name: contains(managementIPAddressObject, 'name') ? (!(empty(managementIPAddressObject.name)) ? managementIPAddressObject.name : '${name}-mip') : '${name}-mip' - publicIpPrefixResourceId: contains(managementIPAddressObject, 'managementIPPrefixResourceId') ? (!(empty(managementIPAddressObject.publicIPPrefixResourceId)) ? managementIPAddressObject.publicIPPrefixResourceId : '') : '' - publicIPAllocationMethod: contains(managementIPAddressObject, 'managementIPAllocationMethod') ? (!(empty(managementIPAddressObject.publicIPAllocationMethod)) ? managementIPAddressObject.publicIPAllocationMethod : 'Static') : 'Static' - skuName: contains(managementIPAddressObject, 'skuName') ? (!(empty(managementIPAddressObject.skuName)) ? managementIPAddressObject.skuName : 'Standard') : 'Standard' - skuTier: contains(managementIPAddressObject, 'skuTier') ? (!(empty(managementIPAddressObject.skuTier)) ? managementIPAddressObject.skuTier : 'Regional') : 'Regional' - roleAssignments: contains(managementIPAddressObject, 'roleAssignments') ? (!empty(managementIPAddressObject.roleAssignments) ? managementIPAddressObject.roleAssignments : []) : [] - diagnosticSettings: managementIPAddressObject.?diagnosticSettings - location: location - tags: managementIPAddressObject.?tags ?? tags - zones: zones - enableTelemetry: managementIPAddressObject.?enableTelemetry ?? enableTelemetry +module managementIPAddress 'br/public:avm/res/network/public-ip-address:0.2.1' = + if (isCreateDefaultManagementIP && azureSkuName == 'AZFW_VNet') { + name: '${uniqueString(deployment().name, location)}-Firewall-MIP' + params: { + name: contains(managementIPAddressObject, 'name') + ? (!(empty(managementIPAddressObject.name)) ? managementIPAddressObject.name : '${name}-mip') + : '${name}-mip' + publicIpPrefixResourceId: contains(managementIPAddressObject, 'managementIPPrefixResourceId') + ? (!(empty(managementIPAddressObject.publicIPPrefixResourceId)) + ? managementIPAddressObject.publicIPPrefixResourceId + : '') + : '' + publicIPAllocationMethod: contains(managementIPAddressObject, 'managementIPAllocationMethod') + ? (!(empty(managementIPAddressObject.publicIPAllocationMethod)) + ? managementIPAddressObject.publicIPAllocationMethod + : 'Static') + : 'Static' + skuName: contains(managementIPAddressObject, 'skuName') + ? (!(empty(managementIPAddressObject.skuName)) ? managementIPAddressObject.skuName : 'Standard') + : 'Standard' + skuTier: contains(managementIPAddressObject, 'skuTier') + ? (!(empty(managementIPAddressObject.skuTier)) ? managementIPAddressObject.skuTier : 'Regional') + : 'Regional' + roleAssignments: contains(managementIPAddressObject, 'roleAssignments') + ? (!empty(managementIPAddressObject.roleAssignments) ? managementIPAddressObject.roleAssignments : []) + : [] + diagnosticSettings: managementIPAddressObject.?diagnosticSettings + location: location + tags: managementIPAddressObject.?tags ?? tags + zones: zones + enableTelemetry: managementIPAddressObject.?enableTelemetry ?? enableTelemetry + } } -} resource azureFirewall 'Microsoft.Network/azureFirewalls@2023-04-01' = { name: name location: location zones: length(zones) == 0 ? null : zones tags: tags - properties: azureSkuName == 'AZFW_VNet' ? { - threatIntelMode: threatIntelMode - firewallPolicy: !empty(firewallPolicyId) ? { - id: firewallPolicyId - } : null - ipConfigurations: ipConfigurations - managementIpConfiguration: requiresManagementIp ? managementIPConfiguration : null - sku: { - name: azureSkuName - tier: azureSkuTier - } - applicationRuleCollections: applicationRuleCollections - natRuleCollections: natRuleCollections - networkRuleCollections: networkRuleCollections - } : { - firewallPolicy: !empty(firewallPolicyId) ? { - id: firewallPolicyId - } : null - sku: { - name: azureSkuName - tier: azureSkuTier - } - hubIPAddresses: !empty(hubIPAddresses) ? hubIPAddresses : null - virtualHub: !empty(virtualHubId) ? { - id: virtualHubId - } : null - } + properties: azureSkuName == 'AZFW_VNet' + ? { + threatIntelMode: threatIntelMode + firewallPolicy: !empty(firewallPolicyId) + ? { + id: firewallPolicyId + } + : null + ipConfigurations: ipConfigurations + managementIpConfiguration: requiresManagementIp ? managementIPConfiguration : null + sku: { + name: azureSkuName + tier: azureSkuTier + } + applicationRuleCollections: applicationRuleCollections + natRuleCollections: natRuleCollections + networkRuleCollections: networkRuleCollections + } + : { + firewallPolicy: !empty(firewallPolicyId) + ? { + id: firewallPolicyId + } + : null + sku: { + name: azureSkuName + tier: azureSkuTier + } + hubIPAddresses: !empty(hubIPAddresses) ? hubIPAddresses : null + virtualHub: !empty(virtualHubId) + ? { + id: virtualHubId + } + : null + } } -resource azureFirewall_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.' +resource azureFirewall_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: azureFirewall } - scope: azureFirewall -} -resource azureFirewall_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 - 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 +resource azureFirewall_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 + 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 + } + scope: azureFirewall } - scope: azureFirewall -}] - -resource azureFirewall_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(azureFirewall.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 +] + +resource azureFirewall_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(azureFirewall.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: azureFirewall } - scope: azureFirewall -}] +] @description('The resource ID of the Azure Firewall.') output resourceId string = azureFirewall.id @@ -290,10 +369,14 @@ output name string = azureFirewall.name output resourceGroupName string = resourceGroup().name @description('The private IP of the Azure firewall.') -output privateIp string = contains(azureFirewall.properties, 'ipConfigurations') ? azureFirewall.properties.ipConfigurations[0].properties.privateIPAddress : '' +output privateIp string = contains(azureFirewall.properties, 'ipConfigurations') + ? azureFirewall.properties.ipConfigurations[0].properties.privateIPAddress + : '' @description('The Public IP configuration object for the Azure Firewall Subnet.') -output ipConfAzureFirewallSubnet object = contains(azureFirewall.properties, 'ipConfigurations') ? azureFirewall.properties.ipConfigurations[0] : {} +output ipConfAzureFirewallSubnet object = contains(azureFirewall.properties, 'ipConfigurations') + ? azureFirewall.properties.ipConfigurations[0] + : {} @description('List of Application Rule Collections.') output applicationRuleCollections array = applicationRuleCollections diff --git a/avm/res/network/azure-firewall/main.json b/avm/res/network/azure-firewall/main.json index 27aaafd57d..b38f878a9d 100644 --- a/avm/res/network/azure-firewall/main.json +++ b/avm/res/network/azure-firewall/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4205211650529288648" + "version": "0.26.54.24096", + "templateHash": "1527004517287633679" }, "name": "Azure Firewalls", "description": "This module deploys an Azure Firewall.", diff --git a/avm/res/network/azure-firewall/tests/e2e/addpip/main.test.bicep b/avm/res/network/azure-firewall/tests/e2e/addpip/main.test.bicep index 28f977e678..d63e79f922 100644 --- a/avm/res/network/azure-firewall/tests/e2e/addpip/main.test.bicep +++ b/avm/res/network/azure-firewall/tests/e2e/addpip/main.test.bicep @@ -47,29 +47,31 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - additionalPublicIpConfigurations: [ - { - name: 'ipConfig01' - publicIPAddressResourceId: nestedDependencies.outputs.publicIPResourceId - } - ] - azureSkuTier: 'Basic' - managementIPAddressObject: { - publicIPAllocationMethod: 'Static' - roleAssignments: [ +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' + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + additionalPublicIpConfigurations: [ { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + name: 'ipConfig01' + publicIPAddressResourceId: nestedDependencies.outputs.publicIPResourceId } ] + azureSkuTier: 'Basic' + managementIPAddressObject: { + publicIPAllocationMethod: 'Static' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + } } } -}] +] diff --git a/avm/res/network/azure-firewall/tests/e2e/custompip/main.test.bicep b/avm/res/network/azure-firewall/tests/e2e/custompip/main.test.bicep index 2891ccb851..2a6977e5d9 100644 --- a/avm/res/network/azure-firewall/tests/e2e/custompip/main.test.bicep +++ b/avm/res/network/azure-firewall/tests/e2e/custompip/main.test.bicep @@ -60,40 +60,42 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - publicIPAddressObject: { - name: 'new-${namePrefix}-pip-${serviceShort}' - publicIPAllocationMethod: 'Static' - publicIPPrefixResourceId: '' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - skuName: 'Standard' - skuTier: 'Regional' - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] +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' + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + publicIPAddressObject: { + name: 'new-${namePrefix}-pip-${serviceShort}' + publicIPAllocationMethod: 'Static' + publicIPPrefixResourceId: '' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + skuName: 'Standard' + skuTier: 'Regional' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } } } -}] +] diff --git a/avm/res/network/azure-firewall/tests/e2e/defaults/main.test.bicep b/avm/res/network/azure-firewall/tests/e2e/defaults/main.test.bicep index 623ae364cb..86ad404cac 100644 --- a/avm/res/network/azure-firewall/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/azure-firewall/tests/e2e/defaults/main.test.bicep @@ -45,12 +45,14 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - location: resourceLocation +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + location: resourceLocation + } } -}] +] diff --git a/avm/res/network/azure-firewall/tests/e2e/hubcommon/main.test.bicep b/avm/res/network/azure-firewall/tests/e2e/hubcommon/main.test.bicep index 91f5a5b7f4..b40d7d6f1d 100644 --- a/avm/res/network/azure-firewall/tests/e2e/hubcommon/main.test.bicep +++ b/avm/res/network/azure-firewall/tests/e2e/hubcommon/main.test.bicep @@ -47,18 +47,20 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - firewallPolicyId: nestedDependencies.outputs.firewallPolicyResourceId - virtualHubId: nestedDependencies.outputs.virtualHubResourceId - hubIPAddresses: { - publicIPs: { - count: 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' + firewallPolicyId: nestedDependencies.outputs.firewallPolicyResourceId + virtualHubId: nestedDependencies.outputs.virtualHubResourceId + hubIPAddresses: { + publicIPs: { + count: 1 + } } } } -}] +] diff --git a/avm/res/network/azure-firewall/tests/e2e/hubmin/main.test.bicep b/avm/res/network/azure-firewall/tests/e2e/hubmin/main.test.bicep index 25efd33efb..5787d13021 100644 --- a/avm/res/network/azure-firewall/tests/e2e/hubmin/main.test.bicep +++ b/avm/res/network/azure-firewall/tests/e2e/hubmin/main.test.bicep @@ -46,17 +46,19 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - virtualHubId: nestedDependencies.outputs.virtualHubResourceId - hubIPAddresses: { - publicIPs: { - count: 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' + virtualHubId: nestedDependencies.outputs.virtualHubResourceId + hubIPAddresses: { + publicIPs: { + count: 1 + } } } } -}] +] diff --git a/avm/res/network/azure-firewall/tests/e2e/max/main.test.bicep b/avm/res/network/azure-firewall/tests/e2e/max/main.test.bicep index c3c6ca138f..7a69b2eebf 100644 --- a/avm/res/network/azure-firewall/tests/e2e/max/main.test.bicep +++ b/avm/res/network/azure-firewall/tests/e2e/max/main.test.bicep @@ -61,139 +61,144 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - applicationRuleCollections: [ - { - name: 'allow-app-rules' - properties: { - action: { - type: 'allow' - } - priority: 100 - rules: [ - { - fqdnTags: [ - 'AppServiceEnvironment' - 'WindowsUpdate' - ] - name: 'allow-ase-tags' - protocols: [ - { - port: '80' - protocolType: 'HTTP' - } - { - port: '443' - protocolType: 'HTTPS' - } - ] - sourceAddresses: [ - '*' - ] +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' + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + applicationRuleCollections: [ + { + name: 'allow-app-rules' + properties: { + action: { + type: 'allow' } + priority: 100 + rules: [ + { + fqdnTags: [ + 'AppServiceEnvironment' + 'WindowsUpdate' + ] + name: 'allow-ase-tags' + protocols: [ + { + port: '80' + protocolType: 'HTTP' + } + { + port: '443' + protocolType: 'HTTPS' + } + ] + sourceAddresses: [ + '*' + ] + } + { + name: 'allow-ase-management' + protocols: [ + { + port: '80' + protocolType: 'HTTP' + } + { + port: '443' + protocolType: 'HTTPS' + } + ] + sourceAddresses: [ + '*' + ] + targetFqdns: [ + 'bing.com' + ] + } + ] + } + } + ] + publicIPResourceID: nestedDependencies.outputs.publicIPResourceId + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ { - name: 'allow-ase-management' - protocols: [ - { - port: '80' - protocolType: 'HTTP' - } - { - port: '443' - protocolType: 'HTTPS' - } - ] - sourceAddresses: [ - '*' - ] - targetFqdns: [ - 'bing.com' - ] + category: 'AllMetrics' } ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - publicIPResourceID: nestedDependencies.outputs.publicIPResourceId - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - networkRuleCollections: [ - { - name: 'allow-network-rules' - properties: { - action: { - type: 'allow' - } - priority: 100 - rules: [ - { - destinationAddresses: [ - '*' - ] - destinationPorts: [ - '12000' - '123' - ] - name: 'allow-ntp' - protocols: [ - 'Any' - ] - sourceAddresses: [ - '*' - ] + networkRuleCollections: [ + { + name: 'allow-network-rules' + properties: { + action: { + type: 'allow' } - ] + priority: 100 + rules: [ + { + destinationAddresses: [ + '*' + ] + destinationPorts: [ + '12000' + '123' + ] + name: 'allow-ntp' + protocols: [ + 'Any' + ] + sourceAddresses: [ + '*' + ] + } + ] + } } + ] + 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' + } + ] + zones: [ + '1' + '2' + '3' + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - 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' - } - ] - zones: [ - '1' - '2' - '3' - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/network/azure-firewall/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/azure-firewall/tests/e2e/waf-aligned/main.test.bicep index 61cca78551..ca84384701 100644 --- a/avm/res/network/azure-firewall/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/azure-firewall/tests/e2e/waf-aligned/main.test.bicep @@ -61,118 +61,120 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - applicationRuleCollections: [ - { - name: 'allow-app-rules' - properties: { - action: { - type: 'allow' - } - priority: 100 - rules: [ - { - fqdnTags: [ - 'AppServiceEnvironment' - 'WindowsUpdate' - ] - name: 'allow-ase-tags' - protocols: [ - { - port: '80' - protocolType: 'HTTP' - } - { - port: '443' - protocolType: 'HTTPS' - } - ] - sourceAddresses: [ - '*' - ] +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' + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + applicationRuleCollections: [ + { + name: 'allow-app-rules' + properties: { + action: { + type: 'allow' } + priority: 100 + rules: [ + { + fqdnTags: [ + 'AppServiceEnvironment' + 'WindowsUpdate' + ] + name: 'allow-ase-tags' + protocols: [ + { + port: '80' + protocolType: 'HTTP' + } + { + port: '443' + protocolType: 'HTTPS' + } + ] + sourceAddresses: [ + '*' + ] + } + { + name: 'allow-ase-management' + protocols: [ + { + port: '80' + protocolType: 'HTTP' + } + { + port: '443' + protocolType: 'HTTPS' + } + ] + sourceAddresses: [ + '*' + ] + targetFqdns: [ + 'bing.com' + ] + } + ] + } + } + ] + publicIPResourceID: nestedDependencies.outputs.publicIPResourceId + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ { - name: 'allow-ase-management' - protocols: [ - { - port: '80' - protocolType: 'HTTP' - } - { - port: '443' - protocolType: 'HTTPS' - } - ] - sourceAddresses: [ - '*' - ] - targetFqdns: [ - 'bing.com' - ] + category: 'AllMetrics' } ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - } - ] - publicIPResourceID: nestedDependencies.outputs.publicIPResourceId - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - networkRuleCollections: [ - { - name: 'allow-network-rules' - properties: { - action: { - type: 'allow' - } - priority: 100 - rules: [ - { - destinationAddresses: [ - '*' - ] - destinationPorts: [ - '12000' - '123' - ] - name: 'allow-ntp' - protocols: [ - 'Any' - ] - sourceAddresses: [ - '*' - ] + ] + networkRuleCollections: [ + { + name: 'allow-network-rules' + properties: { + action: { + type: 'allow' } - ] + priority: 100 + rules: [ + { + destinationAddresses: [ + '*' + ] + destinationPorts: [ + '12000' + '123' + ] + name: 'allow-ntp' + protocols: [ + 'Any' + ] + sourceAddresses: [ + '*' + ] + } + ] + } } + ] + zones: [ + '1' + '2' + '3' + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - zones: [ - '1' - '2' - '3' - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/network/bastion-host/main.bicep b/avm/res/network/bastion-host/main.bicep index c7e49dc622..0ff22f10f2 100644 --- a/avm/res/network/bastion-host/main.bicep +++ b/avm/res/network/bastion-host/main.bicep @@ -66,16 +66,21 @@ param enableTelemetry bool = true var ipConfigurations = [ { name: 'IpConfAzureBastionSubnet' - properties: union({ + properties: union( + { subnet: { id: '${virtualNetworkResourceId}/subnets/AzureBastionSubnet' // The subnet name must be AzureBastionSubnet } - }, { + }, + { //Use existing Public IP, new Public IP created in this module publicIPAddress: { - id: !empty(bastionSubnetPublicIpResourceId) ? bastionSubnetPublicIpResourceId : publicIPAddress.outputs.resourceId + id: !empty(bastionSubnetPublicIpResourceId) + ? bastionSubnetPublicIpResourceId + : publicIPAddress.outputs.resourceId } - }) + } + ) } ] @@ -85,58 +90,76 @@ 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') + '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-bastionhost.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-bastionhost.${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' + } } } } } -} -module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.2.1' = if (empty(bastionSubnetPublicIpResourceId)) { - name: '${uniqueString(deployment().name, location)}-Bastion-PIP' - params: { - name: publicIPAddressObject.name - enableTelemetry: enableTelemetry - location: location - lock: lock - diagnosticSettings: publicIPAddressObject.?diagnosticSettings - publicIPAddressVersion: contains(publicIPAddressObject, 'publicIPAddressVersion') ? publicIPAddressObject.publicIPAddressVersion : 'IPv4' - publicIPAllocationMethod: contains(publicIPAddressObject, 'publicIPAllocationMethod') ? publicIPAddressObject.publicIPAllocationMethod : 'Static' - publicIpPrefixResourceId: contains(publicIPAddressObject, 'publicIPPrefixResourceId') ? publicIPAddressObject.publicIPPrefixResourceId : '' - roleAssignments: contains(publicIPAddressObject, 'roleAssignments') ? publicIPAddressObject.roleAssignments : [] - skuName: contains(publicIPAddressObject, 'skuName') ? publicIPAddressObject.skuName : 'Standard' - skuTier: contains(publicIPAddressObject, 'skuTier') ? publicIPAddressObject.skuTier : 'Regional' - tags: publicIPAddressObject.?tags ?? tags - zones: contains(publicIPAddressObject, 'zones') ? publicIPAddressObject.zones : [] +module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.2.1' = + if (empty(bastionSubnetPublicIpResourceId)) { + name: '${uniqueString(deployment().name, location)}-Bastion-PIP' + params: { + name: publicIPAddressObject.name + enableTelemetry: enableTelemetry + location: location + lock: lock + diagnosticSettings: publicIPAddressObject.?diagnosticSettings + publicIPAddressVersion: contains(publicIPAddressObject, 'publicIPAddressVersion') + ? publicIPAddressObject.publicIPAddressVersion + : 'IPv4' + publicIPAllocationMethod: contains(publicIPAddressObject, 'publicIPAllocationMethod') + ? publicIPAddressObject.publicIPAllocationMethod + : 'Static' + publicIpPrefixResourceId: contains(publicIPAddressObject, 'publicIPPrefixResourceId') + ? publicIPAddressObject.publicIPPrefixResourceId + : '' + roleAssignments: contains(publicIPAddressObject, 'roleAssignments') ? publicIPAddressObject.roleAssignments : [] + skuName: contains(publicIPAddressObject, 'skuName') ? publicIPAddressObject.skuName : 'Standard' + skuTier: contains(publicIPAddressObject, 'skuTier') ? publicIPAddressObject.skuTier : 'Regional' + tags: publicIPAddressObject.?tags ?? tags + zones: contains(publicIPAddressObject, 'zones') ? publicIPAddressObject.zones : [] + } } -} -var bastionpropertiesVar = union({ +var bastionpropertiesVar = union( + { scaleUnits: skuName == 'Basic' ? 2 : scaleUnits ipConfigurations: ipConfigurations enableKerberos: enableKerberos - }, (skuName == 'Standard' ? { - enableTunneling: skuName == 'Standard' - disableCopyPaste: disableCopyPaste - enableFileCopy: enableFileCopy - enableIpConnect: enableIpConnect - enableShareableLink: enableShareableLink - } : {}) + }, + (skuName == 'Standard' + ? { + enableTunneling: skuName == 'Standard' + disableCopyPaste: disableCopyPaste + enableFileCopy: enableFileCopy + enableIpConnect: enableIpConnect + enableShareableLink: enableShareableLink + } + : {}) ) resource azureBastion 'Microsoft.Network/bastionHosts@2022-11-01' = { @@ -149,46 +172,59 @@ resource azureBastion 'Microsoft.Network/bastionHosts@2022-11-01' = { properties: bastionpropertiesVar } -resource azureBastion_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.' +resource azureBastion_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: azureBastion } - scope: azureBastion -} -resource azureBastion_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 +resource azureBastion_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: azureBastion } - scope: azureBastion -}] - -resource azureBastion_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(azureBastion.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 +] + +resource azureBastion_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(azureBastion.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: azureBastion } - scope: azureBastion -}] +] @description('The resource group the Azure Bastion was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/bastion-host/main.json b/avm/res/network/bastion-host/main.json index d16ef2479c..d0d7428e5d 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.25.53.49325", - "templateHash": "403145241490619459" + "version": "0.26.54.24096", + "templateHash": "6331481515117626704" }, "name": "Bastion Hosts", "description": "This module deploys a Bastion Host.", diff --git a/avm/res/network/bastion-host/tests/e2e/custompip/main.test.bicep b/avm/res/network/bastion-host/tests/e2e/custompip/main.test.bicep index 7aaeca854b..7ae927a6ad 100644 --- a/avm/res/network/bastion-host/tests/e2e/custompip/main.test.bicep +++ b/avm/res/network/bastion-host/tests/e2e/custompip/main.test.bicep @@ -60,54 +60,56 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - publicIPAddressObject: { - name: '${namePrefix}${serviceShort}001-pip' - allocationMethod: 'Static' - publicIPPrefixResourceId: '' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - skuName: 'Standard' - skuTier: 'Regional' - zones: [ - '1' - '2' - '3' - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + publicIPAddressObject: { + name: '${namePrefix}${serviceShort}001-pip' + allocationMethod: 'Static' + publicIPPrefixResourceId: '' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + skuName: 'Standard' + skuTier: 'Regional' + zones: [ + '1' + '2' + '3' + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/bastion-host/tests/e2e/defaults/main.test.bicep b/avm/res/network/bastion-host/tests/e2e/defaults/main.test.bicep index 27e87ef3c2..f103fca5f0 100644 --- a/avm/res/network/bastion-host/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/bastion-host/tests/e2e/defaults/main.test.bicep @@ -45,15 +45,17 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId +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 + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/bastion-host/tests/e2e/max/main.test.bicep b/avm/res/network/bastion-host/tests/e2e/max/main.test.bicep index fb76689996..9ade33f499 100644 --- a/avm/res/network/bastion-host/tests/e2e/max/main.test.bicep +++ b/avm/res/network/bastion-host/tests/e2e/max/main.test.bicep @@ -61,58 +61,63 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - bastionSubnetPublicIpResourceId: nestedDependencies.outputs.publicIPResourceId - diagnosticSettings: [ - { - name: 'customSetting' - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + bastionSubnetPublicIpResourceId: nestedDependencies.outputs.publicIPResourceId + diagnosticSettings: [ + { + name: 'customSetting' + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + disableCopyPaste: true + enableFileCopy: false + enableIpConnect: false + enableShareableLink: false + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - disableCopyPaste: true - enableFileCopy: false - enableIpConnect: false - enableShareableLink: false - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' + } + ] + scaleUnits: 4 + skuName: 'Standard' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - 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' - } - ] - scaleUnits: 4 - skuName: 'Standard' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/bastion-host/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/bastion-host/tests/e2e/waf-aligned/main.test.bicep index ac7d900ba9..6fb0ed60a0 100644 --- a/avm/res/network/bastion-host/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/bastion-host/tests/e2e/waf-aligned/main.test.bicep @@ -60,37 +60,39 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - bastionSubnetPublicIpResourceId: nestedDependencies.outputs.publicIPResourceId - diagnosticSettings: [ - { - name: 'customSetting' - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + bastionSubnetPublicIpResourceId: nestedDependencies.outputs.publicIPResourceId + diagnosticSettings: [ + { + name: 'customSetting' + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + disableCopyPaste: true + enableFileCopy: false + enableIpConnect: false + enableShareableLink: false + scaleUnits: 4 + skuName: 'Standard' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - disableCopyPaste: true - enableFileCopy: false - enableIpConnect: false - enableShareableLink: false - scaleUnits: 4 - skuName: 'Standard' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/connection/main.bicep b/avm/res/network/connection/main.bicep index 576ef2253f..5f059b6774 100644 --- a/avm/res/network/connection/main.bicep +++ b/avm/res/network/connection/main.bicep @@ -96,23 +96,24 @@ param authorizationKey string = '' @description('Optional. The local network gateway. Used for connection type [IPsec].') param localNetworkGateway2 object = {} -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.network-connection.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-connection.${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 connection 'Microsoft.Network/connections@2023-04-01' = { name: name @@ -132,32 +133,37 @@ resource connection 'Microsoft.Network/connections@2023-04-01' = { authorizationKey: connectionType == 'ExpressRoute' && !empty(authorizationKey) ? authorizationKey : null sharedKey: connectionType != 'ExpressRoute' ? vpnSharedKey : null usePolicyBasedTrafficSelectors: usePolicyBasedTrafficSelectors - ipsecPolicies: !empty(customIPSecPolicy.ipsecEncryption) ? [ - { - saLifeTimeSeconds: customIPSecPolicy.saLifeTimeSeconds - saDataSizeKilobytes: customIPSecPolicy.saDataSizeKilobytes - ipsecEncryption: customIPSecPolicy.ipsecEncryption - ipsecIntegrity: customIPSecPolicy.ipsecIntegrity - ikeEncryption: customIPSecPolicy.ikeEncryption - ikeIntegrity: customIPSecPolicy.ikeIntegrity - dhGroup: customIPSecPolicy.dhGroup - pfsGroup: customIPSecPolicy.pfsGroup - } - ] : customIPSecPolicy.ipsecEncryption + ipsecPolicies: !empty(customIPSecPolicy.ipsecEncryption) + ? [ + { + saLifeTimeSeconds: customIPSecPolicy.saLifeTimeSeconds + saDataSizeKilobytes: customIPSecPolicy.saDataSizeKilobytes + ipsecEncryption: customIPSecPolicy.ipsecEncryption + ipsecIntegrity: customIPSecPolicy.ipsecIntegrity + ikeEncryption: customIPSecPolicy.ikeEncryption + ikeIntegrity: customIPSecPolicy.ikeIntegrity + dhGroup: customIPSecPolicy.dhGroup + pfsGroup: customIPSecPolicy.pfsGroup + } + ] + : customIPSecPolicy.ipsecEncryption routingWeight: routingWeight enableBgp: enableBgp useLocalAzureIpAddress: connectionType == 'IPsec' ? useLocalAzureIpAddress : null } } -resource connection_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.' +resource connection_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: connection } - scope: connection -} @description('The resource group the remote connection was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/connection/main.json b/avm/res/network/connection/main.json index 5747c1044f..46cc731506 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.25.53.49325", - "templateHash": "16775998299537501869" + "version": "0.26.54.24096", + "templateHash": "17255378550715069548" }, "name": "Virtual Network Gateway Connections", "description": "This module deploys a Virtual Network Gateway Connection.", diff --git a/avm/res/network/connection/tests/e2e/defaults/main.test.bicep b/avm/res/network/connection/tests/e2e/defaults/main.test.bicep index 22eb55b153..173f43b4af 100644 --- a/avm/res/network/connection/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/connection/tests/e2e/defaults/main.test.bicep @@ -54,22 +54,24 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - virtualNetworkGateway1: { - id: nestedDependencies.outputs.primaryVNETGatewayResourceID - } - virtualNetworkGateway2: { - id: nestedDependencies.outputs.secondaryVNETGatewayResourceID +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' + virtualNetworkGateway1: { + id: nestedDependencies.outputs.primaryVNETGatewayResourceID + } + virtualNetworkGateway2: { + id: nestedDependencies.outputs.secondaryVNETGatewayResourceID + } + connectionType: 'Vnet2Vnet' + vpnSharedKey: password } - connectionType: 'Vnet2Vnet' - vpnSharedKey: password + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/connection/tests/e2e/max/main.test.bicep b/avm/res/network/connection/tests/e2e/max/main.test.bicep index 4a085c807f..e1b1154c01 100644 --- a/avm/res/network/connection/tests/e2e/max/main.test.bicep +++ b/avm/res/network/connection/tests/e2e/max/main.test.bicep @@ -54,34 +54,36 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - virtualNetworkGateway1: { - id: nestedDependencies.outputs.primaryVNETGatewayResourceID - } - enableBgp: false - usePolicyBasedTrafficSelectors: false - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - virtualNetworkGateway2: { - id: nestedDependencies.outputs.secondaryVNETGatewayResourceID - } - connectionType: 'Vnet2Vnet' - dpdTimeoutSeconds: 45 - vpnSharedKey: password - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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' + virtualNetworkGateway1: { + id: nestedDependencies.outputs.primaryVNETGatewayResourceID + } + enableBgp: false + usePolicyBasedTrafficSelectors: false + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + virtualNetworkGateway2: { + id: nestedDependencies.outputs.secondaryVNETGatewayResourceID + } + connectionType: 'Vnet2Vnet' + dpdTimeoutSeconds: 45 + vpnSharedKey: password + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/connection/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/connection/tests/e2e/waf-aligned/main.test.bicep index e24ad2beb9..4d13294954 100644 --- a/avm/res/network/connection/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/connection/tests/e2e/waf-aligned/main.test.bicep @@ -54,31 +54,33 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - virtualNetworkGateway1: { - id: nestedDependencies.outputs.primaryVNETGatewayResourceID - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - virtualNetworkGateway2: { - id: nestedDependencies.outputs.secondaryVNETGatewayResourceID - } - connectionType: 'Vnet2Vnet' - vpnSharedKey: password - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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' + virtualNetworkGateway1: { + id: nestedDependencies.outputs.primaryVNETGatewayResourceID + } + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + virtualNetworkGateway2: { + id: nestedDependencies.outputs.secondaryVNETGatewayResourceID + } + connectionType: 'Vnet2Vnet' + vpnSharedKey: password + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/ddos-protection-plan/main.bicep b/avm/res/network/ddos-protection-plan/main.bicep index 3133dab953..7701fad812 100644 --- a/avm/res/network/ddos-protection-plan/main.bicep +++ b/avm/res/network/ddos-protection-plan/main.bicep @@ -25,27 +25,34 @@ 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') + '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-ddosprotectionplan.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-ddosprotectionplan.${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 ddosProtectionPlan 'Microsoft.Network/ddosProtectionPlans@2023-04-01' = { name: name @@ -54,28 +61,37 @@ resource ddosProtectionPlan 'Microsoft.Network/ddosProtectionPlans@2023-04-01' = properties: {} } -resource ddosProtectionPlan_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.' +resource ddosProtectionPlan_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: ddosProtectionPlan } - scope: ddosProtectionPlan -} -resource ddosProtectionPlan_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(ddosProtectionPlan.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 +resource ddosProtectionPlan_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(ddosProtectionPlan.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: ddosProtectionPlan } - scope: ddosProtectionPlan -}] +] @description('The resource group the DDOS protection plan was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/ddos-protection-plan/main.json b/avm/res/network/ddos-protection-plan/main.json index a65b5d480d..79a9acca63 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.25.53.49325", - "templateHash": "1916218161096059486" + "version": "0.26.54.24096", + "templateHash": "1494680317385040277" }, "name": "DDoS Protection Plans", "description": "This module deploys a DDoS Protection Plan.", diff --git a/avm/res/network/ddos-protection-plan/tests/e2e/max/dependencies.bicep b/avm/res/network/ddos-protection-plan/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/network/ddos-protection-plan/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/ddos-protection-plan/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/network/ddos-protection-plan/tests/e2e/max/main.test.bicep b/avm/res/network/ddos-protection-plan/tests/e2e/max/main.test.bicep index cb5de1c255..5b2e34186a 100644 --- a/avm/res/network/ddos-protection-plan/tests/e2e/max/main.test.bicep +++ b/avm/res/network/ddos-protection-plan/tests/e2e/max/main.test.bicep @@ -66,7 +66,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } 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 3050c7c9b5..a78e018085 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.25.53.49325", - "templateHash": "16468651666444588102" + "version": "0.26.54.24096", + "templateHash": "11159744121670173662" }, "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.bicep b/avm/res/network/dns-forwarding-ruleset/main.bicep index b5b04038aa..2595bcf979 100644 --- a/avm/res/network/dns-forwarding-ruleset/main.bicep +++ b/avm/res/network/dns-forwarding-ruleset/main.bicep @@ -32,86 +32,117 @@ param enableTelemetry bool = true var 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') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'DNS Resolver Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d' + ) + 'DNS Zone Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'befefa01-2a29-4197-83a8-272ff33ce314' + ) + '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') + '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') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.network-dnsforwardingruleset.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-dnsforwardingruleset.${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 dnsForwardingRuleset 'Microsoft.Network/dnsForwardingRulesets@2022-07-01' = { name: name location: location tags: tags properties: { - dnsResolverOutboundEndpoints: [for dnsForwardingRulesetOutboundEndpointResourceId in dnsForwardingRulesetOutboundEndpointResourceIds: { - id: dnsForwardingRulesetOutboundEndpointResourceId - }] + dnsResolverOutboundEndpoints: [ + for dnsForwardingRulesetOutboundEndpointResourceId in dnsForwardingRulesetOutboundEndpointResourceIds: { + id: dnsForwardingRulesetOutboundEndpointResourceId + } + ] } } -module dnsForwardingRuleset_forwardingRule 'forwarding-rule/main.bicep' = [for (forwardingRule, index) in (forwardingRules ?? []): { - name: '${uniqueString(deployment().name, location)}-forwardingRule-${index}' - params: { - dnsForwardingRulesetName: dnsForwardingRuleset.name - name: forwardingRule.?name - forwardingRuleState: forwardingRule.?forwardingRuleState ?? 'Enabled' - domainName: forwardingRule.?domainName - targetDnsServers: forwardingRule.?targetDnsServers - metadata: forwardingRule.?metadata +module dnsForwardingRuleset_forwardingRule 'forwarding-rule/main.bicep' = [ + for (forwardingRule, index) in (forwardingRules ?? []): { + name: '${uniqueString(deployment().name, location)}-forwardingRule-${index}' + params: { + dnsForwardingRulesetName: dnsForwardingRuleset.name + name: forwardingRule.?name + forwardingRuleState: forwardingRule.?forwardingRuleState ?? 'Enabled' + domainName: forwardingRule.?domainName + targetDnsServers: forwardingRule.?targetDnsServers + metadata: forwardingRule.?metadata + } } -}] - -module dnsForwardingRuleset_virtualNetworkLinks 'virtual-network-link/main.bicep' = [for (vnetId, index) in (vNetLinks ?? []): { - name: '${uniqueString(deployment().name, location)}-virtualNetworkLink-${index}' - params: { - dnsForwardingRulesetName: dnsForwardingRuleset.name - virtualNetworkResourceId: !empty(vNetLinks) ? vnetId : null +] + +module dnsForwardingRuleset_virtualNetworkLinks 'virtual-network-link/main.bicep' = [ + for (vnetId, index) in (vNetLinks ?? []): { + name: '${uniqueString(deployment().name, location)}-virtualNetworkLink-${index}' + params: { + dnsForwardingRulesetName: dnsForwardingRuleset.name + virtualNetworkResourceId: !empty(vNetLinks) ? vnetId : null + } } -}] - -resource dnsForwardingRuleset_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.' +] + +resource dnsForwardingRuleset_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: dnsForwardingRuleset } - scope: dnsForwardingRuleset -} -resource dnsForwardingRuleset_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(dnsForwardingRuleset.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 +resource dnsForwardingRuleset_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(dnsForwardingRuleset.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: dnsForwardingRuleset } - scope: dnsForwardingRuleset -}] +] @description('The resource group the DNS Forwarding Ruleset was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/dns-forwarding-ruleset/main.json b/avm/res/network/dns-forwarding-ruleset/main.json index c591d647ed..75b2de3482 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.25.53.49325", - "templateHash": "4310630541865622256" + "version": "0.26.54.24096", + "templateHash": "12711184694701779710" }, "name": "Dns Forwarding Rulesets", "description": "This template deploys an dns forwarding ruleset.", @@ -359,8 +359,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16468651666444588102" + "version": "0.26.54.24096", + "templateHash": "11159744121670173662" }, "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.25.53.49325", - "templateHash": "2776981605709910245" + "version": "0.26.54.24096", + "templateHash": "15095816376592886095" }, "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/tests/e2e/defaults/dependencies.bicep b/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/dependencies.bicep index 41fbb37c7e..946812afa8 100644 --- a/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/dependencies.bicep @@ -18,7 +18,9 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { addressPrefix ] } - subnets: map(range(0, 2), i => { + subnets: map( + range(0, 2), + i => { name: 'subnet-${i}' properties: { addressPrefix: cidrSubnet(addressPrefix, 25, i) @@ -31,7 +33,8 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } ] } - }) + } + ) } } diff --git a/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/main.test.bicep b/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/main.test.bicep index 8e5de6d3ad..5c983ca0b6 100644 --- a/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/main.test.bicep @@ -46,17 +46,19 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - dnsForwardingRulesetOutboundEndpointResourceIds: [ - nestedDependencies.outputs.dnsResolverOutboundEndpointsResourceId +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + dnsForwardingRulesetOutboundEndpointResourceIds: [ + nestedDependencies.outputs.dnsResolverOutboundEndpointsResourceId + ] + location: resourceLocation + } + dependsOn: [ + nestedDependencies ] - location: resourceLocation } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/dns-forwarding-ruleset/tests/e2e/max/dependencies.bicep b/avm/res/network/dns-forwarding-ruleset/tests/e2e/max/dependencies.bicep index d1fb3445ee..d98ebb0285 100644 --- a/avm/res/network/dns-forwarding-ruleset/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/dns-forwarding-ruleset/tests/e2e/max/dependencies.bicep @@ -21,7 +21,9 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { addressPrefix ] } - subnets: map(range(0, 2), i => { + subnets: map( + range(0, 2), + i => { name: 'subnet-${i}' properties: { addressPrefix: cidrSubnet(addressPrefix, 25, i) @@ -34,7 +36,8 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } ] } - }) + } + ) } } @@ -45,7 +48,6 @@ resource dnsResolver 'Microsoft.Network/dnsResolvers@2022-07-01' = { virtualNetwork: { id: virtualNetwork.id } - } } diff --git a/avm/res/network/dns-forwarding-ruleset/tests/e2e/max/main.test.bicep b/avm/res/network/dns-forwarding-ruleset/tests/e2e/max/main.test.bicep index 8bb2dacb7f..69be2f690c 100644 --- a/avm/res/network/dns-forwarding-ruleset/tests/e2e/max/main.test.bicep +++ b/avm/res/network/dns-forwarding-ruleset/tests/e2e/max/main.test.bicep @@ -47,59 +47,64 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - dnsForwardingRulesetOutboundEndpointResourceIds: [ - nestedDependencies.outputs.dnsResolverOutboundEndpointsId - ] - vNetLinks: [ - nestedDependencies.outputs.virtualNetworkResourceId - ] - forwardingRules: [ - { - name: 'rule1' - forwardingRuleState: 'Enabled' - domainName: 'contoso.' - targetDnsServers: [ - { - ipAddress: '192.168.0.1' - port: '53' - } - ] +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 + dnsForwardingRulesetOutboundEndpointResourceIds: [ + nestedDependencies.outputs.dnsResolverOutboundEndpointsId + ] + vNetLinks: [ + nestedDependencies.outputs.virtualNetworkResourceId + ] + forwardingRules: [ + { + name: 'rule1' + forwardingRuleState: 'Enabled' + domainName: 'contoso.' + targetDnsServers: [ + { + ipAddress: '192.168.0.1' + port: '53' + } + ] + } + ] + 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' + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - 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' - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/dns-forwarding-ruleset/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/dns-forwarding-ruleset/tests/e2e/waf-aligned/dependencies.bicep index d1fb3445ee..d98ebb0285 100644 --- a/avm/res/network/dns-forwarding-ruleset/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/network/dns-forwarding-ruleset/tests/e2e/waf-aligned/dependencies.bicep @@ -21,7 +21,9 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { addressPrefix ] } - subnets: map(range(0, 2), i => { + subnets: map( + range(0, 2), + i => { name: 'subnet-${i}' properties: { addressPrefix: cidrSubnet(addressPrefix, 25, i) @@ -34,7 +36,8 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } ] } - }) + } + ) } } @@ -45,7 +48,6 @@ resource dnsResolver 'Microsoft.Network/dnsResolvers@2022-07-01' = { virtualNetwork: { id: virtualNetwork.id } - } } diff --git a/avm/res/network/dns-forwarding-ruleset/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/dns-forwarding-ruleset/tests/e2e/waf-aligned/main.test.bicep index 82c1add6d7..3540444952 100644 --- a/avm/res/network/dns-forwarding-ruleset/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/dns-forwarding-ruleset/tests/e2e/waf-aligned/main.test.bicep @@ -47,26 +47,28 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - dnsForwardingRulesetOutboundEndpointResourceIds: [ - nestedDependencies.outputs.dnsResolverOutboundEndpointsId - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + dnsForwardingRulesetOutboundEndpointResourceIds: [ + nestedDependencies.outputs.dnsResolverOutboundEndpointsId + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] 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 1416d30645..caaefb759a 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.25.53.49325", - "templateHash": "2776981605709910245" + "version": "0.26.54.24096", + "templateHash": "15095816376592886095" }, "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 23a17b28c4..8830c57a9c 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.25.53.49325", - "templateHash": "8672047882378700944" + "version": "0.26.54.24096", + "templateHash": "13768999645959207906" }, "name": "DNS Resolver Inbound Endpoint", "description": "This module deploys a DNS Resolver Inbound Endpoint.", diff --git a/avm/res/network/dns-resolver/main.bicep b/avm/res/network/dns-resolver/main.bicep index ebb617fd7d..067169222c 100644 --- a/avm/res/network/dns-resolver/main.bicep +++ b/avm/res/network/dns-resolver/main.bicep @@ -32,34 +32,56 @@ param enableTelemetry bool = true var 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') + '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') + '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') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.network-dnsresolver.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-dnsresolver.${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 dnsResolver 'Microsoft.Network/dnsResolvers@2022-07-01' = { name: name @@ -72,52 +94,65 @@ resource dnsResolver 'Microsoft.Network/dnsResolvers@2022-07-01' = { } } -resource dnsResolver_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.' +resource dnsResolver_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: dnsResolver } - scope: dnsResolver -} -resource dnsResolver_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(dnsResolver.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 +resource dnsResolver_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(dnsResolver.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: dnsResolver } - scope: dnsResolver -}] - -module dnsResolver_inboundEndpoints 'inbound-endpoint/main.bicep' = [for (inboundEndpoint, index) in (inboundEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsResolver-inbound-${index}' - params: { - name: inboundEndpoint.name - tags: inboundEndpoint.?tags ?? tags - location: inboundEndpoint.?location ?? location - dnsResolverName: dnsResolver.name - subnetResourceId: inboundEndpoint.subnetResourceId - privateIpAddress: inboundEndpoint.?privateIpAddress - privateIpAllocationMethod: inboundEndpoint.?privateIpAllocationMethod +] + +module dnsResolver_inboundEndpoints 'inbound-endpoint/main.bicep' = [ + for (inboundEndpoint, index) in (inboundEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsResolver-inbound-${index}' + params: { + name: inboundEndpoint.name + tags: inboundEndpoint.?tags ?? tags + location: inboundEndpoint.?location ?? location + dnsResolverName: dnsResolver.name + subnetResourceId: inboundEndpoint.subnetResourceId + privateIpAddress: inboundEndpoint.?privateIpAddress + privateIpAllocationMethod: inboundEndpoint.?privateIpAllocationMethod + } } -}] - -module dnsResolver_outboundEndpoints 'outbound-endpoint/main.bicep' = [for (outboundEndpoint, index) in (outboundEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsResolver-outbound-${index}' - params: { - name: outboundEndpoint.name - tags: outboundEndpoint.?tags ?? tags - location: outboundEndpoint.?location ?? location - dnsResolverName: dnsResolver.name - subnetResourceId: outboundEndpoint.subnetResourceId +] + +module dnsResolver_outboundEndpoints 'outbound-endpoint/main.bicep' = [ + for (outboundEndpoint, index) in (outboundEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsResolver-outbound-${index}' + params: { + name: outboundEndpoint.name + tags: outboundEndpoint.?tags ?? tags + location: outboundEndpoint.?location ?? location + dnsResolverName: dnsResolver.name + subnetResourceId: outboundEndpoint.subnetResourceId + } } -}] +] @description('The resource group the DNS Private Resolver was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/dns-resolver/main.json b/avm/res/network/dns-resolver/main.json index be81467fb9..a1d1246acc 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.25.53.49325", - "templateHash": "11674721033032796270" + "version": "0.26.54.24096", + "templateHash": "16134836553135167384" }, "name": "DNS Resolver", "description": "This module deploys a DNS Resolver.", @@ -379,8 +379,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8672047882378700944" + "version": "0.26.54.24096", + "templateHash": "13768999645959207906" }, "name": "DNS Resolver Inbound Endpoint", "description": "This module deploys a DNS Resolver Inbound Endpoint.", @@ -530,8 +530,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7237665514415394760" + "version": "0.26.54.24096", + "templateHash": "6638776759595697100" }, "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 b287446a50..2db11de3ef 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.25.53.49325", - "templateHash": "7237665514415394760" + "version": "0.26.54.24096", + "templateHash": "6638776759595697100" }, "name": "DNS Resolver Outbound Endpoint", "description": "This module deploys a DNS Resolver Outbound Endpoint.", diff --git a/avm/res/network/dns-resolver/tests/e2e/defaults/dependencies.bicep b/avm/res/network/dns-resolver/tests/e2e/defaults/dependencies.bicep index f25a4e5ff7..555c9c977b 100644 --- a/avm/res/network/dns-resolver/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/network/dns-resolver/tests/e2e/defaults/dependencies.bicep @@ -18,7 +18,9 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { addressPrefix ] } - subnets: map(range(0, 2), i => { + subnets: map( + range(0, 2), + i => { name: 'subnet-${i}' properties: { addressPrefix: cidrSubnet(addressPrefix, 25, i) @@ -31,7 +33,8 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } ] } - }) + } + ) } } diff --git a/avm/res/network/dns-resolver/tests/e2e/defaults/main.test.bicep b/avm/res/network/dns-resolver/tests/e2e/defaults/main.test.bicep index 5bdcb9bd4a..3ce2bbf07e 100644 --- a/avm/res/network/dns-resolver/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/dns-resolver/tests/e2e/defaults/main.test.bicep @@ -46,12 +46,14 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - location: resourceLocation +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + location: resourceLocation + } } -}] +] diff --git a/avm/res/network/dns-resolver/tests/e2e/max/dependencies.bicep b/avm/res/network/dns-resolver/tests/e2e/max/dependencies.bicep index f25a4e5ff7..555c9c977b 100644 --- a/avm/res/network/dns-resolver/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/dns-resolver/tests/e2e/max/dependencies.bicep @@ -18,7 +18,9 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { addressPrefix ] } - subnets: map(range(0, 2), i => { + subnets: map( + range(0, 2), + i => { name: 'subnet-${i}' properties: { addressPrefix: cidrSubnet(addressPrefix, 25, i) @@ -31,7 +33,8 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } ] } - }) + } + ) } } diff --git a/avm/res/network/dns-resolver/tests/e2e/max/main.test.bicep b/avm/res/network/dns-resolver/tests/e2e/max/main.test.bicep index a942d6711c..b88dfaa63b 100644 --- a/avm/res/network/dns-resolver/tests/e2e/max/main.test.bicep +++ b/avm/res/network/dns-resolver/tests/e2e/max/main.test.bicep @@ -46,50 +46,55 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - 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' - } - ] - inboundEndpoints: [ - { - name: '${namePrefix}${serviceShort}-az-pdnsin-x-001' - subnetResourceId: nestedDependencies.outputs.subnetResourceId_dnsIn +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 + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - outboundEndpoints: [ - { - name: '${namePrefix}${serviceShort}-az-pdnsout-x-001' - subnetResourceId: nestedDependencies.outputs.subnetResourceId_dnsOut + 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' + } + ] + inboundEndpoints: [ + { + name: '${namePrefix}${serviceShort}-az-pdnsin-x-001' + subnetResourceId: nestedDependencies.outputs.subnetResourceId_dnsIn + } + ] + outboundEndpoints: [ + { + name: '${namePrefix}${serviceShort}-az-pdnsout-x-001' + subnetResourceId: nestedDependencies.outputs.subnetResourceId_dnsOut + } + ] + 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/network/dns-resolver/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/dns-resolver/tests/e2e/waf-aligned/dependencies.bicep index f25a4e5ff7..555c9c977b 100644 --- a/avm/res/network/dns-resolver/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/network/dns-resolver/tests/e2e/waf-aligned/dependencies.bicep @@ -18,7 +18,9 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { addressPrefix ] } - subnets: map(range(0, 2), i => { + subnets: map( + range(0, 2), + i => { name: 'subnet-${i}' properties: { addressPrefix: cidrSubnet(addressPrefix, 25, i) @@ -31,7 +33,8 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } ] } - }) + } + ) } } diff --git a/avm/res/network/dns-resolver/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/dns-resolver/tests/e2e/waf-aligned/main.test.bicep index 7f820efb73..04a4057071 100644 --- a/avm/res/network/dns-resolver/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/dns-resolver/tests/e2e/waf-aligned/main.test.bicep @@ -46,33 +46,35 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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: { - name: 'myCustomLockName' - kind: 'CanNotDelete' - } - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId - inboundEndpoints: [ - { - name: '${namePrefix}${serviceShort}-az-pdnsin-x-001' - subnetResourceId: nestedDependencies.outputs.subnetResourceId_dnsIn +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: { + name: 'myCustomLockName' + kind: 'CanNotDelete' } - ] - outboundEndpoints: [ - { - name: '${namePrefix}${serviceShort}-az-pdnsout-x-001' - subnetResourceId: nestedDependencies.outputs.subnetResourceId_dnsOut + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + inboundEndpoints: [ + { + name: '${namePrefix}${serviceShort}-az-pdnsin-x-001' + subnetResourceId: nestedDependencies.outputs.subnetResourceId_dnsIn + } + ] + outboundEndpoints: [ + { + name: '${namePrefix}${serviceShort}-az-pdnsout-x-001' + subnetResourceId: nestedDependencies.outputs.subnetResourceId_dnsOut + } + ] + 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/network/dns-zone/a/main.bicep b/avm/res/network/dns-zone/a/main.bicep index d291137766..848580c988 100644 --- a/avm/res/network/dns-zone/a/main.bicep +++ b/avm/res/network/dns-zone/a/main.bicep @@ -25,16 +25,40 @@ param roleAssignments roleAssignmentType var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { name: dnsZoneName @@ -47,25 +71,33 @@ resource A 'Microsoft.Network/dnsZones/A@2018-05-01' = { ARecords: !empty(aRecords) ? aRecords : null metadata: metadata TTL: ttl - targetResource: !empty(targetResourceId) ? { - id: targetResourceId - } : null + targetResource: !empty(targetResourceId) + ? { + id: targetResourceId + } + : null } } -resource A_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(A.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 +resource A_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(A.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: A } - scope: A -}] +] @description('The name of the deployed A record.') output name string = A.name diff --git a/avm/res/network/dns-zone/a/main.json b/avm/res/network/dns-zone/a/main.json index f95aa9a994..8064fe574b 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.25.53.49325", - "templateHash": "1014861232584705848" + "version": "0.26.54.24096", + "templateHash": "4017689599365774964" }, "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.bicep b/avm/res/network/dns-zone/aaaa/main.bicep index 468cf3399c..291ce5ce3a 100644 --- a/avm/res/network/dns-zone/aaaa/main.bicep +++ b/avm/res/network/dns-zone/aaaa/main.bicep @@ -25,16 +25,40 @@ param roleAssignments roleAssignmentType var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { @@ -48,25 +72,33 @@ resource AAAA 'Microsoft.Network/dnsZones/AAAA@2018-05-01' = { AAAARecords: !empty(aaaaRecords) ? aaaaRecords : null metadata: metadata TTL: ttl - targetResource: !empty(targetResourceId) ? { - id: targetResourceId - } : null + targetResource: !empty(targetResourceId) + ? { + id: targetResourceId + } + : null } } -resource AAAA_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(AAAA.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 +resource AAAA_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(AAAA.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: AAAA } - scope: AAAA -}] +] @description('The name of the deployed AAAA record.') output name string = AAAA.name diff --git a/avm/res/network/dns-zone/aaaa/main.json b/avm/res/network/dns-zone/aaaa/main.json index d0fbec5f0e..60370a5d7d 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.25.53.49325", - "templateHash": "17816545426283561774" + "version": "0.26.54.24096", + "templateHash": "3971171413214558899" }, "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.bicep b/avm/res/network/dns-zone/caa/main.bicep index 72a657fcfc..4f819bdbdf 100644 --- a/avm/res/network/dns-zone/caa/main.bicep +++ b/avm/res/network/dns-zone/caa/main.bicep @@ -22,16 +22,40 @@ param roleAssignments roleAssignmentType var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { @@ -48,19 +72,25 @@ resource CAA 'Microsoft.Network/dnsZones/CAA@2018-05-01' = { } } -resource CAA_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(CAA.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 +resource CAA_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(CAA.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: CAA } - scope: CAA -}] +] @description('The name of the deployed CAA record.') output name string = CAA.name diff --git a/avm/res/network/dns-zone/caa/main.json b/avm/res/network/dns-zone/caa/main.json index c3008da102..e4be71280c 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.25.53.49325", - "templateHash": "2222693701620961150" + "version": "0.26.54.24096", + "templateHash": "8677073922032532586" }, "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.bicep b/avm/res/network/dns-zone/cname/main.bicep index 9e9a1aa682..71aecd0bb9 100644 --- a/avm/res/network/dns-zone/cname/main.bicep +++ b/avm/res/network/dns-zone/cname/main.bicep @@ -25,16 +25,40 @@ param roleAssignments roleAssignmentType var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { @@ -48,25 +72,33 @@ resource CNAME 'Microsoft.Network/dnsZones/CNAME@2018-05-01' = { CNAMERecord: !empty(cnameRecord) ? cnameRecord : null metadata: metadata TTL: ttl - targetResource: !empty(targetResourceId) ? { - id: targetResourceId - } : null + targetResource: !empty(targetResourceId) + ? { + id: targetResourceId + } + : null } } -resource CNAME_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(CNAME.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 +resource CNAME_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(CNAME.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: CNAME } - scope: CNAME -}] +] @description('The name of the deployed CNAME record.') output name string = CNAME.name diff --git a/avm/res/network/dns-zone/cname/main.json b/avm/res/network/dns-zone/cname/main.json index ce4232f426..cc733f096f 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.25.53.49325", - "templateHash": "11680687850109857660" + "version": "0.26.54.24096", + "templateHash": "15885562612097082245" }, "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.bicep b/avm/res/network/dns-zone/main.bicep index 6ecf1f7df9..d0f7457dd2 100644 --- a/avm/res/network/dns-zone/main.bicep +++ b/avm/res/network/dns-zone/main.bicep @@ -54,35 +54,60 @@ param enableTelemetry bool = true var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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-dnszone.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-dnszone.${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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' = { name: name @@ -93,151 +118,180 @@ resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' = { } } -module dnsZone_A 'a/main.bicep' = [for (aRecord, index) in (a ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsZone-ARecord-${index}' - params: { - dnsZoneName: dnsZone.name - name: aRecord.name - aRecords: aRecord.?aRecords - metadata: aRecord.?metadata - ttl: aRecord.?ttl ?? 3600 - targetResourceId: aRecord.?targetResourceId - roleAssignments: aRecord.?roleAssignments +module dnsZone_A 'a/main.bicep' = [ + for (aRecord, index) in (a ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsZone-ARecord-${index}' + params: { + dnsZoneName: dnsZone.name + name: aRecord.name + aRecords: aRecord.?aRecords + metadata: aRecord.?metadata + ttl: aRecord.?ttl ?? 3600 + targetResourceId: aRecord.?targetResourceId + roleAssignments: aRecord.?roleAssignments + } } -}] - -module dnsZone_AAAA 'aaaa/main.bicep' = [for (aaaaRecord, index) in (aaaa ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsZone-AAAARecord-${index}' - params: { - dnsZoneName: dnsZone.name - name: aaaaRecord.name - aaaaRecords: aaaaRecord.?aaaaRecords - metadata: aaaaRecord.?metadata - ttl: aaaaRecord.?ttl ?? 3600 - targetResourceId: aaaaRecord.?targetResourceId - roleAssignments: aaaaRecord.?roleAssignments +] + +module dnsZone_AAAA 'aaaa/main.bicep' = [ + for (aaaaRecord, index) in (aaaa ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsZone-AAAARecord-${index}' + params: { + dnsZoneName: dnsZone.name + name: aaaaRecord.name + aaaaRecords: aaaaRecord.?aaaaRecords + metadata: aaaaRecord.?metadata + ttl: aaaaRecord.?ttl ?? 3600 + targetResourceId: aaaaRecord.?targetResourceId + roleAssignments: aaaaRecord.?roleAssignments + } } -}] - -module dnsZone_CNAME 'cname/main.bicep' = [for (cnameRecord, index) in (cname ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsZone-CNAMERecord-${index}' - params: { - dnsZoneName: dnsZone.name - name: cnameRecord.name - cnameRecord: cnameRecord.?cnameRecord - metadata: cnameRecord.?metadata - ttl: cnameRecord.?ttl ?? 3600 - targetResourceId: cnameRecord.?targetResourceId - roleAssignments: cnameRecord.?roleAssignments +] + +module dnsZone_CNAME 'cname/main.bicep' = [ + for (cnameRecord, index) in (cname ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsZone-CNAMERecord-${index}' + params: { + dnsZoneName: dnsZone.name + name: cnameRecord.name + cnameRecord: cnameRecord.?cnameRecord + metadata: cnameRecord.?metadata + ttl: cnameRecord.?ttl ?? 3600 + targetResourceId: cnameRecord.?targetResourceId + roleAssignments: cnameRecord.?roleAssignments + } } -}] - -module dnsZone_CAA 'caa/main.bicep' = [for (caaRecord, index) in (caa ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsZone-CAARecord-${index}' - params: { - dnsZoneName: dnsZone.name - name: caaRecord.name - metadata: caaRecord.?metadata - caaRecords: caaRecord.?caaRecords - ttl: caaRecord.?ttl ?? 3600 - roleAssignments: caaRecord.?roleAssignments +] + +module dnsZone_CAA 'caa/main.bicep' = [ + for (caaRecord, index) in (caa ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsZone-CAARecord-${index}' + params: { + dnsZoneName: dnsZone.name + name: caaRecord.name + metadata: caaRecord.?metadata + caaRecords: caaRecord.?caaRecords + ttl: caaRecord.?ttl ?? 3600 + roleAssignments: caaRecord.?roleAssignments + } } -}] - -module dnsZone_MX 'mx/main.bicep' = [for (mxRecord, index) in (mx ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsZone-MXRecord-${index}' - params: { - dnsZoneName: dnsZone.name - name: mxRecord.name - metadata: mxRecord.?metadata - mxRecords: mxRecord.?mxRecords - ttl: mxRecord.?ttl ?? 3600 - roleAssignments: mxRecord.?roleAssignments +] + +module dnsZone_MX 'mx/main.bicep' = [ + for (mxRecord, index) in (mx ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsZone-MXRecord-${index}' + params: { + dnsZoneName: dnsZone.name + name: mxRecord.name + metadata: mxRecord.?metadata + mxRecords: mxRecord.?mxRecords + ttl: mxRecord.?ttl ?? 3600 + roleAssignments: mxRecord.?roleAssignments + } } -}] - -module dnsZone_NS 'ns/main.bicep' = [for (nsRecord, index) in (ns ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsZone-NSRecord-${index}' - params: { - dnsZoneName: dnsZone.name - name: nsRecord.name - metadata: nsRecord.?metadata - nsRecords: nsRecord.?nsRecords - ttl: nsRecord.?ttl ?? 3600 - roleAssignments: nsRecord.?roleAssignments +] + +module dnsZone_NS 'ns/main.bicep' = [ + for (nsRecord, index) in (ns ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsZone-NSRecord-${index}' + params: { + dnsZoneName: dnsZone.name + name: nsRecord.name + metadata: nsRecord.?metadata + nsRecords: nsRecord.?nsRecords + ttl: nsRecord.?ttl ?? 3600 + roleAssignments: nsRecord.?roleAssignments + } } -}] - -module dnsZone_PTR 'ptr/main.bicep' = [for (ptrRecord, index) in (ptr ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsZone-PTRRecord-${index}' - params: { - dnsZoneName: dnsZone.name - name: ptrRecord.name - metadata: ptrRecord.?metadata - ptrRecords: ptrRecord.?ptrRecords - ttl: ptrRecord.?ttl ?? 3600 - roleAssignments: ptrRecord.?roleAssignments +] + +module dnsZone_PTR 'ptr/main.bicep' = [ + for (ptrRecord, index) in (ptr ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsZone-PTRRecord-${index}' + params: { + dnsZoneName: dnsZone.name + name: ptrRecord.name + metadata: ptrRecord.?metadata + ptrRecords: ptrRecord.?ptrRecords + ttl: ptrRecord.?ttl ?? 3600 + roleAssignments: ptrRecord.?roleAssignments + } } -}] - -module dnsZone_SOA 'soa/main.bicep' = [for (soaRecord, index) in (soa ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsZone-SOARecord-${index}' - params: { - dnsZoneName: dnsZone.name - name: soaRecord.name - metadata: soaRecord.?metadata - soaRecord: soaRecord.?soaRecord - ttl: soaRecord.?ttl ?? 3600 - roleAssignments: soaRecord.?roleAssignments +] + +module dnsZone_SOA 'soa/main.bicep' = [ + for (soaRecord, index) in (soa ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsZone-SOARecord-${index}' + params: { + dnsZoneName: dnsZone.name + name: soaRecord.name + metadata: soaRecord.?metadata + soaRecord: soaRecord.?soaRecord + ttl: soaRecord.?ttl ?? 3600 + roleAssignments: soaRecord.?roleAssignments + } } -}] - -module dnsZone_SRV 'srv/main.bicep' = [for (srvRecord, index) in (srv ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsZone-SRVRecord-${index}' - params: { - dnsZoneName: dnsZone.name - name: srvRecord.name - metadata: srvRecord.?metadata - srvRecords: srvRecord.?srvRecords - ttl: srvRecord.?ttl ?? 3600 - roleAssignments: srvRecord.?roleAssignments +] + +module dnsZone_SRV 'srv/main.bicep' = [ + for (srvRecord, index) in (srv ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsZone-SRVRecord-${index}' + params: { + dnsZoneName: dnsZone.name + name: srvRecord.name + metadata: srvRecord.?metadata + srvRecords: srvRecord.?srvRecords + ttl: srvRecord.?ttl ?? 3600 + roleAssignments: srvRecord.?roleAssignments + } } -}] - -module dnsZone_TXT 'txt/main.bicep' = [for (txtRecord, index) in (txt ?? []): { - name: '${uniqueString(deployment().name, location)}-dnsZone-TXTRecord-${index}' - params: { - dnsZoneName: dnsZone.name - name: txtRecord.name - metadata: txtRecord.?metadata - txtRecords: txtRecord.?txtRecords - ttl: txtRecord.?ttl ?? 3600 - roleAssignments: txtRecord.?roleAssignments +] + +module dnsZone_TXT 'txt/main.bicep' = [ + for (txtRecord, index) in (txt ?? []): { + name: '${uniqueString(deployment().name, location)}-dnsZone-TXTRecord-${index}' + params: { + dnsZoneName: dnsZone.name + name: txtRecord.name + metadata: txtRecord.?metadata + txtRecords: txtRecord.?txtRecords + ttl: txtRecord.?ttl ?? 3600 + roleAssignments: txtRecord.?roleAssignments + } } -}] - -resource dnsZone_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.' +] + +resource dnsZone_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: dnsZone } - scope: dnsZone -} -resource dnsZone_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(dnsZone.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 +resource dnsZone_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(dnsZone.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: dnsZone } - scope: dnsZone -}] +] @description('The resource group the DNS zone was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/dns-zone/main.json b/avm/res/network/dns-zone/main.json index e13f76988d..86c01a0ee2 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.25.53.49325", - "templateHash": "17409480183805156141" + "version": "0.26.54.24096", + "templateHash": "5460415630390016975" }, "name": "Public DNS Zones", "description": "This module deploys a Public DNS zone.", @@ -343,8 +343,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "1014861232584705848" + "version": "0.26.54.24096", + "templateHash": "4017689599365774964" }, "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.25.53.49325", - "templateHash": "17816545426283561774" + "version": "0.26.54.24096", + "templateHash": "3971171413214558899" }, "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.25.53.49325", - "templateHash": "11680687850109857660" + "version": "0.26.54.24096", + "templateHash": "15885562612097082245" }, "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.25.53.49325", - "templateHash": "2222693701620961150" + "version": "0.26.54.24096", + "templateHash": "8677073922032532586" }, "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.25.53.49325", - "templateHash": "11629556138650955144" + "version": "0.26.54.24096", + "templateHash": "1672903557888274249" }, "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.25.53.49325", - "templateHash": "16161487720425898744" + "version": "0.26.54.24096", + "templateHash": "18007510262177950674" }, "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.25.53.49325", - "templateHash": "7707819456897162158" + "version": "0.26.54.24096", + "templateHash": "9399981109957572409" }, "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.25.53.49325", - "templateHash": "4795044712963544053" + "version": "0.26.54.24096", + "templateHash": "7972019384779517121" }, "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.25.53.49325", - "templateHash": "14428108443514495816" + "version": "0.26.54.24096", + "templateHash": "11464779884101617586" }, "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.25.53.49325", - "templateHash": "789212919897780335" + "version": "0.26.54.24096", + "templateHash": "8936268371142649378" }, "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.bicep b/avm/res/network/dns-zone/mx/main.bicep index 386b4c254a..758fd767d1 100644 --- a/avm/res/network/dns-zone/mx/main.bicep +++ b/avm/res/network/dns-zone/mx/main.bicep @@ -22,16 +22,40 @@ param roleAssignments roleAssignmentType var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { @@ -48,19 +72,25 @@ resource MX 'Microsoft.Network/dnsZones/MX@2018-05-01' = { } } -resource MX_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(MX.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 +resource MX_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(MX.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: MX } - scope: MX -}] +] @description('The name of the deployed MX record.') output name string = MX.name diff --git a/avm/res/network/dns-zone/mx/main.json b/avm/res/network/dns-zone/mx/main.json index fcf04baf23..36bfc0b0ee 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.25.53.49325", - "templateHash": "11629556138650955144" + "version": "0.26.54.24096", + "templateHash": "1672903557888274249" }, "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.bicep b/avm/res/network/dns-zone/ns/main.bicep index 7e1964d6fd..3e4cbe4f40 100644 --- a/avm/res/network/dns-zone/ns/main.bicep +++ b/avm/res/network/dns-zone/ns/main.bicep @@ -22,16 +22,40 @@ param roleAssignments roleAssignmentType var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { name: dnsZoneName @@ -47,19 +71,25 @@ resource NS 'Microsoft.Network/dnsZones/NS@2018-05-01' = { } } -resource NS_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(NS.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 +resource NS_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(NS.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: NS } - scope: NS -}] +] @description('The name of the deployed NS record.') output name string = NS.name diff --git a/avm/res/network/dns-zone/ns/main.json b/avm/res/network/dns-zone/ns/main.json index 46226a0939..f079d87268 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.25.53.49325", - "templateHash": "16161487720425898744" + "version": "0.26.54.24096", + "templateHash": "18007510262177950674" }, "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.bicep b/avm/res/network/dns-zone/ptr/main.bicep index 6a2e0a0dd5..a3463a2ce3 100644 --- a/avm/res/network/dns-zone/ptr/main.bicep +++ b/avm/res/network/dns-zone/ptr/main.bicep @@ -22,16 +22,40 @@ param roleAssignments roleAssignmentType var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { @@ -48,19 +72,25 @@ resource PTR 'Microsoft.Network/dnsZones/PTR@2018-05-01' = { } } -resource PTR_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(PTR.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 +resource PTR_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(PTR.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: PTR } - scope: PTR -}] +] @description('The name of the deployed PTR record.') output name string = PTR.name diff --git a/avm/res/network/dns-zone/ptr/main.json b/avm/res/network/dns-zone/ptr/main.json index cdb6b7f82d..3ffab06b51 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.25.53.49325", - "templateHash": "7707819456897162158" + "version": "0.26.54.24096", + "templateHash": "9399981109957572409" }, "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.bicep b/avm/res/network/dns-zone/soa/main.bicep index b6aea1462b..17eceec692 100644 --- a/avm/res/network/dns-zone/soa/main.bicep +++ b/avm/res/network/dns-zone/soa/main.bicep @@ -22,16 +22,40 @@ param roleAssignments roleAssignmentType var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { @@ -48,19 +72,25 @@ resource SOA 'Microsoft.Network/dnsZones/SOA@2018-05-01' = { } } -resource SOA_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(SOA.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 +resource SOA_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(SOA.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: SOA } - scope: SOA -}] +] @description('The name of the deployed SOA record.') output name string = SOA.name diff --git a/avm/res/network/dns-zone/soa/main.json b/avm/res/network/dns-zone/soa/main.json index 8b0dd53fa1..15636237ab 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.25.53.49325", - "templateHash": "4795044712963544053" + "version": "0.26.54.24096", + "templateHash": "7972019384779517121" }, "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.bicep b/avm/res/network/dns-zone/srv/main.bicep index 83b4ca435d..4250514384 100644 --- a/avm/res/network/dns-zone/srv/main.bicep +++ b/avm/res/network/dns-zone/srv/main.bicep @@ -22,16 +22,40 @@ param roleAssignments roleAssignmentType var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { name: dnsZoneName @@ -47,19 +71,25 @@ resource SRV 'Microsoft.Network/dnsZones/SRV@2018-05-01' = { } } -resource SRV_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(SRV.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 +resource SRV_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(SRV.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: SRV } - scope: SRV -}] +] @description('The name of the deployed SRV record.') output name string = SRV.name diff --git a/avm/res/network/dns-zone/srv/main.json b/avm/res/network/dns-zone/srv/main.json index 56e32bec1e..1ed4aab75e 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.25.53.49325", - "templateHash": "14428108443514495816" + "version": "0.26.54.24096", + "templateHash": "11464779884101617586" }, "name": "Public DNS Zone SRV record", "description": "This module deploys a Public DNS Zone SRV record.", diff --git a/avm/res/network/dns-zone/tests/e2e/defaults/main.test.bicep b/avm/res/network/dns-zone/tests/e2e/defaults/main.test.bicep index 7c97b1e101..41d0b58231 100644 --- a/avm/res/network/dns-zone/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/dns-zone/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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.com' - location: 'global' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001.com' + location: 'global' + } } -}] +] diff --git a/avm/res/network/dns-zone/tests/e2e/max/dependencies.bicep b/avm/res/network/dns-zone/tests/e2e/max/dependencies.bicep index 22bd417624..8f0e73eebf 100644 --- a/avm/res/network/dns-zone/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/dns-zone/tests/e2e/max/dependencies.bicep @@ -8,26 +8,26 @@ param trafficManagerProfileName string param managedIdentityName string resource trafficManagerProfile 'Microsoft.Network/trafficmanagerprofiles@2022-04-01-preview' = { - name: trafficManagerProfileName - location: 'global' - properties: { - trafficRoutingMethod: 'Performance' - maxReturn: 0 - dnsConfig: { - relativeName: trafficManagerProfileName - ttl: 60 - } - monitorConfig: { - protocol: 'HTTP' - port: 80 - path: '/' - } + name: trafficManagerProfileName + location: 'global' + properties: { + trafficRoutingMethod: 'Performance' + maxReturn: 0 + dnsConfig: { + relativeName: trafficManagerProfileName + ttl: 60 } + monitorConfig: { + protocol: 'HTTP' + port: 80 + path: '/' + } + } } resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The resource ID of the created Traffic Manager Profile.') diff --git a/avm/res/network/dns-zone/tests/e2e/max/main.test.bicep b/avm/res/network/dns-zone/tests/e2e/max/main.test.bicep index a7827f4d55..b86e5b815f 100644 --- a/avm/res/network/dns-zone/tests/e2e/max/main.test.bicep +++ b/avm/res/network/dns-zone/tests/e2e/max/main.test.bicep @@ -46,256 +46,282 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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.com' - location: 'global' - a: [ - { - aRecords: [ - { - ipv4Address: '10.240.4.4' - } - ] - name: 'A_10.240.4.4' - 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' - } - ] - ttl: 3600 - } - ] - aaaa: [ - { - aaaaRecords: [ - { - ipv6Address: '2001:0db8:85a3:0000:0000:8a2e:0370:7334' - } - ] - name: 'AAAA_2001_0db8_85a3_0000_0000_8a2e_0370_7334' - ttl: 3600 - } - ] - cname: [ - { - cnameRecord: { - cname: 'test' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001.com' + location: 'global' + a: [ + { + aRecords: [ + { + ipv4Address: '10.240.4.4' + } + ] + name: 'A_10.240.4.4' + 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' + } + ] + ttl: 3600 } - name: 'CNAME_test' - 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' - } - ] - ttl: 3600 - } - { - name: 'CNAME_aliasRecordSet' - targetResourceId: nestedDependencies.outputs.trafficManagerProfileResourceId - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - mx: [ - { - mxRecords: [ - { - exchange: 'contoso.com' - preference: 100 - } - ] - name: 'MX_contoso' - 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' - } - ] - ttl: 3600 - } - ] - ptr: [ - { - name: 'PTR_contoso' - ptrRecords: [ - { - ptrdname: 'contoso.com' - } - ] - 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' - } - ] - ttl: 3600 - } - ] - 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' - } - ] - soa: [ - { - name: '@' - 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' - } - ] - soaRecord: { - email: 'azuredns-hostmaster.microsoft.com' - expireTime: 2419200 - host: 'ns1-04.azure-dns.com.' - minimumTtl: 300 - refreshTime: 3600 - retryTime: 300 - serialNumber: '1' + ] + aaaa: [ + { + aaaaRecords: [ + { + ipv6Address: '2001:0db8:85a3:0000:0000:8a2e:0370:7334' + } + ] + name: 'AAAA_2001_0db8_85a3_0000_0000_8a2e_0370_7334' + ttl: 3600 } - ttl: 3600 - } - ] - srv: [ - { - name: 'SRV_contoso' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + ] + cname: [ + { + cnameRecord: { + cname: 'test' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - srvRecords: [ - { - port: 9332 - priority: 0 - target: 'test.contoso.com' - weight: 0 - } - ] - ttl: 3600 + name: 'CNAME_test' + 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' + } + ] + ttl: 3600 + } + { + name: 'CNAME_aliasRecordSet' + targetResourceId: nestedDependencies.outputs.trafficManagerProfileResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - txt: [ - { - name: 'TXT_test' - 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' - } - ] - ttl: 3600 - txtRecords: [ - { - value: [ - 'test' - ] + mx: [ + { + mxRecords: [ + { + exchange: 'contoso.com' + preference: 100 + } + ] + name: 'MX_contoso' + 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' + } + ] + ttl: 3600 + } + ] + ptr: [ + { + name: 'PTR_contoso' + ptrRecords: [ + { + ptrdname: 'contoso.com' + } + ] + 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' + } + ] + ttl: 3600 + } + ] + 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' + } + ] + soa: [ + { + name: '@' + 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' + } + ] + soaRecord: { + email: 'azuredns-hostmaster.microsoft.com' + expireTime: 2419200 + host: 'ns1-04.azure-dns.com.' + minimumTtl: 300 + refreshTime: 3600 + retryTime: 300 + serialNumber: '1' } - ] + ttl: 3600 + } + ] + srv: [ + { + name: 'SRV_contoso' + 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' + } + ] + srvRecords: [ + { + port: 9332 + priority: 0 + target: 'test.contoso.com' + weight: 0 + } + ] + ttl: 3600 + } + ] + txt: [ + { + name: 'TXT_test' + 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' + } + ] + ttl: 3600 + txtRecords: [ + { + value: [ + 'test' + ] + } + ] + } + ] + 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/network/dns-zone/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/dns-zone/tests/e2e/waf-aligned/dependencies.bicep index 22bd417624..8f0e73eebf 100644 --- a/avm/res/network/dns-zone/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/network/dns-zone/tests/e2e/waf-aligned/dependencies.bicep @@ -8,26 +8,26 @@ param trafficManagerProfileName string param managedIdentityName string resource trafficManagerProfile 'Microsoft.Network/trafficmanagerprofiles@2022-04-01-preview' = { - name: trafficManagerProfileName - location: 'global' - properties: { - trafficRoutingMethod: 'Performance' - maxReturn: 0 - dnsConfig: { - relativeName: trafficManagerProfileName - ttl: 60 - } - monitorConfig: { - protocol: 'HTTP' - port: 80 - path: '/' - } + name: trafficManagerProfileName + location: 'global' + properties: { + trafficRoutingMethod: 'Performance' + maxReturn: 0 + dnsConfig: { + relativeName: trafficManagerProfileName + ttl: 60 } + monitorConfig: { + protocol: 'HTTP' + port: 80 + path: '/' + } + } } resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The resource ID of the created Traffic Manager Profile.') diff --git a/avm/res/network/dns-zone/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/dns-zone/tests/e2e/waf-aligned/main.test.bicep index a3d821e933..fa23869633 100644 --- a/avm/res/network/dns-zone/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/dns-zone/tests/e2e/waf-aligned/main.test.bicep @@ -46,20 +46,22 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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.com' - location: 'global' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001.com' + location: 'global' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/network/dns-zone/txt/main.bicep b/avm/res/network/dns-zone/txt/main.bicep index 225c8baf68..2477ee357e 100644 --- a/avm/res/network/dns-zone/txt/main.bicep +++ b/avm/res/network/dns-zone/txt/main.bicep @@ -22,16 +22,40 @@ param roleAssignments roleAssignmentType var 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') + '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') + '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') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + '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 dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { name: dnsZoneName @@ -47,19 +71,25 @@ resource TXT 'Microsoft.Network/dnsZones/TXT@2018-05-01' = { } } -resource TXT_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(TXT.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 +resource TXT_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(TXT.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: TXT } - scope: TXT -}] +] @description('The name of the deployed TXT record.') output name string = TXT.name diff --git a/avm/res/network/dns-zone/txt/main.json b/avm/res/network/dns-zone/txt/main.json index 0d275f47ee..16576f7f7c 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.25.53.49325", - "templateHash": "789212919897780335" + "version": "0.26.54.24096", + "templateHash": "8936268371142649378" }, "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/main.bicep b/avm/res/network/express-route-circuit/main.bicep index 1394cacf99..20107ec0ec 100644 --- a/avm/res/network/express-route-circuit/main.bicep +++ b/avm/res/network/express-route-circuit/main.bicep @@ -87,30 +87,40 @@ 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') + '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') + '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-expressroutecircuit.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-expressroutecircuit.${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 expressRouteCircuits 'Microsoft.Network/expressRouteCircuits@2023-04-01' = { name: name @@ -125,75 +135,94 @@ resource expressRouteCircuits 'Microsoft.Network/expressRouteCircuits@2023-04-01 allowClassicOperations: allowClassicOperations globalReachEnabled: globalReachEnabled bandwidthInGbps: bandwidthInGbps != 0 ? bandwidthInGbps : null - expressRoutePort: !empty(expressRoutePortResourceId) ? { - id: expressRoutePortResourceId - } : null + expressRoutePort: !empty(expressRoutePortResourceId) + ? { + id: expressRoutePortResourceId + } + : null serviceProviderProperties: { serviceProviderName: serviceProviderName peeringLocation: peeringLocation bandwidthInMbps: bandwidthInMbps } - peerings: peering ? [ - { - name: peeringType - properties: { - peeringType: peeringType - sharedKey: sharedKey - peerASN: peerASN - primaryPeerAddressPrefix: primaryPeerAddressPrefix - secondaryPeerAddressPrefix: secondaryPeerAddressPrefix - vlanId: vlanId - } - } - ] : null + peerings: peering + ? [ + { + name: peeringType + properties: { + peeringType: peeringType + sharedKey: sharedKey + peerASN: peerASN + primaryPeerAddressPrefix: primaryPeerAddressPrefix + secondaryPeerAddressPrefix: secondaryPeerAddressPrefix + vlanId: vlanId + } + } + ] + : null } } -resource expressRouteCircuits_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.' +resource expressRouteCircuits_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: expressRouteCircuits } - scope: expressRouteCircuits -} -resource expressRouteCircuits_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 - 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 +resource expressRouteCircuits_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 + 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 + } + scope: expressRouteCircuits } - scope: expressRouteCircuits -}] - -resource expressRouteCircuits_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(expressRouteCircuits.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 +] + +resource expressRouteCircuits_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(expressRouteCircuits.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: expressRouteCircuits } - scope: expressRouteCircuits -}] +] @description('The resource ID of express route curcuit.') output resourceId string = expressRouteCircuits.id diff --git a/avm/res/network/express-route-circuit/main.json b/avm/res/network/express-route-circuit/main.json index d1deecbc00..4f030b9351 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.25.53.49325", - "templateHash": "1951233357364145060" + "version": "0.26.54.24096", + "templateHash": "12576570459858721920" }, "name": "ExpressRoute Circuits", "description": "This module deploys an Express Route Circuit.", diff --git a/avm/res/network/express-route-circuit/tests/e2e/defaults/main.test.bicep b/avm/res/network/express-route-circuit/tests/e2e/defaults/main.test.bicep index 27ad16cd30..8d241b905b 100644 --- a/avm/res/network/express-route-circuit/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/express-route-circuit/tests/e2e/defaults/main.test.bicep @@ -36,14 +36,16 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - bandwidthInMbps: 50 - peeringLocation: 'Amsterdam' - serviceProviderName: 'Equinix' - location: resourceLocation +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + bandwidthInMbps: 50 + peeringLocation: 'Amsterdam' + serviceProviderName: 'Equinix' + location: resourceLocation + } } -}] +] diff --git a/avm/res/network/express-route-circuit/tests/e2e/max/dependencies.bicep b/avm/res/network/express-route-circuit/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/network/express-route-circuit/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/express-route-circuit/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/network/express-route-circuit/tests/e2e/max/main.test.bicep b/avm/res/network/express-route-circuit/tests/e2e/max/main.test.bicep index fbe38c7edd..56e3591e91 100644 --- a/avm/res/network/express-route-circuit/tests/e2e/max/main.test.bicep +++ b/avm/res/network/express-route-circuit/tests/e2e/max/main.test.bicep @@ -58,58 +58,63 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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 - bandwidthInMbps: 50 - peeringLocation: 'Amsterdam' - serviceProviderName: 'Equinix' - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - 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' +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 + bandwidthInMbps: 50 + peeringLocation: 'Amsterdam' + serviceProviderName: 'Equinix' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' + } + ] + skuFamily: 'MeteredData' + skuTier: 'Standard' + allowClassicOperations: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - skuFamily: 'MeteredData' - skuTier: 'Standard' - allowClassicOperations: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [nestedDependencies] } - dependsOn: [ nestedDependencies ] -}] +] diff --git a/avm/res/network/express-route-circuit/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/express-route-circuit/tests/e2e/waf-aligned/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/network/express-route-circuit/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/network/express-route-circuit/tests/e2e/waf-aligned/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/network/express-route-circuit/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/express-route-circuit/tests/e2e/waf-aligned/main.test.bicep index bd5b28139a..cc8f20a1d2 100644 --- a/avm/res/network/express-route-circuit/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/express-route-circuit/tests/e2e/waf-aligned/main.test.bicep @@ -58,40 +58,42 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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 - bandwidthInMbps: 50 - peeringLocation: 'Amsterdam' - serviceProviderName: 'Equinix' - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + bandwidthInMbps: 50 + peeringLocation: 'Amsterdam' + serviceProviderName: 'Equinix' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + skuFamily: 'MeteredData' + skuTier: 'Standard' + allowClassicOperations: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - skuFamily: 'MeteredData' - skuTier: 'Standard' - allowClassicOperations: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/network/express-route-gateway/main.bicep b/avm/res/network/express-route-gateway/main.bicep index 681e2e9fe7..2dfda0cf5d 100644 --- a/avm/res/network/express-route-gateway/main.bicep +++ b/avm/res/network/express-route-gateway/main.bicep @@ -37,30 +37,40 @@ 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') + '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') + '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-expressroutegateway.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-expressroutegateway.${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 expressRouteGateway 'Microsoft.Network/expressRouteGateways@2023-04-01' = { name: name @@ -81,28 +91,37 @@ resource expressRouteGateway 'Microsoft.Network/expressRouteGateways@2023-04-01' } } -resource expressRouteGateway_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.' +resource expressRouteGateway_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: expressRouteGateway } - scope: expressRouteGateway -} -resource expressRouteGateway_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(expressRouteGateway.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 +resource expressRouteGateway_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(expressRouteGateway.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: expressRouteGateway } - scope: expressRouteGateway -}] +] @description('The resource ID of the ExpressRoute Gateway.') output resourceId string = expressRouteGateway.id diff --git a/avm/res/network/express-route-gateway/main.json b/avm/res/network/express-route-gateway/main.json index 2c4afb55c3..08858bc019 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.25.53.49325", - "templateHash": "5520177504222517638" + "version": "0.26.54.24096", + "templateHash": "7886944632822822023" }, "name": "Express Route Gateways", "description": "This module deploys an Express Route Gateway.", diff --git a/avm/res/network/express-route-gateway/tests/e2e/max/main.test.bicep b/avm/res/network/express-route-gateway/tests/e2e/max/main.test.bicep index 22b0539525..110c5a0026 100644 --- a/avm/res/network/express-route-gateway/tests/e2e/max/main.test.bicep +++ b/avm/res/network/express-route-gateway/tests/e2e/max/main.test.bicep @@ -74,7 +74,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/network/firewall-policy/main.bicep b/avm/res/network/firewall-policy/main.bicep index dfefd95117..5da990e5c2 100644 --- a/avm/res/network/firewall-policy/main.bicep +++ b/avm/res/network/firewall-policy/main.bicep @@ -97,30 +97,37 @@ param enableTelemetry bool = true @description('Optional. Rule collection groups.') param ruleCollectionGroups array? -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: 'UserAssigned' - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null - -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.network-firewallpolicy.${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' +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: 'UserAssigned' + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-firewallpolicy.${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 firewallPolicy 'Microsoft.Network/firewallPolicies@2023-04-01' = { name: name @@ -128,37 +135,47 @@ resource firewallPolicy 'Microsoft.Network/firewallPolicies@2023-04-01' = { tags: tags identity: identity properties: { - basePolicy: !empty(basePolicyResourceId ?? '') ? { - id: basePolicyResourceId - } : null - dnsSettings: enableProxy ? { - enableProxy: enableProxy - servers: servers ?? [] - } : null - insights: insightsIsEnabled ? { - isEnabled: insightsIsEnabled - logAnalyticsResources: { - defaultWorkspaceId: { - id: defaultWorkspaceId + basePolicy: !empty(basePolicyResourceId ?? '') + ? { + id: basePolicyResourceId } - workspaces: workspaces - } - retentionDays: retentionDays - } : null - intrusionDetection: (mode != 'Off') ? { - configuration: { - bypassTrafficSettings: bypassTrafficSettings - signatureOverrides: signatureOverrides - } - mode: mode - } : null + : null + dnsSettings: enableProxy + ? { + enableProxy: enableProxy + servers: servers ?? [] + } + : null + insights: insightsIsEnabled + ? { + isEnabled: insightsIsEnabled + logAnalyticsResources: { + defaultWorkspaceId: { + id: defaultWorkspaceId + } + workspaces: workspaces + } + retentionDays: retentionDays + } + : null + intrusionDetection: (mode != 'Off') + ? { + configuration: { + bypassTrafficSettings: bypassTrafficSettings + signatureOverrides: signatureOverrides + } + mode: mode + } + : null sku: { tier: tier } - snat: !empty(privateRanges) ? { - autoLearnPrivateRanges: autoLearnPrivateRanges - privateRanges: privateRanges - } : null + snat: !empty(privateRanges) + ? { + autoLearnPrivateRanges: autoLearnPrivateRanges + privateRanges: privateRanges + } + : null sql: { allowSqlRedirect: allowSqlRedirect } @@ -167,12 +184,14 @@ resource firewallPolicy 'Microsoft.Network/firewallPolicies@2023-04-01' = { fqdns: fqdns ?? [] ipAddresses: ipAddresses ?? [] } - transportSecurity: (!empty(keyVaultSecretId ?? []) || !empty(certificateName ?? '')) ? { - certificateAuthority: { - keyVaultSecretId: keyVaultSecretId - name: certificateName - } - } : null + transportSecurity: (!empty(keyVaultSecretId ?? []) || !empty(certificateName ?? '')) + ? { + certificateAuthority: { + keyVaultSecretId: keyVaultSecretId + name: certificateName + } + } + : null } } @@ -181,15 +200,17 @@ resource firewallPolicy 'Microsoft.Network/firewallPolicies@2023-04-01' = { // because of concurrent access to the base policy. // The next line forces ARM to deploy them one after the other, so no race concition on the base policy will happen. @batchSize(1) -module firewallPolicy_ruleCollectionGroups 'rule-collection-group/main.bicep' = [for (ruleCollectionGroup, index) in (ruleCollectionGroups ?? []): { - name: '${uniqueString(deployment().name, location)}-firewallPolicy_ruleCollectionGroups-${index}' - params: { - firewallPolicyName: firewallPolicy.name - name: ruleCollectionGroup.name - priority: ruleCollectionGroup.priority - ruleCollections: ruleCollectionGroup.ruleCollections +module firewallPolicy_ruleCollectionGroups 'rule-collection-group/main.bicep' = [ + for (ruleCollectionGroup, index) in (ruleCollectionGroups ?? []): { + name: '${uniqueString(deployment().name, location)}-firewallPolicy_ruleCollectionGroups-${index}' + params: { + firewallPolicyName: firewallPolicy.name + name: ruleCollectionGroup.name + priority: ruleCollectionGroup.priority + ruleCollections: ruleCollectionGroup.ruleCollections + } } -}] +] @description('The name of the deployed firewall policy.') output name string = firewallPolicy.name diff --git a/avm/res/network/firewall-policy/main.json b/avm/res/network/firewall-policy/main.json index 7a05153f27..1316a3c93e 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.25.53.49325", - "templateHash": "8352567375549268667" + "version": "0.26.54.24096", + "templateHash": "5451872777085737013" }, "name": "Firewall Policies", "description": "This module deploys a Firewall Policy.", @@ -311,8 +311,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17945865046689186214" + "version": "0.26.54.24096", + "templateHash": "15656278354863511578" }, "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 b6ec7d3e49..8fd8a36653 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.25.53.49325", - "templateHash": "17945865046689186214" + "version": "0.26.54.24096", + "templateHash": "15656278354863511578" }, "name": "Firewall Policy Rule Collection Groups", "description": "This module deploys a Firewall Policy Rule Collection Group.", diff --git a/avm/res/network/firewall-policy/tests/e2e/defaults/main.test.bicep b/avm/res/network/firewall-policy/tests/e2e/defaults/main.test.bicep index c48fbf7ba4..f63c5d678f 100644 --- a/avm/res/network/firewall-policy/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/firewall-policy/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/firewall-policy/tests/e2e/max/main.test.bicep b/avm/res/network/firewall-policy/tests/e2e/max/main.test.bicep index 0295a163df..b713f73fbf 100644 --- a/avm/res/network/firewall-policy/tests/e2e/max/main.test.bicep +++ b/avm/res/network/firewall-policy/tests/e2e/max/main.test.bicep @@ -45,63 +45,65 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - tier: 'Premium' - mode: 'Alert' - ruleCollectionGroups: [ - { - name: '${namePrefix}-rule-001' - priority: 5000 - ruleCollections: [ - { - action: { - type: 'Allow' - } - name: 'collection002' - priority: 5555 - ruleCollectionType: 'FirewallPolicyFilterRuleCollection' - rules: [ - { - destinationAddresses: [ - '*' - ] - destinationFqdns: [] - destinationIpGroups: [] - destinationPorts: [ - '80' - ] - ipProtocols: [ - 'TCP' - 'UDP' - ] - name: 'rule002' - ruleType: 'NetworkRule' - sourceAddresses: [ - '*' - ] - sourceIpGroups: [] +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 + tier: 'Premium' + mode: 'Alert' + ruleCollectionGroups: [ + { + name: '${namePrefix}-rule-001' + priority: 5000 + ruleCollections: [ + { + action: { + type: 'Allow' } - ] - } + name: 'collection002' + priority: 5555 + ruleCollectionType: 'FirewallPolicyFilterRuleCollection' + rules: [ + { + destinationAddresses: [ + '*' + ] + destinationFqdns: [] + destinationIpGroups: [] + destinationPorts: [ + '80' + ] + ipProtocols: [ + 'TCP' + 'UDP' + ] + name: 'rule002' + ruleType: 'NetworkRule' + sourceAddresses: [ + '*' + ] + sourceIpGroups: [] + } + ] + } + ] + } + ] + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] } - ] - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - 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' + } + allowSqlRedirect: true + autoLearnPrivateRanges: 'Enabled' } - allowSqlRedirect: true - autoLearnPrivateRanges: 'Enabled' } -}] +] diff --git a/avm/res/network/firewall-policy/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/firewall-policy/tests/e2e/waf-aligned/main.test.bicep index 51003decf8..0462603a72 100644 --- a/avm/res/network/firewall-policy/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/firewall-policy/tests/e2e/waf-aligned/main.test.bicep @@ -36,57 +36,59 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - ruleCollectionGroups: [ - { - name: '${namePrefix}-rule-001' - priority: 5000 - ruleCollections: [ - { - action: { - type: 'Allow' - } - name: 'collection002' - priority: 5555 - ruleCollectionType: 'FirewallPolicyFilterRuleCollection' - rules: [ - { - destinationAddresses: [ - '*' - ] - destinationFqdns: [] - destinationIpGroups: [] - destinationPorts: [ - '80' - ] - ipProtocols: [ - 'TCP' - 'UDP' - ] - name: 'rule002' - ruleType: 'NetworkRule' - sourceAddresses: [ - '*' - ] - sourceIpGroups: [] +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 + ruleCollectionGroups: [ + { + name: '${namePrefix}-rule-001' + priority: 5000 + ruleCollections: [ + { + action: { + type: 'Allow' } - ] - } - ] + name: 'collection002' + priority: 5555 + ruleCollectionType: 'FirewallPolicyFilterRuleCollection' + rules: [ + { + destinationAddresses: [ + '*' + ] + destinationFqdns: [] + destinationIpGroups: [] + destinationPorts: [ + '80' + ] + ipProtocols: [ + 'TCP' + 'UDP' + ] + name: 'rule002' + ruleType: 'NetworkRule' + sourceAddresses: [ + '*' + ] + sourceIpGroups: [] + } + ] + } + ] + } + ] + 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' + allowSqlRedirect: true + autoLearnPrivateRanges: 'Enabled' + threatIntelMode: 'Deny' } - allowSqlRedirect: true - autoLearnPrivateRanges: 'Enabled' - threatIntelMode: 'Deny' } -}] +] diff --git a/avm/res/network/front-door-web-application-firewall-policy/main.bicep b/avm/res/network/front-door-web-application-firewall-policy/main.bicep index d49e672750..8ca355b991 100644 --- a/avm/res/network/front-door-web-application-firewall-policy/main.bicep +++ b/avm/res/network/front-door-web-application-firewall-policy/main.bicep @@ -56,7 +56,7 @@ param customRules object = { matchVariable: 'RemoteAddr' operator: 'GeoMatch' negateCondition: true - matchValue: [ 'ZZ' ] + matchValue: ['ZZ'] } ] } @@ -79,27 +79,34 @@ 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') + '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.network-frontdoorwebappfirewallpolicy.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.network-frontdoorwebappfirewallpolicy.${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 frontDoorWAFPolicy 'Microsoft.Network/FrontDoorWebApplicationFirewallPolicies@2022-05-01' = { name: name @@ -115,28 +122,37 @@ resource frontDoorWAFPolicy 'Microsoft.Network/FrontDoorWebApplicationFirewallPo } } -resource frontDoorWAFPolicy_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.' +resource frontDoorWAFPolicy_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: frontDoorWAFPolicy } - scope: frontDoorWAFPolicy -} -resource frontDoorWAFPolicy_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(frontDoorWAFPolicy.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 +resource frontDoorWAFPolicy_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(frontDoorWAFPolicy.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: frontDoorWAFPolicy } - scope: frontDoorWAFPolicy -}] +] @description('The name of the Front Door WAF policy.') output name string = frontDoorWAFPolicy.name 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 4df136f697..54f07df7fe 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.25.53.49325", - "templateHash": "1373577986476180700" + "version": "0.26.54.24096", + "templateHash": "11803357399151500299" }, "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-web-application-firewall-policy/tests/e2e/defaults/main.test.bicep b/avm/res/network/front-door-web-application-firewall-policy/tests/e2e/defaults/main.test.bicep index 92998f86dc..7d35210808 100644 --- a/avm/res/network/front-door-web-application-firewall-policy/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/front-door-web-application-firewall-policy/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { // ============== // @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 +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/front-door-web-application-firewall-policy/tests/e2e/max/main.test.bicep b/avm/res/network/front-door-web-application-firewall-policy/tests/e2e/max/main.test.bicep index e5a2cab892..d79784401c 100644 --- a/avm/res/network/front-door-web-application-firewall-policy/tests/e2e/max/main.test.bicep +++ b/avm/res/network/front-door-web-application-firewall-policy/tests/e2e/max/main.test.bicep @@ -45,100 +45,105 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - } - sku: 'Premium_AzureFrontDoor' - policySettings: { - mode: 'Prevention' - redirectUrl: 'http://www.bing.com' - customBlockResponseStatusCode: 200 - customBlockResponseBody: 'PGh0bWw+CjxoZWFkZXI+PHRpdGxlPkhlbGxvPC90aXRsZT48L2hlYWRlcj4KPGJvZHk+CkhlbGxvIHdvcmxkCjwvYm9keT4KPC9odG1sPg==' - } - customRules: { - rules: [ +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' + } + sku: 'Premium_AzureFrontDoor' + policySettings: { + mode: 'Prevention' + redirectUrl: 'http://www.bing.com' + customBlockResponseStatusCode: 200 + customBlockResponseBody: 'PGh0bWw+CjxoZWFkZXI+PHRpdGxlPkhlbGxvPC90aXRsZT48L2hlYWRlcj4KPGJvZHk+CkhlbGxvIHdvcmxkCjwvYm9keT4KPC9odG1sPg==' + } + customRules: { + rules: [ + { + name: 'CustomRule1' + priority: 2 + enabledState: 'Enabled' + action: 'Block' + ruleType: 'MatchRule' + rateLimitDurationInMinutes: 1 + rateLimitThreshold: 10 + matchConditions: [ + { + matchVariable: 'RemoteAddr' + selector: null + operator: 'GeoMatch' + negateCondition: false + transforms: [] + matchValue: [ + 'CH' + ] + } + { + matchVariable: 'RequestHeader' + selector: 'UserAgent' + operator: 'Contains' + negateCondition: false + transforms: [] + matchValue: [ + 'windows' + ] + } + { + matchVariable: 'QueryString' + operator: 'Contains' + negateCondition: false + transforms: [ + 'UrlDecode' + 'Lowercase' + ] + matchValue: [ + '' + ] + } + ] + } + ] + } + managedRules: { + managedRuleSets: [ + { + ruleSetType: 'Microsoft_BotManagerRuleSet' + ruleSetVersion: '1.0' + } + ] + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + roleAssignments: [ { - name: 'CustomRule1' - priority: 2 - enabledState: 'Enabled' - action: 'Block' - ruleType: 'MatchRule' - rateLimitDurationInMinutes: 1 - rateLimitThreshold: 10 - matchConditions: [ - { - matchVariable: 'RemoteAddr' - selector: null - operator: 'GeoMatch' - negateCondition: false - transforms: [] - matchValue: [ - 'CH' - ] - } - { - matchVariable: 'RequestHeader' - selector: 'UserAgent' - operator: 'Contains' - negateCondition: false - transforms: [] - matchValue: [ - 'windows' - ] - } - { - matchVariable: 'QueryString' - operator: 'Contains' - negateCondition: false - transforms: [ - 'UrlDecode' - 'Lowercase' - ] - matchValue: [ - '' - ] - } - ] + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - ] - } - managedRules: { - managedRuleSets: [ { - ruleSetType: 'Microsoft_BotManagerRuleSet' - ruleSetVersion: '1.0' + 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' - } - 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' - } - ] } -}] +] diff --git a/avm/res/network/front-door-web-application-firewall-policy/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/front-door-web-application-firewall-policy/tests/e2e/waf-aligned/main.test.bicep index 9fc72dff92..ecbe09e12c 100644 --- a/avm/res/network/front-door-web-application-firewall-policy/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/front-door-web-application-firewall-policy/tests/e2e/waf-aligned/main.test.bicep @@ -36,79 +36,81 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { // ============== // @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 - sku: 'Premium_AzureFrontDoor' - policySettings: { - mode: 'Prevention' - redirectUrl: 'http://www.bing.com' - customBlockResponseStatusCode: 200 - customBlockResponseBody: 'PGh0bWw+CjxoZWFkZXI+PHRpdGxlPkhlbGxvPC90aXRsZT48L2hlYWRlcj4KPGJvZHk+CkhlbGxvIHdvcmxkCjwvYm9keT4KPC9odG1sPg==' - } - customRules: { - rules: [ - { - name: 'CustomRule1' - priority: 2 - enabledState: 'Enabled' - action: 'Block' - ruleType: 'MatchRule' - rateLimitDurationInMinutes: 1 - rateLimitThreshold: 10 - matchConditions: [ - { - matchVariable: 'RemoteAddr' - selector: null - operator: 'GeoMatch' - negateCondition: false - transforms: [] - matchValue: [ - 'CH' - ] - } - { - matchVariable: 'RequestHeader' - selector: 'UserAgent' - operator: 'Contains' - negateCondition: false - transforms: [] - matchValue: [ - 'windows' - ] - } - { - matchVariable: 'QueryString' - operator: 'Contains' - negateCondition: false - transforms: [ - 'UrlDecode' - 'Lowercase' - ] - matchValue: [ - '' - ] - } - ] - } - ] - } - managedRules: { - managedRuleSets: [ - { - ruleSetType: 'Microsoft_BotManagerRuleSet' - ruleSetVersion: '1.0' - } - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + sku: 'Premium_AzureFrontDoor' + policySettings: { + mode: 'Prevention' + redirectUrl: 'http://www.bing.com' + customBlockResponseStatusCode: 200 + customBlockResponseBody: 'PGh0bWw+CjxoZWFkZXI+PHRpdGxlPkhlbGxvPC90aXRsZT48L2hlYWRlcj4KPGJvZHk+CkhlbGxvIHdvcmxkCjwvYm9keT4KPC9odG1sPg==' + } + customRules: { + rules: [ + { + name: 'CustomRule1' + priority: 2 + enabledState: 'Enabled' + action: 'Block' + ruleType: 'MatchRule' + rateLimitDurationInMinutes: 1 + rateLimitThreshold: 10 + matchConditions: [ + { + matchVariable: 'RemoteAddr' + selector: null + operator: 'GeoMatch' + negateCondition: false + transforms: [] + matchValue: [ + 'CH' + ] + } + { + matchVariable: 'RequestHeader' + selector: 'UserAgent' + operator: 'Contains' + negateCondition: false + transforms: [] + matchValue: [ + 'windows' + ] + } + { + matchVariable: 'QueryString' + operator: 'Contains' + negateCondition: false + transforms: [ + 'UrlDecode' + 'Lowercase' + ] + matchValue: [ + '' + ] + } + ] + } + ] + } + managedRules: { + managedRuleSets: [ + { + ruleSetType: 'Microsoft_BotManagerRuleSet' + ruleSetVersion: '1.0' + } + ] + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/network/front-door/main.bicep b/avm/res/network/front-door/main.bicep index d121c34cb1..e8844b22a1 100644 --- a/avm/res/network/front-door/main.bicep +++ b/avm/res/network/front-door/main.bicep @@ -55,30 +55,40 @@ param diagnosticSettings diagnosticSettingType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + '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') + '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-frontdoor.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-frontdoor.${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 frontDoor 'Microsoft.Network/frontDoors@2020-05-01' = { name: name @@ -99,51 +109,66 @@ resource frontDoor 'Microsoft.Network/frontDoors@2020-05-01' = { } } -resource frontDoor_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.' +resource frontDoor_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: frontDoor } - scope: frontDoor -} -resource frontDoor_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 - 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 +resource frontDoor_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 + 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 + } + scope: frontDoor } - scope: frontDoor -}] - -resource frontDoor_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(frontDoor.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 +] + +resource frontDoor_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(frontDoor.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: frontDoor } - scope: frontDoor -}] +] @description('The name of the front door.') output name string = frontDoor.name diff --git a/avm/res/network/front-door/main.json b/avm/res/network/front-door/main.json index 140a73c6ad..067451e5f1 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.25.53.49325", - "templateHash": "5209569003361494357" + "version": "0.26.54.24096", + "templateHash": "11688367630078848691" }, "name": "Azure Front Doors", "description": "This module deploys an Azure Front Door.", diff --git a/avm/res/network/front-door/tests/e2e/defaults/main.test.bicep b/avm/res/network/front-door/tests/e2e/defaults/main.test.bicep index 9da362d16d..fc0f9d4bea 100644 --- a/avm/res/network/front-door/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/front-door/tests/e2e/defaults/main.test.bicep @@ -36,90 +36,92 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // var resourceName = '${namePrefix}${serviceShort}001' @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: resourceName - location: resourceLocation - frontendEndpoints: [ - { - name: 'frontEnd' - properties: { - hostName: '${resourceName}.${environment().suffixes.azureFrontDoorEndpointSuffix}' - sessionAffinityEnabledState: 'Disabled' - sessionAffinityTtlSeconds: 60 +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: resourceName + location: resourceLocation + frontendEndpoints: [ + { + name: 'frontEnd' + properties: { + hostName: '${resourceName}.${environment().suffixes.azureFrontDoorEndpointSuffix}' + sessionAffinityEnabledState: 'Disabled' + sessionAffinityTtlSeconds: 60 + } } - } - ] - healthProbeSettings: [ - { - name: 'heathProbe' - properties: { - intervalInSeconds: 60 - path: '/' - protocol: 'Https' + ] + healthProbeSettings: [ + { + name: 'heathProbe' + properties: { + intervalInSeconds: 60 + path: '/' + protocol: 'Https' + } } - } - ] - loadBalancingSettings: [ - { - name: 'loadBalancer' - properties: { - additionalLatencyMilliseconds: 0 - sampleSize: 50 - successfulSamplesRequired: 1 + ] + loadBalancingSettings: [ + { + name: 'loadBalancer' + properties: { + additionalLatencyMilliseconds: 0 + sampleSize: 50 + successfulSamplesRequired: 1 + } } - } - ] - routingRules: [ - { - name: 'routingRule' - properties: { - acceptedProtocols: [ - 'Https' - ] - enabledState: 'Enabled' - frontendEndpoints: [ - { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/FrontendEndpoints/frontEnd' - } - ] - patternsToMatch: [ - '/*' - ] - routeConfiguration: { - '@odata.type': '#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration' - backendPool: { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/BackendPools/backendPool' + ] + routingRules: [ + { + name: 'routingRule' + properties: { + acceptedProtocols: [ + 'Https' + ] + enabledState: 'Enabled' + frontendEndpoints: [ + { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/FrontendEndpoints/frontEnd' + } + ] + patternsToMatch: [ + '/*' + ] + routeConfiguration: { + '@odata.type': '#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration' + backendPool: { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/BackendPools/backendPool' + } } } } - } - ] - backendPools: [ - { - name: 'backendPool' - properties: { - backends: [ - { - address: 'biceptest.local' - backendHostHeader: 'backendAddress' - enabledState: 'Enabled' - httpPort: 80 - httpsPort: 443 - priority: 1 - weight: 50 + ] + backendPools: [ + { + name: 'backendPool' + properties: { + backends: [ + { + address: 'biceptest.local' + backendHostHeader: 'backendAddress' + enabledState: 'Enabled' + httpPort: 80 + httpsPort: 443 + priority: 1 + weight: 50 + } + ] + HealthProbeSettings: { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/HealthProbeSettings/heathProbe' + } + LoadBalancingSettings: { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/LoadBalancingSettings/loadBalancer' } - ] - HealthProbeSettings: { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/HealthProbeSettings/heathProbe' - } - LoadBalancingSettings: { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/LoadBalancingSettings/loadBalancer' } } - } - ] + ] + } } -}] +] diff --git a/avm/res/network/front-door/tests/e2e/max/dependencies.bicep b/avm/res/network/front-door/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/network/front-door/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/front-door/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') 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 aa6d4a9abe..4207e72e65 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 @@ -59,144 +59,149 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // var resourceName = '${namePrefix}${serviceShort}001' @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: resourceName - location: resourceLocation - backendPools: [ - { - name: 'backendPool' - properties: { - backends: [ - { - address: 'biceptest.local' - backendHostHeader: 'backendAddress' - enabledState: 'Enabled' - httpPort: 80 - httpsPort: 443 - priority: 1 - privateLinkAlias: '' - privateLinkApprovalMessage: '' - privateLinkLocation: '' - weight: 50 +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: resourceName + location: resourceLocation + backendPools: [ + { + name: 'backendPool' + properties: { + backends: [ + { + address: 'biceptest.local' + backendHostHeader: 'backendAddress' + enabledState: 'Enabled' + httpPort: 80 + httpsPort: 443 + priority: 1 + privateLinkAlias: '' + privateLinkApprovalMessage: '' + privateLinkLocation: '' + weight: 50 + } + ] + HealthProbeSettings: { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/HealthProbeSettings/heathProbe' + } + LoadBalancingSettings: { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/LoadBalancingSettings/loadBalancer' } - ] - HealthProbeSettings: { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/HealthProbeSettings/heathProbe' } - LoadBalancingSettings: { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/LoadBalancingSettings/loadBalancer' + } + ] + enforceCertificateNameCheck: 'Disabled' + frontendEndpoints: [ + { + name: 'frontEnd' + properties: { + hostName: '${resourceName}.${environment().suffixes.azureFrontDoorEndpointSuffix}' + sessionAffinityEnabledState: 'Disabled' + sessionAffinityTtlSeconds: 60 } } - } - ] - enforceCertificateNameCheck: 'Disabled' - frontendEndpoints: [ - { - name: 'frontEnd' - properties: { - hostName: '${resourceName}.${environment().suffixes.azureFrontDoorEndpointSuffix}' - sessionAffinityEnabledState: 'Disabled' - sessionAffinityTtlSeconds: 60 + ] + healthProbeSettings: [ + { + name: 'heathProbe' + properties: { + enabledState: '' + healthProbeMethod: '' + intervalInSeconds: 60 + path: '/' + protocol: 'Https' + } } - } - ] - healthProbeSettings: [ - { - name: 'heathProbe' - properties: { - enabledState: '' - healthProbeMethod: '' - intervalInSeconds: 60 - path: '/' - protocol: 'Https' + ] + loadBalancingSettings: [ + { + name: 'loadBalancer' + properties: { + additionalLatencyMilliseconds: 0 + sampleSize: 50 + successfulSamplesRequired: 1 + } } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - loadBalancingSettings: [ - { - name: 'loadBalancer' - properties: { - additionalLatencyMilliseconds: 0 - sampleSize: 50 - successfulSamplesRequired: 1 + routingRules: [ + { + name: 'routingRule' + properties: { + acceptedProtocols: [ + 'Http' + 'Https' + ] + enabledState: 'Enabled' + frontendEndpoints: [ + { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/FrontendEndpoints/frontEnd' + } + ] + patternsToMatch: [ + '/*' + ] + routeConfiguration: { + '@odata.type': '#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration' + backendPool: { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/BackendPools/backendPool' + } + forwardingProtocol: 'MatchRequest' + } + } } - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - routingRules: [ - { - name: 'routingRule' - properties: { - acceptedProtocols: [ - 'Http' - 'Https' - ] - enabledState: 'Enabled' - frontendEndpoints: [ + ] + sendRecvTimeoutSeconds: 10 + 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' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/FrontendEndpoints/frontEnd' + category: 'AllMetrics' } ] - patternsToMatch: [ - '/*' - ] - routeConfiguration: { - '@odata.type': '#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration' - backendPool: { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/BackendPools/backendPool' + logCategoriesAndGroups: [ + { + category: 'FrontdoorAccessLog' } - forwardingProtocol: 'MatchRequest' - } + ] + 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' } - ] - sendRecvTimeoutSeconds: 10 - 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' - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - logCategoriesAndGroups: [ - { - category: 'FrontdoorAccessLog' - } - ] - 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/network/front-door/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/front-door/tests/e2e/waf-aligned/main.test.bicep index 99c37e7c9b..fd7839f280 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 @@ -50,112 +50,114 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // var resourceName = '${namePrefix}${serviceShort}001' @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: resourceName - location: resourceLocation - backendPools: [ - { - name: 'backendPool' - properties: { - backends: [ - { - address: 'biceptest.local' - backendHostHeader: 'backendAddress' - enabledState: 'Enabled' - httpPort: 80 - httpsPort: 443 - priority: 1 - privateLinkAlias: '' - privateLinkApprovalMessage: '' - privateLinkLocation: '' - weight: 50 +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: resourceName + location: resourceLocation + backendPools: [ + { + name: 'backendPool' + properties: { + backends: [ + { + address: 'biceptest.local' + backendHostHeader: 'backendAddress' + enabledState: 'Enabled' + httpPort: 80 + httpsPort: 443 + priority: 1 + privateLinkAlias: '' + privateLinkApprovalMessage: '' + privateLinkLocation: '' + weight: 50 + } + ] + HealthProbeSettings: { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/HealthProbeSettings/heathProbe' + } + LoadBalancingSettings: { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/LoadBalancingSettings/loadBalancer' } - ] - HealthProbeSettings: { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/HealthProbeSettings/heathProbe' - } - LoadBalancingSettings: { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/LoadBalancingSettings/loadBalancer' } } - } - ] - enforceCertificateNameCheck: 'Disabled' - frontendEndpoints: [ - { - name: 'frontEnd' - properties: { - hostName: '${resourceName}.${environment().suffixes.azureFrontDoorEndpointSuffix}' - sessionAffinityEnabledState: 'Disabled' - sessionAffinityTtlSeconds: 60 + ] + enforceCertificateNameCheck: 'Disabled' + frontendEndpoints: [ + { + name: 'frontEnd' + properties: { + hostName: '${resourceName}.${environment().suffixes.azureFrontDoorEndpointSuffix}' + sessionAffinityEnabledState: 'Disabled' + sessionAffinityTtlSeconds: 60 + } } - } - ] - healthProbeSettings: [ - { - name: 'heathProbe' - properties: { - enabledState: '' - healthProbeMethod: '' - intervalInSeconds: 60 - path: '/' - protocol: 'Https' + ] + healthProbeSettings: [ + { + name: 'heathProbe' + properties: { + enabledState: '' + healthProbeMethod: '' + intervalInSeconds: 60 + path: '/' + protocol: 'Https' + } } - } - ] - loadBalancingSettings: [ - { - name: 'loadBalancer' - properties: { - additionalLatencyMilliseconds: 0 - sampleSize: 50 - successfulSamplesRequired: 1 + ] + loadBalancingSettings: [ + { + name: 'loadBalancer' + properties: { + additionalLatencyMilliseconds: 0 + sampleSize: 50 + successfulSamplesRequired: 1 + } } - } - ] - routingRules: [ - { - name: 'routingRule' - properties: { - acceptedProtocols: [ - 'Http' - 'Https' - ] - enabledState: 'Enabled' - frontendEndpoints: [ - { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/FrontendEndpoints/frontEnd' + ] + routingRules: [ + { + name: 'routingRule' + properties: { + acceptedProtocols: [ + 'Http' + 'Https' + ] + enabledState: 'Enabled' + frontendEndpoints: [ + { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/FrontendEndpoints/frontEnd' + } + ] + patternsToMatch: [ + '/*' + ] + routeConfiguration: { + '@odata.type': '#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration' + backendPool: { + id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/BackendPools/backendPool' + } + forwardingProtocol: 'MatchRequest' } - ] - patternsToMatch: [ - '/*' - ] - routeConfiguration: { - '@odata.type': '#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration' - backendPool: { - id: '${resourceGroup.id}/providers/Microsoft.Network/frontDoors/${resourceName}/BackendPools/backendPool' - } - forwardingProtocol: 'MatchRequest' } } + ] + sendRecvTimeoutSeconds: 10 + 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' } - ] - sendRecvTimeoutSeconds: 10 - 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/network/ip-group/main.bicep b/avm/res/network/ip-group/main.bicep index 9232554ce1..0363fa601c 100644 --- a/avm/res/network/ip-group/main.bicep +++ b/avm/res/network/ip-group/main.bicep @@ -26,30 +26,40 @@ 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') + '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') + '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 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 @@ -60,28 +70,37 @@ resource ipGroup 'Microsoft.Network/ipGroups@2023-04-01' = { } } -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.' +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 } - 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 +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 } - scope: ipGroup -}] +] @description('The resource ID of the IP group.') output resourceId string = ipGroup.id diff --git a/avm/res/network/ip-group/main.json b/avm/res/network/ip-group/main.json index c190237042..733445b2c1 100644 --- a/avm/res/network/ip-group/main.json +++ b/avm/res/network/ip-group/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3252011302585807507" + "version": "0.26.54.24096", + "templateHash": "6270017838054314226" }, "name": "IP Groups", "description": "This module deploys an IP Group.", 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 index 6341b22f1e..fd0de68ed1 100644 --- a/avm/res/network/ip-group/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/ip-group/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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 index a7f42aee7b..7be39e253a 100644 --- a/avm/res/network/ip-group/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/ip-group/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') 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 index 7e5f42408f..7b64b4b2be 100644 --- a/avm/res/network/ip-group/tests/e2e/max/main.test.bicep +++ b/avm/res/network/ip-group/tests/e2e/max/main.test.bicep @@ -45,41 +45,46 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' +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' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' } - ] - 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 index 9c0a4a3e10..35516eff9a 100644 --- 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 @@ -36,20 +36,22 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' +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/load-balancer/backend-address-pool/main.json b/avm/res/network/load-balancer/backend-address-pool/main.json index ab6d005e2d..f54d506c5f 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.25.53.49325", - "templateHash": "16244632442901566911" + "version": "0.26.54.24096", + "templateHash": "17412878196552582226" }, "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.bicep b/avm/res/network/load-balancer/inbound-nat-rule/main.bicep index cd2a670107..de3cfa7775 100644 --- a/avm/res/network/load-balancer/inbound-nat-rule/main.bicep +++ b/avm/res/network/load-balancer/inbound-nat-rule/main.bicep @@ -60,9 +60,11 @@ resource inboundNatRule 'Microsoft.Network/loadBalancers/inboundNatRules@2023-04 properties: { frontendPort: frontendPort backendPort: backendPort - backendAddressPool: !empty(backendAddressPoolName) ? { - id: '${loadBalancer.id}/backendAddressPools/${backendAddressPoolName}' - } : null + backendAddressPool: !empty(backendAddressPoolName) + ? { + id: '${loadBalancer.id}/backendAddressPools/${backendAddressPoolName}' + } + : null enableFloatingIP: enableFloatingIP enableTcpReset: enableTcpReset frontendIPConfiguration: { 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 08de35dd26..23878519ea 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.25.53.49325", - "templateHash": "17788406033422026149" + "version": "0.26.54.24096", + "templateHash": "7362889285586557037" }, "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 081b5c1b8a..1e956dae91 100644 --- a/avm/res/network/load-balancer/main.bicep +++ b/avm/res/network/load-balancer/main.bicep @@ -57,113 +57,169 @@ param outboundRules array = [] // Variables // // =========== // -var frontendIPConfigurationsVar = [for (frontendIPConfiguration, index) in frontendIPConfigurations: { - name: frontendIPConfiguration.name - properties: { - subnet: contains(frontendIPConfiguration, 'subnetId') && !empty(frontendIPConfiguration.subnetId) ? { - id: frontendIPConfiguration.subnetId - } : null - publicIPAddress: contains(frontendIPConfiguration, 'publicIPAddressId') && !empty(frontendIPConfiguration.publicIPAddressId) ? { - id: frontendIPConfiguration.publicIPAddressId - } : null - privateIPAddress: contains(frontendIPConfiguration, 'privateIPAddress') && !empty(frontendIPConfiguration.privateIPAddress) ? frontendIPConfiguration.privateIPAddress : null - privateIPAddressVersion: contains(frontendIPConfiguration, 'privateIPAddressVersion') ? frontendIPConfiguration.privateIPAddressVersion : 'IPv4' - privateIPAllocationMethod: contains(frontendIPConfiguration, 'subnetId') && !empty(frontendIPConfiguration.subnetId) ? (contains(frontendIPConfiguration, 'privateIPAddress') ? 'Static' : 'Dynamic') : null - gatewayLoadBalancer: contains(frontendIPConfiguration, 'gatewayLoadBalancer') && !empty(frontendIPConfiguration.gatewayLoadBalancer) ? { - id: frontendIPConfiguration.gatewayLoadBalancer - } : null - publicIPPrefix: contains(frontendIPConfiguration, 'publicIPPrefix') && !empty(frontendIPConfiguration.publicIPPrefix) ? { - id: frontendIPConfiguration.publicIPPrefix - } : null - } -}] - -var loadBalancingRulesVar = [for loadBalancingRule in (loadBalancingRules ?? []): { - name: loadBalancingRule.name - properties: { - backendAddressPool: { - id: az.resourceId('Microsoft.Network/loadBalancers/backendAddressPools', name, loadBalancingRule.backendAddressPoolName) - } - backendPort: loadBalancingRule.backendPort - disableOutboundSnat: contains(loadBalancingRule, 'disableOutboundSnat') ? loadBalancingRule.disableOutboundSnat : true - enableFloatingIP: contains(loadBalancingRule, 'enableFloatingIP') ? loadBalancingRule.enableFloatingIP : false - enableTcpReset: contains(loadBalancingRule, 'enableTcpReset') ? loadBalancingRule.enableTcpReset : false - frontendIPConfiguration: { - id: az.resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', name, loadBalancingRule.frontendIPConfigurationName) +var frontendIPConfigurationsVar = [ + for (frontendIPConfiguration, index) in frontendIPConfigurations: { + name: frontendIPConfiguration.name + properties: { + subnet: contains(frontendIPConfiguration, 'subnetId') && !empty(frontendIPConfiguration.subnetId) + ? { + id: frontendIPConfiguration.subnetId + } + : null + publicIPAddress: contains(frontendIPConfiguration, 'publicIPAddressId') && !empty(frontendIPConfiguration.publicIPAddressId) + ? { + id: frontendIPConfiguration.publicIPAddressId + } + : null + privateIPAddress: contains(frontendIPConfiguration, 'privateIPAddress') && !empty(frontendIPConfiguration.privateIPAddress) + ? frontendIPConfiguration.privateIPAddress + : null + privateIPAddressVersion: contains(frontendIPConfiguration, 'privateIPAddressVersion') + ? frontendIPConfiguration.privateIPAddressVersion + : 'IPv4' + privateIPAllocationMethod: contains(frontendIPConfiguration, 'subnetId') && !empty(frontendIPConfiguration.subnetId) + ? (contains(frontendIPConfiguration, 'privateIPAddress') ? 'Static' : 'Dynamic') + : null + gatewayLoadBalancer: contains(frontendIPConfiguration, 'gatewayLoadBalancer') && !empty(frontendIPConfiguration.gatewayLoadBalancer) + ? { + id: frontendIPConfiguration.gatewayLoadBalancer + } + : null + publicIPPrefix: contains(frontendIPConfiguration, 'publicIPPrefix') && !empty(frontendIPConfiguration.publicIPPrefix) + ? { + id: frontendIPConfiguration.publicIPPrefix + } + : null } - frontendPort: loadBalancingRule.frontendPort - idleTimeoutInMinutes: contains(loadBalancingRule, 'idleTimeoutInMinutes') ? loadBalancingRule.idleTimeoutInMinutes : 4 - loadDistribution: contains(loadBalancingRule, 'loadDistribution') ? loadBalancingRule.loadDistribution : 'Default' - probe: { - id: '${az.resourceId('Microsoft.Network/loadBalancers', name)}/probes/${loadBalancingRule.probeName}' + } +] + +var loadBalancingRulesVar = [ + for loadBalancingRule in (loadBalancingRules ?? []): { + name: loadBalancingRule.name + properties: { + backendAddressPool: { + id: az.resourceId( + 'Microsoft.Network/loadBalancers/backendAddressPools', + name, + loadBalancingRule.backendAddressPoolName + ) + } + backendPort: loadBalancingRule.backendPort + disableOutboundSnat: contains(loadBalancingRule, 'disableOutboundSnat') + ? loadBalancingRule.disableOutboundSnat + : true + enableFloatingIP: contains(loadBalancingRule, 'enableFloatingIP') ? loadBalancingRule.enableFloatingIP : false + enableTcpReset: contains(loadBalancingRule, 'enableTcpReset') ? loadBalancingRule.enableTcpReset : false + frontendIPConfiguration: { + id: az.resourceId( + 'Microsoft.Network/loadBalancers/frontendIPConfigurations', + name, + loadBalancingRule.frontendIPConfigurationName + ) + } + frontendPort: loadBalancingRule.frontendPort + idleTimeoutInMinutes: contains(loadBalancingRule, 'idleTimeoutInMinutes') + ? loadBalancingRule.idleTimeoutInMinutes + : 4 + loadDistribution: contains(loadBalancingRule, 'loadDistribution') ? loadBalancingRule.loadDistribution : 'Default' + probe: { + id: '${az.resourceId('Microsoft.Network/loadBalancers', name)}/probes/${loadBalancingRule.probeName}' + } + protocol: contains(loadBalancingRule, 'protocol') ? loadBalancingRule.protocol : 'Tcp' } - protocol: contains(loadBalancingRule, 'protocol') ? loadBalancingRule.protocol : 'Tcp' } -}] - -var outboundRulesVar = [for outboundRule in outboundRules: { - name: outboundRule.name - properties: { - frontendIPConfigurations: [ - { - id: az.resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', name, outboundRule.frontendIPConfigurationName) +] + +var outboundRulesVar = [ + for outboundRule in outboundRules: { + name: outboundRule.name + properties: { + frontendIPConfigurations: [ + { + id: az.resourceId( + 'Microsoft.Network/loadBalancers/frontendIPConfigurations', + name, + outboundRule.frontendIPConfigurationName + ) + } + ] + backendAddressPool: { + id: az.resourceId( + 'Microsoft.Network/loadBalancers/backendAddressPools', + name, + outboundRule.backendAddressPoolName + ) } - ] - backendAddressPool: { - id: az.resourceId('Microsoft.Network/loadBalancers/backendAddressPools', name, outboundRule.backendAddressPoolName) + protocol: contains(outboundRule, 'protocol') ? outboundRule.protocol : 'All' + allocatedOutboundPorts: contains(outboundRule, 'allocatedOutboundPorts') + ? outboundRule.allocatedOutboundPorts + : 63984 + enableTcpReset: contains(outboundRule, 'enableTcpReset') ? outboundRule.enableTcpReset : true + idleTimeoutInMinutes: contains(outboundRule, 'idleTimeoutInMinutes') ? outboundRule.idleTimeoutInMinutes : 4 } - protocol: contains(outboundRule, 'protocol') ? outboundRule.protocol : 'All' - allocatedOutboundPorts: contains(outboundRule, 'allocatedOutboundPorts') ? outboundRule.allocatedOutboundPorts : 63984 - enableTcpReset: contains(outboundRule, 'enableTcpReset') ? outboundRule.enableTcpReset : true - idleTimeoutInMinutes: contains(outboundRule, 'idleTimeoutInMinutes') ? outboundRule.idleTimeoutInMinutes : 4 } -}] - -var probesVar = [for probe in (probes ?? []): { - name: probe.name - properties: { - protocol: contains(probe, 'protocol') ? probe.protocol : 'Tcp' - requestPath: toLower(probe.protocol) != 'tcp' ? probe.requestPath : null - port: contains(probe, 'port') ? probe.port : 80 - intervalInSeconds: contains(probe, 'intervalInSeconds') ? probe.intervalInSeconds : 5 - numberOfProbes: contains(probe, 'numberOfProbes') ? probe.numberOfProbes : 2 +] + +var probesVar = [ + for probe in (probes ?? []): { + name: probe.name + properties: { + protocol: contains(probe, 'protocol') ? probe.protocol : 'Tcp' + requestPath: toLower(probe.protocol) != 'tcp' ? probe.requestPath : null + port: contains(probe, 'port') ? probe.port : 80 + intervalInSeconds: contains(probe, 'intervalInSeconds') ? probe.intervalInSeconds : 5 + numberOfProbes: contains(probe, 'numberOfProbes') ? probe.numberOfProbes : 2 + } } -}] +] -var backendAddressPoolNames = [for backendAddressPool in (backendAddressPools ?? []): { - name: backendAddressPool.name -}] +var backendAddressPoolNames = [ + for backendAddressPool in (backendAddressPools ?? []): { + name: backendAddressPool.name + } +] var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + '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') + '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' + ) } // ============ // // Dependencies // // ============ // -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.network-loadbalancer.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-loadbalancer.${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 loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { name: name @@ -181,78 +237,105 @@ resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { } } -module loadBalancer_backendAddressPools 'backend-address-pool/main.bicep' = [for (backendAddressPool, index) in backendAddressPools ?? []: { - name: '${uniqueString(deployment().name, location)}-loadBalancer-backendAddressPools-${index}' - params: { - loadBalancerName: loadBalancer.name - name: backendAddressPool.name - tunnelInterfaces: contains(backendAddressPool, 'tunnelInterfaces') && !empty(backendAddressPool.tunnelInterfaces) ? backendAddressPool.tunnelInterfaces : [] - loadBalancerBackendAddresses: contains(backendAddressPool, 'loadBalancerBackendAddresses') && !empty(backendAddressPool.loadBalancerBackendAddresses) ? backendAddressPool.loadBalancerBackendAddresses : [] - drainPeriodInSeconds: contains(backendAddressPool, 'drainPeriodInSeconds') ? backendAddressPool.drainPeriodInSeconds : 0 +module loadBalancer_backendAddressPools 'backend-address-pool/main.bicep' = [ + for (backendAddressPool, index) in backendAddressPools ?? []: { + name: '${uniqueString(deployment().name, location)}-loadBalancer-backendAddressPools-${index}' + params: { + loadBalancerName: loadBalancer.name + name: backendAddressPool.name + tunnelInterfaces: contains(backendAddressPool, 'tunnelInterfaces') && !empty(backendAddressPool.tunnelInterfaces) + ? backendAddressPool.tunnelInterfaces + : [] + loadBalancerBackendAddresses: contains(backendAddressPool, 'loadBalancerBackendAddresses') && !empty(backendAddressPool.loadBalancerBackendAddresses) + ? backendAddressPool.loadBalancerBackendAddresses + : [] + drainPeriodInSeconds: contains(backendAddressPool, 'drainPeriodInSeconds') + ? backendAddressPool.drainPeriodInSeconds + : 0 + } } -}] - -module loadBalancer_inboundNATRules 'inbound-nat-rule/main.bicep' = [for (inboundNATRule, index) in inboundNatRules: { - name: '${uniqueString(deployment().name, location)}-LoadBalancer-inboundNatRules-${index}' - params: { - loadBalancerName: loadBalancer.name - name: inboundNATRule.name - frontendIPConfigurationName: inboundNATRule.frontendIPConfigurationName - frontendPort: inboundNATRule.frontendPort - backendPort: contains(inboundNATRule, 'backendPort') ? inboundNATRule.backendPort : inboundNATRule.frontendPort - backendAddressPoolName: contains(inboundNATRule, 'backendAddressPoolName') ? inboundNATRule.backendAddressPoolName : '' - enableFloatingIP: contains(inboundNATRule, 'enableFloatingIP') ? inboundNATRule.enableFloatingIP : false - enableTcpReset: contains(inboundNATRule, 'enableTcpReset') ? inboundNATRule.enableTcpReset : false - frontendPortRangeEnd: contains(inboundNATRule, 'frontendPortRangeEnd') ? inboundNATRule.frontendPortRangeEnd : -1 - frontendPortRangeStart: contains(inboundNATRule, 'frontendPortRangeStart') ? inboundNATRule.frontendPortRangeStart : -1 - idleTimeoutInMinutes: contains(inboundNATRule, 'idleTimeoutInMinutes') ? inboundNATRule.idleTimeoutInMinutes : 4 - protocol: contains(inboundNATRule, 'protocol') ? inboundNATRule.protocol : 'Tcp' +] + +module loadBalancer_inboundNATRules 'inbound-nat-rule/main.bicep' = [ + for (inboundNATRule, index) in inboundNatRules: { + name: '${uniqueString(deployment().name, location)}-LoadBalancer-inboundNatRules-${index}' + params: { + loadBalancerName: loadBalancer.name + name: inboundNATRule.name + frontendIPConfigurationName: inboundNATRule.frontendIPConfigurationName + frontendPort: inboundNATRule.frontendPort + backendPort: contains(inboundNATRule, 'backendPort') ? inboundNATRule.backendPort : inboundNATRule.frontendPort + backendAddressPoolName: contains(inboundNATRule, 'backendAddressPoolName') + ? inboundNATRule.backendAddressPoolName + : '' + enableFloatingIP: contains(inboundNATRule, 'enableFloatingIP') ? inboundNATRule.enableFloatingIP : false + enableTcpReset: contains(inboundNATRule, 'enableTcpReset') ? inboundNATRule.enableTcpReset : false + frontendPortRangeEnd: contains(inboundNATRule, 'frontendPortRangeEnd') ? inboundNATRule.frontendPortRangeEnd : -1 + frontendPortRangeStart: contains(inboundNATRule, 'frontendPortRangeStart') + ? inboundNATRule.frontendPortRangeStart + : -1 + idleTimeoutInMinutes: contains(inboundNATRule, 'idleTimeoutInMinutes') ? inboundNATRule.idleTimeoutInMinutes : 4 + protocol: contains(inboundNATRule, 'protocol') ? inboundNATRule.protocol : 'Tcp' + } + dependsOn: [ + loadBalancer_backendAddressPools + ] } - dependsOn: [ - loadBalancer_backendAddressPools - ] -}] - -resource loadBalancer_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.' +] + +resource loadBalancer_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: loadBalancer } - scope: loadBalancer -} -resource loadBalancer_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 - metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { - category: group.category - enabled: group.?enabled ?? true - timeGrain: null - }] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType +resource loadBalancer_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 + metrics: [ + for group in (diagnosticSetting.?metricCategories ?? [{ category: 'AllMetrics' }]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: loadBalancer } - scope: loadBalancer -}] - -resource loadBalancer_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(loadBalancer.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 +] + +resource loadBalancer_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(loadBalancer.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: loadBalancer } - scope: loadBalancer -}] +] // =========== // // Outputs // diff --git a/avm/res/network/load-balancer/main.json b/avm/res/network/load-balancer/main.json index 0596ec342f..9b5968693a 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.25.53.49325", - "templateHash": "5849926741790594100" + "version": "0.26.54.24096", + "templateHash": "13683964905263959387" }, "name": "Load Balancers", "description": "This module deploys a Load Balancer.", @@ -524,8 +524,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16244632442901566911" + "version": "0.26.54.24096", + "templateHash": "17412878196552582226" }, "name": "Load Balancer Backend Address Pools", "description": "This module deploys a Load Balancer Backend Address Pools.", @@ -661,8 +661,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17788406033422026149" + "version": "0.26.54.24096", + "templateHash": "7362889285586557037" }, "name": "Load Balancer Inbound NAT Rules", "description": "This module deploys a Load Balancer Inbound NAT Rules.", diff --git a/avm/res/network/load-balancer/tests/e2e/defaults/main.test.bicep b/avm/res/network/load-balancer/tests/e2e/defaults/main.test.bicep index 54b6794296..d2253a49c4 100644 --- a/avm/res/network/load-balancer/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/load-balancer/tests/e2e/defaults/main.test.bicep @@ -59,23 +59,25 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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: {} - diagnosticSettings: [] - frontendIPConfigurations: [ - { - name: 'publicIPConfig1' - publicIPAddressId: nestedDependencies.outputs.publicIPResourceId - } +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: {} + diagnosticSettings: [] + frontendIPConfigurations: [ + { + name: 'publicIPConfig1' + publicIPAddressId: nestedDependencies.outputs.publicIPResourceId + } + ] + } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/load-balancer/tests/e2e/internal/main.test.bicep b/avm/res/network/load-balancer/tests/e2e/internal/main.test.bicep index e746a9b672..f0cc0f5f15 100644 --- a/avm/res/network/load-balancer/tests/e2e/internal/main.test.bicep +++ b/avm/res/network/load-balancer/tests/e2e/internal/main.test.bicep @@ -46,91 +46,96 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - frontendIPConfigurations: [ - { - name: 'privateIPConfig1' - subnetId: nestedDependencies.outputs.subnetResourceId - } - ] - backendAddressPools: [ - { - name: 'servers' - } - ] - inboundNatRules: [ - { - backendPort: 443 - enableFloatingIP: false - enableTcpReset: false - frontendIPConfigurationName: 'privateIPConfig1' - frontendPort: 443 - idleTimeoutInMinutes: 4 - name: 'inboundNatRule1' - protocol: 'Tcp' - } - { - backendPort: 3389 - frontendIPConfigurationName: 'privateIPConfig1' - frontendPort: 3389 - name: 'inboundNatRule2' - } - ] - skuName: 'Standard' - loadBalancingRules: [ - { - backendAddressPoolName: 'servers' - backendPort: 0 - disableOutboundSnat: true - enableFloatingIP: true - enableTcpReset: false - frontendIPConfigurationName: 'privateIPConfig1' - frontendPort: 0 - idleTimeoutInMinutes: 4 - loadDistribution: 'Default' - name: 'privateIPLBRule1' - probeName: 'probe1' - protocol: 'All' - } - ] - probes: [ - { - intervalInSeconds: 5 - name: 'probe1' - numberOfProbes: 2 - port: '62000' - protocol: 'Tcp' - } - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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 + frontendIPConfigurations: [ + { + name: 'privateIPConfig1' + subnetId: nestedDependencies.outputs.subnetResourceId + } + ] + backendAddressPools: [ + { + name: 'servers' + } + ] + inboundNatRules: [ + { + backendPort: 443 + enableFloatingIP: false + enableTcpReset: false + frontendIPConfigurationName: 'privateIPConfig1' + frontendPort: 443 + idleTimeoutInMinutes: 4 + name: 'inboundNatRule1' + protocol: 'Tcp' + } + { + backendPort: 3389 + frontendIPConfigurationName: 'privateIPConfig1' + frontendPort: 3389 + name: 'inboundNatRule2' + } + ] + skuName: 'Standard' + loadBalancingRules: [ + { + backendAddressPoolName: 'servers' + backendPort: 0 + disableOutboundSnat: true + enableFloatingIP: true + enableTcpReset: false + frontendIPConfigurationName: 'privateIPConfig1' + frontendPort: 0 + idleTimeoutInMinutes: 4 + loadDistribution: 'Default' + name: 'privateIPLBRule1' + probeName: 'probe1' + protocol: 'All' + } + ] + probes: [ + { + intervalInSeconds: 5 + name: 'probe1' + numberOfProbes: 2 + port: '62000' + protocol: 'Tcp' + } + ] + 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' } - { - 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' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/load-balancer/tests/e2e/max/main.test.bicep b/avm/res/network/load-balancer/tests/e2e/max/main.test.bicep index f65e294ea5..3090e1fd47 100644 --- a/avm/res/network/load-balancer/tests/e2e/max/main.test.bicep +++ b/avm/res/network/load-balancer/tests/e2e/max/main.test.bicep @@ -60,135 +60,140 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - frontendIPConfigurations: [ - { - name: 'publicIPConfig1' - publicIPAddressId: nestedDependencies.outputs.publicIPResourceId - } - ] - backendAddressPools: [ - { - name: 'backendAddressPool1' - } - { - name: 'backendAddressPool2' +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 + frontendIPConfigurations: [ + { + name: 'publicIPConfig1' + publicIPAddressId: nestedDependencies.outputs.publicIPResourceId + } + ] + backendAddressPools: [ + { + name: 'backendAddressPool1' + } + { + name: 'backendAddressPool2' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + inboundNatRules: [ + { + backendPort: 443 + enableFloatingIP: false + enableTcpReset: false + frontendIPConfigurationName: 'publicIPConfig1' + frontendPort: 443 + idleTimeoutInMinutes: 4 + name: 'inboundNatRule1' + protocol: 'Tcp' + } + { + backendPort: 3389 + frontendIPConfigurationName: 'publicIPConfig1' + frontendPort: 3389 + name: 'inboundNatRule2' + } + ] + loadBalancingRules: [ + { + backendAddressPoolName: 'backendAddressPool1' + backendPort: 80 + disableOutboundSnat: true + enableFloatingIP: false + enableTcpReset: false + frontendIPConfigurationName: 'publicIPConfig1' + frontendPort: 80 + idleTimeoutInMinutes: 5 + loadDistribution: 'Default' + name: 'publicIPLBRule1' + probeName: 'probe1' + protocol: 'Tcp' + } + { + backendAddressPoolName: 'backendAddressPool2' + backendPort: 8080 + frontendIPConfigurationName: 'publicIPConfig1' + frontendPort: 8080 + loadDistribution: 'Default' + name: 'publicIPLBRule2' + probeName: 'probe2' + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - inboundNatRules: [ - { - backendPort: 443 - enableFloatingIP: false - enableTcpReset: false - frontendIPConfigurationName: 'publicIPConfig1' - frontendPort: 443 - idleTimeoutInMinutes: 4 - name: 'inboundNatRule1' - protocol: 'Tcp' - } - { - backendPort: 3389 - frontendIPConfigurationName: 'publicIPConfig1' - frontendPort: 3389 - name: 'inboundNatRule2' - } - ] - loadBalancingRules: [ - { - backendAddressPoolName: 'backendAddressPool1' - backendPort: 80 - disableOutboundSnat: true - enableFloatingIP: false - enableTcpReset: false - frontendIPConfigurationName: 'publicIPConfig1' - frontendPort: 80 - idleTimeoutInMinutes: 5 - loadDistribution: 'Default' - name: 'publicIPLBRule1' - probeName: 'probe1' - protocol: 'Tcp' + outboundRules: [ + { + allocatedOutboundPorts: 63984 + backendAddressPoolName: 'backendAddressPool1' + frontendIPConfigurationName: 'publicIPConfig1' + name: 'outboundRule1' + } + ] + probes: [ + { + intervalInSeconds: 10 + name: 'probe1' + numberOfProbes: 5 + port: 80 + protocol: 'Tcp' + } + { + name: 'probe2' + port: 443 + protocol: 'Https' + requestPath: '/' + } + ] + 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' } - { - backendAddressPoolName: 'backendAddressPool2' - backendPort: 8080 - frontendIPConfigurationName: 'publicIPConfig1' - frontendPort: 8080 - loadDistribution: 'Default' - name: 'publicIPLBRule2' - probeName: 'probe2' - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' } - outboundRules: [ - { - allocatedOutboundPorts: 63984 - backendAddressPoolName: 'backendAddressPool1' - frontendIPConfigurationName: 'publicIPConfig1' - name: 'outboundRule1' - } - ] - probes: [ - { - intervalInSeconds: 10 - name: 'probe1' - numberOfProbes: 5 - port: 80 - protocol: 'Tcp' - } - { - name: 'probe2' - port: 443 - protocol: 'Https' - requestPath: '/' - } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] - 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' - } } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/load-balancer/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/load-balancer/tests/e2e/waf-aligned/main.test.bicep index 3392d94b44..de132072e4 100644 --- a/avm/res/network/load-balancer/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/load-balancer/tests/e2e/waf-aligned/main.test.bicep @@ -60,136 +60,141 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - frontendIPConfigurations: [ - { - name: 'publicIPConfig1' - publicIPAddressId: nestedDependencies.outputs.publicIPResourceId - } - ] - backendAddressPools: [ - { - name: 'backendAddressPool1' - } - { - name: 'backendAddressPool2' +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 + frontendIPConfigurations: [ + { + name: 'publicIPConfig1' + publicIPAddressId: nestedDependencies.outputs.publicIPResourceId + } + ] + backendAddressPools: [ + { + name: 'backendAddressPool1' + } + { + name: 'backendAddressPool2' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + inboundNatRules: [ + { + backendPort: 443 + enableFloatingIP: false + enableTcpReset: false + frontendIPConfigurationName: 'publicIPConfig1' + frontendPort: 443 + idleTimeoutInMinutes: 4 + name: 'inboundNatRule1' + protocol: 'Tcp' + } + { + backendPort: 3389 + frontendIPConfigurationName: 'publicIPConfig1' + frontendPort: 3389 + name: 'inboundNatRule2' + } + ] + loadBalancingRules: [ + { + backendAddressPoolName: 'backendAddressPool1' + backendPort: 80 + disableOutboundSnat: true + enableFloatingIP: false + enableTcpReset: false + frontendIPConfigurationName: 'publicIPConfig1' + frontendPort: 80 + idleTimeoutInMinutes: 5 + loadDistribution: 'Default' + name: 'publicIPLBRule1' + probeName: 'probe1' + protocol: 'Tcp' + } + { + backendAddressPoolName: 'backendAddressPool2' + backendPort: 8080 + frontendIPConfigurationName: 'publicIPConfig1' + frontendPort: 8080 + loadDistribution: 'Default' + name: 'publicIPLBRule2' + probeName: 'probe2' + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - inboundNatRules: [ - { - backendPort: 443 - enableFloatingIP: false - enableTcpReset: false - frontendIPConfigurationName: 'publicIPConfig1' - frontendPort: 443 - idleTimeoutInMinutes: 4 - name: 'inboundNatRule1' - protocol: 'Tcp' - } - { - backendPort: 3389 - frontendIPConfigurationName: 'publicIPConfig1' - frontendPort: 3389 - name: 'inboundNatRule2' - } - ] - loadBalancingRules: [ - { - backendAddressPoolName: 'backendAddressPool1' - backendPort: 80 - disableOutboundSnat: true - enableFloatingIP: false - enableTcpReset: false - frontendIPConfigurationName: 'publicIPConfig1' - frontendPort: 80 - idleTimeoutInMinutes: 5 - loadDistribution: 'Default' - name: 'publicIPLBRule1' - probeName: 'probe1' - protocol: 'Tcp' + outboundRules: [ + { + allocatedOutboundPorts: 63984 + backendAddressPoolName: 'backendAddressPool1' + frontendIPConfigurationName: 'publicIPConfig1' + name: 'outboundRule1' + } + ] + probes: [ + { + intervalInSeconds: 10 + name: 'probe1' + numberOfProbes: 5 + port: 80 + protocol: 'Http' + requestPath: '/http-probe' + } + { + name: 'probe2' + port: 443 + protocol: 'Https' + requestPath: '/https-probe' + } + ] + 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' } - { - backendAddressPoolName: 'backendAddressPool2' - backendPort: 8080 - frontendIPConfigurationName: 'publicIPConfig1' - frontendPort: 8080 - loadDistribution: 'Default' - name: 'publicIPLBRule2' - probeName: 'probe2' - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' } - outboundRules: [ - { - allocatedOutboundPorts: 63984 - backendAddressPoolName: 'backendAddressPool1' - frontendIPConfigurationName: 'publicIPConfig1' - name: 'outboundRule1' - } - ] - probes: [ - { - intervalInSeconds: 10 - name: 'probe1' - numberOfProbes: 5 - port: 80 - protocol: 'Http' - requestPath: '/http-probe' - } - { - name: 'probe2' - port: 443 - protocol: 'Https' - requestPath: '/https-probe' - } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] - 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' - } } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/local-network-gateway/main.bicep b/avm/res/network/local-network-gateway/main.bicep index a8ba9836d9..903daef1e4 100644 --- a/avm/res/network/local-network-gateway/main.bicep +++ b/avm/res/network/local-network-gateway/main.bicep @@ -47,30 +47,43 @@ var bgpSettings = { var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + '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') + '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: take('46d3xbcp.res.network-localnetworkgateway.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: take( + '46d3xbcp.res.network-localnetworkgateway.${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 localNetworkGateway 'Microsoft.Network/localNetworkGateways@2023-04-01' = { name: name @@ -86,28 +99,37 @@ resource localNetworkGateway 'Microsoft.Network/localNetworkGateways@2023-04-01' } } -resource localNetworkGateway_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.' +resource localNetworkGateway_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: localNetworkGateway } - scope: localNetworkGateway -} -resource localNetworkGateway_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(localNetworkGateway.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 +resource localNetworkGateway_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(localNetworkGateway.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: localNetworkGateway } - scope: localNetworkGateway -}] +] @description('The resource ID of the local network gateway.') output resourceId string = localNetworkGateway.id diff --git a/avm/res/network/local-network-gateway/main.json b/avm/res/network/local-network-gateway/main.json index 2399fd278e..7f9f8f7f80 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.25.53.49325", - "templateHash": "11943218028925171301" + "version": "0.26.54.24096", + "templateHash": "8917905061877887283" }, "name": "Local Network Gateways", "description": "This module deploys a Local Network Gateway.", diff --git a/avm/res/network/local-network-gateway/tests/e2e/defaults/main.test.bicep b/avm/res/network/local-network-gateway/tests/e2e/defaults/main.test.bicep index 3d8c1fa7b7..1d3a803c22 100644 --- a/avm/res/network/local-network-gateway/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/local-network-gateway/tests/e2e/defaults/main.test.bicep @@ -36,15 +36,17 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - localAddressPrefixes: [ - '192.168.1.0/24' - ] - localGatewayPublicIpAddress: '8.8.8.8' +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' + localAddressPrefixes: [ + '192.168.1.0/24' + ] + localGatewayPublicIpAddress: '8.8.8.8' + } } -}] +] diff --git a/avm/res/network/local-network-gateway/tests/e2e/max/dependencies.bicep b/avm/res/network/local-network-gateway/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/network/local-network-gateway/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/local-network-gateway/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/network/local-network-gateway/tests/e2e/max/main.test.bicep b/avm/res/network/local-network-gateway/tests/e2e/max/main.test.bicep index e2300f1c24..2fa14fcdba 100644 --- a/avm/res/network/local-network-gateway/tests/e2e/max/main.test.bicep +++ b/avm/res/network/local-network-gateway/tests/e2e/max/main.test.bicep @@ -45,43 +45,48 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - localAddressPrefixes: [ - '192.168.1.0/24' - ] - localGatewayPublicIpAddress: '8.8.8.8' - localAsn: '65123' - localBgpPeeringAddress: '192.168.1.5' - 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' +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' + localAddressPrefixes: [ + '192.168.1.0/24' + ] + localGatewayPublicIpAddress: '8.8.8.8' + localAsn: '65123' + localBgpPeeringAddress: '192.168.1.5' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/network/local-network-gateway/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/local-network-gateway/tests/e2e/waf-aligned/main.test.bicep index 0dacd22889..b2f1caefb6 100644 --- a/avm/res/network/local-network-gateway/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/local-network-gateway/tests/e2e/waf-aligned/main.test.bicep @@ -36,26 +36,28 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - localAddressPrefixes: [ - '192.168.1.0/24' - ] - localGatewayPublicIpAddress: '8.8.8.8' - localAsn: '65123' - localBgpPeeringAddress: '192.168.1.5' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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' + localAddressPrefixes: [ + '192.168.1.0/24' + ] + localGatewayPublicIpAddress: '8.8.8.8' + localAsn: '65123' + localBgpPeeringAddress: '192.168.1.5' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/network/nat-gateway/main.bicep b/avm/res/network/nat-gateway/main.bicep index 0790009605..5dc541069b 100644 --- a/avm/res/network/nat-gateway/main.bicep +++ b/avm/res/network/nat-gateway/main.bicep @@ -40,80 +40,100 @@ 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') + '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') + '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: take('46d3xbcp.res.network-natgateway.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: take( + '46d3xbcp.res.network-natgateway.${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' + } } } } } -} -module publicIPAddresses 'br/public:avm/res/network/public-ip-address:0.2.1' = [for (publicIPAddressObject, index) in (publicIPAddressObjects ?? []): { - name: '${uniqueString(deployment().name, location)}-NatGw-PIP-${index}' - params: { - name: contains(publicIPAddressObject, 'name') ? publicIPAddressObject.name : '${name}-pip' - location: location - lock: publicIPAddressObject.?lock ?? lock - diagnosticSettings: publicIPAddressObject.?diagnosticSettings - publicIPAddressVersion: publicIPAddressObject.?publicIPAddressVersion - publicIPAllocationMethod: 'Static' - publicIpPrefixResourceId: publicIPAddressObject.?publicIPPrefixResourceId - roleAssignments: publicIPAddressObject.?roleAssignments - skuName: 'Standard' // Must be standard - skuTier: publicIPAddressObject.?skuTier - tags: publicIPAddressObject.?tags ?? tags - zones: publicIPAddressObject.?zones - enableTelemetry: publicIPAddressObject.?enableTelemetry ?? enableTelemetry - ddosSettings: publicIPAddressObject.?ddosSettings - dnsSettings: publicIPAddressObject.?dnsSettings - idleTimeoutInMinutes: publicIPAddressObject.?idleTimeoutInMinutes +module publicIPAddresses 'br/public:avm/res/network/public-ip-address:0.2.1' = [ + for (publicIPAddressObject, index) in (publicIPAddressObjects ?? []): { + name: '${uniqueString(deployment().name, location)}-NatGw-PIP-${index}' + params: { + name: contains(publicIPAddressObject, 'name') ? publicIPAddressObject.name : '${name}-pip' + location: location + lock: publicIPAddressObject.?lock ?? lock + diagnosticSettings: publicIPAddressObject.?diagnosticSettings + publicIPAddressVersion: publicIPAddressObject.?publicIPAddressVersion + publicIPAllocationMethod: 'Static' + publicIpPrefixResourceId: publicIPAddressObject.?publicIPPrefixResourceId + roleAssignments: publicIPAddressObject.?roleAssignments + skuName: 'Standard' // Must be standard + skuTier: publicIPAddressObject.?skuTier + tags: publicIPAddressObject.?tags ?? tags + zones: publicIPAddressObject.?zones + enableTelemetry: publicIPAddressObject.?enableTelemetry ?? enableTelemetry + ddosSettings: publicIPAddressObject.?ddosSettings + dnsSettings: publicIPAddressObject.?dnsSettings + idleTimeoutInMinutes: publicIPAddressObject.?idleTimeoutInMinutes + } } -}] +] module formattedPublicIpResourceIds 'modules/formatResourceId.bicep' = { name: 'formattedPublicIpResourceIds' params: { - generatedResourceIds: [for (obj, index) in (publicIPAddressObjects ?? []): publicIPAddresses[index].outputs.resourceId] + generatedResourceIds: [ + for (obj, index) in (publicIPAddressObjects ?? []): publicIPAddresses[index].outputs.resourceId + ] providedResourceIds: publicIpResourceIds } } -module publicIPPrefixes 'br/public:avm/res/network/public-ip-prefix:0.1.0' = [for (publicIPPrefixObject, index) in (publicIPPrefixObjects ?? []): { - name: '${uniqueString(deployment().name, location)}-NatGw-Prefix-PIP-${index}' - params: { - name: contains(publicIPPrefixObject, 'name') ? publicIPPrefixObject.name : '${name}-pip' - location: location - lock: publicIPPrefixObject.?lock ?? lock - prefixLength: publicIPPrefixObject.prefixLength - customIPPrefix: publicIPPrefixObject.?customIPPrefix - roleAssignments: publicIPPrefixObject.?roleAssignments - tags: publicIPPrefixObject.?tags ?? tags - enableTelemetry: publicIPPrefixObject.?enableTelemetry ?? enableTelemetry +module publicIPPrefixes 'br/public:avm/res/network/public-ip-prefix:0.1.0' = [ + for (publicIPPrefixObject, index) in (publicIPPrefixObjects ?? []): { + name: '${uniqueString(deployment().name, location)}-NatGw-Prefix-PIP-${index}' + params: { + name: contains(publicIPPrefixObject, 'name') ? publicIPPrefixObject.name : '${name}-pip' + location: location + lock: publicIPPrefixObject.?lock ?? lock + prefixLength: publicIPPrefixObject.prefixLength + customIPPrefix: publicIPPrefixObject.?customIPPrefix + roleAssignments: publicIPPrefixObject.?roleAssignments + tags: publicIPPrefixObject.?tags ?? tags + enableTelemetry: publicIPPrefixObject.?enableTelemetry ?? enableTelemetry + } } -}] +] module formattedPublicIpPrefixResourceIds 'modules/formatResourceId.bicep' = { name: 'formattedPublicIpPrefixResourceIds' params: { - generatedResourceIds: [for (obj, index) in (publicIPPrefixObjects ?? []): publicIPPrefixes[index].outputs.resourceId] + generatedResourceIds: [ + for (obj, index) in (publicIPPrefixObjects ?? []): publicIPPrefixes[index].outputs.resourceId + ] providedResourceIds: publicIPPrefixResourceIds - } } @@ -134,28 +154,37 @@ resource natGateway 'Microsoft.Network/natGateways@2023-04-01' = { zones: zones } -resource natGateway_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.' +resource natGateway_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: natGateway } - scope: natGateway -} -resource natGateway_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(natGateway.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 +resource natGateway_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(natGateway.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: natGateway } - scope: natGateway -}] +] @description('The name of the NAT Gateway.') output name string = natGateway.name diff --git a/avm/res/network/nat-gateway/main.json b/avm/res/network/nat-gateway/main.json index 73b0856160..7ef467d769 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.25.53.49325", - "templateHash": "6217805544789578668" + "version": "0.26.54.24096", + "templateHash": "2169153798099388966" }, "name": "NAT Gateways", "description": "This module deploys a NAT Gateway.", @@ -923,8 +923,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7172917838055782951" + "version": "0.26.54.24096", + "templateHash": "12157242384503109818" } }, "parameters": { @@ -1301,8 +1301,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7172917838055782951" + "version": "0.26.54.24096", + "templateHash": "12157242384503109818" } }, "parameters": { diff --git a/avm/res/network/nat-gateway/tests/e2e/defaults/main.test.bicep b/avm/res/network/nat-gateway/tests/e2e/defaults/main.test.bicep index 911d92d36f..13f80bf394 100644 --- a/avm/res/network/nat-gateway/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/nat-gateway/tests/e2e/defaults/main.test.bicep @@ -38,12 +38,14 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - // You parameters go here - location: resourceLocation - name: '${namePrefix}${serviceShort}001' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + // You parameters go here + location: resourceLocation + name: '${namePrefix}${serviceShort}001' + } } -}] +] diff --git a/avm/res/network/nat-gateway/tests/e2e/max/dependencies.bicep b/avm/res/network/nat-gateway/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/network/nat-gateway/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/nat-gateway/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/network/nat-gateway/tests/e2e/max/main.test.bicep b/avm/res/network/nat-gateway/tests/e2e/max/main.test.bicep index 7f859e396b..8724d4d789 100644 --- a/avm/res/network/nat-gateway/tests/e2e/max/main.test.bicep +++ b/avm/res/network/nat-gateway/tests/e2e/max/main.test.bicep @@ -59,79 +59,87 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - publicIPAddressObjects: [ - { - name: '${namePrefix}${serviceShort}001-pip' - 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' - } - ] - skuTier: 'Regional' - zones: [ - '1' - '2' - '3' - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - 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' +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' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + publicIPAddressObjects: [ + { + name: '${namePrefix}${serviceShort}001-pip' + 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' + } + ] + skuTier: 'Regional' + zones: [ + '1' + '2' + '3' + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + 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' + } + ] + 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/network/nat-gateway/tests/e2e/prefixCombined/main.test.bicep b/avm/res/network/nat-gateway/tests/e2e/prefixCombined/main.test.bicep index 8680b7934d..e92a1f57f8 100644 --- a/avm/res/network/nat-gateway/tests/e2e/prefixCombined/main.test.bicep +++ b/avm/res/network/nat-gateway/tests/e2e/prefixCombined/main.test.bicep @@ -36,20 +36,22 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - publicIPPrefixObjects: [ - { - name: '${namePrefix}${serviceShort}001-pippre' - prefixLength: 30 - tags: { - 'hidden-title': 'CustomTag' +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' + publicIPPrefixObjects: [ + { + name: '${namePrefix}${serviceShort}001-pippre' + prefixLength: 30 + tags: { + 'hidden-title': 'CustomTag' + } } - } - ] + ] + } } -}] +] diff --git a/avm/res/network/nat-gateway/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/nat-gateway/tests/e2e/waf-aligned/main.test.bicep index 710a0de739..e6097bdc39 100644 --- a/avm/res/network/nat-gateway/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/nat-gateway/tests/e2e/waf-aligned/main.test.bicep @@ -50,45 +50,47 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - publicIPAddressObjects: [ - { - name: '${namePrefix}${serviceShort}001-pip' - skuTier: 'Regional' - zones: [ - '1' - '2' - '3' - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] +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' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + publicIPAddressObjects: [ + { + name: '${namePrefix}${serviceShort}001-pip' + skuTier: 'Regional' + zones: [ + '1' + '2' + '3' + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/network/network-interface/main.bicep b/avm/res/network/network-interface/main.bicep index 9a7e7cd809..eb33ce7459 100644 --- a/avm/res/network/network-interface/main.bicep +++ b/avm/res/network/network-interface/main.bicep @@ -65,32 +65,48 @@ param diagnosticSettings diagnosticSettingType var 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') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'DNS Resolver Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d' + ) + 'DNS Zone Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'befefa01-2a29-4197-83a8-272ff33ce314' + ) + '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') + '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') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.network-networkinterface.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-networkinterface.${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 networkInterface 'Microsoft.Network/networkInterfaces@2023-04-01' = { name: name @@ -100,78 +116,119 @@ resource networkInterface 'Microsoft.Network/networkInterfaces@2023-04-01' = { auxiliaryMode: auxiliaryMode auxiliarySku: auxiliarySku disableTcpStateTracking: disableTcpStateTracking - dnsSettings: !empty(dnsServers) ? { - dnsServers: dnsServers - } : null + dnsSettings: !empty(dnsServers) + ? { + dnsServers: dnsServers + } + : null enableAcceleratedNetworking: enableAcceleratedNetworking enableIPForwarding: enableIPForwarding - networkSecurityGroup: !empty(networkSecurityGroupResourceId) ? { - id: networkSecurityGroupResourceId - } : null - ipConfigurations: [for (ipConfiguration, index) in ipConfigurations: { - name: contains(ipConfiguration, 'name') ? ipConfiguration.name : 'ipconfig0${index + 1}' - properties: { - primary: index == 0 ? true : false - privateIPAllocationMethod: contains(ipConfiguration, 'privateIPAllocationMethod') ? (!empty(ipConfiguration.privateIPAllocationMethod) ? ipConfiguration.privateIPAllocationMethod : null) : null - privateIPAddress: contains(ipConfiguration, 'privateIPAddress') ? (!empty(ipConfiguration.privateIPAddress) ? ipConfiguration.privateIPAddress : null) : null - publicIPAddress: contains(ipConfiguration, 'publicIPAddressResourceId') ? (ipConfiguration.publicIPAddressResourceId != null ? { - id: ipConfiguration.publicIPAddressResourceId - } : null) : null - subnet: { - id: ipConfiguration.subnetResourceId + networkSecurityGroup: !empty(networkSecurityGroupResourceId) + ? { + id: networkSecurityGroupResourceId + } + : null + ipConfigurations: [ + for (ipConfiguration, index) in ipConfigurations: { + name: contains(ipConfiguration, 'name') ? ipConfiguration.name : 'ipconfig0${index + 1}' + properties: { + primary: index == 0 ? true : false + privateIPAllocationMethod: contains(ipConfiguration, 'privateIPAllocationMethod') + ? (!empty(ipConfiguration.privateIPAllocationMethod) ? ipConfiguration.privateIPAllocationMethod : null) + : null + privateIPAddress: contains(ipConfiguration, 'privateIPAddress') + ? (!empty(ipConfiguration.privateIPAddress) ? ipConfiguration.privateIPAddress : null) + : null + publicIPAddress: contains(ipConfiguration, 'publicIPAddressResourceId') + ? (ipConfiguration.publicIPAddressResourceId != null + ? { + id: ipConfiguration.publicIPAddressResourceId + } + : null) + : null + subnet: { + id: ipConfiguration.subnetResourceId + } + loadBalancerBackendAddressPools: contains(ipConfiguration, 'loadBalancerBackendAddressPools') + ? ipConfiguration.loadBalancerBackendAddressPools + : null + applicationSecurityGroups: contains(ipConfiguration, 'applicationSecurityGroups') + ? ipConfiguration.applicationSecurityGroups + : null + applicationGatewayBackendAddressPools: contains(ipConfiguration, 'applicationGatewayBackendAddressPools') + ? ipConfiguration.applicationGatewayBackendAddressPools + : null + gatewayLoadBalancer: contains(ipConfiguration, 'gatewayLoadBalancer') + ? ipConfiguration.gatewayLoadBalancer + : null + loadBalancerInboundNatRules: contains(ipConfiguration, 'loadBalancerInboundNatRules') + ? ipConfiguration.loadBalancerInboundNatRules + : null + privateIPAddressVersion: contains(ipConfiguration, 'privateIPAddressVersion') + ? ipConfiguration.privateIPAddressVersion + : null + virtualNetworkTaps: contains(ipConfiguration, 'virtualNetworkTaps') + ? ipConfiguration.virtualNetworkTaps + : null } - loadBalancerBackendAddressPools: contains(ipConfiguration, 'loadBalancerBackendAddressPools') ? ipConfiguration.loadBalancerBackendAddressPools : null - applicationSecurityGroups: contains(ipConfiguration, 'applicationSecurityGroups') ? ipConfiguration.applicationSecurityGroups : null - applicationGatewayBackendAddressPools: contains(ipConfiguration, 'applicationGatewayBackendAddressPools') ? ipConfiguration.applicationGatewayBackendAddressPools : null - gatewayLoadBalancer: contains(ipConfiguration, 'gatewayLoadBalancer') ? ipConfiguration.gatewayLoadBalancer : null - loadBalancerInboundNatRules: contains(ipConfiguration, 'loadBalancerInboundNatRules') ? ipConfiguration.loadBalancerInboundNatRules : null - privateIPAddressVersion: contains(ipConfiguration, 'privateIPAddressVersion') ? ipConfiguration.privateIPAddressVersion : null - virtualNetworkTaps: contains(ipConfiguration, 'virtualNetworkTaps') ? ipConfiguration.virtualNetworkTaps : null } - }] + ] } } -resource networkInterface_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.' +resource networkInterface_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: networkInterface } - scope: networkInterface -} -resource networkInterface_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 - metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { - category: group.category - enabled: group.?enabled ?? true - timeGrain: null - }] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType +resource networkInterface_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 + metrics: [ + for group in (diagnosticSetting.?metricCategories ?? [{ category: 'AllMetrics' }]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: networkInterface } - scope: networkInterface -}] - -resource networkInterface_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(networkInterface.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 +] + +resource networkInterface_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(networkInterface.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: networkInterface } - scope: networkInterface -}] +] // =========== // // Outputs // diff --git a/avm/res/network/network-interface/main.json b/avm/res/network/network-interface/main.json index 75c70024f7..6854045337 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.25.53.49325", - "templateHash": "6823101790014877132" + "version": "0.26.54.24096", + "templateHash": "2895286572225870929" }, "name": "Network Interface", "description": "This module deploys a Network Interface.", diff --git a/avm/res/network/network-interface/tests/e2e/defaults/main.test.bicep b/avm/res/network/network-interface/tests/e2e/defaults/main.test.bicep index e0df5a7930..eb4bb2e19a 100644 --- a/avm/res/network/network-interface/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/network-interface/tests/e2e/defaults/main.test.bicep @@ -45,20 +45,22 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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: 'ipconfig01' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } +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: 'ipconfig01' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + } + dependsOn: [ + nestedDependencies ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/network-interface/tests/e2e/max/main.test.bicep b/avm/res/network/network-interface/tests/e2e/max/main.test.bicep index bc599c8317..fd2dd9578f 100644 --- a/avm/res/network/network-interface/tests/e2e/max/main.test.bicep +++ b/avm/res/network/network-interface/tests/e2e/max/main.test.bicep @@ -62,74 +62,79 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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: [ - { - applicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } - ] - loadBalancerBackendAddressPools: [ - { - id: nestedDependencies.outputs.loadBalancerBackendPoolResourceId - } - ] - name: 'ipconfig01' - subnetResourceId: nestedDependencies.outputs.subnetResourceId +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: [ + { + applicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + loadBalancerBackendAddressPools: [ + { + id: nestedDependencies.outputs.loadBalancerBackendPoolResourceId + } + ] + name: 'ipconfig01' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + applicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - applicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } - ] - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - 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' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - 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' - } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/network-interface/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/network-interface/tests/e2e/waf-aligned/main.test.bicep index 90fb9c34d2..68fcd0f904 100644 --- a/avm/res/network/network-interface/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/network-interface/tests/e2e/waf-aligned/main.test.bicep @@ -61,53 +61,55 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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: [ - { - applicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } - ] - loadBalancerBackendAddressPools: [ - { - id: nestedDependencies.outputs.loadBalancerBackendPoolResourceId - } - ] - name: 'ipconfig01' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - applicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } - ] +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: [ + { + applicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + loadBalancerBackendAddressPools: [ + { + id: nestedDependencies.outputs.loadBalancerBackendPoolResourceId + } + ] + name: 'ipconfig01' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + applicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + 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' } - ] - diagnosticSettings: [ - { - name: 'customSetting' - 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' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/network-manager/connectivity-configuration/main.json b/avm/res/network/network-manager/connectivity-configuration/main.json index 380332c668..52db1d0faa 100644 --- a/avm/res/network/network-manager/connectivity-configuration/main.json +++ b/avm/res/network/network-manager/connectivity-configuration/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16868761662321894920" + "version": "0.26.54.24096", + "templateHash": "3569964888966454016" }, "name": "Network Manager Connectivity Configurations", "description": "This module deploys a Network Manager Connectivity Configuration.\nConnectivity configurations define hub-and-spoke or mesh topologies applied to one or more network groups.", diff --git a/avm/res/network/network-manager/main.bicep b/avm/res/network/network-manager/main.bicep index 21b3090ac4..e01ce22fe4 100644 --- a/avm/res/network/network-manager/main.bicep +++ b/avm/res/network/network-manager/main.bicep @@ -46,33 +46,52 @@ 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') - 'LocalNGFirewallAdministrator role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'IPAM Pool Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7b3e853f-ad5d-4fb5-a7b8-56a3581c7037' + ) + 'LocalNGFirewallAdministrator role': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2' + ) + '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') - 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') - '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 Policy Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '36243c78-bf99-498c-9df9-86d9f8d28608' + ) + '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-networkmanager.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-networkmanager.${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 networkManager 'Microsoft.Network/networkManagers@2023-04-01' = { name: name @@ -85,76 +104,95 @@ resource networkManager 'Microsoft.Network/networkManagers@2023-04-01' = { } } -module networkManager_networkGroups 'network-group/main.bicep' = [for (networkGroup, index) in networkGroups: { - name: '${uniqueString(deployment().name, location)}-NetworkManager-NetworkGroups-${index}' - params: { - name: networkGroup.name - networkManagerName: networkManager.name - description: contains(networkGroup, 'description') ? networkGroup.description : '' - staticMembers: contains(networkGroup, 'staticMembers') ? networkGroup.staticMembers : [] +module networkManager_networkGroups 'network-group/main.bicep' = [ + for (networkGroup, index) in networkGroups: { + name: '${uniqueString(deployment().name, location)}-NetworkManager-NetworkGroups-${index}' + params: { + name: networkGroup.name + networkManagerName: networkManager.name + description: contains(networkGroup, 'description') ? networkGroup.description : '' + staticMembers: contains(networkGroup, 'staticMembers') ? networkGroup.staticMembers : [] + } } -}] - -module networkManager_connectivityConfigurations 'connectivity-configuration/main.bicep' = [for (connectivityConfiguration, index) in connectivityConfigurations: { - name: '${uniqueString(deployment().name, location)}-NetworkManager-ConnectivityConfigurations-${index}' - params: { - name: connectivityConfiguration.name - networkManagerName: networkManager.name - description: contains(connectivityConfiguration, 'description') ? connectivityConfiguration.description : '' - appliesToGroups: connectivityConfiguration.appliesToGroups - connectivityTopology: connectivityConfiguration.connectivityTopology - hubs: contains(connectivityConfiguration, 'hubs') ? connectivityConfiguration.hubs : [] - deleteExistingPeering: contains(connectivityConfiguration, 'hubs') && (connectivityConfiguration.connectivityTopology == 'HubAndSpoke') ? connectivityConfiguration.deleteExistingPeering : 'False' - isGlobal: contains(connectivityConfiguration, 'isGlobal') ? connectivityConfiguration.isGlobal : 'False' +] + +module networkManager_connectivityConfigurations 'connectivity-configuration/main.bicep' = [ + for (connectivityConfiguration, index) in connectivityConfigurations: { + name: '${uniqueString(deployment().name, location)}-NetworkManager-ConnectivityConfigurations-${index}' + params: { + name: connectivityConfiguration.name + networkManagerName: networkManager.name + description: contains(connectivityConfiguration, 'description') ? connectivityConfiguration.description : '' + appliesToGroups: connectivityConfiguration.appliesToGroups + connectivityTopology: connectivityConfiguration.connectivityTopology + hubs: contains(connectivityConfiguration, 'hubs') ? connectivityConfiguration.hubs : [] + deleteExistingPeering: contains(connectivityConfiguration, 'hubs') && (connectivityConfiguration.connectivityTopology == 'HubAndSpoke') + ? connectivityConfiguration.deleteExistingPeering + : 'False' + isGlobal: contains(connectivityConfiguration, 'isGlobal') ? connectivityConfiguration.isGlobal : 'False' + } + dependsOn: networkManager_networkGroups } - dependsOn: networkManager_networkGroups -}] - -module networkManager_scopeConnections 'scope-connection/main.bicep' = [for (scopeConnection, index) in scopeConnections: { - name: '${uniqueString(deployment().name, location)}-NetworkManager-ScopeConnections-${index}' - params: { - name: scopeConnection.name - networkManagerName: networkManager.name - description: scopeConnection.?description - resourceId: scopeConnection.resourceId - tenantId: scopeConnection.tenantId +] + +module networkManager_scopeConnections 'scope-connection/main.bicep' = [ + for (scopeConnection, index) in scopeConnections: { + name: '${uniqueString(deployment().name, location)}-NetworkManager-ScopeConnections-${index}' + params: { + name: scopeConnection.name + networkManagerName: networkManager.name + description: scopeConnection.?description + resourceId: scopeConnection.resourceId + tenantId: scopeConnection.tenantId + } } -}] - -module networkManager_securityAdminConfigurations 'security-admin-configuration/main.bicep' = [for (securityAdminConfiguration, index) in securityAdminConfigurations: { - name: '${uniqueString(deployment().name, location)}-NetworkManager-SecurityAdminConfigurations-${index}' - params: { - name: securityAdminConfiguration.name - networkManagerName: networkManager.name - description: securityAdminConfiguration.?description - applyOnNetworkIntentPolicyBasedServices: securityAdminConfiguration.applyOnNetworkIntentPolicyBasedServices - ruleCollections: securityAdminConfiguration.?ruleCollections +] + +module networkManager_securityAdminConfigurations 'security-admin-configuration/main.bicep' = [ + for (securityAdminConfiguration, index) in securityAdminConfigurations: { + name: '${uniqueString(deployment().name, location)}-NetworkManager-SecurityAdminConfigurations-${index}' + params: { + name: securityAdminConfiguration.name + networkManagerName: networkManager.name + description: securityAdminConfiguration.?description + applyOnNetworkIntentPolicyBasedServices: securityAdminConfiguration.applyOnNetworkIntentPolicyBasedServices + ruleCollections: securityAdminConfiguration.?ruleCollections + } + dependsOn: networkManager_networkGroups } - dependsOn: networkManager_networkGroups -}] - -resource networkManager_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.' +] + +resource networkManager_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: networkManager } - scope: networkManager -} -resource networkManager_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(networkManager.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 +resource networkManager_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(networkManager.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: networkManager } - scope: networkManager -}] +] @sys.description('The resource group the network manager was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/network-manager/main.json b/avm/res/network/network-manager/main.json index f5f2ad12ec..f2e598cb60 100644 --- a/avm/res/network/network-manager/main.json +++ b/avm/res/network/network-manager/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "9720522527868870534" + "version": "0.26.54.24096", + "templateHash": "9790133647197956266" }, "name": "Network Managers", "description": "This module deploys a Network Manager.", @@ -307,8 +307,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6814363898116827751" + "version": "0.26.54.24096", + "templateHash": "4214103423142628663" }, "name": "Network Manager Network Groups", "description": "This module deploys a Network Manager Network Group.\nA network group is a collection of same-type network resources that you can associate with network manager configurations. You can add same-type network resources after you create the network group.", @@ -386,8 +386,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8599408258770736969" + "version": "0.26.54.24096", + "templateHash": "6637396315337813947" }, "name": "Network Manager Network Group Static Members", "description": "This module deploys a Network Manager Network Group Static Member.\nStatic membership allows you to explicitly add virtual networks to a group by manually selecting individual virtual networks.", @@ -525,8 +525,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16868761662321894920" + "version": "0.26.54.24096", + "templateHash": "3569964888966454016" }, "name": "Network Manager Connectivity Configurations", "description": "This module deploys a Network Manager Connectivity Configuration.\nConnectivity configurations define hub-and-spoke or mesh topologies applied to one or more network groups.", @@ -682,8 +682,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16681369558452798358" + "version": "0.26.54.24096", + "templateHash": "8767540456657043434" }, "name": "Network Manager Scope Connections", "description": "This module deploys a Network Manager Scope Connection.\nCreate a cross-tenant connection to manage a resource from another tenant.", @@ -801,8 +801,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7700094852777954431" + "version": "0.26.54.24096", + "templateHash": "254507184583897429" }, "name": "Network Manager Security Admin Configurations", "description": "This module deploys an Network Manager Security Admin Configuration.\nA security admin configuration contains a set of rule collections. Each rule collection contains one or more security admin rules.", @@ -896,8 +896,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6205777935004784732" + "version": "0.26.54.24096", + "templateHash": "14135307535635501181" }, "name": "Network Manager Security Admin Configuration Rule Collections", "description": "This module deploys an Network Manager Security Admin Configuration Rule Collection.\nA security admin configuration contains a set of rule collections. Each rule collection contains one or more security admin rules. Security admin rules allows enforcing security policy criteria that matches the conditions set. Warning: A rule collection without rule will cause a deployment configuration for security admin goal state in network manager to fail.", @@ -1004,8 +1004,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4678937950332023656" + "version": "0.26.54.24096", + "templateHash": "3477492114570114110" }, "name": "Network Manager Security Admin Configuration Rule Collection Rules", "description": "This module deploys an Azure Virtual Network Manager (AVNM) Security Admin Configuration Rule Collection Rule.\nA security admin configuration contains a set of rule collections. Each rule collection contains one or more security admin rules.", diff --git a/avm/res/network/network-manager/network-group/main.bicep b/avm/res/network/network-manager/network-group/main.bicep index f3540354dd..83ae24b489 100644 --- a/avm/res/network/network-manager/network-group/main.bicep +++ b/avm/res/network/network-manager/network-group/main.bicep @@ -29,15 +29,17 @@ resource networkGroup 'Microsoft.Network/networkManagers/networkGroups@2023-04-0 } } -module networkGroup_staticMembers 'static-member/main.bicep' = [for (staticMember, index) in staticMembers: { - name: '${uniqueString(deployment().name)}-NetworkGroup-StaticMembers-${index}' - params: { - networkManagerName: networkManager.name - networkGroupName: networkGroup.name - name: staticMember.name - resourceId: staticMember.resourceId +module networkGroup_staticMembers 'static-member/main.bicep' = [ + for (staticMember, index) in staticMembers: { + name: '${uniqueString(deployment().name)}-NetworkGroup-StaticMembers-${index}' + params: { + networkManagerName: networkManager.name + networkGroupName: networkGroup.name + name: staticMember.name + resourceId: staticMember.resourceId + } } -}] +] @sys.description('The name of the deployed network group.') output name string = networkGroup.name diff --git a/avm/res/network/network-manager/network-group/main.json b/avm/res/network/network-manager/network-group/main.json index 1530879d81..97b0f3c631 100644 --- a/avm/res/network/network-manager/network-group/main.json +++ b/avm/res/network/network-manager/network-group/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6814363898116827751" + "version": "0.26.54.24096", + "templateHash": "4214103423142628663" }, "name": "Network Manager Network Groups", "description": "This module deploys a Network Manager Network Group.\nA network group is a collection of same-type network resources that you can associate with network manager configurations. You can add same-type network resources after you create the network group.", @@ -83,8 +83,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8599408258770736969" + "version": "0.26.54.24096", + "templateHash": "6637396315337813947" }, "name": "Network Manager Network Group Static Members", "description": "This module deploys a Network Manager Network Group Static Member.\nStatic membership allows you to explicitly add virtual networks to a group by manually selecting individual virtual networks.", diff --git a/avm/res/network/network-manager/network-group/static-member/main.json b/avm/res/network/network-manager/network-group/static-member/main.json index 6d345d55e4..5bcd72dbb6 100644 --- a/avm/res/network/network-manager/network-group/static-member/main.json +++ b/avm/res/network/network-manager/network-group/static-member/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8599408258770736969" + "version": "0.26.54.24096", + "templateHash": "6637396315337813947" }, "name": "Network Manager Network Group Static Members", "description": "This module deploys a Network Manager Network Group Static Member.\nStatic membership allows you to explicitly add virtual networks to a group by manually selecting individual virtual networks.", diff --git a/avm/res/network/network-manager/scope-connection/main.json b/avm/res/network/network-manager/scope-connection/main.json index a3cd1c3c1d..ec1b947129 100644 --- a/avm/res/network/network-manager/scope-connection/main.json +++ b/avm/res/network/network-manager/scope-connection/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16681369558452798358" + "version": "0.26.54.24096", + "templateHash": "8767540456657043434" }, "name": "Network Manager Scope Connections", "description": "This module deploys a Network Manager Scope Connection.\nCreate a cross-tenant connection to manage a resource from another tenant.", diff --git a/avm/res/network/network-manager/security-admin-configuration/main.bicep b/avm/res/network/network-manager/security-admin-configuration/main.bicep index ee23d8dc66..f18e53140d 100644 --- a/avm/res/network/network-manager/security-admin-configuration/main.bicep +++ b/avm/res/network/network-manager/security-admin-configuration/main.bicep @@ -20,7 +20,7 @@ param description string = '' 'AllowRulesOnly' ]) @sys.description('Required. Enum list of network intent policy based services.') -param applyOnNetworkIntentPolicyBasedServices array = [ 'None' ] +param applyOnNetworkIntentPolicyBasedServices array = ['None'] @sys.description('Optional. A security admin configuration contains a set of rule collections that are applied to network groups. Each rule collection contains one or more security admin rules.') param ruleCollections array = [] @@ -38,16 +38,18 @@ resource securityAdminConfigurations 'Microsoft.Network/networkManagers/security } } -module securityAdminConfigurations_ruleCollections 'rule-collection/main.bicep' = [for (ruleCollection, index) in ruleCollections: { - name: '${uniqueString(deployment().name)}-SecurityAdminConfigurations-RuleCollections-${index}' - params: { - networkManagerName: networkManager.name - securityAdminConfigurationName: securityAdminConfigurations.name - name: ruleCollection.name - appliesToGroups: ruleCollection.appliesToGroups - rules: contains(ruleCollection, 'rules') ? ruleCollection.rules : [] +module securityAdminConfigurations_ruleCollections 'rule-collection/main.bicep' = [ + for (ruleCollection, index) in ruleCollections: { + name: '${uniqueString(deployment().name)}-SecurityAdminConfigurations-RuleCollections-${index}' + params: { + networkManagerName: networkManager.name + securityAdminConfigurationName: securityAdminConfigurations.name + name: ruleCollection.name + appliesToGroups: ruleCollection.appliesToGroups + rules: contains(ruleCollection, 'rules') ? ruleCollection.rules : [] + } } -}] +] @sys.description('The name of the deployed security admin configuration.') output name string = securityAdminConfigurations.name diff --git a/avm/res/network/network-manager/security-admin-configuration/main.json b/avm/res/network/network-manager/security-admin-configuration/main.json index ae70ce5dd7..a81e94c390 100644 --- a/avm/res/network/network-manager/security-admin-configuration/main.json +++ b/avm/res/network/network-manager/security-admin-configuration/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7700094852777954431" + "version": "0.26.54.24096", + "templateHash": "254507184583897429" }, "name": "Network Manager Security Admin Configurations", "description": "This module deploys an Network Manager Security Admin Configuration.\nA security admin configuration contains a set of rule collections. Each rule collection contains one or more security admin rules.", @@ -99,8 +99,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6205777935004784732" + "version": "0.26.54.24096", + "templateHash": "14135307535635501181" }, "name": "Network Manager Security Admin Configuration Rule Collections", "description": "This module deploys an Network Manager Security Admin Configuration Rule Collection.\nA security admin configuration contains a set of rule collections. Each rule collection contains one or more security admin rules. Security admin rules allows enforcing security policy criteria that matches the conditions set. Warning: A rule collection without rule will cause a deployment configuration for security admin goal state in network manager to fail.", @@ -207,8 +207,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4678937950332023656" + "version": "0.26.54.24096", + "templateHash": "3477492114570114110" }, "name": "Network Manager Security Admin Configuration Rule Collection Rules", "description": "This module deploys an Azure Virtual Network Manager (AVNM) Security Admin Configuration Rule Collection Rule.\nA security admin configuration contains a set of rule collections. Each rule collection contains one or more security admin rules.", diff --git a/avm/res/network/network-manager/security-admin-configuration/rule-collection/main.bicep b/avm/res/network/network-manager/security-admin-configuration/rule-collection/main.bicep index c248ef811a..0d46003890 100644 --- a/avm/res/network/network-manager/security-admin-configuration/rule-collection/main.bicep +++ b/avm/res/network/network-manager/security-admin-configuration/rule-collection/main.bicep @@ -40,24 +40,26 @@ resource ruleCollection 'Microsoft.Network/networkManagers/securityAdminConfigur } } -module securityAdminConfigurations_rules 'rule/main.bicep' = [for (rule, index) in rules: { - name: '${uniqueString(deployment().name)}-RuleCollections-Rules-${index}' - params: { - networkManagerName: networkManager.name - securityAdminConfigurationName: securityAdminConfigurationName - ruleCollectionName: ruleCollection.name - name: rule.name - access: rule.access - description: contains(rule, 'description') ? rule.description : '' - destinationPortRanges: contains(rule, 'destinationPortRanges') ? rule.destinationPortRanges : [] - destinations: contains(rule, 'destinations') ? rule.destinations : [] - direction: rule.direction - priority: rule.priority - protocol: rule.protocol - sourcePortRanges: contains(rule, 'sourcePortRanges') ? rule.sourcePortRanges : [] - sources: contains(rule, 'sources') ? rule.sources : [] +module securityAdminConfigurations_rules 'rule/main.bicep' = [ + for (rule, index) in rules: { + name: '${uniqueString(deployment().name)}-RuleCollections-Rules-${index}' + params: { + networkManagerName: networkManager.name + securityAdminConfigurationName: securityAdminConfigurationName + ruleCollectionName: ruleCollection.name + name: rule.name + access: rule.access + description: contains(rule, 'description') ? rule.description : '' + destinationPortRanges: contains(rule, 'destinationPortRanges') ? rule.destinationPortRanges : [] + destinations: contains(rule, 'destinations') ? rule.destinations : [] + direction: rule.direction + priority: rule.priority + protocol: rule.protocol + sourcePortRanges: contains(rule, 'sourcePortRanges') ? rule.sourcePortRanges : [] + sources: contains(rule, 'sources') ? rule.sources : [] + } } -}] +] @sys.description('The name of the deployed admin rule collection.') output name string = ruleCollection.name diff --git a/avm/res/network/network-manager/security-admin-configuration/rule-collection/main.json b/avm/res/network/network-manager/security-admin-configuration/rule-collection/main.json index 3307d5b494..2c2b95d8c0 100644 --- a/avm/res/network/network-manager/security-admin-configuration/rule-collection/main.json +++ b/avm/res/network/network-manager/security-admin-configuration/rule-collection/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6205777935004784732" + "version": "0.26.54.24096", + "templateHash": "14135307535635501181" }, "name": "Network Manager Security Admin Configuration Rule Collections", "description": "This module deploys an Network Manager Security Admin Configuration Rule Collection.\nA security admin configuration contains a set of rule collections. Each rule collection contains one or more security admin rules. Security admin rules allows enforcing security policy criteria that matches the conditions set. Warning: A rule collection without rule will cause a deployment configuration for security admin goal state in network manager to fail.", @@ -112,8 +112,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4678937950332023656" + "version": "0.26.54.24096", + "templateHash": "3477492114570114110" }, "name": "Network Manager Security Admin Configuration Rule Collection Rules", "description": "This module deploys an Azure Virtual Network Manager (AVNM) Security Admin Configuration Rule Collection Rule.\nA security admin configuration contains a set of rule collections. Each rule collection contains one or more security admin rules.", diff --git a/avm/res/network/network-manager/security-admin-configuration/rule-collection/rule/main.json b/avm/res/network/network-manager/security-admin-configuration/rule-collection/rule/main.json index 83f21a1945..c45d77c10f 100644 --- a/avm/res/network/network-manager/security-admin-configuration/rule-collection/rule/main.json +++ b/avm/res/network/network-manager/security-admin-configuration/rule-collection/rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4678937950332023656" + "version": "0.26.54.24096", + "templateHash": "3477492114570114110" }, "name": "Network Manager Security Admin Configuration Rule Collection Rules", "description": "This module deploys an Azure Virtual Network Manager (AVNM) Security Admin Configuration Rule Collection Rule.\nA security admin configuration contains a set of rule collections. Each rule collection contains one or more security admin rules.", diff --git a/avm/res/network/network-manager/tests/e2e/defaults/main.test.bicep b/avm/res/network/network-manager/tests/e2e/defaults/main.test.bicep index e7494fcccd..ed65356e84 100644 --- a/avm/res/network/network-manager/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/network-manager/tests/e2e/defaults/main.test.bicep @@ -36,19 +36,21 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - networkManagerScopeAccesses: [ - 'Connectivity' - ] - networkManagerScopes: { - subscriptions: [ - subscription().id +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 + networkManagerScopeAccesses: [ + 'Connectivity' ] + networkManagerScopes: { + subscriptions: [ + subscription().id + ] + } } } -}] +] diff --git a/avm/res/network/network-manager/tests/e2e/max/main.test.bicep b/avm/res/network/network-manager/tests/e2e/max/main.test.bicep index d6a524f1ba..2c1ebd6b50 100644 --- a/avm/res/network/network-manager/tests/e2e/max/main.test.bicep +++ b/avm/res/network/network-manager/tests/e2e/max/main.test.bicep @@ -51,217 +51,222 @@ var networkManagerName = '${namePrefix}${serviceShort}001' var networkManagerExpecetedResourceID = '${resourceGroup.id}/providers/Microsoft.Network/networkManagers/${networkManagerName}' @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: networkManagerName - location: resourceLocation - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: networkManagerName + location: resourceLocation + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - 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' - } - ] - networkManagerScopeAccesses: [ - 'Connectivity' - 'SecurityAdmin' - ] - networkManagerScopes: { - managementGroups: [ - // Note: Required the `Microsoft.Network` provider to be registered at management group level via `az provider register --namespace Microsoft.Network -m ''` - '/providers/Microsoft.Management/managementGroups/#_managementGroupId_#' + 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' + } ] - } - networkGroups: [ - { - name: 'network-group-spokes' - description: 'network-group-spokes description' - staticMembers: [ - { - name: 'virtualNetworkSpoke1' - resourceId: nestedDependencies.outputs.virtualNetworkSpoke1Id - } - { - name: 'virtualNetworkSpoke2' - resourceId: nestedDependencies.outputs.virtualNetworkSpoke2Id - } - ] - } - ] - connectivityConfigurations: [ - { - name: 'hubSpokeConnectivity' - description: 'hubSpokeConnectivity description' - connectivityTopology: 'HubAndSpoke' - hubs: [ - { - resourceId: nestedDependencies.outputs.virtualNetworkHubId - resourceType: 'Microsoft.Network/virtualNetworks' - } - ] - deleteExistingPeering: 'True' - isGlobal: 'True' - appliesToGroups: [ - { - networkGroupId: '${networkManagerExpecetedResourceID}/networkGroups/network-group-spokes' - useHubGateway: 'False' - groupConnectivity: 'None' - isGlobal: 'False' - } - ] - } - { - name: 'MeshConnectivity' - description: 'MeshConnectivity description' - connectivityTopology: 'Mesh' - deleteExistingPeering: 'True' - isGlobal: 'True' - appliesToGroups: [ - { - networkGroupId: '${networkManagerExpecetedResourceID}/networkGroups/network-group-spokes' - useHubGateway: 'False' - groupConnectivity: 'None' - isGlobal: 'False' - } + networkManagerScopeAccesses: [ + 'Connectivity' + 'SecurityAdmin' + ] + networkManagerScopes: { + managementGroups: [ + // Note: Required the `Microsoft.Network` provider to be registered at management group level via `az provider register --namespace Microsoft.Network -m ''` + '/providers/Microsoft.Management/managementGroups/#_managementGroupId_#' ] } - ] - scopeConnections: [ - { - name: 'scope-connection-test' - description: 'description of the scope connection' - resourceId: subscription().id - tenantid: tenant().tenantId - } - ] - securityAdminConfigurations: [ - { - name: 'test-security-admin-config' - description: 'description of the security admin config' - applyOnNetworkIntentPolicyBasedServices: [ - 'AllowRulesOnly' - ] - ruleCollections: [ - { - name: 'test-rule-collection-1' - description: 'test-rule-collection-description' - appliesToGroups: [ - { - networkGroupId: '${networkManagerExpecetedResourceID}/networkGroups/network-group-spokes' - } - ] - rules: [ - { - name: 'test-inbound-allow-rule-1' - description: 'test-inbound-allow-rule-1-description' - access: 'Allow' - direction: 'Inbound' - priority: 150 - protocol: 'Tcp' - } - { - name: 'test-outbound-deny-rule-2' - description: 'test-outbound-deny-rule-2-description' - access: 'Deny' - direction: 'Outbound' - priority: 200 - protocol: 'Tcp' - sourcePortRanges: [ - '80' - '442-445' - ] - sources: [ - { - addressPrefix: 'AppService.WestEurope' - addressPrefixType: 'ServiceTag' - } - ] - } - ] - } - { - name: 'test-rule-collection-2' - description: 'test-rule-collection-description' - appliesToGroups: [ - { - networkGroupId: '${networkManagerExpecetedResourceID}/networkGroups/network-group-spokes' - } - ] - rules: [ - { - name: 'test-inbound-allow-rule-3' - description: 'test-inbound-allow-rule-3-description' - access: 'Allow' - direction: 'Inbound' - destinationPortRanges: [ - '80' - '442-445' - ] - destinations: [ - { - addressPrefix: '192.168.20.20' - addressPrefixType: 'IPPrefix' - } - ] - priority: 250 - protocol: 'Tcp' - } - { - name: 'test-inbound-allow-rule-4' - description: 'test-inbound-allow-rule-4-description' - access: 'Allow' - direction: 'Inbound' - sources: [ - { - addressPrefix: '10.0.0.0/24' - addressPrefixType: 'IPPrefix' - } - { - addressPrefix: '100.100.100.100' - addressPrefixType: 'IPPrefix' - } - ] - destinations: [ - { - addressPrefix: '172.16.0.0/24' - addressPrefixType: 'IPPrefix' - } - { - addressPrefix: '172.16.1.0/24' - addressPrefixType: 'IPPrefix' - } - ] - priority: 260 - protocol: 'Tcp' - } - ] - } - ] + networkGroups: [ + { + name: 'network-group-spokes' + description: 'network-group-spokes description' + staticMembers: [ + { + name: 'virtualNetworkSpoke1' + resourceId: nestedDependencies.outputs.virtualNetworkSpoke1Id + } + { + name: 'virtualNetworkSpoke2' + resourceId: nestedDependencies.outputs.virtualNetworkSpoke2Id + } + ] + } + ] + connectivityConfigurations: [ + { + name: 'hubSpokeConnectivity' + description: 'hubSpokeConnectivity description' + connectivityTopology: 'HubAndSpoke' + hubs: [ + { + resourceId: nestedDependencies.outputs.virtualNetworkHubId + resourceType: 'Microsoft.Network/virtualNetworks' + } + ] + deleteExistingPeering: 'True' + isGlobal: 'True' + appliesToGroups: [ + { + networkGroupId: '${networkManagerExpecetedResourceID}/networkGroups/network-group-spokes' + useHubGateway: 'False' + groupConnectivity: 'None' + isGlobal: 'False' + } + ] + } + { + name: 'MeshConnectivity' + description: 'MeshConnectivity description' + connectivityTopology: 'Mesh' + deleteExistingPeering: 'True' + isGlobal: 'True' + appliesToGroups: [ + { + networkGroupId: '${networkManagerExpecetedResourceID}/networkGroups/network-group-spokes' + useHubGateway: 'False' + groupConnectivity: 'None' + isGlobal: 'False' + } + ] + } + ] + scopeConnections: [ + { + name: 'scope-connection-test' + description: 'description of the scope connection' + resourceId: subscription().id + tenantid: tenant().tenantId + } + ] + securityAdminConfigurations: [ + { + name: 'test-security-admin-config' + description: 'description of the security admin config' + applyOnNetworkIntentPolicyBasedServices: [ + 'AllowRulesOnly' + ] + ruleCollections: [ + { + name: 'test-rule-collection-1' + description: 'test-rule-collection-description' + appliesToGroups: [ + { + networkGroupId: '${networkManagerExpecetedResourceID}/networkGroups/network-group-spokes' + } + ] + rules: [ + { + name: 'test-inbound-allow-rule-1' + description: 'test-inbound-allow-rule-1-description' + access: 'Allow' + direction: 'Inbound' + priority: 150 + protocol: 'Tcp' + } + { + name: 'test-outbound-deny-rule-2' + description: 'test-outbound-deny-rule-2-description' + access: 'Deny' + direction: 'Outbound' + priority: 200 + protocol: 'Tcp' + sourcePortRanges: [ + '80' + '442-445' + ] + sources: [ + { + addressPrefix: 'AppService.WestEurope' + addressPrefixType: 'ServiceTag' + } + ] + } + ] + } + { + name: 'test-rule-collection-2' + description: 'test-rule-collection-description' + appliesToGroups: [ + { + networkGroupId: '${networkManagerExpecetedResourceID}/networkGroups/network-group-spokes' + } + ] + rules: [ + { + name: 'test-inbound-allow-rule-3' + description: 'test-inbound-allow-rule-3-description' + access: 'Allow' + direction: 'Inbound' + destinationPortRanges: [ + '80' + '442-445' + ] + destinations: [ + { + addressPrefix: '192.168.20.20' + addressPrefixType: 'IPPrefix' + } + ] + priority: 250 + protocol: 'Tcp' + } + { + name: 'test-inbound-allow-rule-4' + description: 'test-inbound-allow-rule-4-description' + access: 'Allow' + direction: 'Inbound' + sources: [ + { + addressPrefix: '10.0.0.0/24' + addressPrefixType: 'IPPrefix' + } + { + addressPrefix: '100.100.100.100' + addressPrefixType: 'IPPrefix' + } + ] + destinations: [ + { + addressPrefix: '172.16.0.0/24' + addressPrefixType: 'IPPrefix' + } + { + addressPrefix: '172.16.1.0/24' + addressPrefixType: 'IPPrefix' + } + ] + priority: 260 + protocol: 'Tcp' + } + ] + } + ] + } + ] + 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' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/network-manager/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/network-manager/tests/e2e/waf-aligned/main.test.bicep index d52a6465e3..1d025f410c 100644 --- a/avm/res/network/network-manager/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/network-manager/tests/e2e/waf-aligned/main.test.bicep @@ -36,24 +36,26 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { // ============== // @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 - networkManagerScopeAccesses: [ - 'SecurityAdmin' - ] - networkManagerScopes: { - subscriptions: [ - subscription().id +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 + networkManagerScopeAccesses: [ + 'SecurityAdmin' ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + networkManagerScopes: { + subscriptions: [ + subscription().id + ] + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/network/network-security-group/main.bicep b/avm/res/network/network-security-group/main.bicep index b91fa4c876..153ff53214 100644 --- a/avm/res/network/network-security-group/main.bicep +++ b/avm/res/network/network-security-group/main.bicep @@ -31,30 +31,40 @@ 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') + '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') + '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-networksecuritygroup.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-networksecuritygroup.${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 networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-04-01' = { name: name @@ -62,92 +72,152 @@ resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-04-0 tags: tags properties: { flushConnection: flushConnection - securityRules: [for securityRule in securityRules: { - name: securityRule.name - properties: { - protocol: securityRule.properties.protocol - access: securityRule.properties.access - priority: securityRule.properties.priority - direction: securityRule.properties.direction - description: contains(securityRule.properties, 'description') ? securityRule.properties.description : '' - sourcePortRange: contains(securityRule.properties, 'sourcePortRange') ? securityRule.properties.sourcePortRange : '' - sourcePortRanges: contains(securityRule.properties, 'sourcePortRanges') ? securityRule.properties.sourcePortRanges : [] - destinationPortRange: contains(securityRule.properties, 'destinationPortRange') ? securityRule.properties.destinationPortRange : '' - destinationPortRanges: contains(securityRule.properties, 'destinationPortRanges') ? securityRule.properties.destinationPortRanges : [] - sourceAddressPrefix: contains(securityRule.properties, 'sourceAddressPrefix') ? securityRule.properties.sourceAddressPrefix : '' - destinationAddressPrefix: contains(securityRule.properties, 'destinationAddressPrefix') ? securityRule.properties.destinationAddressPrefix : '' - sourceAddressPrefixes: contains(securityRule.properties, 'sourceAddressPrefixes') ? securityRule.properties.sourceAddressPrefixes : [] - destinationAddressPrefixes: contains(securityRule.properties, 'destinationAddressPrefixes') ? securityRule.properties.destinationAddressPrefixes : [] - sourceApplicationSecurityGroups: contains(securityRule.properties, 'sourceApplicationSecurityGroups') ? securityRule.properties.sourceApplicationSecurityGroups : [] - destinationApplicationSecurityGroups: contains(securityRule.properties, 'destinationApplicationSecurityGroups') ? securityRule.properties.destinationApplicationSecurityGroups : [] + securityRules: [ + for securityRule in securityRules: { + name: securityRule.name + properties: { + protocol: securityRule.properties.protocol + access: securityRule.properties.access + priority: securityRule.properties.priority + direction: securityRule.properties.direction + description: contains(securityRule.properties, 'description') ? securityRule.properties.description : '' + sourcePortRange: contains(securityRule.properties, 'sourcePortRange') + ? securityRule.properties.sourcePortRange + : '' + sourcePortRanges: contains(securityRule.properties, 'sourcePortRanges') + ? securityRule.properties.sourcePortRanges + : [] + destinationPortRange: contains(securityRule.properties, 'destinationPortRange') + ? securityRule.properties.destinationPortRange + : '' + destinationPortRanges: contains(securityRule.properties, 'destinationPortRanges') + ? securityRule.properties.destinationPortRanges + : [] + sourceAddressPrefix: contains(securityRule.properties, 'sourceAddressPrefix') + ? securityRule.properties.sourceAddressPrefix + : '' + destinationAddressPrefix: contains(securityRule.properties, 'destinationAddressPrefix') + ? securityRule.properties.destinationAddressPrefix + : '' + sourceAddressPrefixes: contains(securityRule.properties, 'sourceAddressPrefixes') + ? securityRule.properties.sourceAddressPrefixes + : [] + destinationAddressPrefixes: contains(securityRule.properties, 'destinationAddressPrefixes') + ? securityRule.properties.destinationAddressPrefixes + : [] + sourceApplicationSecurityGroups: contains(securityRule.properties, 'sourceApplicationSecurityGroups') + ? securityRule.properties.sourceApplicationSecurityGroups + : [] + destinationApplicationSecurityGroups: contains( + securityRule.properties, + 'destinationApplicationSecurityGroups' + ) + ? securityRule.properties.destinationApplicationSecurityGroups + : [] + } } - }] + ] } } -module networkSecurityGroup_securityRules 'security-rule/main.bicep' = [for (securityRule, index) in securityRules: { - name: '${uniqueString(deployment().name, location)}-NetworkSecurityGroup-SecurityRule-${index}' - params: { - name: securityRule.name - networkSecurityGroupName: networkSecurityGroup.name - protocol: securityRule.properties.protocol - access: securityRule.properties.access - priority: securityRule.properties.priority - direction: securityRule.properties.direction - description: contains(securityRule.properties, 'description') ? securityRule.properties.description : '' - sourcePortRange: contains(securityRule.properties, 'sourcePortRange') ? securityRule.properties.sourcePortRange : '' - sourcePortRanges: contains(securityRule.properties, 'sourcePortRanges') ? securityRule.properties.sourcePortRanges : [] - destinationPortRange: contains(securityRule.properties, 'destinationPortRange') ? securityRule.properties.destinationPortRange : '' - destinationPortRanges: contains(securityRule.properties, 'destinationPortRanges') ? securityRule.properties.destinationPortRanges : [] - sourceAddressPrefix: contains(securityRule.properties, 'sourceAddressPrefix') ? securityRule.properties.sourceAddressPrefix : '' - destinationAddressPrefix: contains(securityRule.properties, 'destinationAddressPrefix') ? securityRule.properties.destinationAddressPrefix : '' - sourceAddressPrefixes: contains(securityRule.properties, 'sourceAddressPrefixes') ? securityRule.properties.sourceAddressPrefixes : [] - destinationAddressPrefixes: contains(securityRule.properties, 'destinationAddressPrefixes') ? securityRule.properties.destinationAddressPrefixes : [] - sourceApplicationSecurityGroups: contains(securityRule.properties, 'sourceApplicationSecurityGroups') ? securityRule.properties.sourceApplicationSecurityGroups : [] - destinationApplicationSecurityGroups: contains(securityRule.properties, 'destinationApplicationSecurityGroups') ? securityRule.properties.destinationApplicationSecurityGroups : [] +module networkSecurityGroup_securityRules 'security-rule/main.bicep' = [ + for (securityRule, index) in securityRules: { + name: '${uniqueString(deployment().name, location)}-NetworkSecurityGroup-SecurityRule-${index}' + params: { + name: securityRule.name + networkSecurityGroupName: networkSecurityGroup.name + protocol: securityRule.properties.protocol + access: securityRule.properties.access + priority: securityRule.properties.priority + direction: securityRule.properties.direction + description: contains(securityRule.properties, 'description') ? securityRule.properties.description : '' + sourcePortRange: contains(securityRule.properties, 'sourcePortRange') + ? securityRule.properties.sourcePortRange + : '' + sourcePortRanges: contains(securityRule.properties, 'sourcePortRanges') + ? securityRule.properties.sourcePortRanges + : [] + destinationPortRange: contains(securityRule.properties, 'destinationPortRange') + ? securityRule.properties.destinationPortRange + : '' + destinationPortRanges: contains(securityRule.properties, 'destinationPortRanges') + ? securityRule.properties.destinationPortRanges + : [] + sourceAddressPrefix: contains(securityRule.properties, 'sourceAddressPrefix') + ? securityRule.properties.sourceAddressPrefix + : '' + destinationAddressPrefix: contains(securityRule.properties, 'destinationAddressPrefix') + ? securityRule.properties.destinationAddressPrefix + : '' + sourceAddressPrefixes: contains(securityRule.properties, 'sourceAddressPrefixes') + ? securityRule.properties.sourceAddressPrefixes + : [] + destinationAddressPrefixes: contains(securityRule.properties, 'destinationAddressPrefixes') + ? securityRule.properties.destinationAddressPrefixes + : [] + sourceApplicationSecurityGroups: contains(securityRule.properties, 'sourceApplicationSecurityGroups') + ? securityRule.properties.sourceApplicationSecurityGroups + : [] + destinationApplicationSecurityGroups: contains(securityRule.properties, 'destinationApplicationSecurityGroups') + ? securityRule.properties.destinationApplicationSecurityGroups + : [] + } } -}] - -resource networkSecurityGroup_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.' +] + +resource networkSecurityGroup_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: networkSecurityGroup } - scope: networkSecurityGroup -} -resource networkSecurityGroup_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 +resource networkSecurityGroup_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: networkSecurityGroup } - scope: networkSecurityGroup -}] - -resource networkSecurityGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(networkSecurityGroup.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 +] + +resource networkSecurityGroup_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(networkSecurityGroup.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: networkSecurityGroup } - scope: networkSecurityGroup -}] +] @description('The resource group the network security group was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/network-security-group/main.json b/avm/res/network/network-security-group/main.json index 5c6096e566..f260b58df4 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.25.53.49325", - "templateHash": "4216984327038707510" + "version": "0.26.54.24096", + "templateHash": "3515627050133600386" }, "name": "Network Security Groups", "description": "This module deploys a Network security Group (NSG).", @@ -446,8 +446,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7870858269129613686" + "version": "0.26.54.24096", + "templateHash": "5675009765675721781" }, "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 f2e48de864..c0aaac0c4b 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.25.53.49325", - "templateHash": "7870858269129613686" + "version": "0.26.54.24096", + "templateHash": "5675009765675721781" }, "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/tests/e2e/defaults/main.test.bicep b/avm/res/network/network-security-group/tests/e2e/defaults/main.test.bicep index 4778e3177b..29e1730be0 100644 --- a/avm/res/network/network-security-group/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/network-security-group/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/network-security-group/tests/e2e/max/main.test.bicep b/avm/res/network/network-security-group/tests/e2e/max/main.test.bicep index eeba0435d6..74d43232b8 100644 --- a/avm/res/network/network-security-group/tests/e2e/max/main.test.bicep +++ b/avm/res/network/network-security-group/tests/e2e/max/main.test.bicep @@ -60,114 +60,119 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - diagnosticSettings: [ - { - name: 'customSetting' - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - 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' - } - ] - securityRules: [ - { - name: 'Specific' - properties: { - access: 'Allow' - description: 'Tests specific IPs and ports' - destinationAddressPrefix: '*' - destinationPortRange: '8080' - direction: 'Inbound' - priority: 100 - protocol: '*' - sourceAddressPrefix: '*' - sourcePortRange: '*' +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 + diagnosticSettings: [ + { + name: 'customSetting' + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - name: 'Ranges' - properties: { - access: 'Allow' - description: 'Tests Ranges' - destinationAddressPrefixes: [ - '10.2.0.0/16' - '10.3.0.0/16' - ] - destinationPortRanges: [ - '90' - '91' - ] - direction: 'Inbound' - priority: 101 - protocol: '*' - sourceAddressPrefixes: [ - '10.0.0.0/16' - '10.1.0.0/16' - ] - sourcePortRanges: [ - '80' - '81' - ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - } - { - name: 'Port_8082' - properties: { - access: 'Allow' - description: 'Allow inbound access on TCP 8082' - destinationApplicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } - ] - destinationPortRange: '8082' - direction: 'Inbound' - priority: 102 - protocol: '*' - sourceApplicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } - ] - sourcePortRange: '*' + { + 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' + } + ] + securityRules: [ + { + name: 'Specific' + properties: { + access: 'Allow' + description: 'Tests specific IPs and ports' + destinationAddressPrefix: '*' + destinationPortRange: '8080' + direction: 'Inbound' + priority: 100 + protocol: '*' + sourceAddressPrefix: '*' + sourcePortRange: '*' + } } + { + name: 'Ranges' + properties: { + access: 'Allow' + description: 'Tests Ranges' + destinationAddressPrefixes: [ + '10.2.0.0/16' + '10.3.0.0/16' + ] + destinationPortRanges: [ + '90' + '91' + ] + direction: 'Inbound' + priority: 101 + protocol: '*' + sourceAddressPrefixes: [ + '10.0.0.0/16' + '10.1.0.0/16' + ] + sourcePortRanges: [ + '80' + '81' + ] + } + } + { + name: 'Port_8082' + properties: { + access: 'Allow' + description: 'Allow inbound access on TCP 8082' + destinationApplicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + destinationPortRange: '8082' + direction: 'Inbound' + priority: 102 + protocol: '*' + sourceApplicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + sourcePortRange: '*' + } + } + ] + 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' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/network-security-group/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/network-security-group/tests/e2e/waf-aligned/main.test.bicep index 9e413ec922..5a5e8f1669 100644 --- a/avm/res/network/network-security-group/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/network-security-group/tests/e2e/waf-aligned/main.test.bicep @@ -59,97 +59,99 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - diagnosticSettings: [ - { - name: 'customSetting' - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - securityRules: [ - { - name: 'Specific' - properties: { - access: 'Allow' - description: 'Tests specific IPs and ports' - destinationAddressPrefix: '*' - destinationPortRange: '8080' - direction: 'Inbound' - priority: 100 - protocol: '*' - sourceAddressPrefix: '*' - sourcePortRange: '*' +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 + diagnosticSettings: [ + { + name: 'customSetting' + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - name: 'Ranges' - properties: { - access: 'Allow' - description: 'Tests Ranges' - destinationAddressPrefixes: [ - '10.2.0.0/16' - '10.3.0.0/16' - ] - destinationPortRanges: [ - '90' - '91' - ] - direction: 'Inbound' - priority: 101 - protocol: '*' - sourceAddressPrefixes: [ - '10.0.0.0/16' - '10.1.0.0/16' - ] - sourcePortRanges: [ - '80' - '81' - ] + securityRules: [ + { + name: 'Specific' + properties: { + access: 'Allow' + description: 'Tests specific IPs and ports' + destinationAddressPrefix: '*' + destinationPortRange: '8080' + direction: 'Inbound' + priority: 100 + protocol: '*' + sourceAddressPrefix: '*' + sourcePortRange: '*' + } } - } - { - name: 'Port_8082' - properties: { - access: 'Allow' - description: 'Allow inbound access on TCP 8082' - destinationApplicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } - ] - destinationPortRange: '8082' - direction: 'Inbound' - priority: 102 - protocol: '*' - sourceApplicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } - ] - sourcePortRange: '*' + { + name: 'Ranges' + properties: { + access: 'Allow' + description: 'Tests Ranges' + destinationAddressPrefixes: [ + '10.2.0.0/16' + '10.3.0.0/16' + ] + destinationPortRanges: [ + '90' + '91' + ] + direction: 'Inbound' + priority: 101 + protocol: '*' + sourceAddressPrefixes: [ + '10.0.0.0/16' + '10.1.0.0/16' + ] + sourcePortRanges: [ + '80' + '81' + ] + } + } + { + name: 'Port_8082' + properties: { + access: 'Allow' + description: 'Allow inbound access on TCP 8082' + destinationApplicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + destinationPortRange: '8082' + direction: 'Inbound' + priority: 102 + protocol: '*' + sourceApplicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + sourcePortRange: '*' + } } + ] + 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' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/private-dns-zone/a/main.bicep b/avm/res/network/private-dns-zone/a/main.bicep index 8d6c525711..9804d60427 100644 --- a/avm/res/network/private-dns-zone/a/main.bicep +++ b/avm/res/network/private-dns-zone/a/main.bicep @@ -22,12 +22,24 @@ param roleAssignments roleAssignmentType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'Private DNS Zone Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b12aa53e-6015-4669-85d0-8515ebb3ae7f' + ) + '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') + '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 privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' existing = { @@ -44,19 +56,25 @@ resource A 'Microsoft.Network/privateDnsZones/A@2020-06-01' = { } } -resource A_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(A.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 +resource A_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(A.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: A } - scope: A -}] +] @description('The name of the deployed A record.') output name string = A.name diff --git a/avm/res/network/private-dns-zone/a/main.json b/avm/res/network/private-dns-zone/a/main.json index 81f4e9fa80..0a939afdf2 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.25.53.49325", - "templateHash": "17565463524922013743" + "version": "0.26.54.24096", + "templateHash": "12306956034851223701" }, "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.bicep b/avm/res/network/private-dns-zone/aaaa/main.bicep index 180e605405..00c814df6a 100644 --- a/avm/res/network/private-dns-zone/aaaa/main.bicep +++ b/avm/res/network/private-dns-zone/aaaa/main.bicep @@ -22,12 +22,24 @@ param roleAssignments roleAssignmentType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'Private DNS Zone Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b12aa53e-6015-4669-85d0-8515ebb3ae7f' + ) + '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') + '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 privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' existing = { @@ -44,19 +56,25 @@ resource AAAA 'Microsoft.Network/privateDnsZones/AAAA@2020-06-01' = { } } -resource AAAA_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(AAAA.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 +resource AAAA_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(AAAA.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: AAAA } - scope: AAAA -}] +] @description('The name of the deployed AAAA record.') output name string = AAAA.name diff --git a/avm/res/network/private-dns-zone/aaaa/main.json b/avm/res/network/private-dns-zone/aaaa/main.json index 00732682f0..86ca4b5bfc 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.25.53.49325", - "templateHash": "14360797759459973436" + "version": "0.26.54.24096", + "templateHash": "15517532978293030748" }, "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.bicep b/avm/res/network/private-dns-zone/cname/main.bicep index 8e63c47f7f..a3923729b5 100644 --- a/avm/res/network/private-dns-zone/cname/main.bicep +++ b/avm/res/network/private-dns-zone/cname/main.bicep @@ -22,12 +22,24 @@ param roleAssignments roleAssignmentType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'Private DNS Zone Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b12aa53e-6015-4669-85d0-8515ebb3ae7f' + ) + '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') + '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 privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' existing = { @@ -44,19 +56,25 @@ resource CNAME 'Microsoft.Network/privateDnsZones/CNAME@2020-06-01' = { } } -resource CNAME_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(CNAME.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 +resource CNAME_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(CNAME.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: CNAME } - scope: CNAME -}] +] @description('The name of the deployed CNAME record.') output name string = CNAME.name diff --git a/avm/res/network/private-dns-zone/cname/main.json b/avm/res/network/private-dns-zone/cname/main.json index f590f488aa..25f8fd4f6e 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.25.53.49325", - "templateHash": "8360937786294538789" + "version": "0.26.54.24096", + "templateHash": "4178056552366181250" }, "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.bicep b/avm/res/network/private-dns-zone/main.bicep index 28881fb037..8d79e045dd 100644 --- a/avm/res/network/private-dns-zone/main.bicep +++ b/avm/res/network/private-dns-zone/main.bicep @@ -49,30 +49,40 @@ 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') + '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') + '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') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.network-privatednszone.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-privatednszone.${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 privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { name: name @@ -80,136 +90,163 @@ resource privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { tags: tags } -module privateDnsZone_A 'a/main.bicep' = [for (aRecord, index) in (a ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-ARecord-${index}' - params: { - privateDnsZoneName: privateDnsZone.name - name: aRecord.name - aRecords: aRecord.?aRecords - metadata: aRecord.?metadata - ttl: aRecord.?ttl ?? 3600 - roleAssignments: aRecord.?roleAssignments +module privateDnsZone_A 'a/main.bicep' = [ + for (aRecord, index) in (a ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-ARecord-${index}' + params: { + privateDnsZoneName: privateDnsZone.name + name: aRecord.name + aRecords: aRecord.?aRecords + metadata: aRecord.?metadata + ttl: aRecord.?ttl ?? 3600 + roleAssignments: aRecord.?roleAssignments + } } -}] - -module privateDnsZone_AAAA 'aaaa/main.bicep' = [for (aaaaRecord, index) in (aaaa ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-AAAARecord-${index}' - params: { - privateDnsZoneName: privateDnsZone.name - name: aaaaRecord.name - aaaaRecords: aaaaRecord.?aaaaRecords - metadata: aaaaRecord.?metadata - ttl: aaaaRecord.?ttl ?? 3600 - roleAssignments: aaaaRecord.?roleAssignments +] + +module privateDnsZone_AAAA 'aaaa/main.bicep' = [ + for (aaaaRecord, index) in (aaaa ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-AAAARecord-${index}' + params: { + privateDnsZoneName: privateDnsZone.name + name: aaaaRecord.name + aaaaRecords: aaaaRecord.?aaaaRecords + metadata: aaaaRecord.?metadata + ttl: aaaaRecord.?ttl ?? 3600 + roleAssignments: aaaaRecord.?roleAssignments + } } -}] - -module privateDnsZone_CNAME 'cname/main.bicep' = [for (cnameRecord, index) in (cname ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-CNAMERecord-${index}' - params: { - privateDnsZoneName: privateDnsZone.name - name: cnameRecord.name - cnameRecord: cnameRecord.?cnameRecord - metadata: cnameRecord.?metadata - ttl: cnameRecord.?ttl ?? 3600 - roleAssignments: cnameRecord.?roleAssignments +] + +module privateDnsZone_CNAME 'cname/main.bicep' = [ + for (cnameRecord, index) in (cname ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-CNAMERecord-${index}' + params: { + privateDnsZoneName: privateDnsZone.name + name: cnameRecord.name + cnameRecord: cnameRecord.?cnameRecord + metadata: cnameRecord.?metadata + ttl: cnameRecord.?ttl ?? 3600 + roleAssignments: cnameRecord.?roleAssignments + } } -}] - -module privateDnsZone_MX 'mx/main.bicep' = [for (mxRecord, index) in (mx ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-MXRecord-${index}' - params: { - privateDnsZoneName: privateDnsZone.name - name: mxRecord.name - metadata: mxRecord.?metadata - mxRecords: mxRecord.?mxRecords - ttl: mxRecord.?ttl ?? 3600 - roleAssignments: mxRecord.?roleAssignments +] + +module privateDnsZone_MX 'mx/main.bicep' = [ + for (mxRecord, index) in (mx ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-MXRecord-${index}' + params: { + privateDnsZoneName: privateDnsZone.name + name: mxRecord.name + metadata: mxRecord.?metadata + mxRecords: mxRecord.?mxRecords + ttl: mxRecord.?ttl ?? 3600 + roleAssignments: mxRecord.?roleAssignments + } } -}] - -module privateDnsZone_PTR 'ptr/main.bicep' = [for (ptrRecord, index) in (ptr ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-PTRRecord-${index}' - params: { - privateDnsZoneName: privateDnsZone.name - name: ptrRecord.name - metadata: ptrRecord.?metadata - ptrRecords: ptrRecord.?ptrRecords - ttl: ptrRecord.?ttl ?? 3600 - roleAssignments: ptrRecord.?roleAssignments +] + +module privateDnsZone_PTR 'ptr/main.bicep' = [ + for (ptrRecord, index) in (ptr ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-PTRRecord-${index}' + params: { + privateDnsZoneName: privateDnsZone.name + name: ptrRecord.name + metadata: ptrRecord.?metadata + ptrRecords: ptrRecord.?ptrRecords + ttl: ptrRecord.?ttl ?? 3600 + roleAssignments: ptrRecord.?roleAssignments + } } -}] - -module privateDnsZone_SOA 'soa/main.bicep' = [for (soaRecord, index) in (soa ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-SOARecord-${index}' - params: { - privateDnsZoneName: privateDnsZone.name - name: soaRecord.name - metadata: soaRecord.?metadata - soaRecord: soaRecord.?soaRecord - ttl: soaRecord.?ttl ?? 3600 - roleAssignments: soaRecord.?roleAssignments +] + +module privateDnsZone_SOA 'soa/main.bicep' = [ + for (soaRecord, index) in (soa ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-SOARecord-${index}' + params: { + privateDnsZoneName: privateDnsZone.name + name: soaRecord.name + metadata: soaRecord.?metadata + soaRecord: soaRecord.?soaRecord + ttl: soaRecord.?ttl ?? 3600 + roleAssignments: soaRecord.?roleAssignments + } } -}] - -module privateDnsZone_SRV 'srv/main.bicep' = [for (srvRecord, index) in (srv ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-SRVRecord-${index}' - params: { - privateDnsZoneName: privateDnsZone.name - name: srvRecord.name - metadata: srvRecord.?metadata - srvRecords: srvRecord.?srvRecords - ttl: srvRecord.?ttl ?? 3600 - roleAssignments: srvRecord.?roleAssignments +] + +module privateDnsZone_SRV 'srv/main.bicep' = [ + for (srvRecord, index) in (srv ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-SRVRecord-${index}' + params: { + privateDnsZoneName: privateDnsZone.name + name: srvRecord.name + metadata: srvRecord.?metadata + srvRecords: srvRecord.?srvRecords + ttl: srvRecord.?ttl ?? 3600 + roleAssignments: srvRecord.?roleAssignments + } } -}] - -module privateDnsZone_TXT 'txt/main.bicep' = [for (txtRecord, index) in (txt ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-TXTRecord-${index}' - params: { - privateDnsZoneName: privateDnsZone.name - name: txtRecord.name - metadata: txtRecord.?metadata - txtRecords: txtRecord.?txtRecords - ttl: txtRecord.?ttl ?? 3600 - roleAssignments: txtRecord.?roleAssignments +] + +module privateDnsZone_TXT 'txt/main.bicep' = [ + for (txtRecord, index) in (txt ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-TXTRecord-${index}' + params: { + privateDnsZoneName: privateDnsZone.name + name: txtRecord.name + metadata: txtRecord.?metadata + txtRecords: txtRecord.?txtRecords + ttl: txtRecord.?ttl ?? 3600 + roleAssignments: txtRecord.?roleAssignments + } } -}] - -module privateDnsZone_virtualNetworkLinks 'virtual-network-link/main.bicep' = [for (virtualNetworkLink, index) in (virtualNetworkLinks ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-VirtualNetworkLink-${index}' - params: { - privateDnsZoneName: privateDnsZone.name - name: virtualNetworkLink.?name ?? '${last(split(virtualNetworkLink.virtualNetworkResourceId, '/'))}-vnetlink' - virtualNetworkResourceId: virtualNetworkLink.virtualNetworkResourceId - location: virtualNetworkLink.?location ?? 'global' - registrationEnabled: virtualNetworkLink.?registrationEnabled ?? false - tags: virtualNetworkLink.?tags ?? tags +] + +module privateDnsZone_virtualNetworkLinks 'virtual-network-link/main.bicep' = [ + for (virtualNetworkLink, index) in (virtualNetworkLinks ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateDnsZone-VirtualNetworkLink-${index}' + params: { + privateDnsZoneName: privateDnsZone.name + name: virtualNetworkLink.?name ?? '${last(split(virtualNetworkLink.virtualNetworkResourceId, '/'))}-vnetlink' + virtualNetworkResourceId: virtualNetworkLink.virtualNetworkResourceId + location: virtualNetworkLink.?location ?? 'global' + registrationEnabled: virtualNetworkLink.?registrationEnabled ?? false + tags: virtualNetworkLink.?tags ?? tags + } } -}] - -resource privateDnsZone_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.' +] + +resource privateDnsZone_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: privateDnsZone } - scope: privateDnsZone -} -resource privateDnsZone_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(privateDnsZone.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 +resource privateDnsZone_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(privateDnsZone.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: privateDnsZone } - scope: privateDnsZone -}] +] @description('The resource group the private DNS zone was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/private-dns-zone/main.json b/avm/res/network/private-dns-zone/main.json index 73b572a650..c8c39f4fd6 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.25.53.49325", - "templateHash": "5015696597887719627" + "version": "0.26.54.24096", + "templateHash": "3327242936340774578" }, "name": "Private DNS Zones", "description": "This module deploys a Private DNS zone.", @@ -323,8 +323,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17565463524922013743" + "version": "0.26.54.24096", + "templateHash": "12306956034851223701" }, "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.25.53.49325", - "templateHash": "14360797759459973436" + "version": "0.26.54.24096", + "templateHash": "15517532978293030748" }, "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.25.53.49325", - "templateHash": "8360937786294538789" + "version": "0.26.54.24096", + "templateHash": "4178056552366181250" }, "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.25.53.49325", - "templateHash": "17929107555284027881" + "version": "0.26.54.24096", + "templateHash": "10977884265298427114" }, "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.25.53.49325", - "templateHash": "5937391315050932617" + "version": "0.26.54.24096", + "templateHash": "10561246444555326733" }, "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.25.53.49325", - "templateHash": "15774595998971084317" + "version": "0.26.54.24096", + "templateHash": "17840534414219914835" }, "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.25.53.49325", - "templateHash": "6637703638195225114" + "version": "0.26.54.24096", + "templateHash": "17625006509638611979" }, "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.25.53.49325", - "templateHash": "4386552419329587852" + "version": "0.26.54.24096", + "templateHash": "1962752727391912227" }, "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.25.53.49325", - "templateHash": "2508137843266136274" + "version": "0.26.54.24096", + "templateHash": "8223766852442158769" }, "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.bicep b/avm/res/network/private-dns-zone/mx/main.bicep index f0f4e5a09e..3430a6af63 100644 --- a/avm/res/network/private-dns-zone/mx/main.bicep +++ b/avm/res/network/private-dns-zone/mx/main.bicep @@ -22,12 +22,24 @@ param roleAssignments roleAssignmentType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'Private DNS Zone Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b12aa53e-6015-4669-85d0-8515ebb3ae7f' + ) + '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') + '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 privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' existing = { @@ -44,19 +56,25 @@ resource MX 'Microsoft.Network/privateDnsZones/MX@2020-06-01' = { } } -resource MX_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(MX.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 +resource MX_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(MX.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: MX } - scope: MX -}] +] @description('The name of the deployed MX record.') output name string = MX.name diff --git a/avm/res/network/private-dns-zone/mx/main.json b/avm/res/network/private-dns-zone/mx/main.json index 651880a641..70582965b0 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.25.53.49325", - "templateHash": "17929107555284027881" + "version": "0.26.54.24096", + "templateHash": "10977884265298427114" }, "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.bicep b/avm/res/network/private-dns-zone/ptr/main.bicep index f4fda1e300..7343b754fb 100644 --- a/avm/res/network/private-dns-zone/ptr/main.bicep +++ b/avm/res/network/private-dns-zone/ptr/main.bicep @@ -22,12 +22,24 @@ param roleAssignments roleAssignmentType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'Private DNS Zone Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b12aa53e-6015-4669-85d0-8515ebb3ae7f' + ) + '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') + '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 privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' existing = { @@ -44,19 +56,25 @@ resource PTR 'Microsoft.Network/privateDnsZones/PTR@2020-06-01' = { } } -resource PTR_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(PTR.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 +resource PTR_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(PTR.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: PTR } - scope: PTR -}] +] @description('The name of the deployed PTR record.') output name string = PTR.name diff --git a/avm/res/network/private-dns-zone/ptr/main.json b/avm/res/network/private-dns-zone/ptr/main.json index 1f2c165b04..59abe7528d 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.25.53.49325", - "templateHash": "5937391315050932617" + "version": "0.26.54.24096", + "templateHash": "10561246444555326733" }, "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.bicep b/avm/res/network/private-dns-zone/soa/main.bicep index ef56247adf..34f5b558da 100644 --- a/avm/res/network/private-dns-zone/soa/main.bicep +++ b/avm/res/network/private-dns-zone/soa/main.bicep @@ -22,12 +22,24 @@ param roleAssignments roleAssignmentType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'Private DNS Zone Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b12aa53e-6015-4669-85d0-8515ebb3ae7f' + ) + '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') + '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 privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' existing = { @@ -44,19 +56,25 @@ resource SOA 'Microsoft.Network/privateDnsZones/SOA@2020-06-01' = { } } -resource SOA_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(SOA.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 +resource SOA_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(SOA.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: SOA } - scope: SOA -}] +] @description('The name of the deployed SOA record.') output name string = SOA.name diff --git a/avm/res/network/private-dns-zone/soa/main.json b/avm/res/network/private-dns-zone/soa/main.json index 700024ee9b..4c7ca7fb2f 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.25.53.49325", - "templateHash": "15774595998971084317" + "version": "0.26.54.24096", + "templateHash": "17840534414219914835" }, "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.bicep b/avm/res/network/private-dns-zone/srv/main.bicep index 1ab0c2cbfc..55e55a56d1 100644 --- a/avm/res/network/private-dns-zone/srv/main.bicep +++ b/avm/res/network/private-dns-zone/srv/main.bicep @@ -22,12 +22,24 @@ param roleAssignments roleAssignmentType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'Private DNS Zone Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b12aa53e-6015-4669-85d0-8515ebb3ae7f' + ) + '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') + '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 privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' existing = { @@ -44,19 +56,25 @@ resource SRV 'Microsoft.Network/privateDnsZones/SRV@2020-06-01' = { } } -resource SRV_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(SRV.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 +resource SRV_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(SRV.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: SRV } - scope: SRV -}] +] @description('The name of the deployed SRV record.') output name string = SRV.name diff --git a/avm/res/network/private-dns-zone/srv/main.json b/avm/res/network/private-dns-zone/srv/main.json index 3d34cfa3fe..2406f41be8 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.25.53.49325", - "templateHash": "6637703638195225114" + "version": "0.26.54.24096", + "templateHash": "17625006509638611979" }, "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/tests/e2e/defaults/main.test.bicep b/avm/res/network/private-dns-zone/tests/e2e/defaults/main.test.bicep index af279b6aa2..81053892b8 100644 --- a/avm/res/network/private-dns-zone/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/private-dns-zone/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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.com' - location: 'global' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001.com' + location: 'global' + } } -}] +] diff --git a/avm/res/network/private-dns-zone/tests/e2e/max/main.test.bicep b/avm/res/network/private-dns-zone/tests/e2e/max/main.test.bicep index e95348146f..d6aa67e9a2 100644 --- a/avm/res/network/private-dns-zone/tests/e2e/max/main.test.bicep +++ b/avm/res/network/private-dns-zone/tests/e2e/max/main.test.bicep @@ -46,258 +46,284 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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.com' - location: 'global' - a: [ - { - aRecords: [ - { - ipv4Address: '10.240.4.4' - } - ] - name: 'A_10.240.4.4' - 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' - } - ] - ttl: 3600 - } - ] - aaaa: [ - { - aaaaRecords: [ - { - ipv6Address: '2001:0db8:85a3:0000:0000:8a2e:0370:7334' - } - ] - name: 'AAAA_2001_0db8_85a3_0000_0000_8a2e_0370_7334' - ttl: 3600 - } - ] - cname: [ - { - cnameRecord: { - cname: 'test' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001.com' + location: 'global' + a: [ + { + aRecords: [ + { + ipv4Address: '10.240.4.4' + } + ] + name: 'A_10.240.4.4' + 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' + } + ] + ttl: 3600 } - name: 'CNAME_test' - 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' - } - ] - ttl: 3600 - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - mx: [ - { - mxRecords: [ - { - exchange: 'contoso.com' - preference: 100 - } - ] - name: 'MX_contoso' - 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' - } - ] - ttl: 3600 - } - ] - ptr: [ - { - name: 'PTR_contoso' - ptrRecords: [ - { - ptrdname: 'contoso.com' - } - ] - 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' - } - ] - ttl: 3600 - } - ] - 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' - } - ] - soa: [ - { - name: '@' - 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' - } - ] - soaRecord: { - email: 'azureprivatedns-host.microsoft.com' - expireTime: 2419200 - host: 'azureprivatedns.net' - minimumTtl: 10 - refreshTime: 3600 - retryTime: 300 - serialNumber: '1' + ] + aaaa: [ + { + aaaaRecords: [ + { + ipv6Address: '2001:0db8:85a3:0000:0000:8a2e:0370:7334' + } + ] + name: 'AAAA_2001_0db8_85a3_0000_0000_8a2e_0370_7334' + ttl: 3600 } - ttl: 3600 - } - ] - srv: [ - { - name: 'SRV_contoso' - 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' + ] + cname: [ + { + cnameRecord: { + cname: 'test' } - ] - srvRecords: [ - { - port: 9332 - priority: 0 - target: 'test.contoso.com' - weight: 0 - } - ] - ttl: 3600 + name: 'CNAME_test' + 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' + } + ] + ttl: 3600 + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - txt: [ - { - name: 'TXT_test' - 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' - } - ] - ttl: 3600 - txtRecords: [ - { - value: [ - 'test' - ] + mx: [ + { + mxRecords: [ + { + exchange: 'contoso.com' + preference: 100 + } + ] + name: 'MX_contoso' + 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' + } + ] + ttl: 3600 + } + ] + ptr: [ + { + name: 'PTR_contoso' + ptrRecords: [ + { + ptrdname: 'contoso.com' + } + ] + 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' + } + ] + ttl: 3600 + } + ] + 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' + } + ] + soa: [ + { + name: '@' + 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' + } + ] + soaRecord: { + email: 'azureprivatedns-host.microsoft.com' + expireTime: 2419200 + host: 'azureprivatedns.net' + minimumTtl: 10 + refreshTime: 3600 + retryTime: 300 + serialNumber: '1' } - ] - } - ] - virtualNetworkLinks: [ - { - registrationEnabled: true - virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + ttl: 3600 + } + ] + srv: [ + { + name: 'SRV_contoso' + 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' + } + ] + srvRecords: [ + { + port: 9332 + priority: 0 + target: 'test.contoso.com' + weight: 0 + } + ] + ttl: 3600 + } + ] + txt: [ + { + name: 'TXT_test' + 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' + } + ] + ttl: 3600 + txtRecords: [ + { + value: [ + 'test' + ] + } + ] + } + ] + virtualNetworkLinks: [ + { + registrationEnabled: true + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + } + ] + 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/network/private-dns-zone/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/private-dns-zone/tests/e2e/waf-aligned/main.test.bicep index cad9a29cfc..465cc291d3 100644 --- a/avm/res/network/private-dns-zone/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/private-dns-zone/tests/e2e/waf-aligned/main.test.bicep @@ -46,20 +46,22 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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.com' - location: 'global' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001.com' + location: 'global' + 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/network/private-dns-zone/txt/main.bicep b/avm/res/network/private-dns-zone/txt/main.bicep index 04989c7146..e472ee984b 100644 --- a/avm/res/network/private-dns-zone/txt/main.bicep +++ b/avm/res/network/private-dns-zone/txt/main.bicep @@ -22,12 +22,24 @@ param roleAssignments roleAssignmentType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'Private DNS Zone Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b12aa53e-6015-4669-85d0-8515ebb3ae7f' + ) + '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') + '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 privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' existing = { @@ -44,19 +56,25 @@ resource TXT 'Microsoft.Network/privateDnsZones/TXT@2020-06-01' = { } } -resource TXT_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(TXT.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 +resource TXT_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(TXT.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: TXT } - scope: TXT -}] +] @description('The name of the deployed TXT record.') output name string = TXT.name diff --git a/avm/res/network/private-dns-zone/txt/main.json b/avm/res/network/private-dns-zone/txt/main.json index f5f483986d..c3747524ef 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.25.53.49325", - "templateHash": "4386552419329587852" + "version": "0.26.54.24096", + "templateHash": "1962752727391912227" }, "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 0591440aad..4c6a56a124 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.25.53.49325", - "templateHash": "2508137843266136274" + "version": "0.26.54.24096", + "templateHash": "8223766852442158769" }, "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/main.bicep b/avm/res/network/private-endpoint/main.bicep index 2a3fc9de61..84caddce5b 100644 --- a/avm/res/network/private-endpoint/main.bicep +++ b/avm/res/network/private-endpoint/main.bicep @@ -49,43 +49,67 @@ param enableTelemetry bool = true var 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') + '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') + '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') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.network-privateendpoint.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-privateendpoint.${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 privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' = { name: name location: location tags: tags properties: { - applicationSecurityGroups: [for applicationSecurityGroupResourceId in (applicationSecurityGroupResourceIds ?? []): { - id: applicationSecurityGroupResourceId - }] + applicationSecurityGroups: [ + for applicationSecurityGroupResourceId in (applicationSecurityGroupResourceIds ?? []): { + id: applicationSecurityGroupResourceId + } + ] customDnsConfigs: customDnsConfigs ?? [] customNetworkInterfaceName: customNetworkInterfaceName ?? '' ipConfigurations: ipConfigurations ?? [] @@ -97,37 +121,47 @@ resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' = { } } -module privateEndpoint_privateDnsZoneGroup 'private-dns-zone-group/main.bicep' = if (!empty(privateDnsZoneResourceIds)) { - name: '${uniqueString(deployment().name)}-PrivateEndpoint-PrivateDnsZoneGroup' - params: { - name: privateDnsZoneGroupName ?? 'default' - privateDNSResourceIds: privateDnsZoneResourceIds ?? [] - privateEndpointName: privateEndpoint.name +module privateEndpoint_privateDnsZoneGroup 'private-dns-zone-group/main.bicep' = + if (!empty(privateDnsZoneResourceIds)) { + name: '${uniqueString(deployment().name)}-PrivateEndpoint-PrivateDnsZoneGroup' + params: { + name: privateDnsZoneGroupName ?? 'default' + privateDNSResourceIds: privateDnsZoneResourceIds ?? [] + privateEndpointName: privateEndpoint.name + } } -} -resource privateEndpoint_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.' +resource privateEndpoint_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: privateEndpoint } - scope: privateEndpoint -} -resource privateEndpoint_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(privateEndpoint.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 +resource privateEndpoint_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(privateEndpoint.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: privateEndpoint } - scope: privateEndpoint -}] +] @description('The resource group the private endpoint was deployed into.') output resourceGroupName string = resourceGroup().name @@ -142,7 +176,9 @@ output name string = privateEndpoint.name 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] +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 b17d43e13f..3dd768bd4c 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.25.53.49325", - "templateHash": "8700281441025836130" + "version": "0.26.54.24096", + "templateHash": "2264842680766745282" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", @@ -476,8 +476,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11244630631275470040" + "version": "0.26.54.24096", + "templateHash": "13696906123248879101" }, "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/private-dns-zone-group/main.bicep b/avm/res/network/private-endpoint/private-dns-zone-group/main.bicep index 623a713cbc..701f48a69c 100644 --- a/avm/res/network/private-endpoint/private-dns-zone-group/main.bicep +++ b/avm/res/network/private-endpoint/private-dns-zone-group/main.bicep @@ -13,12 +13,14 @@ param privateDNSResourceIds array @description('Optional. The name of the private DNS zone group.') param name string = 'default' -var privateDnsZoneConfigs = [for privateDNSResourceId in privateDNSResourceIds: { - name: last(split(privateDNSResourceId, '/'))! - properties: { - privateDnsZoneId: privateDNSResourceId +var privateDnsZoneConfigs = [ + for privateDNSResourceId in privateDNSResourceIds: { + name: last(split(privateDNSResourceId, '/'))! + properties: { + privateDnsZoneId: privateDNSResourceId + } } -}] +] resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' existing = { name: privateEndpointName 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 4428758907..3be73efbf6 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.25.53.49325", - "templateHash": "11244630631275470040" + "version": "0.26.54.24096", + "templateHash": "13696906123248879101" }, "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 c133a0f4af..fb69ae8935 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 @@ -49,34 +49,36 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - subnetResourceId: nestedDependencies.outputs.subnetResourceId - // Workaround for PSRule - lock: {} - roleAssignments: [] - applicationSecurityGroupResourceIds: [] - customNetworkInterfaceName: '' - privateDnsZoneGroupName: '' - ipConfigurations: [] - customDnsConfigs: [] - privateDnsZoneResourceIds: [] - manualPrivateLinkServiceConnections: [] - privateLinkServiceConnections: [ - { - name: '${namePrefix}${serviceShort}001' - properties: { - privateLinkServiceId: nestedDependencies.outputs.keyVaultResourceId - groupIds: [ - 'vault' - ] +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 + subnetResourceId: nestedDependencies.outputs.subnetResourceId + // Workaround for PSRule + lock: {} + roleAssignments: [] + applicationSecurityGroupResourceIds: [] + customNetworkInterfaceName: '' + privateDnsZoneGroupName: '' + ipConfigurations: [] + customDnsConfigs: [] + privateDnsZoneResourceIds: [] + manualPrivateLinkServiceConnections: [] + privateLinkServiceConnections: [ + { + name: '${namePrefix}${serviceShort}001' + properties: { + privateLinkServiceId: nestedDependencies.outputs.keyVaultResourceId + groupIds: [ + 'vault' + ] + } } - } - ] - tags: {} + ] + tags: {} + } } -}] +] 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 50cb5f95c7..22845ca801 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 @@ -51,78 +51,83 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - subnetResourceId: nestedDependencies.outputs.subnetResourceId - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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 + subnetResourceId: nestedDependencies.outputs.subnetResourceId + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - 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' - } - ] - ipConfigurations: [ - { - name: 'myIPconfig' - properties: { - groupId: 'vault' - memberName: 'default' - privateIPAddress: '10.0.0.10' + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - } - ] - customDnsConfigs: [ - { - fqdn: 'abc.keyvault.com' - ipAddresses: [ - '10.0.0.10' - ] - } - ] - customNetworkInterfaceName: '${namePrefix}${serviceShort}001nic' - applicationSecurityGroupResourceIds: [ - nestedDependencies.outputs.applicationSecurityGroupResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - // Workaround for PSRule - privateDnsZoneGroupName: 'default' - manualPrivateLinkServiceConnections: [] - privateLinkServiceConnections: [ - { - name: '${namePrefix}${serviceShort}001' - properties: { - privateLinkServiceId: nestedDependencies.outputs.keyVaultResourceId - groupIds: [ - 'vault' + { + 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' + } + ] + ipConfigurations: [ + { + name: 'myIPconfig' + properties: { + groupId: 'vault' + memberName: 'default' + privateIPAddress: '10.0.0.10' + } + } + ] + customDnsConfigs: [ + { + fqdn: 'abc.keyvault.com' + ipAddresses: [ + '10.0.0.10' ] - requestMessage: 'Hey there' } + ] + customNetworkInterfaceName: '${namePrefix}${serviceShort}001nic' + applicationSecurityGroupResourceIds: [ + nestedDependencies.outputs.applicationSecurityGroupResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] + // Workaround for PSRule + privateDnsZoneGroupName: 'default' + manualPrivateLinkServiceConnections: [] + privateLinkServiceConnections: [ + { + name: '${namePrefix}${serviceShort}001' + properties: { + privateLinkServiceId: nestedDependencies.outputs.keyVaultResourceId + groupIds: [ + 'vault' + ] + requestMessage: 'Hey there' + } + } + ] + } } -}] +] 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 961dfd7d64..f90eb6358f 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 @@ -51,53 +51,55 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - subnetResourceId: nestedDependencies.outputs.subnetResourceId - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - ipConfigurations: [ - { - name: 'myIPconfig' - properties: { - groupId: 'vault' - memberName: 'default' - privateIPAddress: '10.0.0.10' - } +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 + subnetResourceId: nestedDependencies.outputs.subnetResourceId + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - customNetworkInterfaceName: '${namePrefix}${serviceShort}001nic' - applicationSecurityGroupResourceIds: [ - nestedDependencies.outputs.applicationSecurityGroupResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - // Workaround for PSRule - privateDnsZoneGroupName: 'default' - customDnsConfigs: [] - manualPrivateLinkServiceConnections: [] - privateLinkServiceConnections: [ - { - name: '${namePrefix}${serviceShort}001' - properties: { - privateLinkServiceId: nestedDependencies.outputs.keyVaultResourceId - groupIds: [ - 'vault' - ] + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + ipConfigurations: [ + { + name: 'myIPconfig' + properties: { + groupId: 'vault' + memberName: 'default' + privateIPAddress: '10.0.0.10' + } } + ] + customNetworkInterfaceName: '${namePrefix}${serviceShort}001nic' + applicationSecurityGroupResourceIds: [ + nestedDependencies.outputs.applicationSecurityGroupResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] + // Workaround for PSRule + privateDnsZoneGroupName: 'default' + customDnsConfigs: [] + manualPrivateLinkServiceConnections: [] + privateLinkServiceConnections: [ + { + name: '${namePrefix}${serviceShort}001' + properties: { + privateLinkServiceId: nestedDependencies.outputs.keyVaultResourceId + groupIds: [ + 'vault' + ] + } + } + ] + } } -}] +] diff --git a/avm/res/network/private-link-service/main.bicep b/avm/res/network/private-link-service/main.bicep index edf06dc31b..3b2e4fe0f8 100644 --- a/avm/res/network/private-link-service/main.bicep +++ b/avm/res/network/private-link-service/main.bicep @@ -43,31 +43,44 @@ 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') + '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') + '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') + '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 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 @@ -84,28 +97,37 @@ resource privateLinkService 'Microsoft.Network/privateLinkServices@2023-04-01' = } } -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.' +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 } - 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 +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 } - scope: privateLinkService -}] +] @description('The resource group the private link service was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/private-link-service/main.json b/avm/res/network/private-link-service/main.json index 50f7678349..1b3d84fbfc 100644 --- a/avm/res/network/private-link-service/main.json +++ b/avm/res/network/private-link-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3313526188226682107" + "version": "0.26.54.24096", + "templateHash": "3016081933561782423" }, "name": "Private Link Services", "description": "This module deploys a Private Link Service.", 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 index 225912bdc2..133ed317d1 100644 --- 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 @@ -46,26 +46,28 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 +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 - } - ] + ] + loadBalancerFrontendIpConfigurations: [ + { + id: nestedDependencies.outputs.loadBalancerFrontendIpConfigurationResourceId + } + ] + } } -}] +] 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 index 8fd89f8691..1efed5c5a3 100644 --- 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 @@ -47,69 +47,74 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 +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 + loadBalancerFrontendIpConfigurations: [ + { + id: nestedDependencies.outputs.loadBalancerFrontendIpConfigurationResourceId + } ] - } - enableProxyProtocol: true - fqdns: [ - '${serviceShort}.plsfqdn01.azure.privatelinkservice' - '${serviceShort}.plsfqdn02.azure.privatelinkservice' - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + autoApproval: { + subscriptions: [ + '*' + ] } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + visibility: { + subscriptions: [ + subscription().subscriptionId + ] } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' } - ] - 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/main.test.bicep b/avm/res/network/private-link-service/tests/e2e/waf-aligned/main.test.bicep index 1c3944a326..48b68e42be 100644 --- 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 @@ -46,48 +46,50 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 +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: [ + '*' + ] } - ] - loadBalancerFrontendIpConfigurations: [ - { - id: nestedDependencies.outputs.loadBalancerFrontendIpConfigurationResourceId + visibility: { + subscriptions: [ + subscription().subscriptionId + ] } - ] - autoApproval: { - subscriptions: [ - '*' - ] - } - visibility: { - subscriptions: [ - subscription().subscriptionId + enableProxyProtocol: true + fqdns: [ + '${serviceShort}.plsfqdn01.azure.privatelinkservice' + '${serviceShort}.plsfqdn02.azure.privatelinkservice' ] - } - 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' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/network/public-ip-address/main.bicep b/avm/res/network/public-ip-address/main.bicep index ef48ffb569..36c04b157f 100644 --- a/avm/res/network/public-ip-address/main.bicep +++ b/avm/res/network/public-ip-address/main.bicep @@ -72,34 +72,56 @@ param diagnosticSettings diagnosticSettingType var 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') + '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') + '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') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.network-publicipaddress.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-publicipaddress.${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 publicIpAddress 'Microsoft.Network/publicIPAddresses@2023-09-01' = { name: name @@ -115,59 +137,76 @@ resource publicIpAddress 'Microsoft.Network/publicIPAddresses@2023-09-01' = { dnsSettings: dnsSettings publicIPAddressVersion: publicIPAddressVersion publicIPAllocationMethod: publicIPAllocationMethod - publicIPPrefix: !empty(publicIpPrefixResourceId) ? { - id: publicIpPrefixResourceId - } : null + publicIPPrefix: !empty(publicIpPrefixResourceId) + ? { + id: publicIpPrefixResourceId + } + : null idleTimeoutInMinutes: idleTimeoutInMinutes ipTags: [] } } -resource publicIpAddress_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.' +resource publicIpAddress_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: publicIpAddress } - scope: publicIpAddress -} -resource publicIpAddress_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(publicIpAddress.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 +resource publicIpAddress_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(publicIpAddress.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: publicIpAddress } - scope: publicIpAddress -}] +] -resource publicIpAddress_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 - 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 +resource publicIpAddress_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 + 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 + } + scope: publicIpAddress } - scope: publicIpAddress -}] +] @description('The resource group the public IP address was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep b/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep index 8aec5abcad..fa38cabbae 100644 --- a/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep @@ -35,11 +35,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // Test Execution // // ============== // -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 +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/public-ip-address/tests/e2e/max/main.test.bicep b/avm/res/network/public-ip-address/tests/e2e/max/main.test.bicep index 11e3670a5e..9c75dd5ace 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 @@ -58,58 +58,63 @@ module diagnosticDependencies '../../../../../../../avm/utilities/e2e-template-a // Test Execution // // ============== // -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: { - name: 'myCustomLockName' - kind: 'CanNotDelete' - } - dnsSettings: null - ddosSettings: null - publicIpPrefixResourceId: null - publicIPAllocationMethod: 'Static' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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: { + name: 'myCustomLockName' + kind: 'CanNotDelete' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + dnsSettings: null + ddosSettings: null + publicIpPrefixResourceId: null + publicIPAllocationMethod: 'Static' + 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' + } + ] + skuName: 'Standard' + skuTier: 'Regional' + publicIPAddressVersion: 'IPv4' + zones: [ + '1' + '2' + '3' + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - skuName: 'Standard' - skuTier: 'Regional' - publicIPAddressVersion: 'IPv4' - zones: [ - '1' - '2' - '3' - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + diagnosticSettings: [ + { + name: 'customSetting' + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] } - diagnosticSettings: [ - { - name: 'customSetting' - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] } -}] +] 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 ebf0000da7..0a7930b56e 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 @@ -58,58 +58,63 @@ module diagnosticDependencies '../../../../../../../avm/utilities/e2e-template-a // Test Execution // // ============== // -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: { - name: 'myCustomLockName' - kind: 'CanNotDelete' - } - dnsSettings: null - ddosSettings: null - publicIPAllocationMethod: 'Static' - publicIpPrefixResourceId: null - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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: { + name: 'myCustomLockName' + kind: 'CanNotDelete' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + dnsSettings: null + ddosSettings: null + publicIPAllocationMethod: 'Static' + publicIpPrefixResourceId: null + 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' + } + ] + skuName: 'Standard' + skuTier: 'Regional' + publicIPAddressVersion: 'IPv4' + zones: [ + '1' + '2' + '3' + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - skuName: 'Standard' - skuTier: 'Regional' - publicIPAddressVersion: 'IPv4' - zones: [ - '1' - '2' - '3' - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + diagnosticSettings: [ + { + name: 'customSetting' + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] } - diagnosticSettings: [ - { - name: 'customSetting' - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] } -}] +] diff --git a/avm/res/network/public-ip-prefix/main.bicep b/avm/res/network/public-ip-prefix/main.bicep index d9fed7fb9d..91383b47dc 100644 --- a/avm/res/network/public-ip-prefix/main.bicep +++ b/avm/res/network/public-ip-prefix/main.bicep @@ -31,30 +31,40 @@ 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') + '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') + '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-publicipprefix.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-publicipprefix.${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 publicIpPrefix 'Microsoft.Network/publicIPPrefixes@2023-09-01' = { name: name @@ -70,28 +80,37 @@ resource publicIpPrefix 'Microsoft.Network/publicIPPrefixes@2023-09-01' = { } } -resource publicIpPrefix_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.' +resource publicIpPrefix_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: publicIpPrefix } - scope: publicIpPrefix -} -resource publicIpPrefix_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(publicIpPrefix.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 +resource publicIpPrefix_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(publicIpPrefix.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: publicIpPrefix } - scope: publicIpPrefix -}] +] @description('The resource ID of the public IP prefix.') output resourceId string = publicIpPrefix.id diff --git a/avm/res/network/public-ip-prefix/main.json b/avm/res/network/public-ip-prefix/main.json index bf928ff5b7..4e2479e6a3 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.25.53.49325", - "templateHash": "16912543771400413342" + "version": "0.26.54.24096", + "templateHash": "7016457133056549138" }, "name": "Public IP Prefixes", "description": "This module deploys a Public IP Prefix.", 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 70effcbbc5..271d5ed8ee 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 @@ -35,12 +35,14 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { // ============== // @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 - prefixLength: 28 +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 + prefixLength: 28 + } } -}] +] 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 43b2b39c33..7b3d4e8fb0 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 @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') 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 6504f4b21b..c4e9682513 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 @@ -45,38 +45,43 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - prefixLength: 28 - 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' +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 + prefixLength: 28 + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] 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 43b2b39c33..7b3d4e8fb0 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 @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') 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 6e2ba0e646..469fe72abf 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 @@ -36,17 +36,19 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { // ============== // @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 - prefixLength: 28 - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + prefixLength: 28 + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/network/route-table/main.bicep b/avm/res/network/route-table/main.bicep index e5dcc4f652..c26a3d25d1 100644 --- a/avm/res/network/route-table/main.bicep +++ b/avm/res/network/route-table/main.bicep @@ -28,30 +28,43 @@ 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') + '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') + '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: take('46d3xbcp.res.network-routetable.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: take( + '46d3xbcp.res.network-routetable.${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 routeTable 'Microsoft.Network/routeTables@2023-04-01' = { name: name @@ -63,28 +76,37 @@ resource routeTable 'Microsoft.Network/routeTables@2023-04-01' = { } } -resource routeTable_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.' +resource routeTable_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: routeTable } - scope: routeTable -} -resource routeTable_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(routeTable.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 +resource routeTable_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(routeTable.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: routeTable } - scope: routeTable -}] +] @description('The resource group the route table was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/route-table/main.json b/avm/res/network/route-table/main.json index 3f54614e78..e0818709a4 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.25.53.49325", - "templateHash": "1632746009017446160" + "version": "0.26.54.24096", + "templateHash": "3951814789593298488" }, "name": "Route Tables", "description": "This module deploys a User Defined Route Table (UDR).", diff --git a/avm/res/network/route-table/tests/e2e/max/dependencies.bicep b/avm/res/network/route-table/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/network/route-table/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/route-table/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/network/route-table/tests/e2e/max/main.test.bicep b/avm/res/network/route-table/tests/e2e/max/main.test.bicep index 82c3e2627b..52bcc02ac8 100644 --- a/avm/res/network/route-table/tests/e2e/max/main.test.bicep +++ b/avm/res/network/route-table/tests/e2e/max/main.test.bicep @@ -66,7 +66,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/network/trafficmanagerprofile/main.bicep b/avm/res/network/trafficmanagerprofile/main.bicep index fadcb2ff94..77a4f05dad 100644 --- a/avm/res/network/trafficmanagerprofile/main.bicep +++ b/avm/res/network/trafficmanagerprofile/main.bicep @@ -70,31 +70,44 @@ param location string = 'global' var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + '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') - 'Traffic Manager Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'Traffic Manager Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7' + ) + '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-trafficmanagerprofile.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-trafficmanagerprofile.${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 trafficManagerProfile 'Microsoft.Network/trafficmanagerprofiles@2018-08-01' = { name: name @@ -114,51 +127,66 @@ resource trafficManagerProfile 'Microsoft.Network/trafficmanagerprofiles@2018-08 } } -resource trafficManagerProfile_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.' +resource trafficManagerProfile_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: trafficManagerProfile } - scope: trafficManagerProfile -} -resource trafficManagerProfile_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 - 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 +resource trafficManagerProfile_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 + 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 + } + scope: trafficManagerProfile } - scope: trafficManagerProfile -}] - -resource trafficManagerProfile_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(trafficManagerProfile.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 +] + +resource trafficManagerProfile_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(trafficManagerProfile.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: trafficManagerProfile } - scope: trafficManagerProfile -}] +] @description('The resource ID of the traffic manager.') output resourceId string = trafficManagerProfile.id diff --git a/avm/res/network/trafficmanagerprofile/main.json b/avm/res/network/trafficmanagerprofile/main.json index 5eb1678de9..8c4e575316 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.25.53.49325", - "templateHash": "1216778685608382825" + "version": "0.26.54.24096", + "templateHash": "7725817516330218838" }, "name": "Traffic Manager Profiles", "description": "This module deploys a Traffic Manager Profile.", diff --git a/avm/res/network/trafficmanagerprofile/tests/e2e/defaults/main.test.bicep b/avm/res/network/trafficmanagerprofile/tests/e2e/defaults/main.test.bicep index 1f0aca0761..821e67a2cc 100644 --- a/avm/res/network/trafficmanagerprofile/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/trafficmanagerprofile/tests/e2e/defaults/main.test.bicep @@ -35,11 +35,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-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: 'global' +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/network/trafficmanagerprofile/tests/e2e/max/main.test.bicep b/avm/res/network/trafficmanagerprofile/tests/e2e/max/main.test.bicep index b42bac759e..b756d168b8 100644 --- a/avm/res/network/trafficmanagerprofile/tests/e2e/max/main.test.bicep +++ b/avm/res/network/trafficmanagerprofile/tests/e2e/max/main.test.bicep @@ -58,52 +58,57 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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' - relativeName: '${namePrefix}${serviceShort}001-rn' - location: 'global' - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - 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' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + relativeName: '${namePrefix}${serviceShort}001-rn' + location: 'global' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/network/trafficmanagerprofile/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/trafficmanagerprofile/tests/e2e/waf-aligned/main.test.bicep index cb2cc08da1..32d82ac36b 100644 --- a/avm/res/network/trafficmanagerprofile/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/trafficmanagerprofile/tests/e2e/waf-aligned/main.test.bicep @@ -64,63 +64,65 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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' - monitorConfig: { - protocol: 'https' - port: '443' - path: '/' - } - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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' + monitorConfig: { + protocol: 'https' + port: '443' + path: '/' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - endpoints: [ - { - name: 'webApp01Endpoint' - type: 'Microsoft.Network/trafficManagerProfiles/azureEndpoints' - properties: { - targetResourceId: nestedDependencies.outputs.webApp01ResourceId - weight: 1 - priority: 1 - endpointLocation: 'eastus' - endpointStatus: 'Enabled' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - name: 'webApp02Endpoint' - type: 'Microsoft.Network/trafficManagerProfiles/azureEndpoints' - properties: { - targetResourceId: nestedDependencies.outputs.webApp02ResourceId - weight: 1 - priority: 2 - endpointLocation: 'westus' - endpointStatus: 'Enabled' - } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] + endpoints: [ + { + name: 'webApp01Endpoint' + type: 'Microsoft.Network/trafficManagerProfiles/azureEndpoints' + properties: { + targetResourceId: nestedDependencies.outputs.webApp01ResourceId + weight: 1 + priority: 1 + endpointLocation: 'eastus' + endpointStatus: 'Enabled' + } + } + { + name: 'webApp02Endpoint' + type: 'Microsoft.Network/trafficManagerProfiles/azureEndpoints' + properties: { + targetResourceId: nestedDependencies.outputs.webApp02ResourceId + weight: 1 + priority: 2 + endpointLocation: 'westus' + endpointStatus: 'Enabled' + } + } + ] + } } -}] +] diff --git a/avm/res/network/virtual-hub/hub-route-table/main.bicep b/avm/res/network/virtual-hub/hub-route-table/main.bicep index 46d6d2d895..059374a501 100644 --- a/avm/res/network/virtual-hub/hub-route-table/main.bicep +++ b/avm/res/network/virtual-hub/hub-route-table/main.bicep @@ -17,23 +17,24 @@ 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 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 diff --git a/avm/res/network/virtual-hub/hub-route-table/main.json b/avm/res/network/virtual-hub/hub-route-table/main.json index 200e6c44d7..0188d1b4bc 100644 --- a/avm/res/network/virtual-hub/hub-route-table/main.json +++ b/avm/res/network/virtual-hub/hub-route-table/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10525202939204553685" + "version": "0.26.54.24096", + "templateHash": "8788910381196616673" }, "name": "Virtual Hub Route Tables", "description": "This module deploys a Virtual Hub Route Table.", 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 index 6e0c0c3119..3bc4c7e4ec 100644 --- a/avm/res/network/virtual-hub/hub-virtual-network-connection/main.bicep +++ b/avm/res/network/virtual-hub/hub-virtual-network-connection/main.bicep @@ -20,23 +20,24 @@ 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 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 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 index ea8e5a326f..47c9ebd025 100644 --- a/avm/res/network/virtual-hub/hub-virtual-network-connection/main.json +++ b/avm/res/network/virtual-hub/hub-virtual-network-connection/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2449431200083704591" + "version": "0.26.54.24096", + "templateHash": "10987823499253979342" }, "name": "Virtual Hub Virtual Network Connections", "description": "This module deploys a Virtual Hub Virtual Network Connection.", diff --git a/avm/res/network/virtual-hub/main.bicep b/avm/res/network/virtual-hub/main.bicep index e6326c72bf..58c7ad44d2 100644 --- a/avm/res/network/virtual-hub/main.bicep +++ b/avm/res/network/virtual-hub/main.bicep @@ -81,23 +81,27 @@ 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 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 @@ -106,22 +110,32 @@ resource virtualHub 'Microsoft.Network/virtualHubs@2022-11-01' = { properties: { addressPrefix: addressPrefix allowBranchToBranchTraffic: allowBranchToBranchTraffic - azureFirewall: !empty(azureFirewallResourceId) ? { - id: azureFirewallResourceId - } : null - expressRouteGateway: !empty(expressRouteGatewayId) ? { - id: expressRouteGatewayId - } : null - p2SVpnGateway: !empty(p2SVpnGatewayId) ? { - id: p2SVpnGatewayId - } : null + 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 + routeTable: !empty(routeTableRoutes) + ? { + routes: routeTableRoutes + } + : null + securityPartnerProvider: !empty(securityPartnerProviderId) + ? { + id: securityPartnerProviderId + } + : null securityProviderName: securityProviderName sku: sku virtualHubRouteTableV2s: virtualHubRouteTableV2s @@ -130,46 +144,59 @@ resource virtualHub 'Microsoft.Network/virtualHubs@2022-11-01' = { virtualWan: { id: virtualWanId } - vpnGateway: !empty(vpnGatewayId) ? { - id: vpnGatewayId - } : null + 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.' +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 } - 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_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 +] + +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 + ] } - dependsOn: [ - virtualHub_routeTables - ] -}] +] @description('The resource group the virtual hub was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/virtual-hub/main.json b/avm/res/network/virtual-hub/main.json index b230823993..5b75ef5cc5 100644 --- a/avm/res/network/virtual-hub/main.json +++ b/avm/res/network/virtual-hub/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14890345402999745367" + "version": "0.26.54.24096", + "templateHash": "2150058177195720553" }, "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.", @@ -297,8 +297,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10525202939204553685" + "version": "0.26.54.24096", + "templateHash": "8788910381196616673" }, "name": "Virtual Hub Route Tables", "description": "This module deploys a Virtual Hub Route Table.", @@ -434,8 +434,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2449431200083704591" + "version": "0.26.54.24096", + "templateHash": "10987823499253979342" }, "name": "Virtual Hub Virtual Network Connections", "description": "This module deploys a Virtual Hub Virtual Network Connection.", 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 index 5f6bfff780..688058b279 100644 --- a/avm/res/network/virtual-hub/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/virtual-hub/tests/e2e/defaults/main.test.bicep @@ -17,7 +17,6 @@ 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_#' @@ -46,13 +45,15 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 +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 index 9c4af5313d..12d02b46c1 100644 --- a/avm/res/network/virtual-hub/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/virtual-hub/tests/e2e/max/dependencies.bicep @@ -27,7 +27,6 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { { name: 'defaultSubnet' properties: { - addressPrefix: cidrSubnet(addressPrefix, 16, 0) } } 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 index 0e72b20ad4..5b1d77520f 100644 --- a/avm/res/network/virtual-hub/tests/e2e/max/main.test.bicep +++ b/avm/res/network/virtual-hub/tests/e2e/max/main.test.bicep @@ -46,48 +46,50 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' +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' } - ] - 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' - ] + 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' } - ] - 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 index 9c4af5313d..12d02b46c1 100644 --- a/avm/res/network/virtual-hub/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/network/virtual-hub/tests/e2e/waf-aligned/dependencies.bicep @@ -27,7 +27,6 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { { name: 'defaultSubnet' properties: { - addressPrefix: cidrSubnet(addressPrefix, 16, 0) } } 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 index ee601164eb..3d3015b25f 100644 --- 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 @@ -46,48 +46,50 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' +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' } - ] - 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' - ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/network/virtual-network-gateway/main.bicep b/avm/res/network/virtual-network-gateway/main.bicep index 1057d03afd..b27289ffa6 100644 --- a/avm/res/network/virtual-network-gateway/main.bicep +++ b/avm/res/network/virtual-network-gateway/main.bicep @@ -152,12 +152,14 @@ var gatewayPipSku = contains(zoneRedundantSkus, skuName) ? 'Standard' : 'Basic' var gatewayPipAllocationMethod = contains(zoneRedundantSkus, skuName) ? 'Static' : 'Dynamic' var isActiveActiveValid = gatewayType != 'ExpressRoute' ? activeActive : false -var virtualGatewayPipNameVar = isActiveActiveValid ? [ - gatewayPipName - activeGatewayPipName -] : [ - gatewayPipName -] +var virtualGatewayPipNameVar = isActiveActiveValid + ? [ + gatewayPipName + activeGatewayPipName + ] + : [ + gatewayPipName + ] var vpnTypeVar = gatewayType != 'ExpressRoute' ? vpnType : 'PolicyBased' @@ -167,132 +169,159 @@ var bgpSettings = { } // Potential configurations (active-active vs active-passive) -var ipConfiguration = isActiveActiveValid ? [ - { - properties: { - privateIPAllocationMethod: 'Dynamic' - subnet: { - id: '${vNetResourceId}/subnets/GatewaySubnet' - } - publicIPAddress: { - id: az.resourceId('Microsoft.Network/publicIPAddresses', gatewayPipName) - } - } - name: 'vNetGatewayConfig1' - } - { - properties: { - privateIPAllocationMethod: 'Dynamic' - subnet: { - id: '${vNetResourceId}/subnets/GatewaySubnet' - } - publicIPAddress: { - id: isActiveActiveValid ? az.resourceId('Microsoft.Network/publicIPAddresses', activeGatewayPipName) : az.resourceId('Microsoft.Network/publicIPAddresses', gatewayPipName) - } - } - name: 'vNetGatewayConfig2' - } -] : [ - { - properties: { - privateIPAllocationMethod: 'Dynamic' - subnet: { - id: '${vNetResourceId}/subnets/GatewaySubnet' +var ipConfiguration = isActiveActiveValid + ? [ + { + properties: { + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: '${vNetResourceId}/subnets/GatewaySubnet' + } + publicIPAddress: { + id: az.resourceId('Microsoft.Network/publicIPAddresses', gatewayPipName) + } + } + name: 'vNetGatewayConfig1' } - publicIPAddress: { - id: az.resourceId('Microsoft.Network/publicIPAddresses', gatewayPipName) + { + properties: { + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: '${vNetResourceId}/subnets/GatewaySubnet' + } + publicIPAddress: { + id: isActiveActiveValid + ? az.resourceId('Microsoft.Network/publicIPAddresses', activeGatewayPipName) + : az.resourceId('Microsoft.Network/publicIPAddresses', gatewayPipName) + } + } + name: 'vNetGatewayConfig2' } - } - name: 'vNetGatewayConfig1' - } -] - -var vpnClientConfiguration = !empty(clientRootCertData) ? { - vpnClientAddressPool: { - addressPrefixes: [ - vpnClientAddressPoolPrefix ] - } - vpnClientRootCertificates: [ - { - name: 'RootCert1' - properties: { - PublicCertData: clientRootCertData + : [ + { + properties: { + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: '${vNetResourceId}/subnets/GatewaySubnet' + } + publicIPAddress: { + id: az.resourceId('Microsoft.Network/publicIPAddresses', gatewayPipName) + } + } + name: 'vNetGatewayConfig1' } - } - ] - vpnClientRevokedCertificates: !empty(clientRevokedCertThumbprint) ? [ - { - name: 'RevokedCert1' - properties: { - Thumbprint: clientRevokedCertThumbprint + ] + +var vpnClientConfiguration = !empty(clientRootCertData) + ? { + vpnClientAddressPool: { + addressPrefixes: [ + vpnClientAddressPoolPrefix + ] } + vpnClientRootCertificates: [ + { + name: 'RootCert1' + properties: { + PublicCertData: clientRootCertData + } + } + ] + vpnClientRevokedCertificates: !empty(clientRevokedCertThumbprint) + ? [ + { + name: 'RevokedCert1' + properties: { + Thumbprint: clientRevokedCertThumbprint + } + } + ] + : null } - ] : null -} : !empty(vpnClientAadConfiguration) ? { - vpnClientAddressPool: { - addressPrefixes: [ - vpnClientAddressPoolPrefix - ] - } - aadTenant: vpnClientAadConfiguration.aadTenant - aadAudience: vpnClientAadConfiguration.aadAudience - aadIssuer: vpnClientAadConfiguration.aadIssuer - vpnAuthenticationTypes: vpnClientAadConfiguration.vpnAuthenticationTypes - vpnClientProtocols: vpnClientAadConfiguration.vpnClientProtocols -} : null + : !empty(vpnClientAadConfiguration) + ? { + vpnClientAddressPool: { + addressPrefixes: [ + vpnClientAddressPoolPrefix + ] + } + aadTenant: vpnClientAadConfiguration.aadTenant + aadAudience: vpnClientAadConfiguration.aadAudience + aadIssuer: vpnClientAadConfiguration.aadIssuer + vpnAuthenticationTypes: vpnClientAadConfiguration.vpnAuthenticationTypes + vpnClientProtocols: vpnClientAadConfiguration.vpnClientProtocols + } + : null var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + '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') + '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' + ) } // ================// // Deployments // // ================// -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: take('46d3xbcp.res.network-virtualnetworkgateway.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: take( + '46d3xbcp.res.network-virtualnetworkgateway.${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' + } } } } } -} // Public IPs @batchSize(1) -module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.2.0' = [for (virtualGatewayPublicIpName, index) in virtualGatewayPipNameVar: { - name: virtualGatewayPublicIpName - params: { +module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.2.0' = [ + for (virtualGatewayPublicIpName, index) in virtualGatewayPipNameVar: { name: virtualGatewayPublicIpName - diagnosticSettings: publicIpDiagnosticSettings - location: location - lock: lock - publicIPAllocationMethod: gatewayPipAllocationMethod - publicIpPrefixResourceId: !empty(publicIPPrefixResourceId) ? publicIPPrefixResourceId : '' - tags: tags - skuName: gatewayPipSku - zones: contains(zoneRedundantSkus, skuName) ? publicIpZones : [] - dnsSettings: { - domainNameLabel: length(virtualGatewayPipNameVar) == length(domainNameLabel) ? domainNameLabel[index] : virtualGatewayPublicIpName - domainNameLabelScope: '' + params: { + name: virtualGatewayPublicIpName + diagnosticSettings: publicIpDiagnosticSettings + location: location + lock: lock + publicIPAllocationMethod: gatewayPipAllocationMethod + publicIpPrefixResourceId: !empty(publicIPPrefixResourceId) ? publicIPPrefixResourceId : '' + tags: tags + skuName: gatewayPipSku + zones: contains(zoneRedundantSkus, skuName) ? publicIpZones : [] + dnsSettings: { + domainNameLabel: length(virtualGatewayPipNameVar) == length(domainNameLabel) + ? domainNameLabel[index] + : virtualGatewayPublicIpName + domainNameLabelScope: '' + } } } -}] +] // VNET Gateway // ============ @@ -312,9 +341,11 @@ resource virtualNetworkGateway 'Microsoft.Network/virtualNetworkGateways@2023-04 enablePrivateIpAddress: enablePrivateIpAddress enableBgpRouteTranslationForNat: enableBgpRouteTranslationForNat gatewayType: gatewayType - gatewayDefaultSite: !empty(gatewayDefaultSiteLocalNetworkGatewayId) ? { - id: gatewayDefaultSiteLocalNetworkGatewayId - } : null + gatewayDefaultSite: !empty(gatewayDefaultSiteLocalNetworkGatewayId) + ? { + id: gatewayDefaultSiteLocalNetworkGatewayId + } + : null sku: { name: skuName tier: skuName @@ -328,64 +359,81 @@ resource virtualNetworkGateway 'Microsoft.Network/virtualNetworkGateways@2023-04 ] } -module virtualNetworkGateway_natRules 'nat-rule/main.bicep' = [for (natRule, index) in natRules: { - name: '${deployment().name}-NATRule-${index}' - params: { - name: natRule.name - virtualNetworkGatewayName: virtualNetworkGateway.name - externalMappings: contains(natRule, 'externalMappings') ? natRule.externalMappings : [] - internalMappings: contains(natRule, 'internalMappings') ? natRule.internalMappings : [] - ipConfigurationId: contains(natRule, 'ipConfigurationId') ? natRule.ipConfigurationId : '' - mode: contains(natRule, 'mode') ? natRule.mode : '' - type: contains(natRule, 'type') ? natRule.type : '' +module virtualNetworkGateway_natRules 'nat-rule/main.bicep' = [ + for (natRule, index) in natRules: { + name: '${deployment().name}-NATRule-${index}' + params: { + name: natRule.name + virtualNetworkGatewayName: virtualNetworkGateway.name + externalMappings: contains(natRule, 'externalMappings') ? natRule.externalMappings : [] + internalMappings: contains(natRule, 'internalMappings') ? natRule.internalMappings : [] + ipConfigurationId: contains(natRule, 'ipConfigurationId') ? natRule.ipConfigurationId : '' + mode: contains(natRule, 'mode') ? natRule.mode : '' + type: contains(natRule, 'type') ? natRule.type : '' + } } -}] +] -resource virtualNetworkGateway_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.' +resource virtualNetworkGateway_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: virtualNetworkGateway } - scope: virtualNetworkGateway -} -resource virtualNetworkGateway_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 - 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 +resource virtualNetworkGateway_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 + 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 + } + scope: virtualNetworkGateway } - scope: virtualNetworkGateway -}] +] -resource virtualNetworkGateway_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(virtualNetworkGateway.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 +resource virtualNetworkGateway_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(virtualNetworkGateway.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: virtualNetworkGateway } - scope: virtualNetworkGateway -}] +] // ================// // Outputs // diff --git a/avm/res/network/virtual-network-gateway/main.json b/avm/res/network/virtual-network-gateway/main.json index 19057806a9..f8963435bd 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.25.53.49325", - "templateHash": "17858008949530514784" + "version": "0.26.54.24096", + "templateHash": "11853896150592473268" }, "name": "Virtual Network Gateways", "description": "This module deploys a Virtual Network Gateway.", @@ -1278,8 +1278,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3205216051078222233" + "version": "0.26.54.24096", + "templateHash": "3348839995550946472" }, "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 97aea584a5..f2be904ec8 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.25.53.49325", - "templateHash": "3205216051078222233" + "version": "0.26.54.24096", + "templateHash": "3348839995550946472" }, "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/aadvpn/main.test.bicep b/avm/res/network/virtual-network-gateway/tests/e2e/aadvpn/main.test.bicep index 67e5c483fe..0a15304be5 100644 --- a/avm/res/network/virtual-network-gateway/tests/e2e/aadvpn/main.test.bicep +++ b/avm/res/network/virtual-network-gateway/tests/e2e/aadvpn/main.test.bicep @@ -45,39 +45,41 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - skuName: 'VpnGw2AZ' - gatewayType: 'Vpn' - vNetResourceId: nestedDependencies.outputs.vnetResourceId - activeActive: false - domainNameLabel: [ - '${namePrefix}-dm-${serviceShort}' - ] - publicIpZones: [ - '1' - '2' - '3' - ] - vpnClientAadConfiguration: { - // The Application ID of the "Azure VPN" Azure AD Enterprise App for Azure Public - aadAudience: '41b23e61-6c1e-4545-b367-cd054e0ed4b4' - aadIssuer: 'https://sts.windows.net/${tenant().tenantId}/' - aadTenant: '${environment().authentication.loginEndpoint}/${tenant().tenantId}/' - vpnAuthenticationTypes: [ - 'AAD' +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' + skuName: 'VpnGw2AZ' + gatewayType: 'Vpn' + vNetResourceId: nestedDependencies.outputs.vnetResourceId + activeActive: false + domainNameLabel: [ + '${namePrefix}-dm-${serviceShort}' ] - vpnClientProtocols: [ - 'OpenVPN' + publicIpZones: [ + '1' + '2' + '3' ] + vpnClientAadConfiguration: { + // The Application ID of the "Azure VPN" Azure AD Enterprise App for Azure Public + aadAudience: '41b23e61-6c1e-4545-b367-cd054e0ed4b4' + aadIssuer: 'https://sts.windows.net/${tenant().tenantId}/' + aadTenant: '${environment().authentication.loginEndpoint}/${tenant().tenantId}/' + vpnAuthenticationTypes: [ + 'AAD' + ] + vpnClientProtocols: [ + 'OpenVPN' + ] + } + vpnType: 'RouteBased' } - vpnType: 'RouteBased' + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/virtual-network-gateway/tests/e2e/defaults/main.test.bicep b/avm/res/network/virtual-network-gateway/tests/e2e/defaults/main.test.bicep index 30e5429e29..9697d73cd0 100644 --- a/avm/res/network/virtual-network-gateway/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/virtual-network-gateway/tests/e2e/defaults/main.test.bicep @@ -47,22 +47,24 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - skuName: 'VpnGw2AZ' - gatewayType: 'Vpn' - vNetResourceId: nestedDependencies.outputs.vnetResourceId - publicIpZones: [ - '1' - '2' - '3' +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' + skuName: 'VpnGw2AZ' + gatewayType: 'Vpn' + vNetResourceId: nestedDependencies.outputs.vnetResourceId + publicIpZones: [ + '1' + '2' + '3' + ] + } + dependsOn: [ + nestedDependencies ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/virtual-network-gateway/tests/e2e/expressRoute/main.test.bicep b/avm/res/network/virtual-network-gateway/tests/e2e/expressRoute/main.test.bicep index 1c6f1816bd..a029c2890a 100644 --- a/avm/res/network/virtual-network-gateway/tests/e2e/expressRoute/main.test.bicep +++ b/avm/res/network/virtual-network-gateway/tests/e2e/expressRoute/main.test.bicep @@ -45,26 +45,28 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - skuName: 'ErGw1AZ' - gatewayType: 'ExpressRoute' - vNetResourceId: nestedDependencies.outputs.vnetResourceId - domainNameLabel: [ - '${namePrefix}-dm-${serviceShort}' - ] - gatewayPipName: '${namePrefix}-pip-${serviceShort}' - publicIpZones: [ - '1' - '2' - '3' +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' + skuName: 'ErGw1AZ' + gatewayType: 'ExpressRoute' + vNetResourceId: nestedDependencies.outputs.vnetResourceId + domainNameLabel: [ + '${namePrefix}-dm-${serviceShort}' + ] + gatewayPipName: '${namePrefix}-pip-${serviceShort}' + publicIpZones: [ + '1' + '2' + '3' + ] + } + dependsOn: [ + nestedDependencies ] } - dependsOn: [ - nestedDependencies - ] -}] +] 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 74f08061cd..70d7760061 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 @@ -61,108 +61,113 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - vpnGatewayGeneration: 'Generation2' - skuName: 'VpnGw2AZ' - gatewayType: 'Vpn' - vNetResourceId: nestedDependencies.outputs.vnetResourceId - activeActive: true - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - domainNameLabel: [ - '${namePrefix}-dm-${serviceShort}' - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - publicIpZones: [ - '1' - '2' - '3' - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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' + vpnGatewayGeneration: 'Generation2' + skuName: 'VpnGw2AZ' + gatewayType: 'Vpn' + vNetResourceId: nestedDependencies.outputs.vnetResourceId + activeActive: true + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + domainNameLabel: [ + '${namePrefix}-dm-${serviceShort}' + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + publicIpZones: [ + '1' + '2' + '3' + ] + 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' + } + ] + vpnType: 'RouteBased' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - vpnType: 'RouteBased' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + enablePrivateIpAddress: true + gatewayDefaultSiteLocalNetworkGatewayId: nestedDependencies.outputs.localNetworkGatewayResourceId + disableIPSecReplayProtection: true + allowRemoteVnetTraffic: true + natRules: [ + { + name: 'nat-rule-1-static-IngressSnat' + type: 'Static' + mode: 'IngressSnat' + internalMappings: [ + { + addressSpace: '10.100.0.0/24' + portRange: '100' + } + ] + externalMappings: [ + { + addressSpace: '192.168.0.0/24' + portRange: '100' + } + ] + } + { + name: 'nat-rule-2-dynamic-EgressSnat' + type: 'Static' + mode: 'EgressSnat' + internalMappings: [ + { + addressSpace: '172.16.0.0/26' + } + ] + externalMappings: [ + { + addressSpace: '10.200.0.0/26' + } + ] + } + ] + enableBgpRouteTranslationForNat: true } - enablePrivateIpAddress: true - gatewayDefaultSiteLocalNetworkGatewayId: nestedDependencies.outputs.localNetworkGatewayResourceId - disableIPSecReplayProtection: true - allowRemoteVnetTraffic: true - natRules: [ - { - name: 'nat-rule-1-static-IngressSnat' - type: 'Static' - mode: 'IngressSnat' - internalMappings: [ - { - addressSpace: '10.100.0.0/24' - portRange: '100' - } - ] - externalMappings: [ - { - addressSpace: '192.168.0.0/24' - portRange: '100' - } - ] - } - { - name: 'nat-rule-2-dynamic-EgressSnat' - type: 'Static' - mode: 'EgressSnat' - internalMappings: [ - { - addressSpace: '172.16.0.0/26' - } - ] - externalMappings: [ - { - addressSpace: '10.200.0.0/26' - } - ] - } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] - enableBgpRouteTranslationForNat: true } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/virtual-network-gateway/tests/e2e/vpn/main.test.bicep b/avm/res/network/virtual-network-gateway/tests/e2e/vpn/main.test.bicep index 7b8dedc495..678b967648 100644 --- a/avm/res/network/virtual-network-gateway/tests/e2e/vpn/main.test.bicep +++ b/avm/res/network/virtual-network-gateway/tests/e2e/vpn/main.test.bicep @@ -46,33 +46,35 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - vpnGatewayGeneration: 'Generation2' - skuName: 'VpnGw2AZ' - gatewayType: 'Vpn' - vNetResourceId: nestedDependencies.outputs.vnetResourceId - activeActive: true - domainNameLabel: [ - '${namePrefix}-dm-${serviceShort}' - ] - publicIpZones: [ - '1' - '2' - '3' +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' + vpnGatewayGeneration: 'Generation2' + skuName: 'VpnGw2AZ' + gatewayType: 'Vpn' + vNetResourceId: nestedDependencies.outputs.vnetResourceId + activeActive: true + domainNameLabel: [ + '${namePrefix}-dm-${serviceShort}' + ] + publicIpZones: [ + '1' + '2' + '3' + ] + vpnType: 'RouteBased' + enablePrivateIpAddress: true + gatewayDefaultSiteLocalNetworkGatewayId: nestedDependencies.outputs.localNetworkGatewayResourceId + disableIPSecReplayProtection: true + allowRemoteVnetTraffic: true + enableBgpRouteTranslationForNat: true + } + dependsOn: [ + nestedDependencies ] - vpnType: 'RouteBased' - enablePrivateIpAddress: true - gatewayDefaultSiteLocalNetworkGatewayId: nestedDependencies.outputs.localNetworkGatewayResourceId - disableIPSecReplayProtection: true - allowRemoteVnetTraffic: true - enableBgpRouteTranslationForNat: true } - dependsOn: [ - nestedDependencies - ] -}] +] 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 2056a7aeb7..a68a82df32 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 @@ -59,91 +59,93 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - vpnGatewayGeneration: 'Generation2' - skuName: 'VpnGw2AZ' - gatewayType: 'Vpn' - vNetResourceId: nestedDependencies.outputs.vnetResourceId - activeActive: true - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - domainNameLabel: [ - '${namePrefix}-dm-${serviceShort}' - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - publicIpZones: [ - '1' - '2' - '3' - ] - vpnType: 'RouteBased' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - enablePrivateIpAddress: true - gatewayDefaultSiteLocalNetworkGatewayId: nestedDependencies.outputs.localNetworkGatewayResourceId - disableIPSecReplayProtection: true - allowRemoteVnetTraffic: true - natRules: [ - { - name: 'nat-rule-1-static-IngressSnat' - type: 'Static' - mode: 'IngressSnat' - internalMappings: [ - { - addressSpace: '10.100.0.0/24' - portRange: '100' - } - ] - externalMappings: [ - { - addressSpace: '192.168.0.0/24' - portRange: '100' - } - ] +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' + vpnGatewayGeneration: 'Generation2' + skuName: 'VpnGw2AZ' + gatewayType: 'Vpn' + vNetResourceId: nestedDependencies.outputs.vnetResourceId + activeActive: true + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + domainNameLabel: [ + '${namePrefix}-dm-${serviceShort}' + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - name: 'nat-rule-2-dynamic-EgressSnat' - type: 'Static' - mode: 'EgressSnat' - internalMappings: [ - { - addressSpace: '172.16.0.0/26' - } - ] - externalMappings: [ - { - addressSpace: '10.200.0.0/26' - } - ] + publicIpZones: [ + '1' + '2' + '3' + ] + vpnType: 'RouteBased' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } + enablePrivateIpAddress: true + gatewayDefaultSiteLocalNetworkGatewayId: nestedDependencies.outputs.localNetworkGatewayResourceId + disableIPSecReplayProtection: true + allowRemoteVnetTraffic: true + natRules: [ + { + name: 'nat-rule-1-static-IngressSnat' + type: 'Static' + mode: 'IngressSnat' + internalMappings: [ + { + addressSpace: '10.100.0.0/24' + portRange: '100' + } + ] + externalMappings: [ + { + addressSpace: '192.168.0.0/24' + portRange: '100' + } + ] + } + { + name: 'nat-rule-2-dynamic-EgressSnat' + type: 'Static' + mode: 'EgressSnat' + internalMappings: [ + { + addressSpace: '172.16.0.0/26' + } + ] + externalMappings: [ + { + addressSpace: '10.200.0.0/26' + } + ] + } + ] + enableBgpRouteTranslationForNat: true + } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] - enableBgpRouteTranslationForNat: true } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/virtual-network/main.bicep b/avm/res/network/virtual-network/main.bicep index 5a8eaf6be6..e1d6854e1c 100644 --- a/avm/res/network/virtual-network/main.bicep +++ b/avm/res/network/virtual-network/main.bicep @@ -54,34 +54,44 @@ 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') + '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') + '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' + ) } // ============ // // Dependencies // // ============ // -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.network-virtualnetwork.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.network-virtualnetwork.${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 virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { name: name @@ -91,41 +101,61 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { addressSpace: { addressPrefixes: addressPrefixes } - ddosProtectionPlan: !empty(ddosProtectionPlanResourceId) ? { - id: ddosProtectionPlanResourceId - } : null - dhcpOptions: !empty(dnsServers) ? { - dnsServers: array(dnsServers) - } : null + ddosProtectionPlan: !empty(ddosProtectionPlanResourceId) + ? { + id: ddosProtectionPlanResourceId + } + : null + dhcpOptions: !empty(dnsServers) + ? { + dnsServers: array(dnsServers) + } + : null enableDdosProtection: !empty(ddosProtectionPlanResourceId) - encryption: vnetEncryption == true ? { - enabled: vnetEncryption - enforcement: vnetEncryptionEnforcement - } : null + encryption: vnetEncryption == true + ? { + enabled: vnetEncryption + enforcement: vnetEncryptionEnforcement + } + : null flowTimeoutInMinutes: flowTimeoutInMinutes != 0 ? flowTimeoutInMinutes : null - subnets: [for subnet in subnets: { - name: subnet.name - properties: { - addressPrefix: subnet.addressPrefix - addressPrefixes: contains(subnet, 'addressPrefixes') ? subnet.addressPrefixes : [] - applicationGatewayIPConfigurations: contains(subnet, 'applicationGatewayIPConfigurations') ? subnet.applicationGatewayIPConfigurations : [] - delegations: contains(subnet, 'delegations') ? subnet.delegations : [] - ipAllocations: contains(subnet, 'ipAllocations') ? subnet.ipAllocations : [] - natGateway: contains(subnet, 'natGatewayResourceId') ? { - id: subnet.natGatewayResourceId - } : null - networkSecurityGroup: contains(subnet, 'networkSecurityGroupResourceId') ? { - id: subnet.networkSecurityGroupResourceId - } : null - privateEndpointNetworkPolicies: contains(subnet, 'privateEndpointNetworkPolicies') ? subnet.privateEndpointNetworkPolicies : null - privateLinkServiceNetworkPolicies: contains(subnet, 'privateLinkServiceNetworkPolicies') ? subnet.privateLinkServiceNetworkPolicies : null - routeTable: contains(subnet, 'routeTableResourceId') ? { - id: subnet.routeTableResourceId - } : null - serviceEndpoints: contains(subnet, 'serviceEndpoints') ? subnet.serviceEndpoints : [] - serviceEndpointPolicies: contains(subnet, 'serviceEndpointPolicies') ? subnet.serviceEndpointPolicies : [] + subnets: [ + for subnet in subnets: { + name: subnet.name + properties: { + addressPrefix: subnet.addressPrefix + addressPrefixes: contains(subnet, 'addressPrefixes') ? subnet.addressPrefixes : [] + applicationGatewayIPConfigurations: contains(subnet, 'applicationGatewayIPConfigurations') + ? subnet.applicationGatewayIPConfigurations + : [] + delegations: contains(subnet, 'delegations') ? subnet.delegations : [] + ipAllocations: contains(subnet, 'ipAllocations') ? subnet.ipAllocations : [] + natGateway: contains(subnet, 'natGatewayResourceId') + ? { + id: subnet.natGatewayResourceId + } + : null + networkSecurityGroup: contains(subnet, 'networkSecurityGroupResourceId') + ? { + id: subnet.networkSecurityGroupResourceId + } + : null + privateEndpointNetworkPolicies: contains(subnet, 'privateEndpointNetworkPolicies') + ? subnet.privateEndpointNetworkPolicies + : null + privateLinkServiceNetworkPolicies: contains(subnet, 'privateLinkServiceNetworkPolicies') + ? subnet.privateLinkServiceNetworkPolicies + : null + routeTable: contains(subnet, 'routeTableResourceId') + ? { + id: subnet.routeTableResourceId + } + : null + serviceEndpoints: contains(subnet, 'serviceEndpoints') ? subnet.serviceEndpoints : [] + serviceEndpointPolicies: contains(subnet, 'serviceEndpointPolicies') ? subnet.serviceEndpointPolicies : [] + } } - }] + ] } } @@ -137,103 +167,148 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { // You can safely remove the below child module (virtualNetwork_subnets) in your consumption of the module (virtualNetworks) to reduce the template size and duplication. //NOTE End : ------------------------------------ -module virtualNetwork_subnets 'subnet/main.bicep' = [for (subnet, index) in subnets: { - name: '${uniqueString(deployment().name, location)}-subnet-${index}' - params: { - virtualNetworkName: virtualNetwork.name - name: subnet.name - addressPrefix: subnet.addressPrefix - addressPrefixes: contains(subnet, 'addressPrefixes') ? subnet.addressPrefixes : [] - applicationGatewayIPConfigurations: contains(subnet, 'applicationGatewayIPConfigurations') ? subnet.applicationGatewayIPConfigurations : [] - delegations: contains(subnet, 'delegations') ? subnet.delegations : [] - ipAllocations: contains(subnet, 'ipAllocations') ? subnet.ipAllocations : [] - natGatewayResourceId: contains(subnet, 'natGatewayResourceId') ? subnet.natGatewayResourceId : '' - networkSecurityGroupResourceId: contains(subnet, 'networkSecurityGroupResourceId') ? subnet.networkSecurityGroupResourceId : '' - privateEndpointNetworkPolicies: contains(subnet, 'privateEndpointNetworkPolicies') ? subnet.privateEndpointNetworkPolicies : '' - privateLinkServiceNetworkPolicies: contains(subnet, 'privateLinkServiceNetworkPolicies') ? subnet.privateLinkServiceNetworkPolicies : '' - roleAssignments: contains(subnet, 'roleAssignments') ? subnet.roleAssignments : [] - routeTableResourceId: contains(subnet, 'routeTableResourceId') ? subnet.routeTableResourceId : '' - serviceEndpointPolicies: contains(subnet, 'serviceEndpointPolicies') ? subnet.serviceEndpointPolicies : [] - serviceEndpoints: contains(subnet, 'serviceEndpoints') ? subnet.serviceEndpoints : [] +module virtualNetwork_subnets 'subnet/main.bicep' = [ + for (subnet, index) in subnets: { + name: '${uniqueString(deployment().name, location)}-subnet-${index}' + params: { + virtualNetworkName: virtualNetwork.name + name: subnet.name + addressPrefix: subnet.addressPrefix + addressPrefixes: contains(subnet, 'addressPrefixes') ? subnet.addressPrefixes : [] + applicationGatewayIPConfigurations: contains(subnet, 'applicationGatewayIPConfigurations') + ? subnet.applicationGatewayIPConfigurations + : [] + delegations: contains(subnet, 'delegations') ? subnet.delegations : [] + ipAllocations: contains(subnet, 'ipAllocations') ? subnet.ipAllocations : [] + natGatewayResourceId: contains(subnet, 'natGatewayResourceId') ? subnet.natGatewayResourceId : '' + networkSecurityGroupResourceId: contains(subnet, 'networkSecurityGroupResourceId') + ? subnet.networkSecurityGroupResourceId + : '' + privateEndpointNetworkPolicies: contains(subnet, 'privateEndpointNetworkPolicies') + ? subnet.privateEndpointNetworkPolicies + : '' + privateLinkServiceNetworkPolicies: contains(subnet, 'privateLinkServiceNetworkPolicies') + ? subnet.privateLinkServiceNetworkPolicies + : '' + roleAssignments: contains(subnet, 'roleAssignments') ? subnet.roleAssignments : [] + routeTableResourceId: contains(subnet, 'routeTableResourceId') ? subnet.routeTableResourceId : '' + serviceEndpointPolicies: contains(subnet, 'serviceEndpointPolicies') ? subnet.serviceEndpointPolicies : [] + serviceEndpoints: contains(subnet, 'serviceEndpoints') ? subnet.serviceEndpoints : [] + } } -}] +] // Local to Remote peering -module virtualNetwork_peering_local 'virtual-network-peering/main.bicep' = [for (peering, index) in peerings: { - name: '${uniqueString(deployment().name, location)}-virtualNetworkPeering-local-${index}' - params: { - localVnetName: virtualNetwork.name - remoteVirtualNetworkId: peering.remoteVirtualNetworkId - name: contains(peering, 'name') ? peering.name : '${name}-${last(split(peering.remoteVirtualNetworkId, '/'))}' - allowForwardedTraffic: contains(peering, 'allowForwardedTraffic') ? peering.allowForwardedTraffic : true - allowGatewayTransit: contains(peering, 'allowGatewayTransit') ? peering.allowGatewayTransit : false - allowVirtualNetworkAccess: contains(peering, 'allowVirtualNetworkAccess') ? peering.allowVirtualNetworkAccess : true - doNotVerifyRemoteGateways: contains(peering, 'doNotVerifyRemoteGateways') ? peering.doNotVerifyRemoteGateways : true - useRemoteGateways: contains(peering, 'useRemoteGateways') ? peering.useRemoteGateways : false +module virtualNetwork_peering_local 'virtual-network-peering/main.bicep' = [ + for (peering, index) in peerings: { + name: '${uniqueString(deployment().name, location)}-virtualNetworkPeering-local-${index}' + params: { + localVnetName: virtualNetwork.name + remoteVirtualNetworkId: peering.remoteVirtualNetworkId + name: contains(peering, 'name') ? peering.name : '${name}-${last(split(peering.remoteVirtualNetworkId, '/'))}' + allowForwardedTraffic: contains(peering, 'allowForwardedTraffic') ? peering.allowForwardedTraffic : true + allowGatewayTransit: contains(peering, 'allowGatewayTransit') ? peering.allowGatewayTransit : false + allowVirtualNetworkAccess: contains(peering, 'allowVirtualNetworkAccess') + ? peering.allowVirtualNetworkAccess + : true + doNotVerifyRemoteGateways: contains(peering, 'doNotVerifyRemoteGateways') + ? peering.doNotVerifyRemoteGateways + : true + useRemoteGateways: contains(peering, 'useRemoteGateways') ? peering.useRemoteGateways : false + } } -}] +] // Remote to local peering (reverse) -module virtualNetwork_peering_remote 'virtual-network-peering/main.bicep' = [for (peering, index) in peerings: if (contains(peering, 'remotePeeringEnabled') ? peering.remotePeeringEnabled == true : false) { - name: '${uniqueString(deployment().name, location)}-virtualNetworkPeering-remote-${index}' - scope: resourceGroup(split(peering.remoteVirtualNetworkId, '/')[2], split(peering.remoteVirtualNetworkId, '/')[4]) - params: { - localVnetName: last(split(peering.remoteVirtualNetworkId, '/'))! - remoteVirtualNetworkId: virtualNetwork.id - name: contains(peering, 'remotePeeringName') ? peering.remotePeeringName : '${last(split(peering.remoteVirtualNetworkId, '/'))}-${name}' - allowForwardedTraffic: contains(peering, 'remotePeeringAllowForwardedTraffic') ? peering.remotePeeringAllowForwardedTraffic : true - allowGatewayTransit: contains(peering, 'remotePeeringAllowGatewayTransit') ? peering.remotePeeringAllowGatewayTransit : false - allowVirtualNetworkAccess: contains(peering, 'remotePeeringAllowVirtualNetworkAccess') ? peering.remotePeeringAllowVirtualNetworkAccess : true - doNotVerifyRemoteGateways: contains(peering, 'remotePeeringDoNotVerifyRemoteGateways') ? peering.remotePeeringDoNotVerifyRemoteGateways : true - useRemoteGateways: contains(peering, 'remotePeeringUseRemoteGateways') ? peering.remotePeeringUseRemoteGateways : false +module virtualNetwork_peering_remote 'virtual-network-peering/main.bicep' = [ + for (peering, index) in peerings: if (contains(peering, 'remotePeeringEnabled') + ? peering.remotePeeringEnabled == true + : false) { + name: '${uniqueString(deployment().name, location)}-virtualNetworkPeering-remote-${index}' + scope: resourceGroup(split(peering.remoteVirtualNetworkId, '/')[2], split(peering.remoteVirtualNetworkId, '/')[4]) + params: { + localVnetName: last(split(peering.remoteVirtualNetworkId, '/'))! + remoteVirtualNetworkId: virtualNetwork.id + name: contains(peering, 'remotePeeringName') + ? peering.remotePeeringName + : '${last(split(peering.remoteVirtualNetworkId, '/'))}-${name}' + allowForwardedTraffic: contains(peering, 'remotePeeringAllowForwardedTraffic') + ? peering.remotePeeringAllowForwardedTraffic + : true + allowGatewayTransit: contains(peering, 'remotePeeringAllowGatewayTransit') + ? peering.remotePeeringAllowGatewayTransit + : false + allowVirtualNetworkAccess: contains(peering, 'remotePeeringAllowVirtualNetworkAccess') + ? peering.remotePeeringAllowVirtualNetworkAccess + : true + doNotVerifyRemoteGateways: contains(peering, 'remotePeeringDoNotVerifyRemoteGateways') + ? peering.remotePeeringDoNotVerifyRemoteGateways + : true + useRemoteGateways: contains(peering, 'remotePeeringUseRemoteGateways') + ? peering.remotePeeringUseRemoteGateways + : false + } } -}] - -resource virtualNetwork_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.' +] + +resource virtualNetwork_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: virtualNetwork } - scope: virtualNetwork -} -resource virtualNetwork_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 - 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 +resource virtualNetwork_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 + 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 + } + scope: virtualNetwork } - scope: virtualNetwork -}] - -resource virtualNetwork_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(virtualNetwork.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) - properties: { - roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : 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 +] + +resource virtualNetwork_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(virtualNetwork.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) + ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] + : 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: virtualNetwork } - scope: virtualNetwork -}] +] @description('The resource group the virtual network was deployed into.') output resourceGroupName string = resourceGroup().name @@ -248,7 +323,9 @@ output name string = virtualNetwork.name output subnetNames array = [for subnet in subnets: subnet.name] @description('The resource IDs of the deployed subnets.') -output subnetResourceIds array = [for subnet in subnets: az.resourceId('Microsoft.Network/virtualNetworks/subnets', name, subnet.name)] +output subnetResourceIds array = [ + for subnet in subnets: az.resourceId('Microsoft.Network/virtualNetworks/subnets', name, subnet.name) +] @description('The location the resource was deployed into.') output location string = virtualNetwork.location diff --git a/avm/res/network/virtual-network/main.json b/avm/res/network/virtual-network/main.json index 755e75f48d..8e3664e661 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.25.53.49325", - "templateHash": "10848130532872395336" + "version": "0.26.54.24096", + "templateHash": "11377673418536997302" }, "name": "Virtual Networks", "description": "This module deploys a Virtual Network (vNet).", @@ -523,8 +523,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17033578581013380517" + "version": "0.26.54.24096", + "templateHash": "11309828149329550402" }, "name": "Virtual Network Subnets", "description": "This module deploys a Virtual Network Subnet.", @@ -849,8 +849,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12334551415753639891" + "version": "0.26.54.24096", + "templateHash": "2926837656927862519" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", @@ -994,8 +994,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12334551415753639891" + "version": "0.26.54.24096", + "templateHash": "2926837656927862519" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", diff --git a/avm/res/network/virtual-network/subnet/main.bicep b/avm/res/network/virtual-network/subnet/main.bicep index f3b7d07615..bbfc27b1ab 100644 --- a/avm/res/network/virtual-network/subnet/main.bicep +++ b/avm/res/network/virtual-network/subnet/main.bicep @@ -59,11 +59,20 @@ param roleAssignments roleAssignmentType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + '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') + '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 virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' existing = { @@ -75,19 +84,27 @@ resource subnet 'Microsoft.Network/virtualNetworks/subnets@2023-04-01' = { parent: virtualNetwork properties: { addressPrefix: addressPrefix - networkSecurityGroup: !empty(networkSecurityGroupResourceId) ? { - id: networkSecurityGroupResourceId - } : null - routeTable: !empty(routeTableResourceId) ? { - id: routeTableResourceId - } : null - natGateway: !empty(natGatewayResourceId) ? { - id: natGatewayResourceId - } : null + networkSecurityGroup: !empty(networkSecurityGroupResourceId) + ? { + id: networkSecurityGroupResourceId + } + : null + routeTable: !empty(routeTableResourceId) + ? { + id: routeTableResourceId + } + : null + natGateway: !empty(natGatewayResourceId) + ? { + id: natGatewayResourceId + } + : null serviceEndpoints: serviceEndpoints delegations: delegations privateEndpointNetworkPolicies: !empty(privateEndpointNetworkPolicies) ? any(privateEndpointNetworkPolicies) : null - privateLinkServiceNetworkPolicies: !empty(privateLinkServiceNetworkPolicies) ? any(privateLinkServiceNetworkPolicies) : null + privateLinkServiceNetworkPolicies: !empty(privateLinkServiceNetworkPolicies) + ? any(privateLinkServiceNetworkPolicies) + : null addressPrefixes: addressPrefixes applicationGatewayIPConfigurations: applicationGatewayIPConfigurations ipAllocations: ipAllocations @@ -95,19 +112,23 @@ resource subnet 'Microsoft.Network/virtualNetworks/subnets@2023-04-01' = { } } -resource subnet_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(subnet.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) - properties: { - roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : 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 +resource subnet_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(subnet.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) + ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] + : 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: subnet } - scope: subnet -}] +] @description('The resource group the virtual network peering was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/virtual-network/subnet/main.json b/avm/res/network/virtual-network/subnet/main.json index 55f868f9fd..4134fdbfa4 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.25.53.49325", - "templateHash": "17033578581013380517" + "version": "0.26.54.24096", + "templateHash": "11309828149329550402" }, "name": "Virtual Network Subnets", "description": "This module deploys a Virtual Network Subnet.", diff --git a/avm/res/network/virtual-network/tests/e2e/defaults/main.test.bicep b/avm/res/network/virtual-network/tests/e2e/defaults/main.test.bicep index c5023d1f86..2c649a41d8 100644 --- a/avm/res/network/virtual-network/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/virtual-network/tests/e2e/defaults/main.test.bicep @@ -36,14 +36,16 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - addressPrefixes: [ - '10.0.0.0/16' - ] +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 + addressPrefixes: [ + '10.0.0.0/16' + ] + } } -}] +] diff --git a/avm/res/network/virtual-network/tests/e2e/max/main.test.bicep b/avm/res/network/virtual-network/tests/e2e/max/main.test.bicep index 130570f046..0eff43a79d 100644 --- a/avm/res/network/virtual-network/tests/e2e/max/main.test.bicep +++ b/avm/res/network/virtual-network/tests/e2e/max/main.test.bicep @@ -63,109 +63,111 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t var addressPrefix = '10.0.0.0/16' @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 - addressPrefixes: [ - addressPrefix - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - dnsServers: [ - '10.0.1.4' - '10.0.1.5' - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - flowTimeoutInMinutes: 20 - subnets: [ - { - addressPrefix: cidrSubnet(addressPrefix, 24, 0) - name: 'GatewaySubnet' - } - { - addressPrefix: cidrSubnet(addressPrefix, 24, 1) - name: '${namePrefix}-az-subnet-x-001' - networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - routeTableResourceId: nestedDependencies.outputs.routeTableResourceId - serviceEndpoints: [ - { - service: 'Microsoft.Storage' - } - { - service: 'Microsoft.Sql' - } - ] - } - { - addressPrefix: cidrSubnet(addressPrefix, 24, 2) - delegations: [ - { - name: 'netappDel' - properties: { - serviceName: 'Microsoft.Netapp/volumes' +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 + addressPrefixes: [ + addressPrefix + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' } - } - ] - name: '${namePrefix}-az-subnet-x-002' - networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId - } - { - addressPrefix: cidrSubnet(addressPrefix, 24, 3) - name: '${namePrefix}-az-subnet-x-003' - networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId - privateEndpointNetworkPolicies: 'Disabled' - privateLinkServiceNetworkPolicies: 'Enabled' + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + dnsServers: [ + '10.0.1.4' + '10.0.1.5' + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - addressPrefix: cidrSubnet(addressPrefix, 24, 4) - name: 'AzureBastionSubnet' - networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupBastionResourceId - } - { - addressPrefix: cidrSubnet(addressPrefix, 24, 5) - name: 'AzureFirewallSubnet' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + flowTimeoutInMinutes: 20 + subnets: [ + { + addressPrefix: cidrSubnet(addressPrefix, 24, 0) + name: 'GatewaySubnet' + } + { + addressPrefix: cidrSubnet(addressPrefix, 24, 1) + name: '${namePrefix}-az-subnet-x-001' + networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + routeTableResourceId: nestedDependencies.outputs.routeTableResourceId + serviceEndpoints: [ + { + service: 'Microsoft.Storage' + } + { + service: 'Microsoft.Sql' + } + ] + } + { + addressPrefix: cidrSubnet(addressPrefix, 24, 2) + delegations: [ + { + name: 'netappDel' + properties: { + serviceName: 'Microsoft.Netapp/volumes' + } + } + ] + name: '${namePrefix}-az-subnet-x-002' + networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId + } + { + addressPrefix: cidrSubnet(addressPrefix, 24, 3) + name: '${namePrefix}-az-subnet-x-003' + networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId + privateEndpointNetworkPolicies: 'Disabled' + privateLinkServiceNetworkPolicies: 'Enabled' + } + { + addressPrefix: cidrSubnet(addressPrefix, 24, 4) + name: 'AzureBastionSubnet' + networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupBastionResourceId + } + { + addressPrefix: cidrSubnet(addressPrefix, 24, 5) + name: 'AzureFirewallSubnet' + } + ] + 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' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/network/virtual-network/tests/e2e/vnetPeering/main.test.bicep b/avm/res/network/virtual-network/tests/e2e/vnetPeering/main.test.bicep index 9acbeebb62..cbb86623e3 100644 --- a/avm/res/network/virtual-network/tests/e2e/vnetPeering/main.test.bicep +++ b/avm/res/network/virtual-network/tests/e2e/vnetPeering/main.test.bicep @@ -46,50 +46,52 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - addressPrefixes: [ - '10.1.0.0/24' - ] - subnets: [ - { - addressPrefix: '10.1.0.0/26' - name: 'GatewaySubnet' - } - { - addressPrefix: '10.1.0.64/26' - name: 'AzureBastionSubnet' - networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupBastionResourceId +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 + addressPrefixes: [ + '10.1.0.0/24' + ] + subnets: [ + { + addressPrefix: '10.1.0.0/26' + name: 'GatewaySubnet' + } + { + addressPrefix: '10.1.0.64/26' + name: 'AzureBastionSubnet' + networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupBastionResourceId + } + { + addressPrefix: '10.1.0.128/26' + name: 'AzureFirewallSubnet' + } + ] + peerings: [ + { + allowForwardedTraffic: true + allowGatewayTransit: false + allowVirtualNetworkAccess: true + remotePeeringAllowForwardedTraffic: true + remotePeeringAllowVirtualNetworkAccess: true + remotePeeringEnabled: true + remotePeeringName: 'customName' + remoteVirtualNetworkId: nestedDependencies.outputs.virtualNetworkResourceId + useRemoteGateways: false + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - addressPrefix: '10.1.0.128/26' - name: 'AzureFirewallSubnet' - } - ] - peerings: [ - { - allowForwardedTraffic: true - allowGatewayTransit: false - allowVirtualNetworkAccess: true - remotePeeringAllowForwardedTraffic: true - remotePeeringAllowVirtualNetworkAccess: true - remotePeeringEnabled: true - remotePeeringName: 'customName' - remoteVirtualNetworkId: nestedDependencies.outputs.virtualNetworkResourceId - useRemoteGateways: false - } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/virtual-network/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/virtual-network/tests/e2e/waf-aligned/main.test.bicep index d1063b5fdc..b5f66c589d 100644 --- a/avm/res/network/virtual-network/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/virtual-network/tests/e2e/waf-aligned/main.test.bicep @@ -63,102 +63,104 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t var addressPrefix = '10.0.0.0/16' @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 - addressPrefixes: [ - addressPrefix - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - dnsServers: [ - '10.0.1.4' - '10.0.1.5' - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - flowTimeoutInMinutes: 20 - subnets: [ - { - addressPrefix: cidrSubnet(addressPrefix, 24, 0) - name: 'GatewaySubnet' - } - { - addressPrefix: cidrSubnet(addressPrefix, 24, 1) - name: '${namePrefix}-az-subnet-x-001' - networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - routeTableResourceId: nestedDependencies.outputs.routeTableResourceId - serviceEndpoints: [ - { - service: 'Microsoft.Storage' - } - { - service: 'Microsoft.Sql' - } - ] - } - { - addressPrefix: cidrSubnet(addressPrefix, 24, 2) - delegations: [ - { - name: 'netappDel' - properties: { - serviceName: 'Microsoft.Netapp/volumes' +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 + addressPrefixes: [ + addressPrefix + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' } - } - ] - name: '${namePrefix}-az-subnet-x-002' - networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId - } - { - addressPrefix: cidrSubnet(addressPrefix, 24, 3) - name: '${namePrefix}-az-subnet-x-003' - networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId - privateEndpointNetworkPolicies: 'Disabled' - privateLinkServiceNetworkPolicies: 'Enabled' - } - { - addressPrefix: cidrSubnet(addressPrefix, 24, 4) - name: 'AzureBastionSubnet' - networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupBastionResourceId + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + dnsServers: [ + '10.0.1.4' + '10.0.1.5' + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - addressPrefix: cidrSubnet(addressPrefix, 24, 5) - name: 'AzureFirewallSubnet' + flowTimeoutInMinutes: 20 + subnets: [ + { + addressPrefix: cidrSubnet(addressPrefix, 24, 0) + name: 'GatewaySubnet' + } + { + addressPrefix: cidrSubnet(addressPrefix, 24, 1) + name: '${namePrefix}-az-subnet-x-001' + networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + routeTableResourceId: nestedDependencies.outputs.routeTableResourceId + serviceEndpoints: [ + { + service: 'Microsoft.Storage' + } + { + service: 'Microsoft.Sql' + } + ] + } + { + addressPrefix: cidrSubnet(addressPrefix, 24, 2) + delegations: [ + { + name: 'netappDel' + properties: { + serviceName: 'Microsoft.Netapp/volumes' + } + } + ] + name: '${namePrefix}-az-subnet-x-002' + networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId + } + { + addressPrefix: cidrSubnet(addressPrefix, 24, 3) + name: '${namePrefix}-az-subnet-x-003' + networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupResourceId + privateEndpointNetworkPolicies: 'Disabled' + privateLinkServiceNetworkPolicies: 'Enabled' + } + { + addressPrefix: cidrSubnet(addressPrefix, 24, 4) + name: 'AzureBastionSubnet' + networkSecurityGroupResourceId: nestedDependencies.outputs.networkSecurityGroupBastionResourceId + } + { + addressPrefix: cidrSubnet(addressPrefix, 24, 5) + name: 'AzureFirewallSubnet' + } + ] + 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' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] 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 2c6b4fadea..b28eeb4471 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.25.53.49325", - "templateHash": "12334551415753639891" + "version": "0.26.54.24096", + "templateHash": "2926837656927862519" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", diff --git a/avm/res/network/virtual-wan/main.bicep b/avm/res/network/virtual-wan/main.bicep index c130a7eae3..c3c2777288 100644 --- a/avm/res/network/virtual-wan/main.bicep +++ b/avm/res/network/virtual-wan/main.bicep @@ -38,30 +38,40 @@ 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') + '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') + '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 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 @@ -75,28 +85,37 @@ resource virtualWan 'Microsoft.Network/virtualWans@2023-04-01' = { } } -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.' +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 } - 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 +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 } - scope: virtualWan -}] +] @description('The name of the virtual WAN.') output name string = virtualWan.name diff --git a/avm/res/network/virtual-wan/main.json b/avm/res/network/virtual-wan/main.json index 4bdfcb62dc..5b286a4756 100644 --- a/avm/res/network/virtual-wan/main.json +++ b/avm/res/network/virtual-wan/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "5785178353049312317" + "version": "0.26.54.24096", + "templateHash": "8898881452138081725" }, "name": "Virtual WANs", "description": "This module deploys a Virtual WAN.", 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 index 02d9cb1c28..4a655c13bf 100644 --- a/avm/res/network/virtual-wan/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/virtual-wan/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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 index 2ab8334b56..9f6d367115 100644 --- a/avm/res/network/virtual-wan/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/virtual-wan/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param resourceLocation string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: resourceLocation + name: managedIdentityName + location: resourceLocation } @description('The principal ID of the created Managed Identity.') 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 index ba7df165ee..909f2c7969 100644 --- a/avm/res/network/virtual-wan/tests/e2e/max/main.test.bicep +++ b/avm/res/network/virtual-wan/tests/e2e/max/main.test.bicep @@ -45,44 +45,49 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' +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' } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' } - { - 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' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] 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 index a7f42aee7b..7be39e253a 100644 --- a/avm/res/network/virtual-wan/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/network/virtual-wan/tests/e2e/waf-aligned/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') 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 index 9ccbb889d3..bed35b64ae 100644 --- 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 @@ -45,23 +45,25 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' +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' + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/vpn-gateway/main.bicep b/avm/res/network/vpn-gateway/main.bicep index 436d997355..b917b16560 100644 --- a/avm/res/network/vpn-gateway/main.bicep +++ b/avm/res/network/vpn-gateway/main.bicep @@ -38,23 +38,27 @@ param lock lockType @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: take('46d3xbcp.res.network-vpngateway.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: take( + '46d3xbcp.res.network-vpngateway.${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 vpnGateway 'Microsoft.Network/vpnGateways@2023-04-01' = { name: name @@ -65,75 +69,86 @@ resource vpnGateway 'Microsoft.Network/vpnGateways@2023-04-01' = { enableBgpRouteTranslationForNat: enableBgpRouteTranslationForNat isRoutingPreferenceInternet: isRoutingPreferenceInternet vpnGatewayScaleUnit: vpnGatewayScaleUnit - connections: [for (connection, index) in vpnConnections: { - name: connection.name - properties: { - connectionBandwidth: connection.?connectionBandwidth - enableBgp: connection.?enableBgp - enableInternetSecurity: connection.?enableInternetSecurity - remoteVpnSite: contains(connection, 'remoteVpnSiteResourceId') ? { - id: connection.remoteVpnSiteResourceId - } : null - enableRateLimiting: connection.?enableRateLimiting - routingConfiguration: connection.?routingConfiguration - routingWeight: connection.?routingWeight - sharedKey: connection.?sharedKey - useLocalAzureIpAddress: connection.?useLocalAzureIpAddress - usePolicyBasedTrafficSelectors: connection.?usePolicyBasedTrafficSelectors - vpnConnectionProtocolType: connection.?vpnConnectionProtocolType - ipsecPolicies: connection.?ipsecPolicies - trafficSelectorPolicies: connection.?trafficSelectorPolicies - vpnLinkConnections: connection.?vpnLinkConnections + connections: [ + for (connection, index) in vpnConnections: { + name: connection.name + properties: { + connectionBandwidth: connection.?connectionBandwidth + enableBgp: connection.?enableBgp + enableInternetSecurity: connection.?enableInternetSecurity + remoteVpnSite: contains(connection, 'remoteVpnSiteResourceId') + ? { + id: connection.remoteVpnSiteResourceId + } + : null + enableRateLimiting: connection.?enableRateLimiting + routingConfiguration: connection.?routingConfiguration + routingWeight: connection.?routingWeight + sharedKey: connection.?sharedKey + useLocalAzureIpAddress: connection.?useLocalAzureIpAddress + usePolicyBasedTrafficSelectors: connection.?usePolicyBasedTrafficSelectors + vpnConnectionProtocolType: connection.?vpnConnectionProtocolType + ipsecPolicies: connection.?ipsecPolicies + trafficSelectorPolicies: connection.?trafficSelectorPolicies + vpnLinkConnections: connection.?vpnLinkConnections + } } - }] + ] virtualHub: { id: virtualHubResourceId } } } -resource vpnGateway_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.' +resource vpnGateway_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: vpnGateway } - scope: vpnGateway -} -module vpnGateway_natRules 'nat-rule/main.bicep' = [for (natRule, index) in natRules: { - name: '${deployment().name}-NATRule-${index}' - params: { - name: natRule.name - vpnGatewayName: vpnGateway.name - externalMappings: contains(natRule, 'externalMappings') ? natRule.externalMappings : [] - internalMappings: contains(natRule, 'internalMappings') ? natRule.internalMappings : [] - ipConfigurationId: contains(natRule, 'ipConfigurationId') ? natRule.ipConfigurationId : '' - mode: natRule.?mode - type: natRule.?type +module vpnGateway_natRules 'nat-rule/main.bicep' = [ + for (natRule, index) in natRules: { + name: '${deployment().name}-NATRule-${index}' + params: { + name: natRule.name + vpnGatewayName: vpnGateway.name + externalMappings: contains(natRule, 'externalMappings') ? natRule.externalMappings : [] + internalMappings: contains(natRule, 'internalMappings') ? natRule.internalMappings : [] + ipConfigurationId: contains(natRule, 'ipConfigurationId') ? natRule.ipConfigurationId : '' + mode: natRule.?mode + type: natRule.?type + } } -}] - -module vpnGateway_vpnConnections 'vpn-connection/main.bicep' = [for (connection, index) in vpnConnections: { - name: '${deployment().name}-Connection-${index}' - params: { - name: connection.name - vpnGatewayName: vpnGateway.name - connectionBandwidth: connection.?connectionBandwidth - enableBgp: connection.?enableBgp - enableInternetSecurity: connection.?enableInternetSecurity - remoteVpnSiteResourceId: connection.?remoteVpnSiteResourceId - enableRateLimiting: connection.?enableRateLimiting - routingConfiguration: connection.?routingConfiguration - routingWeight: connection.?routingWeight - sharedKey: connection.?sharedKey - useLocalAzureIpAddress: connection.?useLocalAzureIpAddress - usePolicyBasedTrafficSelectors: connection.?usePolicyBasedTrafficSelectors - vpnConnectionProtocolType: connection.?vpnConnectionProtocolType - trafficSelectorPolicies: connection.?trafficSelectorPolicies - vpnLinkConnections: connection.?vpnLinkConnections +] + +module vpnGateway_vpnConnections 'vpn-connection/main.bicep' = [ + for (connection, index) in vpnConnections: { + name: '${deployment().name}-Connection-${index}' + params: { + name: connection.name + vpnGatewayName: vpnGateway.name + connectionBandwidth: connection.?connectionBandwidth + enableBgp: connection.?enableBgp + enableInternetSecurity: connection.?enableInternetSecurity + remoteVpnSiteResourceId: connection.?remoteVpnSiteResourceId + enableRateLimiting: connection.?enableRateLimiting + routingConfiguration: connection.?routingConfiguration + routingWeight: connection.?routingWeight + sharedKey: connection.?sharedKey + useLocalAzureIpAddress: connection.?useLocalAzureIpAddress + usePolicyBasedTrafficSelectors: connection.?usePolicyBasedTrafficSelectors + vpnConnectionProtocolType: connection.?vpnConnectionProtocolType + trafficSelectorPolicies: connection.?trafficSelectorPolicies + vpnLinkConnections: connection.?vpnLinkConnections + } } -}] +] @description('The name of the VPN gateway.') output name string = vpnGateway.name diff --git a/avm/res/network/vpn-gateway/main.json b/avm/res/network/vpn-gateway/main.json index 515119c148..57d805dbfa 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.25.53.49325", - "templateHash": "18311728331837293497" + "version": "0.26.54.24096", + "templateHash": "16246563114829739207" }, "name": "VPN Gateways", "description": "This module deploys a VPN Gateway.", @@ -235,8 +235,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10009969919084019961" + "version": "0.26.54.24096", + "templateHash": "15540036539979482149" }, "name": "VPN Gateway NAT Rules", "description": "This module deploys a VPN Gateway NAT Rule.", @@ -417,8 +417,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2523279657002252302" + "version": "0.26.54.24096", + "templateHash": "13703101435058090684" }, "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 8cb6ebdcd5..efeb649095 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.25.53.49325", - "templateHash": "10009969919084019961" + "version": "0.26.54.24096", + "templateHash": "15540036539979482149" }, "name": "VPN Gateway NAT Rules", "description": "This module deploys a VPN Gateway NAT Rule.", diff --git a/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep b/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep index f87549450c..8debc2b069 100644 --- a/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep @@ -46,15 +46,17 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - virtualHubResourceId: nestedDependencies.outputs.virtualHubResourceId +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' + virtualHubResourceId: nestedDependencies.outputs.virtualHubResourceId + } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep b/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep index 57f89afa57..b51c76ee82 100644 --- a/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep +++ b/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep @@ -46,59 +46,61 @@ module nestedDependencies 'dependencies.bicep' = { // 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' - virtualHubResourceId: nestedDependencies.outputs.virtualHubResourceId - bgpSettings: { - asn: 65515 - peerWeight: 0 - } - vpnConnections: [ - { - connectionBandwidth: 100 - enableBgp: false - name: 'Connection-${last(split(nestedDependencies.outputs.vpnSiteResourceId, '/'))}' - remoteVpnSiteResourceId: nestedDependencies.outputs.vpnSiteResourceId - enableInternetSecurity: true - vpnConnectionProtocolType: 'IKEv2' - enableRateLimiting: false - useLocalAzureIpAddress: false - usePolicyBasedTrafficSelectors: false - routingWeight: 0 +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' + virtualHubResourceId: nestedDependencies.outputs.virtualHubResourceId + bgpSettings: { + asn: 65515 + peerWeight: 0 } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - natRules: [ - { - externalMappings: [ - { - addressSpace: '192.168.21.0/24' - } - ] - internalMappings: [ - { - addressSpace: '10.4.0.0/24' - } - ] - mode: 'EgressSnat' - name: 'natRule1' - type: 'Static' + vpnConnections: [ + { + connectionBandwidth: 100 + enableBgp: false + name: 'Connection-${last(split(nestedDependencies.outputs.vpnSiteResourceId, '/'))}' + remoteVpnSiteResourceId: nestedDependencies.outputs.vpnSiteResourceId + enableInternetSecurity: true + vpnConnectionProtocolType: 'IKEv2' + enableRateLimiting: false + useLocalAzureIpAddress: false + usePolicyBasedTrafficSelectors: false + routingWeight: 0 + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + natRules: [ + { + externalMappings: [ + { + addressSpace: '192.168.21.0/24' + } + ] + internalMappings: [ + { + addressSpace: '10.4.0.0/24' + } + ] + mode: 'EgressSnat' + name: 'natRule1' + type: 'Static' + } + ] + 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' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep index 69c900d82b..5213b39d56 100644 --- a/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep @@ -46,59 +46,61 @@ module nestedDependencies 'dependencies.bicep' = { // 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' - virtualHubResourceId: nestedDependencies.outputs.virtualHubResourceId - bgpSettings: { - asn: 65515 - peerWeight: 0 - } - vpnConnections: [ - { - connectionBandwidth: 100 - enableBgp: false - name: 'Connection-${last(split(nestedDependencies.outputs.vpnSiteResourceId, '/'))}' - remoteVpnSiteResourceId: nestedDependencies.outputs.vpnSiteResourceId - enableInternetSecurity: true - vpnConnectionProtocolType: 'IKEv2' - enableRateLimiting: false - useLocalAzureIpAddress: false - usePolicyBasedTrafficSelectors: false - routingWeight: 0 +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' + virtualHubResourceId: nestedDependencies.outputs.virtualHubResourceId + bgpSettings: { + asn: 65515 + peerWeight: 0 } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - natRules: [ - { - externalMappings: [ - { - addressSpace: '192.168.21.0/24' - } - ] - internalMappings: [ - { - addressSpace: '10.4.0.0/24' - } - ] - mode: 'EgressSnat' - name: 'natRule1' - type: 'Static' + vpnConnections: [ + { + connectionBandwidth: 100 + enableBgp: false + name: 'Connection-${last(split(nestedDependencies.outputs.vpnSiteResourceId, '/'))}' + remoteVpnSiteResourceId: nestedDependencies.outputs.vpnSiteResourceId + enableInternetSecurity: true + vpnConnectionProtocolType: 'IKEv2' + enableRateLimiting: false + useLocalAzureIpAddress: false + usePolicyBasedTrafficSelectors: false + routingWeight: 0 + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + natRules: [ + { + externalMappings: [ + { + addressSpace: '192.168.21.0/24' + } + ] + internalMappings: [ + { + addressSpace: '10.4.0.0/24' + } + ] + mode: 'EgressSnat' + name: 'natRule1' + type: 'Static' + } + ] + 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' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/vpn-gateway/vpn-connection/main.bicep b/avm/res/network/vpn-gateway/vpn-connection/main.bicep index f189154ce4..3f3bb8beac 100644 --- a/avm/res/network/vpn-gateway/vpn-connection/main.bicep +++ b/avm/res/network/vpn-gateway/vpn-connection/main.bicep @@ -68,9 +68,11 @@ resource vpnConnection 'Microsoft.Network/vpnGateways/vpnConnections@2023-04-01' enableInternetSecurity: enableInternetSecurity enableRateLimiting: enableRateLimiting ipsecPolicies: ipsecPolicies - remoteVpnSite: !empty(remoteVpnSiteResourceId) ? { - id: remoteVpnSiteResourceId - } : null + remoteVpnSite: !empty(remoteVpnSiteResourceId) + ? { + id: remoteVpnSiteResourceId + } + : null routingConfiguration: routingConfiguration routingWeight: routingWeight sharedKey: sharedKey diff --git a/avm/res/network/vpn-gateway/vpn-connection/main.json b/avm/res/network/vpn-gateway/vpn-connection/main.json index 7ec547d29d..06889f1399 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.25.53.49325", - "templateHash": "2523279657002252302" + "version": "0.26.54.24096", + "templateHash": "13703101435058090684" }, "name": "VPN Gateway VPN Connections", "description": "This module deploys a VPN Gateway VPN Connection.", diff --git a/avm/res/network/vpn-site/main.bicep b/avm/res/network/vpn-site/main.bicep index 4b5c0354d6..d2ff28fcf8 100644 --- a/avm/res/network/vpn-site/main.bicep +++ b/avm/res/network/vpn-site/main.bicep @@ -46,39 +46,54 @@ param roleAssignments roleAssignmentType var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + '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') + '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: take('46d3xbcp.res.network-vpnsite.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: take( + '46d3xbcp.res.network-vpnsite.${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 vpnSite 'Microsoft.Network/vpnSites@2023-04-01' = { name: name location: location tags: tags properties: { - addressSpace: !empty(addressPrefixes) ? { - addressPrefixes: addressPrefixes - } : null + addressSpace: !empty(addressPrefixes) + ? { + addressPrefixes: addressPrefixes + } + : null bgpProperties: !empty(bgpProperties) ? bgpProperties : null deviceProperties: !empty(deviceProperties) ? deviceProperties : null ipAddress: !empty(ipAddress) ? ipAddress : null @@ -91,28 +106,37 @@ resource vpnSite 'Microsoft.Network/vpnSites@2023-04-01' = { } } -resource vpnSite_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.' +resource vpnSite_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: vpnSite } - scope: vpnSite -} -resource vpnSite_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(vpnSite.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 +resource vpnSite_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(vpnSite.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: vpnSite } - scope: vpnSite -}] +] @description('The name of the VPN site.') output name string = vpnSite.name diff --git a/avm/res/network/vpn-site/main.json b/avm/res/network/vpn-site/main.json index 158bb5fe53..fb99d8c873 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.25.53.49325", - "templateHash": "15929978987009174743" + "version": "0.26.54.24096", + "templateHash": "14637032224635942457" }, "name": "VPN Sites", "description": "This module deploys a VPN Site.", diff --git a/avm/res/network/vpn-site/tests/e2e/defaults/main.test.bicep b/avm/res/network/vpn-site/tests/e2e/defaults/main.test.bicep index 40b66391a9..4818c6fb53 100644 --- a/avm/res/network/vpn-site/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/vpn-site/tests/e2e/defaults/main.test.bicep @@ -45,19 +45,21 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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}' - virtualWanId: nestedDependencies.outputs.virtualWWANResourceId - addressPrefixes: [ - '10.0.0.0/16' +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}' + virtualWanId: nestedDependencies.outputs.virtualWWANResourceId + addressPrefixes: [ + '10.0.0.0/16' + ] + ipAddress: '1.2.3.4' + } + dependsOn: [ + nestedDependencies ] - ipAddress: '1.2.3.4' } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/vpn-site/tests/e2e/max/main.test.bicep b/avm/res/network/vpn-site/tests/e2e/max/main.test.bicep index bc4ee85f75..bd72eae845 100644 --- a/avm/res/network/vpn-site/tests/e2e/max/main.test.bicep +++ b/avm/res/network/vpn-site/tests/e2e/max/main.test.bicep @@ -46,81 +46,86 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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}' - virtualWanId: nestedDependencies.outputs.virtualWWANResourceId - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - tagA: 'valueA' - tagB: 'valueB' - } - deviceProperties: { - linkSpeedInMbps: 0 - } - vpnSiteLinks: [ - { - name: '${namePrefix}-vSite-${serviceShort}' - properties: { - bgpProperties: { - asn: 65010 - bgpPeeringAddress: '1.1.1.1' - } - ipAddress: '1.2.3.4' - linkProperties: { - linkProviderName: 'contoso' - linkSpeedInMbps: 5 - } - } +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}' + virtualWanId: nestedDependencies.outputs.virtualWWANResourceId + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + tagA: 'valueA' + tagB: 'valueB' + } + deviceProperties: { + linkSpeedInMbps: 0 } - { - name: 'Link1' - properties: { - bgpProperties: { - asn: 65020 - bgpPeeringAddress: '192.168.1.0' + vpnSiteLinks: [ + { + name: '${namePrefix}-vSite-${serviceShort}' + properties: { + bgpProperties: { + asn: 65010 + bgpPeeringAddress: '1.1.1.1' + } + ipAddress: '1.2.3.4' + linkProperties: { + linkProviderName: 'contoso' + linkSpeedInMbps: 5 + } } - ipAddress: '2.2.2.2' - linkProperties: { - linkProviderName: 'contoso' - linkSpeedInMbps: 5 + } + { + name: 'Link1' + properties: { + bgpProperties: { + asn: 65020 + bgpPeeringAddress: '192.168.1.0' + } + ipAddress: '2.2.2.2' + linkProperties: { + linkProviderName: 'contoso' + linkSpeedInMbps: 5 + } } } + ] + o365Policy: { + breakOutCategories: { + optimize: true + allow: true + default: true + } } - ] - o365Policy: { - breakOutCategories: { - optimize: true - allow: true - default: true - } + 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' + } + ] } - 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' - } + dependsOn: [ + nestedDependencies ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/network/vpn-site/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/vpn-site/tests/e2e/waf-aligned/main.test.bicep index 89d8b6d746..5f582100f2 100644 --- a/avm/res/network/vpn-site/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/vpn-site/tests/e2e/waf-aligned/main.test.bicep @@ -46,64 +46,66 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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}' - virtualWanId: nestedDependencies.outputs.virtualWWANResourceId - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - tagA: 'valueA' - tagB: 'valueB' - } - deviceProperties: { - linkSpeedInMbps: 0 - } - vpnSiteLinks: [ - { - name: '${namePrefix}-vSite-${serviceShort}' - properties: { - bgpProperties: { - asn: 65010 - bgpPeeringAddress: '1.1.1.1' - } - ipAddress: '1.2.3.4' - linkProperties: { - linkProviderName: 'contoso' - linkSpeedInMbps: 5 - } - } +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}' + virtualWanId: nestedDependencies.outputs.virtualWWANResourceId + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + tagA: 'valueA' + tagB: 'valueB' } - { - name: 'Link1' - properties: { - bgpProperties: { - asn: 65020 - bgpPeeringAddress: '192.168.1.0' + deviceProperties: { + linkSpeedInMbps: 0 + } + vpnSiteLinks: [ + { + name: '${namePrefix}-vSite-${serviceShort}' + properties: { + bgpProperties: { + asn: 65010 + bgpPeeringAddress: '1.1.1.1' + } + ipAddress: '1.2.3.4' + linkProperties: { + linkProviderName: 'contoso' + linkSpeedInMbps: 5 + } } - ipAddress: '2.2.2.2' - linkProperties: { - linkProviderName: 'contoso' - linkSpeedInMbps: 5 + } + { + name: 'Link1' + properties: { + bgpProperties: { + asn: 65020 + bgpPeeringAddress: '192.168.1.0' + } + ipAddress: '2.2.2.2' + linkProperties: { + linkProviderName: 'contoso' + linkSpeedInMbps: 5 + } } } - } - ] - o365Policy: { - breakOutCategories: { - optimize: true - allow: true - default: true + ] + o365Policy: { + breakOutCategories: { + optimize: true + allow: true + default: true + } } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/operational-insights/workspace/data-export/main.json b/avm/res/operational-insights/workspace/data-export/main.json index 950108de7f..740f371a8c 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.25.53.49325", - "templateHash": "12543023571728523937" + "version": "0.26.54.24096", + "templateHash": "5632716318105950604" }, "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.bicep b/avm/res/operational-insights/workspace/data-source/main.bicep index 64fc1b3371..905ff55e0e 100644 --- a/avm/res/operational-insights/workspace/data-source/main.bicep +++ b/avm/res/operational-insights/workspace/data-source/main.bicep @@ -70,13 +70,23 @@ resource dataSource 'Microsoft.OperationalInsights/workspaces/dataSources@2020-0 linkedResourceId: !empty(kind) && kind == 'AzureActivityLog' ? linkedResourceId : null eventLogName: !empty(kind) && kind == 'WindowsEvent' ? eventLogName : null eventTypes: !empty(kind) && kind == 'WindowsEvent' ? eventTypes : null - objectName: !empty(kind) && (kind == 'WindowsPerformanceCounter' || kind == 'LinuxPerformanceObject') ? objectName : null - instanceName: !empty(kind) && (kind == 'WindowsPerformanceCounter' || kind == 'LinuxPerformanceObject') ? instanceName : null - intervalSeconds: !empty(kind) && (kind == 'WindowsPerformanceCounter' || kind == 'LinuxPerformanceObject') ? intervalSeconds : null + objectName: !empty(kind) && (kind == 'WindowsPerformanceCounter' || kind == 'LinuxPerformanceObject') + ? objectName + : null + instanceName: !empty(kind) && (kind == 'WindowsPerformanceCounter' || kind == 'LinuxPerformanceObject') + ? instanceName + : null + intervalSeconds: !empty(kind) && (kind == 'WindowsPerformanceCounter' || kind == 'LinuxPerformanceObject') + ? intervalSeconds + : null counterName: !empty(kind) && kind == 'WindowsPerformanceCounter' ? counterName : null - state: !empty(kind) && (kind == 'IISLogs' || kind == 'LinuxSyslogCollection' || kind == 'LinuxPerformanceCollection') ? state : null + state: !empty(kind) && (kind == 'IISLogs' || kind == 'LinuxSyslogCollection' || kind == 'LinuxPerformanceCollection') + ? state + : null syslogName: !empty(kind) && kind == 'LinuxSyslog' ? syslogName : null - syslogSeverities: !empty(kind) && (kind == 'LinuxSyslog' || kind == 'LinuxPerformanceObject') ? syslogSeverities : null + syslogSeverities: !empty(kind) && (kind == 'LinuxSyslog' || kind == 'LinuxPerformanceObject') + ? syslogSeverities + : null performanceCounters: !empty(kind) && kind == 'LinuxPerformanceObject' ? performanceCounters : null } } diff --git a/avm/res/operational-insights/workspace/data-source/main.json b/avm/res/operational-insights/workspace/data-source/main.json index d77dd6f3af..53bded2d65 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.25.53.49325", - "templateHash": "14032975851567807564" + "version": "0.26.54.24096", + "templateHash": "16469989668419642499" }, "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 816832ad7c..1ce0ba554a 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.25.53.49325", - "templateHash": "14301767156435143002" + "version": "0.26.54.24096", + "templateHash": "7204307644126778192" }, "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 701593c238..faf6726913 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.25.53.49325", - "templateHash": "6713282874166856483" + "version": "0.26.54.24096", + "templateHash": "8359295346488843789" }, "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 79621f30ce..37603b1ef1 100644 --- a/avm/res/operational-insights/workspace/main.bicep +++ b/avm/res/operational-insights/workspace/main.bicep @@ -97,44 +97,77 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? 'SystemAssigned' : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? 'SystemAssigned' + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null 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') - 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') - 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + 'Log Analytics Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '92aaf0da-9dab-42b6-94a3-d43ce8d16293' + ) + 'Log Analytics Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '73c42c96-874c-492b-b04d-ab87d138a893' + ) + 'Monitoring Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '749f88d5-cbae-40b8-bcfc-e573ddc772fa' + ) + 'Monitoring Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '43d0d8ad-25c7-4714-9337-8ba259a9fe05' + ) 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') - 'Security Admin': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb1c8493-542b-48eb-b624-b4c8fea62acd') - 'Security Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '39bc4728-0917-49c7-9d2c-d95423bc2eb4') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'Security Admin': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'fb1c8493-542b-48eb-b624-b4c8fea62acd' + ) + 'Security Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '39bc4728-0917-49c7-9d2c-d95423bc2eb4' + ) + '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.operationalinsights-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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.operationalinsights-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 logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { location: location @@ -160,156 +193,187 @@ resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10 identity: identity } -resource logAnalyticsWorkspace_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 - 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 +resource logAnalyticsWorkspace_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 + 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 + } + scope: logAnalyticsWorkspace } - scope: logAnalyticsWorkspace -}] - -module logAnalyticsWorkspace_storageInsightConfigs 'storage-insight-config/main.bicep' = [for (storageInsightsConfig, index) in storageInsightsConfigs: { - name: '${uniqueString(deployment().name, location)}-LAW-StorageInsightsConfig-${index}' - params: { - logAnalyticsWorkspaceName: logAnalyticsWorkspace.name - containers: contains(storageInsightsConfig, 'containers') ? storageInsightsConfig.containers : [] - tables: contains(storageInsightsConfig, 'tables') ? storageInsightsConfig.tables : [] - storageAccountResourceId: storageInsightsConfig.storageAccountResourceId +] + +module logAnalyticsWorkspace_storageInsightConfigs 'storage-insight-config/main.bicep' = [ + for (storageInsightsConfig, index) in storageInsightsConfigs: { + name: '${uniqueString(deployment().name, location)}-LAW-StorageInsightsConfig-${index}' + params: { + logAnalyticsWorkspaceName: logAnalyticsWorkspace.name + containers: contains(storageInsightsConfig, 'containers') ? storageInsightsConfig.containers : [] + tables: contains(storageInsightsConfig, 'tables') ? storageInsightsConfig.tables : [] + storageAccountResourceId: storageInsightsConfig.storageAccountResourceId + } } -}] - -module logAnalyticsWorkspace_linkedServices 'linked-service/main.bicep' = [for (linkedService, index) in linkedServices: { - name: '${uniqueString(deployment().name, location)}-LAW-LinkedService-${index}' - params: { - logAnalyticsWorkspaceName: logAnalyticsWorkspace.name - name: linkedService.name - resourceId: contains(linkedService, 'resourceId') ? linkedService.resourceId : '' - writeAccessResourceId: contains(linkedService, 'writeAccessResourceId') ? linkedService.writeAccessResourceId : '' +] + +module logAnalyticsWorkspace_linkedServices 'linked-service/main.bicep' = [ + for (linkedService, index) in linkedServices: { + name: '${uniqueString(deployment().name, location)}-LAW-LinkedService-${index}' + params: { + logAnalyticsWorkspaceName: logAnalyticsWorkspace.name + name: linkedService.name + resourceId: contains(linkedService, 'resourceId') ? linkedService.resourceId : '' + writeAccessResourceId: contains(linkedService, 'writeAccessResourceId') ? linkedService.writeAccessResourceId : '' + } } -}] - -module logAnalyticsWorkspace_linkedStorageAccounts 'linked-storage-account/main.bicep' = [for (linkedStorageAccount, index) in linkedStorageAccounts: { - name: '${uniqueString(deployment().name, location)}-LAW-LinkedStorageAccount-${index}' - params: { - logAnalyticsWorkspaceName: logAnalyticsWorkspace.name - name: linkedStorageAccount.name - resourceId: linkedStorageAccount.resourceId +] + +module logAnalyticsWorkspace_linkedStorageAccounts 'linked-storage-account/main.bicep' = [ + for (linkedStorageAccount, index) in linkedStorageAccounts: { + name: '${uniqueString(deployment().name, location)}-LAW-LinkedStorageAccount-${index}' + params: { + logAnalyticsWorkspaceName: logAnalyticsWorkspace.name + name: linkedStorageAccount.name + resourceId: linkedStorageAccount.resourceId + } } -}] - -module logAnalyticsWorkspace_savedSearches 'saved-search/main.bicep' = [for (savedSearch, index) in savedSearches: { - name: '${uniqueString(deployment().name, location)}-LAW-SavedSearch-${index}' - params: { - logAnalyticsWorkspaceName: logAnalyticsWorkspace.name - name: '${savedSearch.name}${uniqueString(deployment().name)}' - etag: savedSearch.?etag - displayName: savedSearch.displayName - category: savedSearch.category - query: savedSearch.query - functionAlias: savedSearch.?functionAlias - functionParameters: savedSearch.?functionParameters - version: savedSearch.?version +] + +module logAnalyticsWorkspace_savedSearches 'saved-search/main.bicep' = [ + for (savedSearch, index) in savedSearches: { + name: '${uniqueString(deployment().name, location)}-LAW-SavedSearch-${index}' + params: { + logAnalyticsWorkspaceName: logAnalyticsWorkspace.name + name: '${savedSearch.name}${uniqueString(deployment().name)}' + etag: savedSearch.?etag + displayName: savedSearch.displayName + category: savedSearch.category + query: savedSearch.query + functionAlias: savedSearch.?functionAlias + functionParameters: savedSearch.?functionParameters + version: savedSearch.?version + } + dependsOn: [ + logAnalyticsWorkspace_linkedStorageAccounts + ] } - dependsOn: [ - logAnalyticsWorkspace_linkedStorageAccounts - ] -}] - -module logAnalyticsWorkspace_dataExports 'data-export/main.bicep' = [for (dataExport, index) in dataExports: { - name: '${uniqueString(deployment().name, location)}-LAW-DataExport-${index}' - params: { - workspaceName: logAnalyticsWorkspace.name - name: dataExport.name - destination: contains(dataExport, 'destination') ? dataExport.destination : {} - enable: contains(dataExport, 'enable') ? dataExport.enable : false - tableNames: contains(dataExport, 'tableNames') ? dataExport.tableNames : [] +] + +module logAnalyticsWorkspace_dataExports 'data-export/main.bicep' = [ + for (dataExport, index) in dataExports: { + name: '${uniqueString(deployment().name, location)}-LAW-DataExport-${index}' + params: { + workspaceName: logAnalyticsWorkspace.name + name: dataExport.name + destination: contains(dataExport, 'destination') ? dataExport.destination : {} + enable: contains(dataExport, 'enable') ? dataExport.enable : false + tableNames: contains(dataExport, 'tableNames') ? dataExport.tableNames : [] + } } -}] - -module logAnalyticsWorkspace_dataSources 'data-source/main.bicep' = [for (dataSource, index) in dataSources: { - name: '${uniqueString(deployment().name, location)}-LAW-DataSource-${index}' - params: { - logAnalyticsWorkspaceName: logAnalyticsWorkspace.name - name: dataSource.name - kind: dataSource.kind - linkedResourceId: contains(dataSource, 'linkedResourceId') ? dataSource.linkedResourceId : '' - eventLogName: contains(dataSource, 'eventLogName') ? dataSource.eventLogName : '' - eventTypes: contains(dataSource, 'eventTypes') ? dataSource.eventTypes : [] - objectName: contains(dataSource, 'objectName') ? dataSource.objectName : '' - instanceName: contains(dataSource, 'instanceName') ? dataSource.instanceName : '' - intervalSeconds: contains(dataSource, 'intervalSeconds') ? dataSource.intervalSeconds : 60 - counterName: contains(dataSource, 'counterName') ? dataSource.counterName : '' - state: contains(dataSource, 'state') ? dataSource.state : '' - syslogName: contains(dataSource, 'syslogName') ? dataSource.syslogName : '' - syslogSeverities: contains(dataSource, 'syslogSeverities') ? dataSource.syslogSeverities : [] - performanceCounters: contains(dataSource, 'performanceCounters') ? dataSource.performanceCounters : [] +] + +module logAnalyticsWorkspace_dataSources 'data-source/main.bicep' = [ + for (dataSource, index) in dataSources: { + name: '${uniqueString(deployment().name, location)}-LAW-DataSource-${index}' + params: { + logAnalyticsWorkspaceName: logAnalyticsWorkspace.name + name: dataSource.name + kind: dataSource.kind + linkedResourceId: contains(dataSource, 'linkedResourceId') ? dataSource.linkedResourceId : '' + eventLogName: contains(dataSource, 'eventLogName') ? dataSource.eventLogName : '' + eventTypes: contains(dataSource, 'eventTypes') ? dataSource.eventTypes : [] + objectName: contains(dataSource, 'objectName') ? dataSource.objectName : '' + instanceName: contains(dataSource, 'instanceName') ? dataSource.instanceName : '' + intervalSeconds: contains(dataSource, 'intervalSeconds') ? dataSource.intervalSeconds : 60 + counterName: contains(dataSource, 'counterName') ? dataSource.counterName : '' + state: contains(dataSource, 'state') ? dataSource.state : '' + syslogName: contains(dataSource, 'syslogName') ? dataSource.syslogName : '' + syslogSeverities: contains(dataSource, 'syslogSeverities') ? dataSource.syslogSeverities : [] + performanceCounters: contains(dataSource, 'performanceCounters') ? dataSource.performanceCounters : [] + } } -}] - -module logAnalyticsWorkspace_tables 'table/main.bicep' = [for (table, index) in tables: { - name: '${uniqueString(deployment().name, location)}-LAW-Table-${index}' - params: { - workspaceName: logAnalyticsWorkspace.name - name: table.name - plan: table.?plan - schema: table.?schema - retentionInDays: table.?retentionInDays - totalRetentionInDays: table.?totalRetentionInDays - restoredLogs: table.?restoredLogs - searchResults: table.?searchResults - roleAssignments: table.?roleAssignments +] + +module logAnalyticsWorkspace_tables 'table/main.bicep' = [ + for (table, index) in tables: { + name: '${uniqueString(deployment().name, location)}-LAW-Table-${index}' + params: { + workspaceName: logAnalyticsWorkspace.name + name: table.name + plan: table.?plan + schema: table.?schema + retentionInDays: table.?retentionInDays + totalRetentionInDays: table.?totalRetentionInDays + restoredLogs: table.?restoredLogs + searchResults: table.?searchResults + roleAssignments: table.?roleAssignments + } } -}] - -module logAnalyticsWorkspace_solutions 'br/public:avm/res/operations-management/solution:0.1.0' = [for (gallerySolution, index) in gallerySolutions: if (!empty(gallerySolutions)) { - name: '${uniqueString(deployment().name, location)}-LAW-Solution-${index}' - params: { - name: gallerySolution.name - location: location - logAnalyticsWorkspaceName: logAnalyticsWorkspace.name - product: contains(gallerySolution, 'product') ? gallerySolution.product : 'OMSGallery' - publisher: contains(gallerySolution, 'publisher') ? gallerySolution.publisher : 'Microsoft' - enableTelemetry: gallerySolution.?enableTelemetry ?? enableTelemetry +] + +module logAnalyticsWorkspace_solutions 'br/public:avm/res/operations-management/solution:0.1.0' = [ + for (gallerySolution, index) in gallerySolutions: if (!empty(gallerySolutions)) { + name: '${uniqueString(deployment().name, location)}-LAW-Solution-${index}' + params: { + name: gallerySolution.name + location: location + logAnalyticsWorkspaceName: logAnalyticsWorkspace.name + product: contains(gallerySolution, 'product') ? gallerySolution.product : 'OMSGallery' + publisher: contains(gallerySolution, 'publisher') ? gallerySolution.publisher : 'Microsoft' + enableTelemetry: gallerySolution.?enableTelemetry ?? enableTelemetry + } } -}] - -resource logAnalyticsWorkspace_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.' +] + +resource logAnalyticsWorkspace_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: logAnalyticsWorkspace } - scope: logAnalyticsWorkspace -} -resource logAnalyticsWorkspace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(logAnalyticsWorkspace.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 +resource logAnalyticsWorkspace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(logAnalyticsWorkspace.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: logAnalyticsWorkspace } - scope: logAnalyticsWorkspace -}] +] @description('The resource ID of the deployed log analytics workspace.') output resourceId string = logAnalyticsWorkspace.id diff --git a/avm/res/operational-insights/workspace/main.json b/avm/res/operational-insights/workspace/main.json index 3b5d442bbf..fc85a91285 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.25.53.49325", - "templateHash": "13719053295620709128" + "version": "0.26.54.24096", + "templateHash": "12748269165141825812" }, "name": "Log Analytics Workspaces", "description": "This module deploys a Log Analytics Workspace.", @@ -606,8 +606,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4862843187650272248" + "version": "0.26.54.24096", + "templateHash": "8017888514977253474" }, "name": "Log Analytics Workspace Storage Insight Configs", "description": "This module deploys a Log Analytics Workspace Storage Insight Config.", @@ -746,8 +746,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14301767156435143002" + "version": "0.26.54.24096", + "templateHash": "7204307644126778192" }, "name": "Log Analytics Workspace Linked Services", "description": "This module deploys a Log Analytics Workspace Linked Service.", @@ -868,8 +868,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6713282874166856483" + "version": "0.26.54.24096", + "templateHash": "8359295346488843789" }, "name": "Log Analytics Workspace Linked Storage Accounts", "description": "This module deploys a Log Analytics Workspace Linked Storage Account.", @@ -991,8 +991,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17950009471823327560" + "version": "0.26.54.24096", + "templateHash": "1713932205136149020" }, "name": "Log Analytics Workspace Saved Searches", "description": "This module deploys a Log Analytics Workspace Saved Search.", @@ -1151,8 +1151,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12543023571728523937" + "version": "0.26.54.24096", + "templateHash": "5632716318105950604" }, "name": "Log Analytics Workspace Data Exports", "description": "This module deploys a Log Analytics Workspace Data Export.", @@ -1278,8 +1278,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14032975851567807564" + "version": "0.26.54.24096", + "templateHash": "16469989668419642499" }, "name": "Log Analytics Workspace Datasources", "description": "This module deploys a Log Analytics Workspace Data Source.", @@ -1509,8 +1509,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4932423807790181892" + "version": "0.26.54.24096", + "templateHash": "5509602447929603635" }, "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 1c32337b14..2c0198f9cf 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.25.53.49325", - "templateHash": "17950009471823327560" + "version": "0.26.54.24096", + "templateHash": "1713932205136149020" }, "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 fa8367fe5c..8c7e403d99 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.25.53.49325", - "templateHash": "4862843187650272248" + "version": "0.26.54.24096", + "templateHash": "8017888514977253474" }, "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.bicep b/avm/res/operational-insights/workspace/table/main.bicep index e0df3b94f4..3bbbc6f38b 100644 --- a/avm/res/operational-insights/workspace/table/main.bicep +++ b/avm/res/operational-insights/workspace/table/main.bicep @@ -43,14 +43,32 @@ param roleAssignments roleAssignmentType 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') - 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') - 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + 'Log Analytics Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '92aaf0da-9dab-42b6-94a3-d43ce8d16293' + ) + 'Log Analytics Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '73c42c96-874c-492b-b04d-ab87d138a893' + ) + 'Monitoring Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '749f88d5-cbae-40b8-bcfc-e573ddc772fa' + ) + 'Monitoring Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '43d0d8ad-25c7-4714-9337-8ba259a9fe05' + ) 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') + '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' + ) } // =============== // @@ -74,19 +92,25 @@ resource table 'Microsoft.OperationalInsights/workspaces/tables@2022-10-01' = { } } -resource table_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(table.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 +resource table_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(table.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: table } - scope: table -}] +] // =========== // // Outputs // diff --git a/avm/res/operational-insights/workspace/table/main.json b/avm/res/operational-insights/workspace/table/main.json index 94607473ef..2b283e3b8e 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.25.53.49325", - "templateHash": "4932423807790181892" + "version": "0.26.54.24096", + "templateHash": "5509602447929603635" }, "name": "Log Analytics Workspace Tables", "description": "This module deploys a Log Analytics Workspace Table.", diff --git a/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep b/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep index 26a40f0653..8bfaf20aee 100644 --- a/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep +++ b/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep @@ -63,283 +63,291 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - dailyQuotaGb: 10 - dataSources: [ - { - eventLogName: 'Application' - eventTypes: [ - { - eventType: 'Error' - } - { - eventType: 'Warning' - } - { - eventType: 'Information' - } - ] - kind: 'WindowsEvent' - name: 'applicationEvent' - } - { - counterName: '% Processor Time' - instanceName: '*' - intervalSeconds: 60 - kind: 'WindowsPerformanceCounter' - name: 'windowsPerfCounter1' - objectName: 'Processor' - } - { - kind: 'IISLogs' - name: 'sampleIISLog1' - state: 'OnPremiseEnabled' - } - { - kind: 'LinuxSyslog' - name: 'sampleSyslog1' - syslogName: 'kern' - syslogSeverities: [ - { - severity: 'emerg' - } - { - severity: 'alert' - } - { - severity: 'crit' - } - { - severity: 'err' - } - { - severity: 'warning' - } - ] - } - { - kind: 'LinuxSyslogCollection' - name: 'sampleSyslogCollection1' - state: 'Enabled' - } - { - instanceName: '*' - intervalSeconds: 10 - kind: 'LinuxPerformanceObject' - name: 'sampleLinuxPerf1' - objectName: 'Logical Disk' - syslogSeverities: [ - { - counterName: '% Used Inodes' - } - { - counterName: 'Free Megabytes' - } - { - counterName: '% Used Space' - } - { - counterName: 'Disk Transfers/sec' - } - { - counterName: 'Disk Reads/sec' - } - { - counterName: 'Disk Writes/sec' - } - ] - } - { - kind: 'LinuxPerformanceCollection' - name: 'sampleLinuxPerfCollection1' - state: 'Enabled' - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - gallerySolutions: [ - { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' - } - ] - linkedServices: [ - { - name: 'Automation' - resourceId: nestedDependencies.outputs.automationAccountResourceId - } - ] - linkedStorageAccounts: [ - { - name: 'Query' - resourceId: nestedDependencies.outputs.storageAccountResourceId - } - ] - publicNetworkAccessForIngestion: 'Disabled' - publicNetworkAccessForQuery: 'Disabled' - savedSearches: [ - { - category: 'VDC Saved Searches' - displayName: 'VMSS Instance Count2' - name: 'VMSSQueries' - query: 'Event | where Source == ServiceFabricNodeBootstrapAgent | summarize AggregatedValue = count() by Computer' - } - ] - storageInsightsConfigs: [ - { - storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - tables: [ - 'LinuxsyslogVer2v0' - 'WADETWEventTable' - 'WADServiceFabric*EventTable' - 'WADWindowsEventLogsTable' - ] - } - ] - useResourcePermissions: true - tables: [ - { - name: 'CustomTableBasic_CL' - schema: { - name: 'CustomTableBasic_CL' - columns: [ +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 + dailyQuotaGb: 10 + dataSources: [ + { + eventLogName: 'Application' + eventTypes: [ + { + eventType: 'Error' + } { - name: 'TimeGenerated' - type: 'DateTime' + eventType: 'Warning' } { - name: 'RawData' - type: 'String' + eventType: 'Information' } ] + kind: 'WindowsEvent' + name: 'applicationEvent' } - totalRetentionInDays: 90 - retentionInDays: 60 - 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' - } - ] - } - { - name: 'CustomTableAdvanced_CL' - schema: { - name: 'CustomTableAdvanced_CL' - columns: [ + { + counterName: '% Processor Time' + instanceName: '*' + intervalSeconds: 60 + kind: 'WindowsPerformanceCounter' + name: 'windowsPerfCounter1' + objectName: 'Processor' + } + { + kind: 'IISLogs' + name: 'sampleIISLog1' + state: 'OnPremiseEnabled' + } + { + kind: 'LinuxSyslog' + name: 'sampleSyslog1' + syslogName: 'kern' + syslogSeverities: [ + { + severity: 'emerg' + } + { + severity: 'alert' + } + { + severity: 'crit' + } { - name: 'TimeGenerated' - type: 'DateTime' + severity: 'err' } { - name: 'EventTime' - type: 'DateTime' + severity: 'warning' + } + ] + } + { + kind: 'LinuxSyslogCollection' + name: 'sampleSyslogCollection1' + state: 'Enabled' + } + { + instanceName: '*' + intervalSeconds: 10 + kind: 'LinuxPerformanceObject' + name: 'sampleLinuxPerf1' + objectName: 'Logical Disk' + syslogSeverities: [ + { + counterName: '% Used Inodes' + } + { + counterName: 'Free Megabytes' } { - name: 'EventLevel' - type: 'String' + counterName: '% Used Space' } { - name: 'EventCode' - type: 'Int' + counterName: 'Disk Transfers/sec' } { - name: 'Message' - type: 'String' + counterName: 'Disk Reads/sec' } { - name: 'RawData' - type: 'String' + counterName: 'Disk Writes/sec' } ] } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + { + kind: 'LinuxPerformanceCollection' + name: 'sampleLinuxPerfCollection1' + state: 'Enabled' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + gallerySolutions: [ + { + name: 'AzureAutomation' + product: 'OMSGallery' + publisher: 'Microsoft' + } + ] + linkedServices: [ + { + name: 'Automation' + resourceId: nestedDependencies.outputs.automationAccountResourceId + } + ] + linkedStorageAccounts: [ + { + name: 'Query' + resourceId: nestedDependencies.outputs.storageAccountResourceId + } + ] + publicNetworkAccessForIngestion: 'Disabled' + publicNetworkAccessForQuery: 'Disabled' + savedSearches: [ + { + category: 'VDC Saved Searches' + displayName: 'VMSS Instance Count2' + name: 'VMSSQueries' + query: 'Event | where Source == ServiceFabricNodeBootstrapAgent | summarize AggregatedValue = count() by Computer' + } + ] + storageInsightsConfigs: [ + { + storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + tables: [ + 'LinuxsyslogVer2v0' + 'WADETWEventTable' + 'WADServiceFabric*EventTable' + 'WADWindowsEventLogsTable' + ] + } + ] + useResourcePermissions: true + tables: [ + { + name: 'CustomTableBasic_CL' + schema: { + name: 'CustomTableBasic_CL' + columns: [ + { + name: 'TimeGenerated' + type: 'DateTime' + } + { + name: 'RawData' + type: 'String' + } + ] } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + totalRetentionInDays: 90 + retentionInDays: 60 + 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' + } + ] + } + { + name: 'CustomTableAdvanced_CL' + schema: { + name: 'CustomTableAdvanced_CL' + columns: [ + { + name: 'TimeGenerated' + type: 'DateTime' + } + { + name: 'EventTime' + type: 'DateTime' + } + { + name: 'EventLevel' + type: 'String' + } + { + name: 'EventCode' + type: 'Int' + } + { + name: 'Message' + type: 'String' + } + { + name: 'RawData' + type: 'String' + } + ] } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + 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' + } + ] + } + ] + dataExports: [ + { + name: 'eventHubExport' + enable: true + destination: { + resourceId: nestedDependencies.outputs.eventHubNamespaceResourceId + metaData: { + eventHubName: nestedDependencies.outputs.eventHubName + } } - ] - } - ] - dataExports: [ - { - name: 'eventHubExport' - enable: true - destination: { - resourceId: nestedDependencies.outputs.eventHubNamespaceResourceId - metaData: { - eventHubName: nestedDependencies.outputs.eventHubName + tableNames: [ + 'Alert' + 'InsightsMetrics' + ] + } + { + name: 'storageAccountExport' + enable: true + destination: { + resourceId: nestedDependencies.outputs.storageAccountResourceId } + tableNames: [ + 'Operation' + ] } - tableNames: [ - 'Alert' - 'InsightsMetrics' + ] + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] } - { - name: 'storageAccountExport' - enable: true - destination: { - resourceId: nestedDependencies.outputs.storageAccountResourceId - } - tableNames: [ - 'Operation' - ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/operational-insights/workspace/tests/e2e/defaults/main.test.bicep b/avm/res/operational-insights/workspace/tests/e2e/defaults/main.test.bicep index 1239251a63..be86d0d2e5 100644 --- a/avm/res/operational-insights/workspace/tests/e2e/defaults/main.test.bicep +++ b/avm/res/operational-insights/workspace/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { // ============== // @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 +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/operational-insights/workspace/tests/e2e/max/main.test.bicep b/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep index c294bdd177..6de957e29f 100644 --- a/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep @@ -61,286 +61,297 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - dailyQuotaGb: 10 - dataSources: [ - { - eventLogName: 'Application' - eventTypes: [ - { - eventType: 'Error' - } - { - eventType: 'Warning' - } - { - eventType: 'Information' - } - ] - kind: 'WindowsEvent' - name: 'applicationEvent' - } - { - counterName: '% Processor Time' - instanceName: '*' - intervalSeconds: 60 - kind: 'WindowsPerformanceCounter' - name: 'windowsPerfCounter1' - objectName: 'Processor' - } - { - kind: 'IISLogs' - name: 'sampleIISLog1' - state: 'OnPremiseEnabled' - } - { - kind: 'LinuxSyslog' - name: 'sampleSyslog1' - syslogName: 'kern' - syslogSeverities: [ - { - severity: 'emerg' - } - { - severity: 'alert' - } - { - severity: 'crit' - } - { - severity: 'err' - } - { - severity: 'warning' - } - ] - } - { - kind: 'LinuxSyslogCollection' - name: 'sampleSyslogCollection1' - state: 'Enabled' - } - { - instanceName: '*' - intervalSeconds: 10 - kind: 'LinuxPerformanceObject' - name: 'sampleLinuxPerf1' - objectName: 'Logical Disk' - syslogSeverities: [ - { - counterName: '% Used Inodes' - } - { - counterName: 'Free Megabytes' - } - { - counterName: '% Used Space' - } - { - counterName: 'Disk Transfers/sec' - } - { - counterName: 'Disk Reads/sec' - } - { - counterName: 'Disk Writes/sec' - } - ] - } - { - kind: 'LinuxPerformanceCollection' - name: 'sampleLinuxPerfCollection1' - state: 'Enabled' - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - gallerySolutions: [ - { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' - } - ] - linkedServices: [ - { - name: 'Automation' - resourceId: nestedDependencies.outputs.automationAccountResourceId - } - ] - linkedStorageAccounts: [ - { - name: 'Query' - resourceId: nestedDependencies.outputs.storageAccountResourceId - } - ] - tables: [ - { - name: 'CustomTableBasic_CL' - schema: { - name: 'CustomTableBasic_CL' - columns: [ +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 + dailyQuotaGb: 10 + dataSources: [ + { + eventLogName: 'Application' + eventTypes: [ + { + eventType: 'Error' + } { - name: 'TimeGenerated' - type: 'DateTime' + eventType: 'Warning' } { - name: 'RawData' - type: 'String' + eventType: 'Information' } ] + kind: 'WindowsEvent' + name: 'applicationEvent' } - totalRetentionInDays: 90 - retentionInDays: 60 - 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' - } - ] - } - { - name: 'CustomTableAdvanced_CL' - schema: { - name: 'CustomTableAdvanced_CL' - columns: [ + { + counterName: '% Processor Time' + instanceName: '*' + intervalSeconds: 60 + kind: 'WindowsPerformanceCounter' + name: 'windowsPerfCounter1' + objectName: 'Processor' + } + { + kind: 'IISLogs' + name: 'sampleIISLog1' + state: 'OnPremiseEnabled' + } + { + kind: 'LinuxSyslog' + name: 'sampleSyslog1' + syslogName: 'kern' + syslogSeverities: [ { - name: 'TimeGenerated' - type: 'DateTime' + severity: 'emerg' } { - name: 'EventTime' - type: 'DateTime' + severity: 'alert' } { - name: 'EventLevel' - type: 'String' + severity: 'crit' + } + { + severity: 'err' + } + { + severity: 'warning' + } + ] + } + { + kind: 'LinuxSyslogCollection' + name: 'sampleSyslogCollection1' + state: 'Enabled' + } + { + instanceName: '*' + intervalSeconds: 10 + kind: 'LinuxPerformanceObject' + name: 'sampleLinuxPerf1' + objectName: 'Logical Disk' + syslogSeverities: [ + { + counterName: '% Used Inodes' } { - name: 'EventCode' - type: 'Int' + counterName: 'Free Megabytes' } { - name: 'Message' - type: 'String' + counterName: '% Used Space' } { - name: 'RawData' - type: 'String' + counterName: 'Disk Transfers/sec' + } + { + counterName: 'Disk Reads/sec' + } + { + counterName: 'Disk Writes/sec' } ] } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + { + kind: 'LinuxPerformanceCollection' + name: 'sampleLinuxPerfCollection1' + state: 'Enabled' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + gallerySolutions: [ + { + name: 'AzureAutomation' + product: 'OMSGallery' + publisher: 'Microsoft' + } + ] + linkedServices: [ + { + name: 'Automation' + resourceId: nestedDependencies.outputs.automationAccountResourceId + } + ] + linkedStorageAccounts: [ + { + name: 'Query' + resourceId: nestedDependencies.outputs.storageAccountResourceId + } + ] + tables: [ + { + name: 'CustomTableBasic_CL' + schema: { + name: 'CustomTableBasic_CL' + columns: [ + { + name: 'TimeGenerated' + type: 'DateTime' + } + { + name: 'RawData' + type: 'String' + } + ] } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + totalRetentionInDays: 90 + retentionInDays: 60 + 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' + } + ] + } + { + name: 'CustomTableAdvanced_CL' + schema: { + name: 'CustomTableAdvanced_CL' + columns: [ + { + name: 'TimeGenerated' + type: 'DateTime' + } + { + name: 'EventTime' + type: 'DateTime' + } + { + name: 'EventLevel' + type: 'String' + } + { + name: 'EventCode' + type: 'Int' + } + { + name: 'Message' + type: 'String' + } + { + name: 'RawData' + type: 'String' + } + ] } - ] + 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' + } + ] + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - publicNetworkAccessForIngestion: 'Disabled' - publicNetworkAccessForQuery: 'Disabled' - savedSearches: [ - { - category: 'VDC Saved Searches' - displayName: 'VMSS Instance Count2' - name: 'VMSSQueries' - query: 'Event | where Source == ServiceFabricNodeBootstrapAgent | summarize AggregatedValue = count() by Computer' - tags: [ - { - Name: 'Environment' - Value: 'Non-Prod' - } - { - Name: 'Role' - Value: 'DeploymentValidation' - } - ] + publicNetworkAccessForIngestion: 'Disabled' + publicNetworkAccessForQuery: 'Disabled' + savedSearches: [ + { + category: 'VDC Saved Searches' + displayName: 'VMSS Instance Count2' + name: 'VMSSQueries' + query: 'Event | where Source == ServiceFabricNodeBootstrapAgent | summarize AggregatedValue = count() by Computer' + tags: [ + { + Name: 'Environment' + Value: 'Non-Prod' + } + { + Name: 'Role' + Value: 'DeploymentValidation' + } + ] + } + ] + storageInsightsConfigs: [ + { + storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + tables: [ + 'LinuxsyslogVer2v0' + 'WADETWEventTable' + 'WADServiceFabric*EventTable' + 'WADWindowsEventLogsTable' + ] + } + ] + useResourcePermissions: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - storageInsightsConfigs: [ - { - storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - tables: [ - 'LinuxsyslogVer2v0' - 'WADETWEventTable' - 'WADServiceFabric*EventTable' - 'WADWindowsEventLogsTable' - ] + managedIdentities: { + systemAssigned: true } - ] - useResourcePermissions: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - managedIdentities: { - systemAssigned: true + 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' + } + ] } - 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' - } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep index 03149b975f..62e91d5492 100644 --- a/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -60,155 +60,157 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 - dailyQuotaGb: 10 - dataSources: [ - { - eventLogName: 'Application' - eventTypes: [ - { - eventType: 'Error' - } - { - eventType: 'Warning' - } - { - eventType: 'Information' - } - ] - kind: 'WindowsEvent' - name: 'applicationEvent' - } - { - counterName: '% Processor Time' - instanceName: '*' - intervalSeconds: 60 - kind: 'WindowsPerformanceCounter' - name: 'windowsPerfCounter1' - objectName: 'Processor' - } - { - kind: 'IISLogs' - name: 'sampleIISLog1' - state: 'OnPremiseEnabled' - } - { - kind: 'LinuxSyslog' - name: 'sampleSyslog1' - syslogName: 'kern' - syslogSeverities: [ - { - severity: 'emerg' - } - { - severity: 'alert' - } - { - severity: 'crit' - } - { - severity: 'err' - } - { - severity: 'warning' - } - ] +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 + dailyQuotaGb: 10 + dataSources: [ + { + eventLogName: 'Application' + eventTypes: [ + { + eventType: 'Error' + } + { + eventType: 'Warning' + } + { + eventType: 'Information' + } + ] + kind: 'WindowsEvent' + name: 'applicationEvent' + } + { + counterName: '% Processor Time' + instanceName: '*' + intervalSeconds: 60 + kind: 'WindowsPerformanceCounter' + name: 'windowsPerfCounter1' + objectName: 'Processor' + } + { + kind: 'IISLogs' + name: 'sampleIISLog1' + state: 'OnPremiseEnabled' + } + { + kind: 'LinuxSyslog' + name: 'sampleSyslog1' + syslogName: 'kern' + syslogSeverities: [ + { + severity: 'emerg' + } + { + severity: 'alert' + } + { + severity: 'crit' + } + { + severity: 'err' + } + { + severity: 'warning' + } + ] + } + { + kind: 'LinuxSyslogCollection' + name: 'sampleSyslogCollection1' + state: 'Enabled' + } + { + instanceName: '*' + intervalSeconds: 10 + kind: 'LinuxPerformanceObject' + name: 'sampleLinuxPerf1' + objectName: 'Logical Disk' + syslogSeverities: [ + { + counterName: '% Used Inodes' + } + { + counterName: 'Free Megabytes' + } + { + counterName: '% Used Space' + } + { + counterName: 'Disk Transfers/sec' + } + { + counterName: 'Disk Reads/sec' + } + { + counterName: 'Disk Writes/sec' + } + ] + } + { + kind: 'LinuxPerformanceCollection' + name: 'sampleLinuxPerfCollection1' + state: 'Enabled' + } + ] + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + gallerySolutions: [ + { + name: 'AzureAutomation' + product: 'OMSGallery' + publisher: 'Microsoft' + } + ] + linkedServices: [ + { + name: 'Automation' + resourceId: nestedDependencies.outputs.automationAccountResourceId + } + ] + linkedStorageAccounts: [ + { + name: 'Query' + resourceId: nestedDependencies.outputs.storageAccountResourceId + } + ] + publicNetworkAccessForIngestion: 'Disabled' + publicNetworkAccessForQuery: 'Disabled' + storageInsightsConfigs: [ + { + storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + tables: [ + 'LinuxsyslogVer2v0' + 'WADETWEventTable' + 'WADServiceFabric*EventTable' + 'WADWindowsEventLogsTable' + ] + } + ] + useResourcePermissions: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - kind: 'LinuxSyslogCollection' - name: 'sampleSyslogCollection1' - state: 'Enabled' + managedIdentities: { + systemAssigned: true } - { - instanceName: '*' - intervalSeconds: 10 - kind: 'LinuxPerformanceObject' - name: 'sampleLinuxPerf1' - objectName: 'Logical Disk' - syslogSeverities: [ - { - counterName: '% Used Inodes' - } - { - counterName: 'Free Megabytes' - } - { - counterName: '% Used Space' - } - { - counterName: 'Disk Transfers/sec' - } - { - counterName: 'Disk Reads/sec' - } - { - counterName: 'Disk Writes/sec' - } - ] - } - { - kind: 'LinuxPerformanceCollection' - name: 'sampleLinuxPerfCollection1' - state: 'Enabled' - } - ] - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - gallerySolutions: [ - { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' - } - ] - linkedServices: [ - { - name: 'Automation' - resourceId: nestedDependencies.outputs.automationAccountResourceId - } - ] - linkedStorageAccounts: [ - { - name: 'Query' - resourceId: nestedDependencies.outputs.storageAccountResourceId - } - ] - publicNetworkAccessForIngestion: 'Disabled' - publicNetworkAccessForQuery: 'Disabled' - storageInsightsConfigs: [ - { - storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - tables: [ - 'LinuxsyslogVer2v0' - 'WADETWEventTable' - 'WADServiceFabric*EventTable' - 'WADWindowsEventLogsTable' - ] - } - ] - useResourcePermissions: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - managedIdentities: { - systemAssigned: true } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/operations-management/solution/main.bicep b/avm/res/operations-management/solution/main.bicep index 5b5a475ae2..ba755c0e30 100644 --- a/avm/res/operations-management/solution/main.bicep +++ b/avm/res/operations-management/solution/main.bicep @@ -20,23 +20,24 @@ param publisher string = 'Microsoft' @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.operationsmanagement-solution.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.operationsmanagement-solution.${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 logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = { name: logAnalyticsWorkspaceName diff --git a/avm/res/operations-management/solution/main.json b/avm/res/operations-management/solution/main.json index 3edc6a4986..dce939ae5e 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.25.53.49325", - "templateHash": "2322213504829983181" + "version": "0.26.54.24096", + "templateHash": "6056662833176375018" }, "name": "Operations Management Solutions", "description": "This module deploys an Operations Management Solution.", diff --git a/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep b/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep index 5fa771d83f..606797373d 100644 --- a/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep @@ -45,14 +45,16 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: 'AzureAutomation' - location: resourceLocation - logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName - product: 'OMSGallery' - publisher: 'Microsoft' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: 'AzureAutomation' + location: resourceLocation + logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName + product: 'OMSGallery' + publisher: 'Microsoft' + } } -}] +] diff --git a/avm/res/power-bi-dedicated/capacity/main.bicep b/avm/res/power-bi-dedicated/capacity/main.bicep index 0a007fd465..96139932db 100644 --- a/avm/res/power-bi-dedicated/capacity/main.bicep +++ b/avm/res/power-bi-dedicated/capacity/main.bicep @@ -35,31 +35,44 @@ param roleAssignments roleAssignmentType 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') + 'Log Analytics Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '92aaf0da-9dab-42b6-94a3-d43ce8d16293' + ) + 'Log Analytics Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '73c42c96-874c-492b-b04d-ab87d138a893' + ) 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') + '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 defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableTelemetry) { - name: '46d3xbcp.res.powerbidedicated-capacity.${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 defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.powerbidedicated-capacity.${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 capacity 'Microsoft.PowerBIDedicated/capacities@2021-01-01' = { name: name @@ -78,28 +91,37 @@ resource capacity 'Microsoft.PowerBIDedicated/capacities@2021-01-01' = { } } -resource capacity_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.' +resource capacity_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: capacity } - scope: capacity -} -resource capacity_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(capacity.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 +resource capacity_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(capacity.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: capacity } - scope: capacity -}] +] @description('The resource ID of the PowerBi Embedded instance.') output resourceId string = capacity.id diff --git a/avm/res/power-bi-dedicated/capacity/main.json b/avm/res/power-bi-dedicated/capacity/main.json index d50d7153e0..e69dccfb92 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.25.53.49325", - "templateHash": "401112188619972880" + "version": "0.26.54.24096", + "templateHash": "6849452941887309833" }, "name": "Power BI Dedicated Capacities", "description": "This module deploys a Power BI Dedicated Capacity.", diff --git a/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/dependencies.bicep b/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/main.test.bicep b/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/main.test.bicep index db1935917b..515de7d0b9 100644 --- a/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/main.test.bicep +++ b/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/main.test.bicep @@ -45,17 +45,19 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - sku: { - capacity: 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' + sku: { + capacity: 1 + } + members: [ + nestedDependencies.outputs.managedIdentityPrincipalId + ] + location: resourceLocation } - members: [ - nestedDependencies.outputs.managedIdentityPrincipalId - ] - location: resourceLocation } -}] +] diff --git a/avm/res/power-bi-dedicated/capacity/tests/e2e/max/dependencies.bicep b/avm/res/power-bi-dedicated/capacity/tests/e2e/max/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/power-bi-dedicated/capacity/tests/e2e/max/dependencies.bicep +++ b/avm/res/power-bi-dedicated/capacity/tests/e2e/max/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/power-bi-dedicated/capacity/tests/e2e/max/main.test.bicep b/avm/res/power-bi-dedicated/capacity/tests/e2e/max/main.test.bicep index 2e6a779030..5284ba311d 100644 --- a/avm/res/power-bi-dedicated/capacity/tests/e2e/max/main.test.bicep +++ b/avm/res/power-bi-dedicated/capacity/tests/e2e/max/main.test.bicep @@ -45,46 +45,51 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - sku: { - capacity: 1 - name: 'A1' - tier: 'PBIE_Azure' - } - mode: 'Gen2' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - members: [ - nestedDependencies.outputs.managedIdentityPrincipalId - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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 + sku: { + capacity: 1 + name: 'A1' + tier: 'PBIE_Azure' } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + mode: 'Gen2' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + members: [ + nestedDependencies.outputs.managedIdentityPrincipalId + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/dependencies.bicep index a7f42aee7b..7be39e253a 100644 --- a/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/dependencies.bicep @@ -5,8 +5,8 @@ param location string = resourceGroup().location param managedIdentityName string resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location + name: managedIdentityName + location: location } @description('The principal ID of the created Managed Identity.') diff --git a/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/main.test.bicep b/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/main.test.bicep index c412a4ef4a..06d353ab48 100644 --- a/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/main.test.bicep @@ -45,26 +45,28 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - sku: { - capacity: 1 - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - members: [ - nestedDependencies.outputs.managedIdentityPrincipalId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +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 + sku: { + capacity: 1 + } + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + members: [ + nestedDependencies.outputs.managedIdentityPrincipalId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } } -}] +] diff --git a/avm/res/purview/account/main.bicep b/avm/res/purview/account/main.bicep index a62c667df3..dd883a0b37 100644 --- a/avm/res/purview/account/main.bicep +++ b/avm/res/purview/account/main.bicep @@ -58,7 +58,11 @@ param lock lockType // Variables // // =========== // -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } var identity = { type: !empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned' @@ -69,27 +73,34 @@ 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') + '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.purview-account.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.purview-account.${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 account 'Microsoft.Purview/accounts@2021-07-01' = { name: name @@ -103,261 +114,326 @@ resource account 'Microsoft.Purview/accounts@2021-07-01' = { } } -resource account_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.' +resource account_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: account } - scope: account -} -resource account_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 - 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 +resource account_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 + 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 + } + scope: account } - scope: account -}] - -module account_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [for (privateEndpoint, index) in (accountPrivateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Account-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' - properties: { - privateLinkServiceId: account.id - groupIds: [ - privateEndpoint.?service ?? 'account' +] + +module account_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ + for (privateEndpoint, index) in (accountPrivateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Account-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' + properties: { + privateLinkServiceId: account.id + groupIds: [ + privateEndpoint.?service ?? 'account' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' - properties: { - privateLinkServiceId: account.id - groupIds: [ - privateEndpoint.?service ?? 'account' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' + properties: { + privateLinkServiceId: account.id + groupIds: [ + privateEndpoint.?service ?? 'account' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] - -module portal_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [for (privateEndpoint, index) in (portalPrivateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Portal-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'portal'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'portal'}-${index}' - properties: { - privateLinkServiceId: account.id - groupIds: [ - privateEndpoint.?service ?? 'portal' +] + +module portal_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ + for (privateEndpoint, index) in (portalPrivateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Portal-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'portal'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'portal'}-${index}' + properties: { + privateLinkServiceId: account.id + groupIds: [ + privateEndpoint.?service ?? 'portal' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'portal'}-${index}' - properties: { - privateLinkServiceId: account.id - groupIds: [ - privateEndpoint.?service ?? 'portal' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'portal'}-${index}' + properties: { + privateLinkServiceId: account.id + groupIds: [ + privateEndpoint.?service ?? 'portal' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] - -module blob_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [for (privateEndpoint, index) in (storageBlobPrivateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Storage-Blob-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'blob'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'blob'}-${index}' - properties: { - privateLinkServiceId: account.properties.managedResources.storageAccount - groupIds: [ - privateEndpoint.?service ?? 'blob' +] + +module blob_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ + for (privateEndpoint, index) in (storageBlobPrivateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Storage-Blob-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'blob'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'blob'}-${index}' + properties: { + privateLinkServiceId: account.properties.managedResources.storageAccount + groupIds: [ + privateEndpoint.?service ?? 'blob' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'blob'}-${index}' - properties: { - privateLinkServiceId: account.properties.managedResources.storageAccount - groupIds: [ - privateEndpoint.?service ?? 'blob' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'blob'}-${index}' + properties: { + privateLinkServiceId: account.properties.managedResources.storageAccount + groupIds: [ + privateEndpoint.?service ?? 'blob' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] - -module queue_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [for (privateEndpoint, index) in (storageQueuePrivateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Storage-Queue-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'queue'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'queue'}-${index}' - properties: { - privateLinkServiceId: account.properties.managedResources.storageAccount - groupIds: [ - privateEndpoint.?service ?? 'queue' +] + +module queue_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ + for (privateEndpoint, index) in (storageQueuePrivateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Storage-Queue-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'queue'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'queue'}-${index}' + properties: { + privateLinkServiceId: account.properties.managedResources.storageAccount + groupIds: [ + privateEndpoint.?service ?? 'queue' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'queue'}-${index}' - properties: { - privateLinkServiceId: account.properties.managedResources.storageAccount - groupIds: [ - privateEndpoint.?service ?? 'queue' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'queue'}-${index}' + properties: { + privateLinkServiceId: account.properties.managedResources.storageAccount + groupIds: [ + privateEndpoint.?service ?? 'queue' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] - -module eventHub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [for (privateEndpoint, index) in (eventHubPrivateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Eventhub-Namespace-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' - properties: { - privateLinkServiceId: account.properties.managedResources.eventHubNamespace - groupIds: [ - privateEndpoint.?service ?? 'namespace' +] + +module eventHub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ + for (privateEndpoint, index) in (eventHubPrivateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Eventhub-Namespace-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + properties: { + privateLinkServiceId: account.properties.managedResources.eventHubNamespace + groupIds: [ + privateEndpoint.?service ?? 'namespace' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' - properties: { - privateLinkServiceId: account.properties.managedResources.eventHubNamespace - groupIds: [ - privateEndpoint.?service ?? 'namespace' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + properties: { + privateLinkServiceId: account.properties.managedResources.eventHubNamespace + groupIds: [ + privateEndpoint.?service ?? 'namespace' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource account_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(account.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 +resource account_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(account.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: account } - scope: account -}] +] @description('The name of the Purview Account.') output name string = account.name diff --git a/avm/res/purview/account/main.json b/avm/res/purview/account/main.json index 6c09d3b5cc..369cfa5e26 100644 --- a/avm/res/purview/account/main.json +++ b/avm/res/purview/account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11885849494373802730" + "version": "0.26.54.24096", + "templateHash": "6363425469984006749" }, "name": "Purview Accounts", "description": "This module deploys a Purview Account.", diff --git a/avm/res/purview/account/tests/e2e/defaults/main.test.bicep b/avm/res/purview/account/tests/e2e/defaults/main.test.bicep index 3963519084..d1f45f3886 100644 --- a/avm/res/purview/account/tests/e2e/defaults/main.test.bicep +++ b/avm/res/purview/account/tests/e2e/defaults/main.test.bicep @@ -39,11 +39,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - scope: resourceGroup - params: { - name: '${namePrefix}${serviceShort}001' - location: enforcedLocation +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + scope: resourceGroup + params: { + name: '${namePrefix}${serviceShort}001' + location: enforcedLocation + } } -}] +] diff --git a/avm/res/purview/account/tests/e2e/max/dependencies.bicep b/avm/res/purview/account/tests/e2e/max/dependencies.bicep index 1edeb81930..c04042fcfd 100644 --- a/avm/res/purview/account/tests/e2e/max/dependencies.bicep +++ b/avm/res/purview/account/tests/e2e/max/dependencies.bicep @@ -43,10 +43,12 @@ resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018- } @batchSize(1) -resource privateDNSZones 'Microsoft.Network/privateDnsZones@2020-06-01' = [for privateDNSZone in privateDNSZoneNames: { - name: privateDNSZone - location: 'global' -}] +resource privateDNSZones 'Microsoft.Network/privateDnsZones@2020-06-01' = [ + for privateDNSZone in privateDNSZoneNames: { + name: privateDNSZone + location: 'global' + } +] @description('The resource ID of the created Virtual Network Subnet.') output subnetResourceId string = virtualNetwork.properties.subnets[0].id diff --git a/avm/res/purview/account/tests/e2e/max/main.test.bicep b/avm/res/purview/account/tests/e2e/max/main.test.bicep index 4debba85ac..bd88978cbe 100644 --- a/avm/res/purview/account/tests/e2e/max/main.test.bicep +++ b/avm/res/purview/account/tests/e2e/max/main.test.bicep @@ -64,144 +64,149 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - scope: resourceGroup - params: { - name: '${namePrefix}${serviceShort}001' - location: enforcedLocation - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - managedIdentities: { - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - managedResourceGroupName: '${namePrefix}${serviceShort}001-managed-rg' - publicNetworkAccess: 'Disabled' - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - 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' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + scope: resourceGroup + params: { + name: '${namePrefix}${serviceShort}001' + location: enforcedLocation + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - 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' - } - ] - accountPrivateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.purviewAccountPrivateDNSResourceId + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] - service: 'account' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } - ] - portalPrivateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.purviewPortalPrivateDNSResourceId - ] - service: 'portal' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + managedResourceGroupName: '${namePrefix}${serviceShort}001-managed-rg' + publicNetworkAccess: 'Disabled' + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.purviewPortalPrivateDNSResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - storageBlobPrivateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.storageBlobPrivateDNSResourceId - ] - service: 'blob' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - } - ] - storageQueuePrivateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.storageQueuePrivateDNSResourceId - ] - service: 'queue' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.storageQueuePrivateDNSResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - eventHubPrivateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.eventHubPrivateDNSResourceId - ] - service: 'namespace' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + { + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } + ] + accountPrivateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.purviewAccountPrivateDNSResourceId + ] + service: 'account' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + portalPrivateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.purviewPortalPrivateDNSResourceId + ] + service: 'portal' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.purviewPortalPrivateDNSResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + storageBlobPrivateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.storageBlobPrivateDNSResourceId + ] + service: 'blob' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + storageQueuePrivateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.storageQueuePrivateDNSResourceId + ] + service: 'queue' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.storageQueuePrivateDNSResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + eventHubPrivateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.eventHubPrivateDNSResourceId + ] + service: 'namespace' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/purview/account/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/purview/account/tests/e2e/waf-aligned/dependencies.bicep index b6aef8ecb2..fc85bdd382 100644 --- a/avm/res/purview/account/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/purview/account/tests/e2e/waf-aligned/dependencies.bicep @@ -35,10 +35,12 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } @batchSize(1) -resource privateDNSZones 'Microsoft.Network/privateDnsZones@2020-06-01' = [for privateDNSZone in privateDNSZoneNames: { - name: privateDNSZone - location: 'global' -}] +resource privateDNSZones 'Microsoft.Network/privateDnsZones@2020-06-01' = [ + for privateDNSZone in privateDNSZoneNames: { + name: privateDNSZone + location: 'global' + } +] @description('The resource ID of the created Virtual Network Subnet.') output subnetResourceId string = virtualNetwork.properties.subnets[0].id diff --git a/avm/res/purview/account/tests/e2e/waf-aligned/main.test.bicep b/avm/res/purview/account/tests/e2e/waf-aligned/main.test.bicep index 88ca4c893b..b42f8a72fc 100644 --- a/avm/res/purview/account/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/purview/account/tests/e2e/waf-aligned/main.test.bicep @@ -55,7 +55,6 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' location: enforcedLocation - } } @@ -64,75 +63,77 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - scope: resourceGroup - params: { - name: '${namePrefix}${serviceShort}001' - location: enforcedLocation - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - managedResourceGroupName: '${namePrefix}${serviceShort}001-managed-rg' - publicNetworkAccess: 'Disabled' - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - accountPrivateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.purviewAccountPrivateDNSResourceId - ] - service: 'account' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - portalPrivateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.purviewPortalPrivateDNSResourceId - ] - service: 'portal' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - storageBlobPrivateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.storageBlobPrivateDNSResourceId - ] - service: 'blob' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - storageQueuePrivateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.storageQueuePrivateDNSResourceId - ] - service: 'queue' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - eventHubPrivateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.eventHubPrivateDNSResourceId - ] - service: 'namespace' - subnetResourceId: nestedDependencies.outputs.subnetResourceId +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + scope: resourceGroup + params: { + name: '${namePrefix}${serviceShort}001' + location: enforcedLocation + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } + managedResourceGroupName: '${namePrefix}${serviceShort}001-managed-rg' + publicNetworkAccess: 'Disabled' + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + accountPrivateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.purviewAccountPrivateDNSResourceId + ] + service: 'account' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + portalPrivateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.purviewPortalPrivateDNSResourceId + ] + service: 'portal' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + storageBlobPrivateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.storageBlobPrivateDNSResourceId + ] + service: 'blob' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + storageQueuePrivateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.storageQueuePrivateDNSResourceId + ] + service: 'queue' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + eventHubPrivateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.eventHubPrivateDNSResourceId + ] + service: 'namespace' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/recovery-services/vault/backup-config/main.json b/avm/res/recovery-services/vault/backup-config/main.json index e8f0e8c0a5..12babe6214 100644 --- a/avm/res/recovery-services/vault/backup-config/main.json +++ b/avm/res/recovery-services/vault/backup-config/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15423985878725052790" + "version": "0.26.54.24096", + "templateHash": "13689565005288174531" }, "name": "Recovery Services Vault Backup Config", "description": "This module deploys a Recovery Services Vault Backup Config.", diff --git a/avm/res/recovery-services/vault/backup-fabric/protection-container/main.bicep b/avm/res/recovery-services/vault/backup-fabric/protection-container/main.bicep index 693126a32f..a534228768 100644 --- a/avm/res/recovery-services/vault/backup-fabric/protection-container/main.bicep +++ b/avm/res/recovery-services/vault/backup-fabric/protection-container/main.bicep @@ -58,18 +58,20 @@ resource protectionContainer 'Microsoft.RecoveryServices/vaults/backupFabrics/pr } } -module protectionContainer_protectedItems 'protected-item/main.bicep' = [for (protectedItem, index) in protectedItems: { - name: '${uniqueString(deployment().name, location)}-ProtectedItem-${index}' - params: { - policyId: protectedItem.policyId - name: protectedItem.name - protectedItemType: protectedItem.protectedItemType - protectionContainerName: protectionContainer.name - recoveryVaultName: recoveryVaultName - sourceResourceId: protectedItem.sourceResourceId - location: location +module protectionContainer_protectedItems 'protected-item/main.bicep' = [ + for (protectedItem, index) in protectedItems: { + name: '${uniqueString(deployment().name, location)}-ProtectedItem-${index}' + params: { + policyId: protectedItem.policyId + name: protectedItem.name + protectedItemType: protectedItem.protectedItemType + protectionContainerName: protectionContainer.name + recoveryVaultName: recoveryVaultName + sourceResourceId: protectedItem.sourceResourceId + location: location + } } -}] +] @description('The name of the Resource Group the Protection Container was created in.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/recovery-services/vault/backup-fabric/protection-container/main.json b/avm/res/recovery-services/vault/backup-fabric/protection-container/main.json index 9a0b367fcc..56dc62a966 100644 --- a/avm/res/recovery-services/vault/backup-fabric/protection-container/main.json +++ b/avm/res/recovery-services/vault/backup-fabric/protection-container/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "5887508216739936022" + "version": "0.26.54.24096", + "templateHash": "16058746935194459972" }, "name": "Recovery Services Vault Protection Container", "description": "This module deploys a Recovery Services Vault Protection Container.", @@ -144,8 +144,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15677187951825533891" + "version": "0.26.54.24096", + "templateHash": "5385249890312845255" }, "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/recovery-services/vault/backup-fabric/protection-container/protected-item/main.json b/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.json index 880a35cef4..76594a6483 100644 --- a/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.json +++ b/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15677187951825533891" + "version": "0.26.54.24096", + "templateHash": "5385249890312845255" }, "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/recovery-services/vault/backup-policy/main.json b/avm/res/recovery-services/vault/backup-policy/main.json index 53c8a67f66..88ac90efb1 100644 --- a/avm/res/recovery-services/vault/backup-policy/main.json +++ b/avm/res/recovery-services/vault/backup-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3329904805287164035" + "version": "0.26.54.24096", + "templateHash": "53495924931537880" }, "name": "Recovery Services Vault Backup Policies", "description": "This module deploys a Recovery Services Vault Backup Policy.", diff --git a/avm/res/recovery-services/vault/backup-storage-config/main.json b/avm/res/recovery-services/vault/backup-storage-config/main.json index 829a4157b1..ffabea5a26 100644 --- a/avm/res/recovery-services/vault/backup-storage-config/main.json +++ b/avm/res/recovery-services/vault/backup-storage-config/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16823125725342753814" + "version": "0.26.54.24096", + "templateHash": "7323008272687100781" }, "name": "Recovery Services Vault Backup Storage Config", "description": "This module deploys a Recovery Service Vault Backup Storage Configuration.", diff --git a/avm/res/recovery-services/vault/main.bicep b/avm/res/recovery-services/vault/main.bicep index 16126e1d3d..7b19a5708a 100644 --- a/avm/res/recovery-services/vault/main.bicep +++ b/avm/res/recovery-services/vault/main.bicep @@ -63,44 +63,77 @@ param securitySettings object = {} ]) param publicNetworkAccess string = 'Disabled' -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - 'Backup Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b') - 'Backup Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324') - 'Backup Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a795c7a0-d4a2-40c1-ae25-d81f01202912') + 'Backup Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '5e467623-bb1f-42f4-a55d-6e525e11384b' + ) + 'Backup Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '00c29273-979b-4161-815c-10b084fb9324' + ) + 'Backup Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a795c7a0-d4a2-40c1-ae25-d81f01202912' + ) 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') - 'Site Recovery Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567') - 'Site Recovery Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca') - 'Site Recovery Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'dbaa88c4-0c30-4179-9fb3-46319faa6149') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'Site Recovery Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '6670b86e-a3f7-4917-ac9b-5d6ab1be4567' + ) + 'Site Recovery Operator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '494ae006-db33-4328-bf46-533a6560a3ca' + ) + 'Site Recovery Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'dbaa88c4-0c30-4179-9fb3-46319faa6149' + ) + '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.recoveryservices-vault.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.recoveryservices-vault.${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 rsv 'Microsoft.RecoveryServices/vaults@2023-01-01' = { name: name @@ -118,176 +151,232 @@ resource rsv 'Microsoft.RecoveryServices/vaults@2023-01-01' = { } } -module rsv_replicationFabrics 'replication-fabric/main.bicep' = [for (replicationFabric, index) in replicationFabrics: { - name: '${uniqueString(deployment().name, location)}-RSV-Fabric-${index}' - params: { - recoveryVaultName: rsv.name - name: contains(replicationFabric, 'name') ? replicationFabric.name : replicationFabric.location - location: replicationFabric.location - replicationContainers: contains(replicationFabric, 'replicationContainers') ? replicationFabric.replicationContainers : [] +module rsv_replicationFabrics 'replication-fabric/main.bicep' = [ + for (replicationFabric, index) in replicationFabrics: { + name: '${uniqueString(deployment().name, location)}-RSV-Fabric-${index}' + params: { + recoveryVaultName: rsv.name + name: contains(replicationFabric, 'name') ? replicationFabric.name : replicationFabric.location + location: replicationFabric.location + replicationContainers: contains(replicationFabric, 'replicationContainers') + ? replicationFabric.replicationContainers + : [] + } + dependsOn: [ + rsv_replicationPolicies + ] } - dependsOn: [ - rsv_replicationPolicies - ] -}] - -module rsv_replicationPolicies 'replication-policy/main.bicep' = [for (replicationPolicy, index) in replicationPolicies: { - name: '${uniqueString(deployment().name, location)}-RSV-Policy-${index}' - params: { - name: replicationPolicy.name - recoveryVaultName: rsv.name - appConsistentFrequencyInMinutes: contains(replicationPolicy, 'appConsistentFrequencyInMinutes') ? replicationPolicy.appConsistentFrequencyInMinutes : 60 - crashConsistentFrequencyInMinutes: contains(replicationPolicy, 'crashConsistentFrequencyInMinutes') ? replicationPolicy.crashConsistentFrequencyInMinutes : 5 - multiVmSyncStatus: contains(replicationPolicy, 'multiVmSyncStatus') ? replicationPolicy.multiVmSyncStatus : 'Enable' - recoveryPointHistory: contains(replicationPolicy, 'recoveryPointHistory') ? replicationPolicy.recoveryPointHistory : 1440 +] + +module rsv_replicationPolicies 'replication-policy/main.bicep' = [ + for (replicationPolicy, index) in replicationPolicies: { + name: '${uniqueString(deployment().name, location)}-RSV-Policy-${index}' + params: { + name: replicationPolicy.name + recoveryVaultName: rsv.name + appConsistentFrequencyInMinutes: contains(replicationPolicy, 'appConsistentFrequencyInMinutes') + ? replicationPolicy.appConsistentFrequencyInMinutes + : 60 + crashConsistentFrequencyInMinutes: contains(replicationPolicy, 'crashConsistentFrequencyInMinutes') + ? replicationPolicy.crashConsistentFrequencyInMinutes + : 5 + multiVmSyncStatus: contains(replicationPolicy, 'multiVmSyncStatus') + ? replicationPolicy.multiVmSyncStatus + : 'Enable' + recoveryPointHistory: contains(replicationPolicy, 'recoveryPointHistory') + ? replicationPolicy.recoveryPointHistory + : 1440 + } } -}] - -module rsv_backupStorageConfiguration 'backup-storage-config/main.bicep' = if (!empty(backupStorageConfig)) { - name: '${uniqueString(deployment().name, location)}-RSV-BackupStorageConfig' - params: { - recoveryVaultName: rsv.name - storageModelType: backupStorageConfig.storageModelType - crossRegionRestoreFlag: backupStorageConfig.crossRegionRestoreFlag +] + +module rsv_backupStorageConfiguration 'backup-storage-config/main.bicep' = + if (!empty(backupStorageConfig)) { + name: '${uniqueString(deployment().name, location)}-RSV-BackupStorageConfig' + params: { + recoveryVaultName: rsv.name + storageModelType: backupStorageConfig.storageModelType + crossRegionRestoreFlag: backupStorageConfig.crossRegionRestoreFlag + } } -} -module rsv_backupFabric_protectionContainers 'backup-fabric/protection-container/main.bicep' = [for (protectionContainer, index) in protectionContainers: { - name: '${uniqueString(deployment().name, location)}-RSV-ProtectionContainers-${index}' - params: { - recoveryVaultName: rsv.name - name: protectionContainer.name - sourceResourceId: protectionContainer.?sourceResourceId - friendlyName: protectionContainer.?friendlyName - backupManagementType: protectionContainer.?backupManagementType - containerType: protectionContainer.?containerType - protectedItems: contains(protectionContainer, 'protectedItems') ? protectionContainer.protectedItems : [] - location: location +module rsv_backupFabric_protectionContainers 'backup-fabric/protection-container/main.bicep' = [ + for (protectionContainer, index) in protectionContainers: { + name: '${uniqueString(deployment().name, location)}-RSV-ProtectionContainers-${index}' + params: { + recoveryVaultName: rsv.name + name: protectionContainer.name + sourceResourceId: protectionContainer.?sourceResourceId + friendlyName: protectionContainer.?friendlyName + backupManagementType: protectionContainer.?backupManagementType + containerType: protectionContainer.?containerType + protectedItems: contains(protectionContainer, 'protectedItems') ? protectionContainer.protectedItems : [] + location: location + } } -}] - -module rsv_backupPolicies 'backup-policy/main.bicep' = [for (backupPolicy, index) in backupPolicies: { - name: '${uniqueString(deployment().name, location)}-RSV-BackupPolicy-${index}' - params: { - recoveryVaultName: rsv.name - name: backupPolicy.name - properties: backupPolicy.properties +] + +module rsv_backupPolicies 'backup-policy/main.bicep' = [ + for (backupPolicy, index) in backupPolicies: { + name: '${uniqueString(deployment().name, location)}-RSV-BackupPolicy-${index}' + params: { + recoveryVaultName: rsv.name + name: backupPolicy.name + properties: backupPolicy.properties + } } -}] - -module rsv_backupConfig 'backup-config/main.bicep' = if (!empty(backupConfig)) { - name: '${uniqueString(deployment().name, location)}-RSV-BackupConfig' - params: { - recoveryVaultName: rsv.name - name: contains(backupConfig, 'name') ? backupConfig.name : 'vaultconfig' - enhancedSecurityState: contains(backupConfig, 'enhancedSecurityState') ? backupConfig.enhancedSecurityState : 'Enabled' - resourceGuardOperationRequests: contains(backupConfig, 'resourceGuardOperationRequests') ? backupConfig.resourceGuardOperationRequests : [] - softDeleteFeatureState: contains(backupConfig, 'softDeleteFeatureState') ? backupConfig.softDeleteFeatureState : 'Enabled' - storageModelType: contains(backupConfig, 'storageModelType') ? backupConfig.storageModelType : 'GeoRedundant' - storageType: contains(backupConfig, 'storageType') ? backupConfig.storageType : 'GeoRedundant' - storageTypeState: contains(backupConfig, 'storageTypeState') ? backupConfig.storageTypeState : 'Locked' - isSoftDeleteFeatureStateEditable: contains(backupConfig, 'isSoftDeleteFeatureStateEditable') ? backupConfig.isSoftDeleteFeatureStateEditable : true +] + +module rsv_backupConfig 'backup-config/main.bicep' = + if (!empty(backupConfig)) { + name: '${uniqueString(deployment().name, location)}-RSV-BackupConfig' + params: { + recoveryVaultName: rsv.name + name: contains(backupConfig, 'name') ? backupConfig.name : 'vaultconfig' + enhancedSecurityState: contains(backupConfig, 'enhancedSecurityState') + ? backupConfig.enhancedSecurityState + : 'Enabled' + resourceGuardOperationRequests: contains(backupConfig, 'resourceGuardOperationRequests') + ? backupConfig.resourceGuardOperationRequests + : [] + softDeleteFeatureState: contains(backupConfig, 'softDeleteFeatureState') + ? backupConfig.softDeleteFeatureState + : 'Enabled' + storageModelType: contains(backupConfig, 'storageModelType') ? backupConfig.storageModelType : 'GeoRedundant' + storageType: contains(backupConfig, 'storageType') ? backupConfig.storageType : 'GeoRedundant' + storageTypeState: contains(backupConfig, 'storageTypeState') ? backupConfig.storageTypeState : 'Locked' + isSoftDeleteFeatureStateEditable: contains(backupConfig, 'isSoftDeleteFeatureStateEditable') + ? backupConfig.isSoftDeleteFeatureStateEditable + : true + } } -} -module rsv_replicationAlertSettings 'replication-alert-setting/main.bicep' = if (!empty(replicationAlertSettings)) { - name: '${uniqueString(deployment().name, location)}-RSV-replicationAlertSettings' - params: { - name: 'defaultAlertSetting' - recoveryVaultName: rsv.name - customEmailAddresses: contains(replicationAlertSettings, 'customEmailAddresses') ? replicationAlertSettings.customEmailAddresses : [] - locale: contains(replicationAlertSettings, 'locale') ? replicationAlertSettings.locale : '' - sendToOwners: contains(replicationAlertSettings, 'sendToOwners') ? replicationAlertSettings.sendToOwners : 'Send' +module rsv_replicationAlertSettings 'replication-alert-setting/main.bicep' = + if (!empty(replicationAlertSettings)) { + name: '${uniqueString(deployment().name, location)}-RSV-replicationAlertSettings' + params: { + name: 'defaultAlertSetting' + recoveryVaultName: rsv.name + customEmailAddresses: contains(replicationAlertSettings, 'customEmailAddresses') + ? replicationAlertSettings.customEmailAddresses + : [] + locale: contains(replicationAlertSettings, 'locale') ? replicationAlertSettings.locale : '' + sendToOwners: contains(replicationAlertSettings, 'sendToOwners') ? replicationAlertSettings.sendToOwners : 'Send' + } } -} -resource rsv_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.' +resource rsv_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: rsv } - scope: rsv -} -resource rsv_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 - 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 +resource rsv_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 + 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 + } + scope: rsv } - scope: rsv -}] - -module rsv_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-RSV-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(rsv.id, '/'))}-${privateEndpoint.?service ?? 'AzureSiteRecovery'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(rsv.id, '/'))}-${privateEndpoint.?service ?? 'AzureSiteRecovery'}-${index}' - properties: { - privateLinkServiceId: rsv.id - groupIds: [ - privateEndpoint.?service ?? 'AzureSiteRecovery' +] + +module rsv_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-RSV-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(rsv.id, '/'))}-${privateEndpoint.?service ?? 'AzureSiteRecovery'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(rsv.id, '/'))}-${privateEndpoint.?service ?? 'AzureSiteRecovery'}-${index}' + properties: { + privateLinkServiceId: rsv.id + groupIds: [ + privateEndpoint.?service ?? 'AzureSiteRecovery' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(rsv.id, '/'))}-${privateEndpoint.?service ?? 'AzureSiteRecovery'}-${index}' - properties: { - privateLinkServiceId: rsv.id - groupIds: [ - privateEndpoint.?service ?? 'AzureSiteRecovery' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(rsv.id, '/'))}-${privateEndpoint.?service ?? 'AzureSiteRecovery'}-${index}' + properties: { + privateLinkServiceId: rsv.id + groupIds: [ + privateEndpoint.?service ?? 'AzureSiteRecovery' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource rsv_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(rsv.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 +resource rsv_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(rsv.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: rsv } - scope: rsv -}] +] @description('The resource ID of the recovery services vault.') output resourceId string = rsv.id diff --git a/avm/res/recovery-services/vault/main.json b/avm/res/recovery-services/vault/main.json index 686a7aa5d3..83b7e86188 100644 --- a/avm/res/recovery-services/vault/main.json +++ b/avm/res/recovery-services/vault/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "916737030536129910" + "version": "0.26.54.24096", + "templateHash": "544770798724307182" }, "name": "Recovery Services Vaults", "description": "This module deploys a Recovery Services Vault.", @@ -725,8 +725,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "9213187265421923503" + "version": "0.26.54.24096", + "templateHash": "10579941098853248837" }, "name": "Recovery Services Vault Replication Fabrics", "description": "This module deploys a Replication Fabric for Azure to Azure disaster recovery scenario of Azure Site Recovery.\n\n> Note: this module currently support only the `instanceType: 'Azure'` scenario.", @@ -804,8 +804,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "584392949528635994" + "version": "0.26.54.24096", + "templateHash": "16016202718205451628" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Containers", "description": "This module deploys a Recovery Services Vault Replication Protection Container.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario.", @@ -887,8 +887,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8286726590589779511" + "version": "0.26.54.24096", + "templateHash": "16134780575393361186" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Container Replication Protection Container Mappings", "description": "This module deploys a Recovery Services Vault (RSV) Replication Protection Container Mapping.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario.", @@ -1096,8 +1096,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12506498029720805552" + "version": "0.26.54.24096", + "templateHash": "13701757307300485900" }, "name": "Recovery Services Vault Replication Policies", "description": "This module deploys a Recovery Services Vault Replication Policy for Disaster Recovery scenario.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario.", @@ -1221,8 +1221,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16823125725342753814" + "version": "0.26.54.24096", + "templateHash": "7323008272687100781" }, "name": "Recovery Services Vault Backup Storage Config", "description": "This module deploys a Recovery Service Vault Backup Storage Configuration.", @@ -1347,8 +1347,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "5887508216739936022" + "version": "0.26.54.24096", + "templateHash": "16058746935194459972" }, "name": "Recovery Services Vault Protection Container", "description": "This module deploys a Recovery Services Vault Protection Container.", @@ -1486,8 +1486,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15677187951825533891" + "version": "0.26.54.24096", + "templateHash": "5385249890312845255" }, "name": "Recovery Service Vaults Protection Container Protected Item", "description": "This module deploys a Recovery Services Vault Protection Container Protected Item.", @@ -1652,8 +1652,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3329904805287164035" + "version": "0.26.54.24096", + "templateHash": "53495924931537880" }, "name": "Recovery Services Vault Backup Policies", "description": "This module deploys a Recovery Services Vault Backup Policy.", @@ -1745,8 +1745,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15423985878725052790" + "version": "0.26.54.24096", + "templateHash": "13689565005288174531" }, "name": "Recovery Services Vault Backup Config", "description": "This module deploys a Recovery Services Vault Backup Config.", @@ -1912,8 +1912,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15609344101830369541" + "version": "0.26.54.24096", + "templateHash": "7725737508882142877" }, "name": "Recovery Services Vault Replication Alert Settings", "description": "This module deploys a Recovery Services Vault Replication Alert Settings.", diff --git a/avm/res/recovery-services/vault/replication-alert-setting/main.json b/avm/res/recovery-services/vault/replication-alert-setting/main.json index a3659c2417..2ce087db13 100644 --- a/avm/res/recovery-services/vault/replication-alert-setting/main.json +++ b/avm/res/recovery-services/vault/replication-alert-setting/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15609344101830369541" + "version": "0.26.54.24096", + "templateHash": "7725737508882142877" }, "name": "Recovery Services Vault Replication Alert Settings", "description": "This module deploys a Recovery Services Vault Replication Alert Settings.", diff --git a/avm/res/recovery-services/vault/replication-fabric/main.bicep b/avm/res/recovery-services/vault/replication-fabric/main.bicep index 5156981ed4..e7b7f91869 100644 --- a/avm/res/recovery-services/vault/replication-fabric/main.bicep +++ b/avm/res/recovery-services/vault/replication-fabric/main.bicep @@ -26,18 +26,22 @@ resource replicationFabric 'Microsoft.RecoveryServices/vaults/replicationFabrics } } -module fabric_replicationContainers 'replication-protection-container/main.bicep' = [for (container, index) in replicationContainers: { - name: '${deployment().name}-RCont-${index}' - params: { - name: container.name - recoveryVaultName: recoveryVaultName - replicationFabricName: name - replicationContainerMappings: contains(container, 'replicationContainerMappings') ? container.replicationContainerMappings : [] +module fabric_replicationContainers 'replication-protection-container/main.bicep' = [ + for (container, index) in replicationContainers: { + name: '${deployment().name}-RCont-${index}' + params: { + name: container.name + recoveryVaultName: recoveryVaultName + replicationFabricName: name + replicationContainerMappings: contains(container, 'replicationContainerMappings') + ? container.replicationContainerMappings + : [] + } + dependsOn: [ + replicationFabric + ] } - dependsOn: [ - replicationFabric - ] -}] +] @description('The name of the replication fabric.') output name string = replicationFabric.name diff --git a/avm/res/recovery-services/vault/replication-fabric/main.json b/avm/res/recovery-services/vault/replication-fabric/main.json index 5be50536e8..3b86dad90a 100644 --- a/avm/res/recovery-services/vault/replication-fabric/main.json +++ b/avm/res/recovery-services/vault/replication-fabric/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "9213187265421923503" + "version": "0.26.54.24096", + "templateHash": "10579941098853248837" }, "name": "Recovery Services Vault Replication Fabrics", "description": "This module deploys a Replication Fabric for Azure to Azure disaster recovery scenario of Azure Site Recovery.\n\n> Note: this module currently support only the `instanceType: 'Azure'` scenario.", @@ -83,8 +83,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "584392949528635994" + "version": "0.26.54.24096", + "templateHash": "16016202718205451628" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Containers", "description": "This module deploys a Recovery Services Vault Replication Protection Container.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario.", @@ -166,8 +166,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8286726590589779511" + "version": "0.26.54.24096", + "templateHash": "16134780575393361186" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Container Replication Protection Container Mappings", "description": "This module deploys a Recovery Services Vault (RSV) Replication Protection Container Mapping.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario.", diff --git a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.bicep b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.bicep index 4e23d2b5d3..95114d9bcb 100644 --- a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.bicep +++ b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.bicep @@ -27,23 +27,29 @@ resource replicationContainer 'Microsoft.RecoveryServices/vaults/replicationFabr } } -module fabric_container_containerMappings 'replication-protection-container-mapping/main.bicep' = [for (mapping, index) in replicationContainerMappings: { - name: '${deployment().name}-Map-${index}' - params: { - name: contains(mapping, 'name') ? mapping.name : '' - policyId: contains(mapping, 'policyId') ? mapping.policyId : '' - policyName: contains(mapping, 'policyName') ? mapping.policyName : '' - recoveryVaultName: recoveryVaultName - replicationFabricName: replicationFabricName - sourceProtectionContainerName: name - targetProtectionContainerId: contains(mapping, 'targetProtectionContainerId') ? mapping.targetProtectionContainerId : '' - targetContainerFabricName: contains(mapping, 'targetContainerFabricName') ? mapping.targetContainerFabricName : replicationFabricName - targetContainerName: contains(mapping, 'targetContainerName') ? mapping.targetContainerName : '' +module fabric_container_containerMappings 'replication-protection-container-mapping/main.bicep' = [ + for (mapping, index) in replicationContainerMappings: { + name: '${deployment().name}-Map-${index}' + params: { + name: contains(mapping, 'name') ? mapping.name : '' + policyId: contains(mapping, 'policyId') ? mapping.policyId : '' + policyName: contains(mapping, 'policyName') ? mapping.policyName : '' + recoveryVaultName: recoveryVaultName + replicationFabricName: replicationFabricName + sourceProtectionContainerName: name + targetProtectionContainerId: contains(mapping, 'targetProtectionContainerId') + ? mapping.targetProtectionContainerId + : '' + targetContainerFabricName: contains(mapping, 'targetContainerFabricName') + ? mapping.targetContainerFabricName + : replicationFabricName + targetContainerName: contains(mapping, 'targetContainerName') ? mapping.targetContainerName : '' + } + dependsOn: [ + replicationContainer + ] } - dependsOn: [ - replicationContainer - ] -}] +] @description('The name of the replication container.') output name string = replicationContainer.name diff --git a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.json b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.json index 78784a2039..61cab34cde 100644 --- a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.json +++ b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "584392949528635994" + "version": "0.26.54.24096", + "templateHash": "16016202718205451628" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Containers", "description": "This module deploys a Recovery Services Vault Replication Protection Container.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario.", @@ -87,8 +87,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8286726590589779511" + "version": "0.26.54.24096", + "templateHash": "16134780575393361186" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Container Replication Protection Container Mappings", "description": "This module deploys a Recovery Services Vault (RSV) Replication Protection Container Mapping.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario.", diff --git a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.bicep b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.bicep index 1e0fc30ec9..2d50d4933d 100644 --- a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.bicep +++ b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.bicep @@ -31,9 +31,20 @@ param policyName string = '' @description('Optional. The name of the replication container mapping. If not provided, it will be automatically generated as `-`.') param name string = '' -var policyResourceId = policyId != '' ? policyId : subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', recoveryVaultName, policyName) -var targetProtectionContainerResourceId = targetProtectionContainerId != '' ? targetProtectionContainerId : subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', recoveryVaultName, targetContainerFabricName, targetContainerName) -var mappingName = !empty(name) ? name : '${sourceProtectionContainerName}-${split(targetProtectionContainerResourceId, '/')[10]}' +var policyResourceId = policyId != '' + ? policyId + : subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', recoveryVaultName, policyName) +var targetProtectionContainerResourceId = targetProtectionContainerId != '' + ? targetProtectionContainerId + : subscriptionResourceId( + 'Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', + recoveryVaultName, + targetContainerFabricName, + targetContainerName + ) +var mappingName = !empty(name) + ? name + : '${sourceProtectionContainerName}-${split(targetProtectionContainerResourceId, '/')[10]}' resource replicationContainer 'Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings@2022-10-01' = { name: '${recoveryVaultName}/${replicationFabricName}/${sourceProtectionContainerName}/${mappingName}' diff --git a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.json b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.json index 2c633c2461..2285b6b368 100644 --- a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.json +++ b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8286726590589779511" + "version": "0.26.54.24096", + "templateHash": "16134780575393361186" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Container Replication Protection Container Mappings", "description": "This module deploys a Recovery Services Vault (RSV) Replication Protection Container Mapping.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario.", diff --git a/avm/res/recovery-services/vault/replication-policy/main.json b/avm/res/recovery-services/vault/replication-policy/main.json index e67e01104b..488af5ff5a 100644 --- a/avm/res/recovery-services/vault/replication-policy/main.json +++ b/avm/res/recovery-services/vault/replication-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12506498029720805552" + "version": "0.26.54.24096", + "templateHash": "13701757307300485900" }, "name": "Recovery Services Vault Replication Policies", "description": "This module deploys a Recovery Services Vault Replication Policy for Disaster Recovery scenario.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario.", diff --git a/avm/res/recovery-services/vault/tests/e2e/defaults/main.test.bicep b/avm/res/recovery-services/vault/tests/e2e/defaults/main.test.bicep index 3444eae1ee..7431e75ceb 100644 --- a/avm/res/recovery-services/vault/tests/e2e/defaults/main.test.bicep +++ b/avm/res/recovery-services/vault/tests/e2e/defaults/main.test.bicep @@ -39,24 +39,26 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - location: resourceLocation - enableTelemetry: enableDefaultTelemetry - name: '${namePrefix}${serviceShort}001' - replicationAlertSettings: { - customEmailAddresses: [ - 'test.user@testcompany.com' - ] - locale: 'en-US' - sendToOwners: 'Send' - } - securitySettings: { - immutabilitySettings: { - state: 'Unlocked' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + location: resourceLocation + enableTelemetry: enableDefaultTelemetry + name: '${namePrefix}${serviceShort}001' + replicationAlertSettings: { + customEmailAddresses: [ + 'test.user@testcompany.com' + ] + locale: 'en-US' + sendToOwners: 'Send' + } + securitySettings: { + immutabilitySettings: { + state: 'Unlocked' + } } } } -}] +] diff --git a/avm/res/recovery-services/vault/tests/e2e/dr/main.test.bicep b/avm/res/recovery-services/vault/tests/e2e/dr/main.test.bicep index f372f3c6e7..adc3b5f0c2 100644 --- a/avm/res/recovery-services/vault/tests/e2e/dr/main.test.bicep +++ b/avm/res/recovery-services/vault/tests/e2e/dr/main.test.bicep @@ -39,72 +39,74 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // var rsvName = '${namePrefix}${serviceShort}001' @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - location: resourceLocation - enableTelemetry: enableDefaultTelemetry - name: rsvName - replicationFabrics: [ - { - location: 'NorthEurope' - replicationContainers: [ - { - name: 'ne-container1' - replicationContainerMappings: [ - { - policyName: 'Default_values' - targetContainerName: 'pluto' - targetProtectionContainerId: '${resourceGroup.id}/providers/Microsoft.RecoveryServices/vaults/${rsvName}/replicationFabrics/NorthEurope/replicationProtectionContainers/ne-container2' - } - ] - } - { - name: 'ne-container2' - replicationContainerMappings: [ - { - policyName: 'Default_values' - targetContainerFabricName: 'WE-2' - targetContainerName: 'we-container1' - } - ] - } - ] +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + location: resourceLocation + enableTelemetry: enableDefaultTelemetry + name: rsvName + replicationFabrics: [ + { + location: 'NorthEurope' + replicationContainers: [ + { + name: 'ne-container1' + replicationContainerMappings: [ + { + policyName: 'Default_values' + targetContainerName: 'pluto' + targetProtectionContainerId: '${resourceGroup.id}/providers/Microsoft.RecoveryServices/vaults/${rsvName}/replicationFabrics/NorthEurope/replicationProtectionContainers/ne-container2' + } + ] + } + { + name: 'ne-container2' + replicationContainerMappings: [ + { + policyName: 'Default_values' + targetContainerFabricName: 'WE-2' + targetContainerName: 'we-container1' + } + ] + } + ] + } + { + location: 'WestEurope' + name: 'WE-2' + replicationContainers: [ + { + name: 'we-container1' + replicationContainerMappings: [ + { + policyName: 'Default_values' + targetContainerFabricName: 'NorthEurope' + targetContainerName: 'ne-container2' + } + ] + } + ] + } + ] + replicationPolicies: [ + { + name: 'Default_values' + } + { + appConsistentFrequencyInMinutes: 240 + crashConsistentFrequencyInMinutes: 7 + multiVmSyncStatus: 'Disable' + name: 'Custom_values' + recoveryPointHistory: 2880 + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - location: 'WestEurope' - name: 'WE-2' - replicationContainers: [ - { - name: 'we-container1' - replicationContainerMappings: [ - { - policyName: 'Default_values' - targetContainerFabricName: 'NorthEurope' - targetContainerName: 'ne-container2' - } - ] - } - ] - } - ] - replicationPolicies: [ - { - name: 'Default_values' - } - { - appConsistentFrequencyInMinutes: 240 - crashConsistentFrequencyInMinutes: 7 - multiVmSyncStatus: 'Disable' - name: 'Custom_values' - recoveryPointHistory: 2880 - } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep b/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep index 1232ad832e..3c5618b5b6 100644 --- a/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep +++ b/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep @@ -63,371 +63,376 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - location: resourceLocation - enableTelemetry: enableDefaultTelemetry - name: '${namePrefix}${serviceShort}001' - backupConfig: { - enhancedSecurityState: 'Disabled' - softDeleteFeatureState: 'Disabled' - } - backupPolicies: [ - { - name: 'VMpolicy' - properties: { - backupManagementType: 'AzureIaasVM' - instantRPDetails: {} - instantRpRetentionRangeInDays: 2 - protectedItemsCount: 0 - retentionPolicy: { - dailySchedule: { - retentionDuration: { - count: 180 - durationType: 'Days' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + location: resourceLocation + enableTelemetry: enableDefaultTelemetry + name: '${namePrefix}${serviceShort}001' + backupConfig: { + enhancedSecurityState: 'Disabled' + softDeleteFeatureState: 'Disabled' + } + backupPolicies: [ + { + name: 'VMpolicy' + properties: { + backupManagementType: 'AzureIaasVM' + instantRPDetails: {} + instantRpRetentionRangeInDays: 2 + protectedItemsCount: 0 + retentionPolicy: { + dailySchedule: { + retentionDuration: { + count: 180 + durationType: 'Days' + } + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] } - retentionTimes: [ - '2019-11-07T07:00:00Z' - ] - } - monthlySchedule: { - retentionDuration: { - count: 60 - durationType: 'Months' + monthlySchedule: { + retentionDuration: { + count: 60 + durationType: 'Months' + } + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] } - retentionScheduleFormatType: 'Weekly' - retentionScheduleWeekly: { + retentionPolicyType: 'LongTermRetentionPolicy' + weeklySchedule: { daysOfTheWeek: [ 'Sunday' ] - weeksOfTheMonth: [ - 'First' + retentionDuration: { + count: 12 + durationType: 'Weeks' + } + retentionTimes: [ + '2019-11-07T07:00:00Z' ] } - retentionTimes: [ - '2019-11-07T07:00:00Z' - ] - } - retentionPolicyType: 'LongTermRetentionPolicy' - weeklySchedule: { - daysOfTheWeek: [ - 'Sunday' - ] - retentionDuration: { - count: 12 - durationType: 'Weeks' - } - retentionTimes: [ - '2019-11-07T07:00:00Z' - ] - } - yearlySchedule: { - monthsOfYear: [ - 'January' - ] - retentionDuration: { - count: 10 - durationType: 'Years' - } - retentionScheduleFormatType: 'Weekly' - retentionScheduleWeekly: { - daysOfTheWeek: [ - 'Sunday' + yearlySchedule: { + monthsOfYear: [ + 'January' ] - weeksOfTheMonth: [ - 'First' + retentionDuration: { + count: 10 + durationType: 'Years' + } + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T07:00:00Z' ] } - retentionTimes: [ + } + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunFrequency: 'Daily' + scheduleRunTimes: [ '2019-11-07T07:00:00Z' ] + scheduleWeeklyFrequency: 0 } - } - schedulePolicy: { - schedulePolicyType: 'SimpleSchedulePolicy' - scheduleRunFrequency: 'Daily' - scheduleRunTimes: [ - '2019-11-07T07:00:00Z' - ] - scheduleWeeklyFrequency: 0 - } - timeZone: 'UTC' - } - } - { - name: 'sqlpolicy' - properties: { - backupManagementType: 'AzureWorkload' - protectedItemsCount: 0 - settings: { - isCompression: true - issqlcompression: true timeZone: 'UTC' } - subProtectionPolicy: [ - { - policyType: 'Full' - retentionPolicy: { - monthlySchedule: { - retentionDuration: { - count: 60 - durationType: 'Months' + } + { + name: 'sqlpolicy' + properties: { + backupManagementType: 'AzureWorkload' + protectedItemsCount: 0 + settings: { + isCompression: true + issqlcompression: true + timeZone: 'UTC' + } + subProtectionPolicy: [ + { + policyType: 'Full' + retentionPolicy: { + monthlySchedule: { + retentionDuration: { + count: 60 + durationType: 'Months' + } + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T22:00:00Z' + ] } - retentionScheduleFormatType: 'Weekly' - retentionScheduleWeekly: { + retentionPolicyType: 'LongTermRetentionPolicy' + weeklySchedule: { daysOfTheWeek: [ 'Sunday' ] - weeksOfTheMonth: [ - 'First' + retentionDuration: { + count: 104 + durationType: 'Weeks' + } + retentionTimes: [ + '2019-11-07T22:00:00Z' + ] + } + yearlySchedule: { + monthsOfYear: [ + 'January' + ] + retentionDuration: { + count: 10 + durationType: 'Years' + } + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T22:00:00Z' ] } - retentionTimes: [ - '2019-11-07T22:00:00Z' - ] } - retentionPolicyType: 'LongTermRetentionPolicy' - weeklySchedule: { - daysOfTheWeek: [ + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunDays: [ 'Sunday' ] - retentionDuration: { - count: 104 - durationType: 'Weeks' - } - retentionTimes: [ + scheduleRunFrequency: 'Weekly' + scheduleRunTimes: [ '2019-11-07T22:00:00Z' ] + scheduleWeeklyFrequency: 0 } - yearlySchedule: { - monthsOfYear: [ - 'January' - ] + } + { + policyType: 'Differential' + retentionPolicy: { retentionDuration: { - count: 10 - durationType: 'Years' - } - retentionScheduleFormatType: 'Weekly' - retentionScheduleWeekly: { - daysOfTheWeek: [ - 'Sunday' - ] - weeksOfTheMonth: [ - 'First' - ] + count: 30 + durationType: 'Days' } - retentionTimes: [ - '2019-11-07T22:00:00Z' + retentionPolicyType: 'SimpleRetentionPolicy' + } + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunDays: [ + 'Monday' + ] + scheduleRunFrequency: 'Weekly' + scheduleRunTimes: [ + '2017-03-07T02:00:00Z' ] + scheduleWeeklyFrequency: 0 } } - schedulePolicy: { - schedulePolicyType: 'SimpleSchedulePolicy' - scheduleRunDays: [ - 'Sunday' - ] - scheduleRunFrequency: 'Weekly' - scheduleRunTimes: [ - '2019-11-07T22:00:00Z' - ] - scheduleWeeklyFrequency: 0 + { + policyType: 'Log' + retentionPolicy: { + retentionDuration: { + count: 15 + durationType: 'Days' + } + retentionPolicyType: 'SimpleRetentionPolicy' + } + schedulePolicy: { + scheduleFrequencyInMins: 120 + schedulePolicyType: 'LogSchedulePolicy' + } } - } - { - policyType: 'Differential' - retentionPolicy: { + ] + workLoadType: 'SQLDataBase' + } + } + { + name: 'filesharepolicy' + properties: { + backupManagementType: 'AzureStorage' + protectedItemsCount: 0 + retentionPolicy: { + dailySchedule: { retentionDuration: { count: 30 durationType: 'Days' } - retentionPolicyType: 'SimpleRetentionPolicy' - } - schedulePolicy: { - schedulePolicyType: 'SimpleSchedulePolicy' - scheduleRunDays: [ - 'Monday' - ] - scheduleRunFrequency: 'Weekly' - scheduleRunTimes: [ - '2017-03-07T02:00:00Z' + retentionTimes: [ + '2019-11-07T04:30:00Z' ] - scheduleWeeklyFrequency: 0 - } - } - { - policyType: 'Log' - retentionPolicy: { - retentionDuration: { - count: 15 - durationType: 'Days' - } - retentionPolicyType: 'SimpleRetentionPolicy' - } - schedulePolicy: { - scheduleFrequencyInMins: 120 - schedulePolicyType: 'LogSchedulePolicy' } + retentionPolicyType: 'LongTermRetentionPolicy' } - ] - workLoadType: 'SQLDataBase' - } - } - { - name: 'filesharepolicy' - properties: { - backupManagementType: 'AzureStorage' - protectedItemsCount: 0 - retentionPolicy: { - dailySchedule: { - retentionDuration: { - count: 30 - durationType: 'Days' - } - retentionTimes: [ + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunFrequency: 'Daily' + scheduleRunTimes: [ '2019-11-07T04:30:00Z' ] + scheduleWeeklyFrequency: 0 } - retentionPolicyType: 'LongTermRetentionPolicy' - } - schedulePolicy: { - schedulePolicyType: 'SimpleSchedulePolicy' - scheduleRunFrequency: 'Daily' - scheduleRunTimes: [ - '2019-11-07T04:30:00Z' - ] - scheduleWeeklyFrequency: 0 + timeZone: 'UTC' + workloadType: 'AzureFileShare' } - timeZone: 'UTC' - workloadType: 'AzureFileShare' } - } - ] - backupStorageConfig: { - crossRegionRestoreFlag: true - storageModelType: 'GeoRedundant' - } - replicationAlertSettings: { - customEmailAddresses: [ - 'test.user@testcompany.com' ] - locale: 'en-US' - sendToOwners: 'Send' - } - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } + backupStorageConfig: { + crossRegionRestoreFlag: true + storageModelType: 'GeoRedundant' + } + replicationAlertSettings: { + customEmailAddresses: [ + 'test.user@testcompany.com' ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + locale: 'en-US' + sendToOwners: 'Send' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } ] - } - privateEndpoints: [ - { - ipConfigurations: [ - { - name: 'myIpConfig-1' - properties: { - groupId: 'AzureSiteRecovery' - memberName: 'SiteRecovery-tel1' - privateIPAddress: '10.0.0.10' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + privateEndpoints: [ + { + ipConfigurations: [ + { + name: 'myIpConfig-1' + properties: { + groupId: 'AzureSiteRecovery' + memberName: 'SiteRecovery-tel1' + privateIPAddress: '10.0.0.10' + } } - } - { - name: 'myIPconfig-2' - properties: { - groupId: 'AzureSiteRecovery' - memberName: 'SiteRecovery-prot2' - privateIPAddress: '10.0.0.11' + { + name: 'myIPconfig-2' + properties: { + groupId: 'AzureSiteRecovery' + memberName: 'SiteRecovery-prot2' + privateIPAddress: '10.0.0.11' + } } - } - { - name: 'myIPconfig-3' - properties: { - groupId: 'AzureSiteRecovery' - memberName: 'SiteRecovery-srs1' - privateIPAddress: '10.0.0.12' + { + name: 'myIPconfig-3' + properties: { + groupId: 'AzureSiteRecovery' + memberName: 'SiteRecovery-srs1' + privateIPAddress: '10.0.0.12' + } } - } - { - name: 'myIPconfig-4' - properties: { - groupId: 'AzureSiteRecovery' - memberName: 'SiteRecovery-rcm1' - privateIPAddress: '10.0.0.13' + { + name: 'myIPconfig-4' + properties: { + groupId: 'AzureSiteRecovery' + memberName: 'SiteRecovery-rcm1' + privateIPAddress: '10.0.0.13' + } } - } - { - name: 'myIPconfig-5' - properties: { - groupId: 'AzureSiteRecovery' - memberName: 'SiteRecovery-id1' - privateIPAddress: '10.0.0.14' + { + name: 'myIPconfig-5' + properties: { + groupId: 'AzureSiteRecovery' + memberName: 'SiteRecovery-id1' + privateIPAddress: '10.0.0.14' + } } + ] + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - 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: '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' + } + ] + monitoringSettings: { + azureMonitorAlertSettings: { + alertsForAllJobFailures: 'Enabled' + } + classicAlertSettings: { + alertsForCriticalOperations: 'Enabled' } } - ] - 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' - } - ] - monitoringSettings: { - azureMonitorAlertSettings: { - alertsForAllJobFailures: 'Enabled' - } - classicAlertSettings: { - alertsForCriticalOperations: 'Enabled' + securitySettings: { + immutabilitySettings: { + state: 'Unlocked' + } } - } - securitySettings: { - immutabilitySettings: { - state: 'Unlocked' + 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/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep b/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep index 22605d1d30..6b74206104 100644 --- a/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep @@ -63,354 +63,356 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - location: resourceLocation - enableTelemetry: enableDefaultTelemetry - name: '${namePrefix}${serviceShort}001' - backupConfig: { - enhancedSecurityState: 'Disabled' - softDeleteFeatureState: 'Disabled' - } - backupPolicies: [ - { - name: 'VMpolicy' - properties: { - backupManagementType: 'AzureIaasVM' - instantRPDetails: {} - instantRpRetentionRangeInDays: 2 - protectedItemsCount: 0 - retentionPolicy: { - dailySchedule: { - retentionDuration: { - count: 180 - durationType: 'Days' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + location: resourceLocation + enableTelemetry: enableDefaultTelemetry + name: '${namePrefix}${serviceShort}001' + backupConfig: { + enhancedSecurityState: 'Disabled' + softDeleteFeatureState: 'Disabled' + } + backupPolicies: [ + { + name: 'VMpolicy' + properties: { + backupManagementType: 'AzureIaasVM' + instantRPDetails: {} + instantRpRetentionRangeInDays: 2 + protectedItemsCount: 0 + retentionPolicy: { + dailySchedule: { + retentionDuration: { + count: 180 + durationType: 'Days' + } + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] } - retentionTimes: [ - '2019-11-07T07:00:00Z' - ] - } - monthlySchedule: { - retentionDuration: { - count: 60 - durationType: 'Months' + monthlySchedule: { + retentionDuration: { + count: 60 + durationType: 'Months' + } + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] } - retentionScheduleFormatType: 'Weekly' - retentionScheduleWeekly: { + retentionPolicyType: 'LongTermRetentionPolicy' + weeklySchedule: { daysOfTheWeek: [ 'Sunday' ] - weeksOfTheMonth: [ - 'First' + retentionDuration: { + count: 12 + durationType: 'Weeks' + } + retentionTimes: [ + '2019-11-07T07:00:00Z' ] } - retentionTimes: [ - '2019-11-07T07:00:00Z' - ] - } - retentionPolicyType: 'LongTermRetentionPolicy' - weeklySchedule: { - daysOfTheWeek: [ - 'Sunday' - ] - retentionDuration: { - count: 12 - durationType: 'Weeks' - } - retentionTimes: [ - '2019-11-07T07:00:00Z' - ] - } - yearlySchedule: { - monthsOfYear: [ - 'January' - ] - retentionDuration: { - count: 10 - durationType: 'Years' - } - retentionScheduleFormatType: 'Weekly' - retentionScheduleWeekly: { - daysOfTheWeek: [ - 'Sunday' + yearlySchedule: { + monthsOfYear: [ + 'January' ] - weeksOfTheMonth: [ - 'First' + retentionDuration: { + count: 10 + durationType: 'Years' + } + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T07:00:00Z' ] } - retentionTimes: [ + } + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunFrequency: 'Daily' + scheduleRunTimes: [ '2019-11-07T07:00:00Z' ] + scheduleWeeklyFrequency: 0 } - } - schedulePolicy: { - schedulePolicyType: 'SimpleSchedulePolicy' - scheduleRunFrequency: 'Daily' - scheduleRunTimes: [ - '2019-11-07T07:00:00Z' - ] - scheduleWeeklyFrequency: 0 - } - timeZone: 'UTC' - } - } - { - name: 'sqlpolicy' - properties: { - backupManagementType: 'AzureWorkload' - protectedItemsCount: 0 - settings: { - isCompression: true - issqlcompression: true timeZone: 'UTC' } - subProtectionPolicy: [ - { - policyType: 'Full' - retentionPolicy: { - monthlySchedule: { - retentionDuration: { - count: 60 - durationType: 'Months' + } + { + name: 'sqlpolicy' + properties: { + backupManagementType: 'AzureWorkload' + protectedItemsCount: 0 + settings: { + isCompression: true + issqlcompression: true + timeZone: 'UTC' + } + subProtectionPolicy: [ + { + policyType: 'Full' + retentionPolicy: { + monthlySchedule: { + retentionDuration: { + count: 60 + durationType: 'Months' + } + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T22:00:00Z' + ] } - retentionScheduleFormatType: 'Weekly' - retentionScheduleWeekly: { + retentionPolicyType: 'LongTermRetentionPolicy' + weeklySchedule: { daysOfTheWeek: [ 'Sunday' ] - weeksOfTheMonth: [ - 'First' + retentionDuration: { + count: 104 + durationType: 'Weeks' + } + retentionTimes: [ + '2019-11-07T22:00:00Z' + ] + } + yearlySchedule: { + monthsOfYear: [ + 'January' + ] + retentionDuration: { + count: 10 + durationType: 'Years' + } + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T22:00:00Z' ] } - retentionTimes: [ - '2019-11-07T22:00:00Z' - ] } - retentionPolicyType: 'LongTermRetentionPolicy' - weeklySchedule: { - daysOfTheWeek: [ + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunDays: [ 'Sunday' ] - retentionDuration: { - count: 104 - durationType: 'Weeks' - } - retentionTimes: [ + scheduleRunFrequency: 'Weekly' + scheduleRunTimes: [ '2019-11-07T22:00:00Z' ] + scheduleWeeklyFrequency: 0 } - yearlySchedule: { - monthsOfYear: [ - 'January' - ] + } + { + policyType: 'Differential' + retentionPolicy: { retentionDuration: { - count: 10 - durationType: 'Years' - } - retentionScheduleFormatType: 'Weekly' - retentionScheduleWeekly: { - daysOfTheWeek: [ - 'Sunday' - ] - weeksOfTheMonth: [ - 'First' - ] + count: 30 + durationType: 'Days' } - retentionTimes: [ - '2019-11-07T22:00:00Z' + retentionPolicyType: 'SimpleRetentionPolicy' + } + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunDays: [ + 'Monday' ] + scheduleRunFrequency: 'Weekly' + scheduleRunTimes: [ + '2017-03-07T02:00:00Z' + ] + scheduleWeeklyFrequency: 0 } } - schedulePolicy: { - schedulePolicyType: 'SimpleSchedulePolicy' - scheduleRunDays: [ - 'Sunday' - ] - scheduleRunFrequency: 'Weekly' - scheduleRunTimes: [ - '2019-11-07T22:00:00Z' - ] - scheduleWeeklyFrequency: 0 + { + policyType: 'Log' + retentionPolicy: { + retentionDuration: { + count: 15 + durationType: 'Days' + } + retentionPolicyType: 'SimpleRetentionPolicy' + } + schedulePolicy: { + scheduleFrequencyInMins: 120 + schedulePolicyType: 'LogSchedulePolicy' + } } - } - { - policyType: 'Differential' - retentionPolicy: { + ] + workLoadType: 'SQLDataBase' + } + } + { + name: 'filesharepolicy' + properties: { + backupManagementType: 'AzureStorage' + protectedItemsCount: 0 + retentionPolicy: { + dailySchedule: { retentionDuration: { count: 30 durationType: 'Days' } - retentionPolicyType: 'SimpleRetentionPolicy' - } - schedulePolicy: { - schedulePolicyType: 'SimpleSchedulePolicy' - scheduleRunDays: [ - 'Monday' - ] - scheduleRunFrequency: 'Weekly' - scheduleRunTimes: [ - '2017-03-07T02:00:00Z' + retentionTimes: [ + '2019-11-07T04:30:00Z' ] - scheduleWeeklyFrequency: 0 - } - } - { - policyType: 'Log' - retentionPolicy: { - retentionDuration: { - count: 15 - durationType: 'Days' - } - retentionPolicyType: 'SimpleRetentionPolicy' - } - schedulePolicy: { - scheduleFrequencyInMins: 120 - schedulePolicyType: 'LogSchedulePolicy' } + retentionPolicyType: 'LongTermRetentionPolicy' } - ] - workLoadType: 'SQLDataBase' - } - } - { - name: 'filesharepolicy' - properties: { - backupManagementType: 'AzureStorage' - protectedItemsCount: 0 - retentionPolicy: { - dailySchedule: { - retentionDuration: { - count: 30 - durationType: 'Days' - } - retentionTimes: [ + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunFrequency: 'Daily' + scheduleRunTimes: [ '2019-11-07T04:30:00Z' ] + scheduleWeeklyFrequency: 0 } - retentionPolicyType: 'LongTermRetentionPolicy' - } - schedulePolicy: { - schedulePolicyType: 'SimpleSchedulePolicy' - scheduleRunFrequency: 'Daily' - scheduleRunTimes: [ - '2019-11-07T04:30:00Z' - ] - scheduleWeeklyFrequency: 0 + timeZone: 'UTC' + workloadType: 'AzureFileShare' } - timeZone: 'UTC' - workloadType: 'AzureFileShare' } - } - ] - backupStorageConfig: { - crossRegionRestoreFlag: true - storageModelType: 'GeoRedundant' - } - replicationAlertSettings: { - customEmailAddresses: [ - 'test.user@testcompany.com' ] - locale: 'en-US' - sendToOwners: 'Send' - } - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } + backupStorageConfig: { + crossRegionRestoreFlag: true + storageModelType: 'GeoRedundant' + } + replicationAlertSettings: { + customEmailAddresses: [ + 'test.user@testcompany.com' ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + locale: 'en-US' + sendToOwners: 'Send' } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } ] - } - privateEndpoints: [ - { - ipConfigurations: [ - { - name: 'myIpConfig-1' - properties: { - groupId: 'AzureSiteRecovery' - memberName: 'SiteRecovery-tel1' - privateIPAddress: '10.0.0.10' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + privateEndpoints: [ + { + ipConfigurations: [ + { + name: 'myIpConfig-1' + properties: { + groupId: 'AzureSiteRecovery' + memberName: 'SiteRecovery-tel1' + privateIPAddress: '10.0.0.10' + } } - } - { - name: 'myIPconfig-2' - properties: { - groupId: 'AzureSiteRecovery' - memberName: 'SiteRecovery-prot2' - privateIPAddress: '10.0.0.11' + { + name: 'myIPconfig-2' + properties: { + groupId: 'AzureSiteRecovery' + memberName: 'SiteRecovery-prot2' + privateIPAddress: '10.0.0.11' + } } - } - { - name: 'myIPconfig-3' - properties: { - groupId: 'AzureSiteRecovery' - memberName: 'SiteRecovery-srs1' - privateIPAddress: '10.0.0.12' + { + name: 'myIPconfig-3' + properties: { + groupId: 'AzureSiteRecovery' + memberName: 'SiteRecovery-srs1' + privateIPAddress: '10.0.0.12' + } } - } - { - name: 'myIPconfig-4' - properties: { - groupId: 'AzureSiteRecovery' - memberName: 'SiteRecovery-rcm1' - privateIPAddress: '10.0.0.13' + { + name: 'myIPconfig-4' + properties: { + groupId: 'AzureSiteRecovery' + memberName: 'SiteRecovery-rcm1' + privateIPAddress: '10.0.0.13' + } } - } - { - name: 'myIPconfig-5' - properties: { - groupId: 'AzureSiteRecovery' - memberName: 'SiteRecovery-id1' - privateIPAddress: '10.0.0.14' + { + name: 'myIPconfig-5' + properties: { + groupId: 'AzureSiteRecovery' + memberName: 'SiteRecovery-id1' + privateIPAddress: '10.0.0.14' + } } + ] + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + } + ] + monitoringSettings: { + azureMonitorAlertSettings: { + alertsForAllJobFailures: 'Enabled' + } + classicAlertSettings: { + alertsForCriticalOperations: 'Enabled' } } - ] - monitoringSettings: { - azureMonitorAlertSettings: { - alertsForAllJobFailures: 'Enabled' - } - classicAlertSettings: { - alertsForCriticalOperations: 'Enabled' + securitySettings: { + immutabilitySettings: { + state: 'Unlocked' + } } - } - securitySettings: { - immutabilitySettings: { - state: 'Unlocked' + 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/resource-graph/query/main.bicep b/avm/res/resource-graph/query/main.bicep index c5e14f413c..d80d1dcd9d 100644 --- a/avm/res/resource-graph/query/main.bicep +++ b/avm/res/resource-graph/query/main.bicep @@ -38,40 +38,50 @@ 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') + '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 // // ================ // -resource rgQuery_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.' +resource rgQuery_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: rgQuery } - scope: rgQuery -} -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.resourcegraph-query.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.resourcegraph-query.${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 rgQuery 'Microsoft.ResourceGraph/queries@2018-09-01-preview' = { name: name @@ -83,19 +93,25 @@ resource rgQuery 'Microsoft.ResourceGraph/queries@2018-09-01-preview' = { } } -resource rgQuery_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(rgQuery.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 +resource rgQuery_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(rgQuery.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: rgQuery } - scope: rgQuery -}] +] // ================ // // Outputs // diff --git a/avm/res/resource-graph/query/main.json b/avm/res/resource-graph/query/main.json index c83a3bcccc..e4cd74859c 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.25.53.49325", - "templateHash": "11608089387685875892" + "version": "0.26.54.24096", + "templateHash": "9585256428416945935" }, "name": "Resource Graph Queries", "description": "This module deploys a Resource Graph Query.", diff --git a/avm/res/resource-graph/query/tests/e2e/max/main.test.bicep b/avm/res/resource-graph/query/tests/e2e/max/main.test.bicep index 3f7e8edead..d5075817e7 100644 --- a/avm/res/resource-graph/query/tests/e2e/max/main.test.bicep +++ b/avm/res/resource-graph/query/tests/e2e/max/main.test.bicep @@ -65,7 +65,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/resources/deployment-script/main.bicep b/avm/res/resources/deployment-script/main.bicep index 0a6d1f7a51..262a54aea0 100644 --- a/avm/res/resources/deployment-script/main.bicep +++ b/avm/res/resources/deployment-script/main.bicep @@ -92,80 +92,110 @@ 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') + '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' + ) } -var subnetIds = [for subnetResourceId in (subnetResourceIds ?? []): { - id: subnetResourceId -}] +var subnetIds = [ + for subnetResourceId in (subnetResourceIds ?? []): { + id: subnetResourceId + } +] var containerSettings = { containerGroupName: containerGroupName subnetIds: !empty(subnetIds ?? []) ? subnetIds : null } -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: !empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-04-01' existing = if (!empty(storageAccountResourceId)) { - name: last(split((!empty(storageAccountResourceId) ? storageAccountResourceId : 'dummyAccount'), '/'))! - scope: resourceGroup(split((!empty(storageAccountResourceId) ? storageAccountResourceId : '//'), '/')[2], split((!empty(storageAccountResourceId) ? storageAccountResourceId : '////'), '/')[4]) -} +var identity = !empty(managedIdentities) + ? { + type: !empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null + +resource storageAccount 'Microsoft.Storage/storageAccounts@2021-04-01' existing = + if (!empty(storageAccountResourceId)) { + name: last(split((!empty(storageAccountResourceId) ? storageAccountResourceId : 'dummyAccount'), '/'))! + scope: resourceGroup( + split((!empty(storageAccountResourceId) ? storageAccountResourceId : '//'), '/')[2], + split((!empty(storageAccountResourceId) ? storageAccountResourceId : '////'), '/')[4] + ) + } -var storageAccountSettings = !empty(storageAccountResourceId) ? { - storageAccountKey: empty(subnetResourceIds) ? listKeys(storageAccount.id, '2023-01-01').keys[0].value : null - storageAccountName: last(split(storageAccountResourceId, '/')) -} : null +var storageAccountSettings = !empty(storageAccountResourceId) + ? { + storageAccountKey: empty(subnetResourceIds) ? listKeys(storageAccount.id, '2023-01-01').keys[0].value : null + storageAccountName: last(split(storageAccountResourceId, '/')) + } + : null // ============ // // Dependencies // // ============ // -resource deploymentScript_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.' +resource deploymentScript_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: deploymentScript } - scope: deploymentScript -} -resource deploymentScript_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(deploymentScript.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 +resource deploymentScript_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(deploymentScript.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: deploymentScript } - scope: deploymentScript -}] - -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.resources-deploymentscript.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.resources-deploymentscript.${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' + } } } } } -} // ================ // // Resources // diff --git a/avm/res/resources/deployment-script/main.json b/avm/res/resources/deployment-script/main.json index 4001d00487..7e14a29e6d 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.25.53.49325", - "templateHash": "11832942286479289748" + "version": "0.26.54.24096", + "templateHash": "6519455487255292674" }, "name": "Deployment Scripts", "description": "This module deploys Deployment Scripts.", diff --git a/avm/res/resources/deployment-script/tests/e2e/max/main.test.bicep b/avm/res/resources/deployment-script/tests/e2e/max/main.test.bicep index 7e327c6e68..9af8441a2c 100644 --- a/avm/res/resources/deployment-script/tests/e2e/max/main.test.bicep +++ b/avm/res/resources/deployment-script/tests/e2e/max/main.test.bicep @@ -94,7 +94,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/resources/resource-group/main.bicep b/avm/res/resources/resource-group/main.bicep index aba3a31722..70c3c63f76 100644 --- a/avm/res/resources/resource-group/main.bicep +++ b/avm/res/resources/resource-group/main.bicep @@ -22,24 +22,25 @@ param tags object? @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.resources-resourcegroup.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.resources-resourcegroup.${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 resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { location: location @@ -49,22 +50,24 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { properties: {} } -module resourceGroup_lock 'modules/nested_lock.bicep' = if (!empty(lock ?? {}) && lock.?kind != 'None') { - name: '${uniqueString(deployment().name, location)}-RG-Lock' - params: { - lock: lock - name: resourceGroup.name +module resourceGroup_lock 'modules/nested_lock.bicep' = + if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: '${uniqueString(deployment().name, location)}-RG-Lock' + params: { + lock: lock + name: resourceGroup.name + } + scope: resourceGroup } - scope: resourceGroup -} -module resourceGroup_roleAssignments 'modules/nested_roleAssignments.bicep' = if (!empty(roleAssignments ?? [])) { - name: '${uniqueString(deployment().name, location)}-RG-RoleAssignments' - params: { - roleAssignments: roleAssignments +module resourceGroup_roleAssignments 'modules/nested_roleAssignments.bicep' = + if (!empty(roleAssignments ?? [])) { + name: '${uniqueString(deployment().name, location)}-RG-RoleAssignments' + params: { + roleAssignments: roleAssignments + } + scope: resourceGroup } - scope: resourceGroup -} @description('The name of the resource group.') output name string = resourceGroup.name diff --git a/avm/res/resources/resource-group/main.json b/avm/res/resources/resource-group/main.json index 0a38a86917..8a95c3e2fc 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.25.53.49325", - "templateHash": "4726997439042123327" + "version": "0.26.54.24096", + "templateHash": "13773232964847117245" }, "name": "Resource Groups", "description": "This module deploys a Resource Group.", @@ -202,8 +202,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7668050384482764751" + "version": "0.26.54.24096", + "templateHash": "1401075311163527928" } }, "definitions": { @@ -288,8 +288,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3156241559834375483" + "version": "0.26.54.24096", + "templateHash": "5825198357776663348" } }, "definitions": { diff --git a/avm/res/resources/resource-group/tests/e2e/defaults/main.test.bicep b/avm/res/resources/resource-group/tests/e2e/defaults/main.test.bicep index 63ad08354a..265479917f 100644 --- a/avm/res/resources/resource-group/tests/e2e/defaults/main.test.bicep +++ b/avm/res/resources/resource-group/tests/e2e/defaults/main.test.bicep @@ -21,10 +21,12 @@ param namePrefix string = '#_namePrefix_#' // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - name: 'avm-${namePrefix}-resources.resourcegroups-${serviceShort}-rg' - location: resourceLocation +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: 'avm-${namePrefix}-resources.resourcegroups-${serviceShort}-rg' + location: resourceLocation + } } -}] +] diff --git a/avm/res/resources/resource-group/tests/e2e/max/main.test.bicep b/avm/res/resources/resource-group/tests/e2e/max/main.test.bicep index 08e5060ba4..37a96bfff5 100644 --- a/avm/res/resources/resource-group/tests/e2e/max/main.test.bicep +++ b/avm/res/resources/resource-group/tests/e2e/max/main.test.bicep @@ -65,7 +65,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/search/search-service/main.bicep b/avm/res/search/search-service/main.bicep index 3ad29c9c68..3325879f8a 100644 --- a/avm/res/search/search-service/main.bicep +++ b/avm/res/search/search-service/main.bicep @@ -101,9 +101,11 @@ param tags object? // Variables // // ============= // -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? 'SystemAssigned' : 'None' -} : null +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) ? 'SystemAssigned' : 'None' + } + : null // =============== // // Deployments // @@ -113,30 +115,46 @@ 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') - 'Search Index Data Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8ebe5a00-799e-43f5-93ac-243d3dce84a7') - 'Search Index Data Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1407120a-92aa-4202-b7e9-c0e197c71c8f') - 'Search Service Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7ca78c08-252a-4471-8644-bb5ff32d4ba0') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'Search Index Data Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '8ebe5a00-799e-43f5-93ac-243d3dce84a7' + ) + 'Search Index Data Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1407120a-92aa-4202-b7e9-c0e197c71c8f' + ) + 'Search Service Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7ca78c08-252a-4471-8644-bb5ff32d4ba0' + ) + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.search-searchservice.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.search-searchservice.${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 searchService 'Microsoft.Search/searchServices@2023-11-01' = { location: location @@ -161,109 +179,138 @@ resource searchService 'Microsoft.Search/searchServices@2023-11-01' = { } } -resource searchService_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 - 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 +resource searchService_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 + 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 + } + scope: searchService } - scope: searchService -}] +] -resource searchService_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.' +resource searchService_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: searchService } - scope: searchService -} -resource searchService_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(searchService.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 +resource searchService_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(searchService.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: searchService } - scope: searchService -}] - -module searchService_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-SearchService-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(searchService.id, '/'))}-${privateEndpoint.?service ?? 'searchService'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(searchService.id, '/'))}-${privateEndpoint.?service ?? 'searchService'}-${index}' - properties: { - privateLinkServiceId: searchService.id - groupIds: [ - privateEndpoint.?service ?? 'searchService' +] + +module searchService_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-SearchService-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(searchService.id, '/'))}-${privateEndpoint.?service ?? 'searchService'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(searchService.id, '/'))}-${privateEndpoint.?service ?? 'searchService'}-${index}' + properties: { + privateLinkServiceId: searchService.id + groupIds: [ + privateEndpoint.?service ?? 'searchService' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(searchService.id, '/'))}-${privateEndpoint.?service ?? 'searchService'}-${index}' - properties: { - privateLinkServiceId: searchService.id - groupIds: [ - privateEndpoint.?service ?? 'searchService' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(searchService.id, '/'))}-${privateEndpoint.?service ?? 'searchService'}-${index}' + properties: { + privateLinkServiceId: searchService.id + groupIds: [ + privateEndpoint.?service ?? 'searchService' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] // The Shared Private Link Resources must be deployed sequentially // otherwise the deployment may fail. // Using batchSize(1) to deploy them one by one @batchSize(1) -module searchService_sharedPrivateLinkResources 'shared-private-link-resource/main.bicep' = [for (sharedPrivateLinkResource, index) in sharedPrivateLinkResources: { - name: '${uniqueString(deployment().name, location)}-searchService-SharedPrivateLink-${index}' - params: { - name: contains(sharedPrivateLinkResource, 'name') ? sharedPrivateLinkResource.name : 'spl-${last(split(searchService.id, '/'))}-${sharedPrivateLinkResource.groupId}-${index}' - searchServiceName: searchService.name - privateLinkResourceId: sharedPrivateLinkResource.privateLinkResourceId - groupId: sharedPrivateLinkResource.groupId - requestMessage: sharedPrivateLinkResource.requestMessage - resourceRegion: sharedPrivateLinkResource.?resourceRegion +module searchService_sharedPrivateLinkResources 'shared-private-link-resource/main.bicep' = [ + for (sharedPrivateLinkResource, index) in sharedPrivateLinkResources: { + name: '${uniqueString(deployment().name, location)}-searchService-SharedPrivateLink-${index}' + params: { + name: contains(sharedPrivateLinkResource, 'name') + ? sharedPrivateLinkResource.name + : 'spl-${last(split(searchService.id, '/'))}-${sharedPrivateLinkResource.groupId}-${index}' + searchServiceName: searchService.name + privateLinkResourceId: sharedPrivateLinkResource.privateLinkResourceId + groupId: sharedPrivateLinkResource.groupId + requestMessage: sharedPrivateLinkResource.requestMessage + resourceRegion: sharedPrivateLinkResource.?resourceRegion + } } -}] +] // =========== // // Outputs // diff --git a/avm/res/search/search-service/main.json b/avm/res/search/search-service/main.json index 742aa10355..6ebfa62b98 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.25.53.49325", - "templateHash": "3319927828453224724" + "version": "0.26.54.24096", + "templateHash": "12548869810736085047" }, "name": "Search Services", "description": "This module deploys a Search Service.", @@ -1424,8 +1424,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7674026452917741601" + "version": "0.26.54.24096", + "templateHash": "4284041533987186633" }, "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 3532ebe6b0..e6f281a453 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 @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7674026452917741601" + "version": "0.26.54.24096", + "templateHash": "4284041533987186633" }, "name": "Search Services Private Link Resources", "description": "This module deploys a Search Service Private Link Resource.", diff --git a/avm/res/search/search-service/tests/e2e/max/main.test.bicep b/avm/res/search/search-service/tests/e2e/max/main.test.bicep index bca042441d..c20835fdea 100644 --- a/avm/res/search/search-service/tests/e2e/max/main.test.bicep +++ b/avm/res/search/search-service/tests/e2e/max/main.test.bicep @@ -95,7 +95,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/service-bus/namespace/authorization-rule/main.json b/avm/res/service-bus/namespace/authorization-rule/main.json index e7f310864e..213b672df5 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.25.53.49325", - "templateHash": "2305438159110957656" + "version": "0.26.54.24096", + "templateHash": "17436716625562680995" }, "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 b3c6887e73..7269a6568a 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.25.53.49325", - "templateHash": "4852834945333619424" + "version": "0.26.54.24096", + "templateHash": "5141733056602320076" }, "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 cfd5c17710..5af577f1e5 100644 --- a/avm/res/service-bus/namespace/main.bicep +++ b/avm/res/service-bus/namespace/main.bicep @@ -95,55 +95,88 @@ param customerManagedKey customerManagedKeyType @description('Optional. Enable infrastructure encryption (double encryption). Note, this setting requires the configuration of Customer-Managed-Keys (CMK) via the corresponding module parameters.') param requireInfrastructureEncryption bool = true -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - 'Azure Service Bus Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419') - 'Azure Service Bus Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0') - 'Azure Service Bus Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39') + 'Azure Service Bus Data Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '090c5cfd-751d-490a-894a-3ce6f1109419' + ) + 'Azure Service Bus Data Receiver': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0' + ) + 'Azure Service Bus Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39' + ) 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') + '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.servicebus-namespace.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.servicebus-namespace.${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 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 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 serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' = { name: name @@ -155,206 +188,250 @@ resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview } identity: identity properties: { - publicNetworkAccess: !empty(publicNetworkAccess) ? publicNetworkAccess : (!empty(privateEndpoints) && empty(networkRuleSets) ? 'Disabled' : 'Enabled') + publicNetworkAccess: !empty(publicNetworkAccess) + ? publicNetworkAccess + : (!empty(privateEndpoints) && empty(networkRuleSets) ? 'Disabled' : 'Enabled') minimumTlsVersion: minimumTlsVersion alternateName: alternateName zoneRedundant: zoneRedundant disableLocalAuth: disableLocalAuth premiumMessagingPartitions: skuObject.name == 'Premium' ? premiumMessagingPartitions : 0 - encryption: !empty(customerManagedKey) ? { - keySource: 'Microsoft.KeyVault' - keyVaultProperties: [ - { - identity: !empty(customerManagedKey.?userAssignedIdentityResourceId) ? { - userAssignedIdentity: cMKUserAssignedIdentity.id - } : null - keyName: customerManagedKey!.keyName - keyVaultUri: cMKKeyVault.properties.vaultUri - keyVersion: !empty(customerManagedKey.?keyVersion ?? '') ? customerManagedKey!.keyVersion : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) + encryption: !empty(customerManagedKey) + ? { + keySource: 'Microsoft.KeyVault' + keyVaultProperties: [ + { + identity: !empty(customerManagedKey.?userAssignedIdentityResourceId) + ? { + userAssignedIdentity: cMKUserAssignedIdentity.id + } + : null + keyName: customerManagedKey!.keyName + keyVaultUri: cMKKeyVault.properties.vaultUri + keyVersion: !empty(customerManagedKey.?keyVersion ?? '') + ? customerManagedKey!.keyVersion + : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) + } + ] + requireInfrastructureEncryption: requireInfrastructureEncryption } - ] - requireInfrastructureEncryption: requireInfrastructureEncryption - } : null + : null } } -module serviceBusNamespace_authorizationRules 'authorization-rule/main.bicep' = [for (authorizationRule, index) in authorizationRules: { - name: '${uniqueString(deployment().name, location)}-AuthorizationRules-${index}' - params: { - namespaceName: serviceBusNamespace.name - name: authorizationRule.name - rights: authorizationRule.?rights +module serviceBusNamespace_authorizationRules 'authorization-rule/main.bicep' = [ + for (authorizationRule, index) in authorizationRules: { + name: '${uniqueString(deployment().name, location)}-AuthorizationRules-${index}' + params: { + namespaceName: serviceBusNamespace.name + name: authorizationRule.name + rights: authorizationRule.?rights + } } -}] - -module serviceBusNamespace_disasterRecoveryConfig 'disaster-recovery-config/main.bicep' = if (!empty(disasterRecoveryConfig)) { - name: '${uniqueString(deployment().name, location)}-DisasterRecoveryConfig' - params: { - namespaceName: serviceBusNamespace.name - name: disasterRecoveryConfig.?name ?? 'default' - alternateName: disasterRecoveryConfig.?alternateName - partnerNamespaceResourceID: disasterRecoveryConfig.?partnerNamespace +] + +module serviceBusNamespace_disasterRecoveryConfig 'disaster-recovery-config/main.bicep' = + if (!empty(disasterRecoveryConfig)) { + name: '${uniqueString(deployment().name, location)}-DisasterRecoveryConfig' + params: { + namespaceName: serviceBusNamespace.name + name: disasterRecoveryConfig.?name ?? 'default' + alternateName: disasterRecoveryConfig.?alternateName + partnerNamespaceResourceID: disasterRecoveryConfig.?partnerNamespace + } } -} -module serviceBusNamespace_migrationConfigurations 'migration-configuration/main.bicep' = if (!empty(migrationConfiguration ?? {})) { - name: '${uniqueString(deployment().name, location)}-MigrationConfigurations' - params: { - namespaceName: serviceBusNamespace.name - postMigrationName: migrationConfiguration!.postMigrationName - targetNamespaceResourceId: migrationConfiguration!.targetNamespace +module serviceBusNamespace_migrationConfigurations 'migration-configuration/main.bicep' = + if (!empty(migrationConfiguration ?? {})) { + name: '${uniqueString(deployment().name, location)}-MigrationConfigurations' + params: { + namespaceName: serviceBusNamespace.name + postMigrationName: migrationConfiguration!.postMigrationName + targetNamespaceResourceId: migrationConfiguration!.targetNamespace + } } -} -module serviceBusNamespace_networkRuleSet 'network-rule-set/main.bicep' = if (!empty(networkRuleSets) || !empty(privateEndpoints)) { - name: '${uniqueString(deployment().name, location)}-NetworkRuleSet' - params: { - namespaceName: serviceBusNamespace.name - publicNetworkAccess: networkRuleSets.?publicNetworkAccess ?? (!empty(privateEndpoints) && empty(networkRuleSets) ? 'Disabled' : 'Enabled') - defaultAction: networkRuleSets.?defaultAction ?? 'Allow' - trustedServiceAccessEnabled: networkRuleSets.?trustedServiceAccessEnabled ?? true - ipRules: networkRuleSets.?ipRules ?? [] - virtualNetworkRules: networkRuleSets.?virtualNetworkRules ?? [] +module serviceBusNamespace_networkRuleSet 'network-rule-set/main.bicep' = + if (!empty(networkRuleSets) || !empty(privateEndpoints)) { + name: '${uniqueString(deployment().name, location)}-NetworkRuleSet' + params: { + namespaceName: serviceBusNamespace.name + publicNetworkAccess: networkRuleSets.?publicNetworkAccess ?? (!empty(privateEndpoints) && empty(networkRuleSets) + ? 'Disabled' + : 'Enabled') + defaultAction: networkRuleSets.?defaultAction ?? 'Allow' + trustedServiceAccessEnabled: networkRuleSets.?trustedServiceAccessEnabled ?? true + ipRules: networkRuleSets.?ipRules ?? [] + virtualNetworkRules: networkRuleSets.?virtualNetworkRules ?? [] + } } -} -module serviceBusNamespace_queues 'queue/main.bicep' = [for (queue, index) in (queues ?? []): { - name: '${uniqueString(deployment().name, location)}-Queue-${index}' - params: { - namespaceName: serviceBusNamespace.name - name: queue.name - autoDeleteOnIdle: queue.?autoDeleteOnIdle - forwardDeadLetteredMessagesTo: queue.?forwardDeadLetteredMessagesTo - forwardTo: queue.?forwardTo - maxMessageSizeInKilobytes: queue.?maxMessageSizeInKilobytes - authorizationRules: queue.?authorizationRules - deadLetteringOnMessageExpiration: queue.?deadLetteringOnMessageExpiration - defaultMessageTimeToLive: queue.?defaultMessageTimeToLive - duplicateDetectionHistoryTimeWindow: queue.?duplicateDetectionHistoryTimeWindow - enableBatchedOperations: queue.?enableBatchedOperations - enableExpress: queue.?enableExpress - enablePartitioning: queue.?enablePartitioning - lock: queue.?lock ?? lock - lockDuration: queue.?lockDuration - maxDeliveryCount: queue.?maxDeliveryCount - maxSizeInMegabytes: queue.?maxSizeInMegabytes - requiresDuplicateDetection: queue.?requiresDuplicateDetection - requiresSession: queue.?requiresSession - roleAssignments: queue.?roleAssignments - status: queue.?status +module serviceBusNamespace_queues 'queue/main.bicep' = [ + for (queue, index) in (queues ?? []): { + name: '${uniqueString(deployment().name, location)}-Queue-${index}' + params: { + namespaceName: serviceBusNamespace.name + name: queue.name + autoDeleteOnIdle: queue.?autoDeleteOnIdle + forwardDeadLetteredMessagesTo: queue.?forwardDeadLetteredMessagesTo + forwardTo: queue.?forwardTo + maxMessageSizeInKilobytes: queue.?maxMessageSizeInKilobytes + authorizationRules: queue.?authorizationRules + deadLetteringOnMessageExpiration: queue.?deadLetteringOnMessageExpiration + defaultMessageTimeToLive: queue.?defaultMessageTimeToLive + duplicateDetectionHistoryTimeWindow: queue.?duplicateDetectionHistoryTimeWindow + enableBatchedOperations: queue.?enableBatchedOperations + enableExpress: queue.?enableExpress + enablePartitioning: queue.?enablePartitioning + lock: queue.?lock ?? lock + lockDuration: queue.?lockDuration + maxDeliveryCount: queue.?maxDeliveryCount + maxSizeInMegabytes: queue.?maxSizeInMegabytes + requiresDuplicateDetection: queue.?requiresDuplicateDetection + requiresSession: queue.?requiresSession + roleAssignments: queue.?roleAssignments + status: queue.?status + } } -}] - -module serviceBusNamespace_topics 'topic/main.bicep' = [for (topic, index) in (topics ?? []): { - name: '${uniqueString(deployment().name, location)}-Topic-${index}' - params: { - namespaceName: serviceBusNamespace.name - name: topic.name - authorizationRules: topic.?authorizationRules - autoDeleteOnIdle: topic.?autoDeleteOnIdle - defaultMessageTimeToLive: topic.?defaultMessageTimeToLive - duplicateDetectionHistoryTimeWindow: topic.?duplicateDetectionHistoryTimeWindow - enableBatchedOperations: topic.?enableBatchedOperations - enableExpress: topic.?enableExpress - enablePartitioning: topic.?enablePartitioning - lock: topic.?lock ?? lock - maxMessageSizeInKilobytes: topic.?maxMessageSizeInKilobytes - requiresDuplicateDetection: topic.?requiresDuplicateDetection - roleAssignments: topic.?roleAssignments - status: topic.?status - supportOrdering: topic.?supportOrdering - subscriptions: topic.?subscriptions - maxSizeInMegabytes: topic.?maxSizeInMegabytes +] + +module serviceBusNamespace_topics 'topic/main.bicep' = [ + for (topic, index) in (topics ?? []): { + name: '${uniqueString(deployment().name, location)}-Topic-${index}' + params: { + namespaceName: serviceBusNamespace.name + name: topic.name + authorizationRules: topic.?authorizationRules + autoDeleteOnIdle: topic.?autoDeleteOnIdle + defaultMessageTimeToLive: topic.?defaultMessageTimeToLive + duplicateDetectionHistoryTimeWindow: topic.?duplicateDetectionHistoryTimeWindow + enableBatchedOperations: topic.?enableBatchedOperations + enableExpress: topic.?enableExpress + enablePartitioning: topic.?enablePartitioning + lock: topic.?lock ?? lock + maxMessageSizeInKilobytes: topic.?maxMessageSizeInKilobytes + requiresDuplicateDetection: topic.?requiresDuplicateDetection + roleAssignments: topic.?roleAssignments + status: topic.?status + supportOrdering: topic.?supportOrdering + subscriptions: topic.?subscriptions + maxSizeInMegabytes: topic.?maxSizeInMegabytes + } } -}] +] -resource serviceBusNamespace_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.' +resource serviceBusNamespace_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: serviceBusNamespace } - scope: serviceBusNamespace -} -resource serviceBusNamespace_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 - 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 +resource serviceBusNamespace_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 + 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 + } + scope: serviceBusNamespace } - scope: serviceBusNamespace -}] - -module serviceBusNamespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-ServiceBusNamespace-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(serviceBusNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(serviceBusNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' - properties: { - privateLinkServiceId: serviceBusNamespace.id - groupIds: [ - privateEndpoint.?service ?? 'namespace' +] + +module serviceBusNamespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-ServiceBusNamespace-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(serviceBusNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(serviceBusNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + properties: { + privateLinkServiceId: serviceBusNamespace.id + groupIds: [ + privateEndpoint.?service ?? 'namespace' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(serviceBusNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' - properties: { - privateLinkServiceId: serviceBusNamespace.id - groupIds: [ - privateEndpoint.?service ?? 'namespace' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(serviceBusNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + properties: { + privateLinkServiceId: serviceBusNamespace.id + groupIds: [ + privateEndpoint.?service ?? 'namespace' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource serviceBusNamespace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(serviceBusNamespace.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 +resource serviceBusNamespace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(serviceBusNamespace.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: serviceBusNamespace } - scope: serviceBusNamespace -}] +] @description('The resource ID of the deployed service bus namespace.') output resourceId string = serviceBusNamespace.id @@ -667,7 +744,16 @@ type queueType = { roleAssignments: roleAssignmentType? @description('Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown.') - status: ('Active' | 'Disabled' | 'Restoring' | 'SendDisabled' | 'ReceiveDisabled' | 'Creating' | 'Deleting' | 'Renaming' | 'Unknown')? + status: ( + | 'Active' + | 'Disabled' + | 'Restoring' + | 'SendDisabled' + | 'ReceiveDisabled' + | 'Creating' + | 'Deleting' + | 'Renaming' + | 'Unknown')? }[]? type topicType = { @@ -711,7 +797,16 @@ type topicType = { roleAssignments: roleAssignmentType? @description('Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown.') - status: ('Active' | 'Disabled' | 'Restoring' | 'SendDisabled' | 'ReceiveDisabled' | 'Creating' | 'Deleting' | 'Renaming' | 'Unknown')? + status: ( + | 'Active' + | 'Disabled' + | 'Restoring' + | 'SendDisabled' + | 'ReceiveDisabled' + | 'Creating' + | 'Deleting' + | 'Renaming' + | 'Unknown')? @description('Optional. Value that indicates whether the topic supports ordering.') supportOrdering: bool? @@ -770,6 +865,15 @@ type topicType = { requiresSession: bool? @description('Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown.') - status: ('Active' | 'Disabled' | 'Restoring' | 'SendDisabled' | 'ReceiveDisabled' | 'Creating' | 'Deleting' | 'Renaming' | 'Unknown')? + status: ( + | 'Active' + | 'Disabled' + | 'Restoring' + | 'SendDisabled' + | 'ReceiveDisabled' + | 'Creating' + | 'Deleting' + | 'Renaming' + | 'Unknown')? }[]? }[]? diff --git a/avm/res/service-bus/namespace/main.json b/avm/res/service-bus/namespace/main.json index fc0cee646a..e3ddb14be7 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.25.53.49325", - "templateHash": "11816477645345189868" + "version": "0.26.54.24096", + "templateHash": "9615956004888490264" }, "name": "Service Bus Namespaces", "description": "This module deploys a Service Bus Namespace.", @@ -1454,8 +1454,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2305438159110957656" + "version": "0.26.54.24096", + "templateHash": "17436716625562680995" }, "name": "Service Bus Namespace Authorization Rules", "description": "This module deploys a Service Bus Namespace Authorization Rule.", @@ -1558,8 +1558,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4852834945333619424" + "version": "0.26.54.24096", + "templateHash": "5141733056602320076" }, "name": "Service Bus Namespace Disaster Recovery Configs", "description": "This module deploys a Service Bus Namespace Disaster Recovery Config", @@ -1663,8 +1663,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7096240042982673427" + "version": "0.26.54.24096", + "templateHash": "15192198614426327006" }, "name": "Service Bus Namespace Migration Configuration", "description": "This module deploys a Service Bus Namespace Migration Configuration.", @@ -1768,8 +1768,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12312948750335282178" + "version": "0.26.54.24096", + "templateHash": "4933314100479664510" }, "name": "Service Bus Namespace Network Rule Sets", "description": "This module deploys a ServiceBus Namespace Network Rule Set.", @@ -1968,8 +1968,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "1862386755569893710" + "version": "0.26.54.24096", + "templateHash": "5679821968845040041" }, "name": "Service Bus Namespace Queue", "description": "This module deploys a Service Bus Namespace Queue.", @@ -2353,8 +2353,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11143403540623996438" + "version": "0.26.54.24096", + "templateHash": "11000394867797752922" }, "name": "Service Bus Namespace Queue Authorization Rules", "description": "This module deploys a Service Bus Namespace Queue Authorization Rule.", @@ -2534,8 +2534,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "13105717209289706682" + "version": "0.26.54.24096", + "templateHash": "2743713566937430307" }, "name": "Service Bus Namespace Topic", "description": "This module deploys a Service Bus Namespace Topic.", @@ -3017,8 +3017,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7067820889223773244" + "version": "0.26.54.24096", + "templateHash": "8469884519860433031" }, "name": "Service Bus Namespace Topic Authorization Rules", "description": "This module deploys a Service Bus Namespace Topic Authorization Rule.", @@ -3167,8 +3167,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10626633836251297018" + "version": "0.26.54.24096", + "templateHash": "14842378053022621119" }, "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 3de44c3b32..5949d14b2e 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.25.53.49325", - "templateHash": "7096240042982673427" + "version": "0.26.54.24096", + "templateHash": "15192198614426327006" }, "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.bicep b/avm/res/service-bus/namespace/network-rule-set/main.bicep index c65c86e112..ac842a0442 100644 --- a/avm/res/service-bus/namespace/network-rule-set/main.bicep +++ b/avm/res/service-bus/namespace/network-rule-set/main.bicep @@ -30,12 +30,18 @@ param virtualNetworkRules array = [] @description('Optional. List of IpRules. It will not be set if publicNetworkAccess is "Disabled". Otherwise, when used, defaultAction will be set to "Deny".') param ipRules array = [] -var networkRules = [for (virtualNetworkRule, index) in virtualNetworkRules: { - ignoreMissingVnetServiceEndpoint: contains(virtualNetworkRule, 'ignoreMissingVnetServiceEndpoint') ? virtualNetworkRule.ignoreMissingVnetServiceEndpoint : null - subnet: contains(virtualNetworkRule, 'subnetResourceId') ? { - id: virtualNetworkRule.subnetResourceId - } : null -}] +var networkRules = [ + for (virtualNetworkRule, index) in virtualNetworkRules: { + ignoreMissingVnetServiceEndpoint: contains(virtualNetworkRule, 'ignoreMissingVnetServiceEndpoint') + ? virtualNetworkRule.ignoreMissingVnetServiceEndpoint + : null + subnet: contains(virtualNetworkRule, 'subnetResourceId') + ? { + id: virtualNetworkRule.subnetResourceId + } + : null + } +] resource namespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' existing = { name: namespaceName @@ -46,7 +52,9 @@ resource networkRuleSet 'Microsoft.ServiceBus/namespaces/networkRuleSets@2022-10 parent: namespace properties: { publicNetworkAccess: publicNetworkAccess - defaultAction: publicNetworkAccess == 'Enabled' ? (!empty(ipRules) || !empty(virtualNetworkRules) ? 'Deny' : defaultAction) : null + defaultAction: publicNetworkAccess == 'Enabled' + ? (!empty(ipRules) || !empty(virtualNetworkRules) ? 'Deny' : defaultAction) + : null trustedServiceAccessEnabled: publicNetworkAccess == 'Enabled' ? trustedServiceAccessEnabled : null ipRules: publicNetworkAccess == 'Enabled' ? ipRules : null virtualNetworkRules: publicNetworkAccess == 'Enabled' ? networkRules : null 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 c7e7350de1..aa8079beeb 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.25.53.49325", - "templateHash": "12312948750335282178" + "version": "0.26.54.24096", + "templateHash": "4933314100479664510" }, "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 46b1f26e50..b343e9a4ef 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.25.53.49325", - "templateHash": "11143403540623996438" + "version": "0.26.54.24096", + "templateHash": "11000394867797752922" }, "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.bicep b/avm/res/service-bus/namespace/queue/main.bicep index db033ef614..520bd73926 100644 --- a/avm/res/service-bus/namespace/queue/main.bicep +++ b/avm/res/service-bus/namespace/queue/main.bicep @@ -92,14 +92,29 @@ param lock lockType param roleAssignments roleAssignmentType var builtInRoleNames = { - 'Azure Service Bus Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419') - 'Azure Service Bus Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0') - 'Azure Service Bus Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39') + 'Azure Service Bus Data Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '090c5cfd-751d-490a-894a-3ce6f1109419' + ) + 'Azure Service Bus Data Receiver': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0' + ) + 'Azure Service Bus Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39' + ) 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') + '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 namespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' existing = { @@ -129,38 +144,49 @@ resource queue 'Microsoft.ServiceBus/namespaces/queues@2022-10-01-preview' = { } } -module queue_authorizationRules 'authorization-rule/main.bicep' = [for (authorizationRule, index) in authorizationRules: { - name: '${deployment().name}-AuthRule-${index}' - params: { - namespaceName: namespaceName - queueName: queue.name - name: authorizationRule.name - rights: authorizationRule.?rights ?? [] +module queue_authorizationRules 'authorization-rule/main.bicep' = [ + for (authorizationRule, index) in authorizationRules: { + name: '${deployment().name}-AuthRule-${index}' + params: { + namespaceName: namespaceName + queueName: queue.name + name: authorizationRule.name + rights: authorizationRule.?rights ?? [] + } } -}] +] -resource queue_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.' +resource queue_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: queue } - scope: queue -} -resource queue_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(queue.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 +resource queue_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(queue.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: queue } - scope: queue -}] +] @description('The name of the deployed queue.') output name string = queue.name diff --git a/avm/res/service-bus/namespace/queue/main.json b/avm/res/service-bus/namespace/queue/main.json index 98b2b87112..bca571c612 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.25.53.49325", - "templateHash": "1862386755569893710" + "version": "0.26.54.24096", + "templateHash": "5679821968845040041" }, "name": "Service Bus Namespace Queue", "description": "This module deploys a Service Bus Namespace Queue.", @@ -390,8 +390,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11143403540623996438" + "version": "0.26.54.24096", + "templateHash": "11000394867797752922" }, "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/tests/e2e/defaults/main.test.bicep b/avm/res/service-bus/namespace/tests/e2e/defaults/main.test.bicep index ba24f47f74..3d75b0c635 100644 --- a/avm/res/service-bus/namespace/tests/e2e/defaults/main.test.bicep +++ b/avm/res/service-bus/namespace/tests/e2e/defaults/main.test.bicep @@ -36,14 +36,16 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - skuObject: { - name: 'Basic' +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 + skuObject: { + name: 'Basic' + } } } -}] +] diff --git a/avm/res/service-bus/namespace/tests/e2e/encr/dependencies.bicep b/avm/res/service-bus/namespace/tests/e2e/encr/dependencies.bicep index 91bcb7661d..5afdae26cd 100644 --- a/avm/res/service-bus/namespace/tests/e2e/encr/dependencies.bicep +++ b/avm/res/service-bus/namespace/tests/e2e/encr/dependencies.bicep @@ -69,7 +69,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { properties: { principalId: managedIdentity.properties.principalId // Key Vault Crypto User - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) principalType: 'ServicePrincipal' } } diff --git a/avm/res/service-bus/namespace/tests/e2e/encr/main.test.bicep b/avm/res/service-bus/namespace/tests/e2e/encr/main.test.bicep index 0d8f78b1fa..9a02d24b0c 100644 --- a/avm/res/service-bus/namespace/tests/e2e/encr/main.test.bicep +++ b/avm/res/service-bus/namespace/tests/e2e/encr/main.test.bicep @@ -51,29 +51,31 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - skuObject: { - name: 'Premium' - capacity: 1 - } - location: resourceLocation - managedIdentities: { - systemAssigned: false - userAssignedResourcesIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - customerManagedKey: { - keyName: nestedDependencies.outputs.keyName - keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + skuObject: { + name: 'Premium' + capacity: 1 + } + location: resourceLocation + managedIdentities: { + systemAssigned: false + userAssignedResourcesIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + customerManagedKey: { + keyName: nestedDependencies.outputs.keyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/service-bus/namespace/tests/e2e/max/main.test.bicep b/avm/res/service-bus/namespace/tests/e2e/max/main.test.bicep index 8948e8ae44..a1a500e934 100644 --- a/avm/res/service-bus/namespace/tests/e2e/max/main.test.bicep +++ b/avm/res/service-bus/namespace/tests/e2e/max/main.test.bicep @@ -60,205 +60,207 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - location: resourceLocation - skuObject: { - name: 'Premium' - capacity: 16 - } - premiumMessagingPartitions: 1 - zoneRedundant: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - - principalType: 'ServicePrincipal' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - networkRuleSets: { - defaultAction: 'Deny' - trustedServiceAccessEnabled: true - virtualNetworkRules: [ - { - ignoreMissingVnetServiceEndpoint: true - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - ipRules: [ - { - ipMask: '10.0.1.0/32' - action: 'Allow' - } + location: resourceLocation + skuObject: { + name: 'Premium' + capacity: 16 + } + premiumMessagingPartitions: 1 + zoneRedundant: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + roleAssignments: [ { - ipMask: '10.0.2.0/32' - action: 'Allow' + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + + principalType: 'ServicePrincipal' } ] - } - authorizationRules: [ - { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] - } - { - name: 'AnotherKey' - rights: [ - 'Listen' - 'Send' - ] - } - ] - queues: [ - { - name: '${namePrefix}${serviceShort}q001' - roleAssignments: [ + networkRuleSets: { + defaultAction: 'Deny' + trustedServiceAccessEnabled: true + virtualNetworkRules: [ { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + ignoreMissingVnetServiceEndpoint: true + subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] - authorizationRules: [ + ipRules: [ { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] + ipMask: '10.0.1.0/32' + action: 'Allow' } { - name: 'AnotherKey' - rights: [ - 'Listen' - 'Send' - ] + ipMask: '10.0.2.0/32' + action: 'Allow' } ] - autoDeleteOnIdle: 'PT5M' - maxMessageSizeInKilobytes: 2048 } - ] - topics: [ - { - name: '${namePrefix}${serviceShort}t001' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - authorizationRules: [ - { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] - } - { - name: 'AnotherKey' - rights: [ - 'Listen' - 'Send' - ] - } - ] - subscriptions: [ - { - name: 'subscription001' - } - ] - } - ] - diagnosticSettings: [ - { - name: '${namePrefix}-diagnosticsetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - logCategoriesAndGroups: [ - { - category: 'RuntimeAuditLogs' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] } - ipConfigurations: [ - { - name: 'myIPconfig' - properties: { - groupId: 'namespace' - memberName: 'namespace' - privateIPAddress: '10.0.0.10' + { + name: 'AnotherKey' + rights: [ + 'Listen' + 'Send' + ] + } + ] + queues: [ + { + name: '${namePrefix}${serviceShort}q001' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } + ] + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'AnotherKey' + rights: [ + 'Listen' + 'Send' + ] + } + ] + autoDeleteOnIdle: 'PT5M' + maxMessageSizeInKilobytes: 2048 + } + ] + topics: [ + { + name: '${namePrefix}${serviceShort}t001' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'AnotherKey' + rights: [ + 'Listen' + 'Send' + ] + } + ] + subscriptions: [ + { + name: 'subscription001' + } + ] + } + ] + diagnosticSettings: [ + { + name: '${namePrefix}-diagnosticsetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + logCategoriesAndGroups: [ + { + category: 'RuntimeAuditLogs' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - customDnsConfigs: [ - { - fqdn: 'abc.namespace.com' - ipAddresses: [ - '10.0.0.10' - ] - } - ] - } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId + ipConfigurations: [ + { + name: 'myIPconfig' + properties: { + groupId: 'namespace' + memberName: 'namespace' + privateIPAddress: '10.0.0.10' + } + } + ] + customDnsConfigs: [ + { + fqdn: 'abc.namespace.com' + ipAddresses: [ + '10.0.0.10' + ] + } + ] + } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourcesIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] } - ] - managedIdentities: { - systemAssigned: true - userAssignedResourcesIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] + disableLocalAuth: true + publicNetworkAccess: 'Enabled' + minimumTlsVersion: '1.2' } - disableLocalAuth: true - publicNetworkAccess: 'Enabled' - minimumTlsVersion: '1.2' + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/service-bus/namespace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/service-bus/namespace/tests/e2e/waf-aligned/main.test.bicep index 543060cd91..cbd896930d 100644 --- a/avm/res/service-bus/namespace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/service-bus/namespace/tests/e2e/waf-aligned/main.test.bicep @@ -60,147 +60,149 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - location: resourceLocation - skuObject: { - name: 'Premium' - capacity: 2 - } - premiumMessagingPartitions: 1 - zoneRedundant: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - roleAssignments: [] - networkRuleSets: { - defaultAction: 'Deny' - trustedServiceAccessEnabled: true - virtualNetworkRules: [ - { - ignoreMissingVnetServiceEndpoint: true - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - ipRules: [ - { - ipMask: '10.0.1.0/32' - action: 'Allow' - } - { - ipMask: '10.0.2.0/32' - action: 'Allow' - } - ] - } - authorizationRules: [ - { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - name: 'AnotherKey' - rights: [ - 'Listen' - 'Send' - ] + location: resourceLocation + skuObject: { + name: 'Premium' + capacity: 2 } - ] - queues: [ - { - name: '${namePrefix}${serviceShort}q001' - roleAssignments: [] - authorizationRules: [ - { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] - } + premiumMessagingPartitions: 1 + zoneRedundant: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + roleAssignments: [] + networkRuleSets: { + defaultAction: 'Deny' + trustedServiceAccessEnabled: true + virtualNetworkRules: [ { - name: 'AnotherKey' - rights: [ - 'Listen' - 'Send' - ] + ignoreMissingVnetServiceEndpoint: true + subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] - autoDeleteOnIdle: 'PT5M' - maxMessageSizeInKilobytes: 2048 - } - ] - topics: [ - { - name: '${namePrefix}${serviceShort}t001' - roleAssignments: [] - authorizationRules: [ + ipRules: [ { - name: 'RootManageSharedAccessKey' - rights: [ - 'Listen' - 'Manage' - 'Send' - ] + ipMask: '10.0.1.0/32' + action: 'Allow' } { - name: 'AnotherKey' - rights: [ - 'Listen' - 'Send' - ] + ipMask: '10.0.2.0/32' + action: 'Allow' } ] } - ] - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - privateEndpoints: [ - { - service: 'namespace' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'AnotherKey' + rights: [ + 'Listen' + 'Send' + ] + } + ] + queues: [ + { + name: '${namePrefix}${serviceShort}q001' + roleAssignments: [] + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'AnotherKey' + rights: [ + 'Listen' + 'Send' + ] + } + ] + autoDeleteOnIdle: 'PT5M' + maxMessageSizeInKilobytes: 2048 } - } - ] - managedIdentities: { - systemAssigned: true - userAssignedResourcesIds: [ - nestedDependencies.outputs.managedIdentityResourceId ] + topics: [ + { + name: '${namePrefix}${serviceShort}t001' + roleAssignments: [] + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'AnotherKey' + rights: [ + 'Listen' + 'Send' + ] + } + ] + } + ] + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + privateEndpoints: [ + { + service: 'namespace' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourcesIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + disableLocalAuth: true + publicNetworkAccess: 'Enabled' + minimumTlsVersion: '1.2' } - disableLocalAuth: true - publicNetworkAccess: 'Enabled' - minimumTlsVersion: '1.2' + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] 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 104532158b..b2ba653765 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.25.53.49325", - "templateHash": "7067820889223773244" + "version": "0.26.54.24096", + "templateHash": "8469884519860433031" }, "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.bicep b/avm/res/service-bus/namespace/topic/main.bicep index 1262f6baae..aafb8dfc01 100644 --- a/avm/res/service-bus/namespace/topic/main.bicep +++ b/avm/res/service-bus/namespace/topic/main.bicep @@ -80,14 +80,29 @@ param roleAssignments roleAssignmentType param subscriptions array = [] var builtInRoleNames = { - 'Azure Service Bus Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419') - 'Azure Service Bus Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0') - 'Azure Service Bus Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39') + 'Azure Service Bus Data Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '090c5cfd-751d-490a-894a-3ce6f1109419' + ) + 'Azure Service Bus Data Receiver': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0' + ) + 'Azure Service Bus Data Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39' + ) 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') + '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 namespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' existing = { @@ -97,7 +112,8 @@ resource namespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' existing resource topic 'Microsoft.ServiceBus/namespaces/topics@2022-10-01-preview' = { name: name parent: namespace - properties: union({ + properties: union( + { autoDeleteOnIdle: autoDeleteOnIdle defaultMessageTimeToLive: defaultMessageTimeToLive duplicateDetectionHistoryTimeWindow: duplicateDetectionHistoryTimeWindow @@ -107,67 +123,84 @@ resource topic 'Microsoft.ServiceBus/namespaces/topics@2022-10-01-preview' = { status: status supportOrdering: supportOrdering maxSizeInMegabytes: maxSizeInMegabytes - }, (namespace.sku.name == 'Premium') ? { - enableExpress: enableExpress - maxMessageSizeInKilobytes: maxMessageSizeInKilobytes - } : {}) + }, + (namespace.sku.name == 'Premium') + ? { + enableExpress: enableExpress + maxMessageSizeInKilobytes: maxMessageSizeInKilobytes + } + : {} + ) } -module topic_authorizationRules 'authorization-rule/main.bicep' = [for (authorizationRule, index) in authorizationRules: { - name: '${deployment().name}-AuthRule-${index}' - params: { - namespaceName: namespaceName - topicName: topic.name - name: authorizationRule.name - rights: contains(authorizationRule, 'rights') ? authorizationRule.rights : [] +module topic_authorizationRules 'authorization-rule/main.bicep' = [ + for (authorizationRule, index) in authorizationRules: { + name: '${deployment().name}-AuthRule-${index}' + params: { + namespaceName: namespaceName + topicName: topic.name + name: authorizationRule.name + rights: contains(authorizationRule, 'rights') ? authorizationRule.rights : [] + } } -}] +] -resource topic_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.' +resource topic_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: topic } - scope: topic -} -resource topic_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(topic.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 +resource topic_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(topic.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: topic } - scope: topic -}] - -module topic_subscription 'subscription/main.bicep' = [for (subscription, index) in (subscriptions ?? []): { - name: '${deployment().name}-subscription-${index}' - params: { - name: subscription.name - namespaceName: namespace.name - topicName: topic.name - autoDeleteOnIdle: subscription.?autoDeleteOnIdle ?? 'PT1H' - defaultMessageTimeToLive: subscription.?defaultMessageTimeToLive ?? 'P14D' - duplicateDetectionHistoryTimeWindow: subscription.?duplicateDetectionHistoryTimeWindow ?? 'PT10M' - enableBatchedOperations: subscription.?enableBatchedOperations ?? true - clientAffineProperties: subscription.?clientAffineProperties ?? {} - deadLetteringOnFilterEvaluationExceptions: subscription.?deadLetteringOnFilterEvaluationExceptions ?? true - deadLetteringOnMessageExpiration: subscription.?deadLetteringOnMessageExpiration ?? false - forwardDeadLetteredMessagesTo: subscription.?forwardDeadLetteredMessagesTo - forwardTo: subscription.?forwardTo - isClientAffine: subscription.?isClientAffine ?? false - lockDuration: subscription.?lockDuration ?? 'PT1M' - maxDeliveryCount: subscription.?maxDeliveryCount ?? 10 - requiresSession: subscription.?requiresSession ?? false - status: subscription.?status ?? 'Active' +] + +module topic_subscription 'subscription/main.bicep' = [ + for (subscription, index) in (subscriptions ?? []): { + name: '${deployment().name}-subscription-${index}' + params: { + name: subscription.name + namespaceName: namespace.name + topicName: topic.name + autoDeleteOnIdle: subscription.?autoDeleteOnIdle ?? 'PT1H' + defaultMessageTimeToLive: subscription.?defaultMessageTimeToLive ?? 'P14D' + duplicateDetectionHistoryTimeWindow: subscription.?duplicateDetectionHistoryTimeWindow ?? 'PT10M' + enableBatchedOperations: subscription.?enableBatchedOperations ?? true + clientAffineProperties: subscription.?clientAffineProperties ?? {} + deadLetteringOnFilterEvaluationExceptions: subscription.?deadLetteringOnFilterEvaluationExceptions ?? true + deadLetteringOnMessageExpiration: subscription.?deadLetteringOnMessageExpiration ?? false + forwardDeadLetteredMessagesTo: subscription.?forwardDeadLetteredMessagesTo + forwardTo: subscription.?forwardTo + isClientAffine: subscription.?isClientAffine ?? false + lockDuration: subscription.?lockDuration ?? 'PT1M' + maxDeliveryCount: subscription.?maxDeliveryCount ?? 10 + requiresSession: subscription.?requiresSession ?? false + status: subscription.?status ?? 'Active' + } } -}] +] @description('The name of the deployed topic.') output name string = topic.name @@ -266,5 +299,14 @@ type subscriptionsType = { requiresSession: bool? @description('Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown.') - status: ('Active' | 'Disabled' | 'Restoring' | 'SendDisabled' | 'ReceiveDisabled' | 'Creating' | 'Deleting' | 'Renaming' | 'Unknown')? + status: ( + | 'Active' + | 'Disabled' + | 'Restoring' + | 'SendDisabled' + | 'ReceiveDisabled' + | 'Creating' + | 'Deleting' + | 'Renaming' + | 'Unknown')? }[]? diff --git a/avm/res/service-bus/namespace/topic/main.json b/avm/res/service-bus/namespace/topic/main.json index ed97a90dcd..1bbf1eca82 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.25.53.49325", - "templateHash": "13105717209289706682" + "version": "0.26.54.24096", + "templateHash": "2743713566937430307" }, "name": "Service Bus Namespace Topic", "description": "This module deploys a Service Bus Namespace Topic.", @@ -488,8 +488,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7067820889223773244" + "version": "0.26.54.24096", + "templateHash": "8469884519860433031" }, "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.25.53.49325", - "templateHash": "10626633836251297018" + "version": "0.26.54.24096", + "templateHash": "14842378053022621119" }, "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 ae24b1d16b..3e87e184d8 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.25.53.49325", - "templateHash": "10626633836251297018" + "version": "0.26.54.24096", + "templateHash": "14842378053022621119" }, "name": "Service Bus Namespace Topic Subscription", "description": "This module deploys a Service Bus Namespace Topic Subscription.", diff --git a/avm/res/signal-r-service/signal-r/main.bicep b/avm/res/signal-r-service/signal-r/main.bicep index 9e0509c365..6cd2b791ba 100644 --- a/avm/res/signal-r-service/signal-r/main.bicep +++ b/avm/res/signal-r-service/signal-r/main.bicep @@ -33,7 +33,9 @@ param sku string = 'Standard_S1' 'Standard' ]) @description('Optional. The tier of the service.') -param tier string = sku == 'Free_F1' ? 'Free' : sku == 'Standard_S1' || sku == 'Standard_S2' || sku == 'Standard_S3' ? 'Standard' : 'Premium' +param tier string = sku == 'Free_F1' + ? 'Free' + : sku == 'Standard_S1' || sku == 'Standard_S2' || sku == 'Standard_S3' ? 'Standard' : 'Premium' @description('Optional. The unit count of the resource.') param capacity int = 1 @@ -108,49 +110,84 @@ param roleAssignments roleAssignmentType @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var liveTraceCatagories = [for configuration in liveTraceCatagoriesToEnable: { - name: configuration - enabled: 'true' -}] +var liveTraceCatagories = [ + for configuration in liveTraceCatagoriesToEnable: { + name: configuration + enabled: 'true' + } +] -var resourceLogConfiguration = [for configuration in resourceLogConfigurationsToEnable: { - name: configuration - enabled: 'true' -}] +var resourceLogConfiguration = [ + for configuration in resourceLogConfigurationsToEnable: { + name: configuration + enabled: 'true' + } +] 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') - 'SignalR AccessKey Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '04165923-9d83-45d5-8227-78b77b0a687e') - 'SignalR App Server': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '420fcaa2-552c-430f-98ca-3264be4806c7') - 'SignalR REST API Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fd53cd77-2268-407a-8f46-7e7863d0f521') - 'SignalR REST API Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ddde6b66-c0df-4114-a159-3618637b3035') - 'SignalR Service Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7e4f1700-ea5a-4f59-8f37-079cfe29dce3') - 'SignalR/Web PubSub Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8cf5e20a-e4b2-4e9d-b3a1-5ceb692c2761') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') - 'Web PubSub Service Owner (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12cf5a90-567b-43ae-8102-96cf46c7d9b4') - 'Web PubSub Service Reader (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'bfb1c7d2-fb1a-466b-b2ba-aee63b92deaf') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'SignalR AccessKey Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '04165923-9d83-45d5-8227-78b77b0a687e' + ) + 'SignalR App Server': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '420fcaa2-552c-430f-98ca-3264be4806c7' + ) + 'SignalR REST API Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'fd53cd77-2268-407a-8f46-7e7863d0f521' + ) + 'SignalR REST API Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'ddde6b66-c0df-4114-a159-3618637b3035' + ) + 'SignalR Service Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7e4f1700-ea5a-4f59-8f37-079cfe29dce3' + ) + 'SignalR/Web PubSub Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '8cf5e20a-e4b2-4e9d-b3a1-5ceb692c2761' + ) + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) + 'Web PubSub Service Owner (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12cf5a90-567b-43ae-8102-96cf46c7d9b4' + ) + 'Web PubSub Service Reader (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'bfb1c7d2-fb1a-466b-b2ba-aee63b92deaf' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.signalrservice-signalr.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.signalrservice-signalr.${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 signalR 'Microsoft.SignalRService/signalR@2022-02-01' = { name: name @@ -169,87 +206,112 @@ resource signalR 'Microsoft.SignalRService/signalR@2022-02-01' = { disableAadAuth: disableAadAuth disableLocalAuth: disableLocalAuth features: features - liveTraceConfiguration: !empty(liveTraceCatagoriesToEnable) ? { - categories: liveTraceCatagories - } : {} + liveTraceConfiguration: !empty(liveTraceCatagoriesToEnable) + ? { + categories: liveTraceCatagories + } + : {} networkACLs: !empty(networkAcls) ? any(networkAcls) : null - publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) : (!empty(privateEndpoints) && empty(networkAcls) ? 'Disabled' : null) + publicNetworkAccess: !empty(publicNetworkAccess) + ? any(publicNetworkAccess) + : (!empty(privateEndpoints) && empty(networkAcls) ? 'Disabled' : null) resourceLogConfiguration: { categories: resourceLogConfiguration } tls: { clientCertEnabled: clientCertEnabled } - upstream: !empty(upstreamTemplatesToEnable) ? { - templates: upstreamTemplatesToEnable - } : {} + upstream: !empty(upstreamTemplatesToEnable) + ? { + templates: upstreamTemplatesToEnable + } + : {} } } -module signalR_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-signalR-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(signalR.id, '/'))}-${privateEndpoint.?service ?? 'signalr'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(signalR.id, '/'))}-${privateEndpoint.?service ?? 'signalr'}-${index}' - properties: { - privateLinkServiceId: signalR.id - groupIds: [ - privateEndpoint.?service ?? 'signalr' +module signalR_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-signalR-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(signalR.id, '/'))}-${privateEndpoint.?service ?? 'signalr'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(signalR.id, '/'))}-${privateEndpoint.?service ?? 'signalr'}-${index}' + properties: { + privateLinkServiceId: signalR.id + groupIds: [ + privateEndpoint.?service ?? 'signalr' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(signalR.id, '/'))}-${privateEndpoint.?service ?? 'signalr'}-${index}' - properties: { - privateLinkServiceId: signalR.id - groupIds: [ - privateEndpoint.?service ?? 'signalr' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(signalR.id, '/'))}-${privateEndpoint.?service ?? 'signalr'}-${index}' + properties: { + privateLinkServiceId: signalR.id + groupIds: [ + privateEndpoint.?service ?? 'signalr' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource signalR_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.' +resource signalR_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: signalR } - scope: signalR -} -resource signalR_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(signalR.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 +resource signalR_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(signalR.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: signalR } - scope: signalR -}] +] @description('The SignalR name.') output name string = signalR.name diff --git a/avm/res/signal-r-service/signal-r/main.json b/avm/res/signal-r-service/signal-r/main.json index cdf2a9c339..4a39843b52 100644 --- a/avm/res/signal-r-service/signal-r/main.json +++ b/avm/res/signal-r-service/signal-r/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12709667084412433453" + "version": "0.26.54.24096", + "templateHash": "4485935239460152406" }, "name": "SignalR Service SignalR", "description": "This module deploys a SignalR Service SignalR.", diff --git a/avm/res/signal-r-service/signal-r/tests/e2e/defaults/main.test.bicep b/avm/res/signal-r-service/signal-r/tests/e2e/defaults/main.test.bicep index eb83b896b0..8f4198f941 100644 --- a/avm/res/signal-r-service/signal-r/tests/e2e/defaults/main.test.bicep +++ b/avm/res/signal-r-service/signal-r/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/signal-r-service/signal-r/tests/e2e/max/main.test.bicep b/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep index ea3760d496..21e8ab2c5b 100644 --- a/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep +++ b/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep @@ -46,89 +46,93 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - capacity: 2 - clientCertEnabled: false - disableAadAuth: false - disableLocalAuth: true - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - kind: 'SignalR' - networkAcls: { - defaultAction: 'Allow' - privateEndpoints: [ - { +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 + capacity: 2 + clientCertEnabled: false + disableAadAuth: false + disableLocalAuth: true + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + kind: 'SignalR' + networkAcls: { + defaultAction: 'Allow' + privateEndpoints: [ + { + allow: [] + deny: [ + 'ServerConnection' + 'Trace' + ] + name: 'pe-${namePrefix}-${serviceShort}-001' + } + ] + publicNetwork: { allow: [] deny: [ - 'ServerConnection' + 'RESTAPI' 'Trace' ] - name: 'pe-${namePrefix}-${serviceShort}-001' - } - ] - publicNetwork: { - allow: [] - deny: [ - 'RESTAPI' - 'Trace' - ] } - } - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + resourceLogConfigurationsToEnable: [ + 'ConnectivityLogs' + ] + 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' + } + ] + sku: 'Standard_S1' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - resourceLogConfigurationsToEnable: [ - 'ConnectivityLogs' - ] - 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' - } - ] - sku: 'Standard_S1' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep b/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep index 14a5ab8f7c..51ca8dd306 100644 --- a/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep @@ -45,62 +45,63 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - capacity: 2 - clientCertEnabled: false - disableAadAuth: false - disableLocalAuth: true - kind: 'SignalR' - networkAcls: { - defaultAction: 'Allow' - privateEndpoints: [ - { +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 + capacity: 2 + clientCertEnabled: false + disableAadAuth: false + disableLocalAuth: true + kind: 'SignalR' + networkAcls: { + defaultAction: 'Allow' + privateEndpoints: [ + { + allow: [] + deny: [ + 'ServerConnection' + 'Trace' + ] + name: 'pe-${namePrefix}-${serviceShort}-001' + } + ] + publicNetwork: { allow: [] deny: [ - 'ServerConnection' + 'RESTAPI' 'Trace' ] - name: 'pe-${namePrefix}-${serviceShort}-001' - } - ] - publicNetwork: { - allow: [] - deny: [ - 'RESTAPI' - 'Trace' - ] } - } - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } + ] + resourceLogConfigurationsToEnable: [ + 'ConnectivityLogs' + ] + sku: 'Standard_S1' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - resourceLogConfigurationsToEnable: [ - 'ConnectivityLogs' - ] - sku: 'Standard_S1' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/signal-r-service/web-pub-sub/main.bicep b/avm/res/signal-r-service/web-pub-sub/main.bicep index 32b0b0252f..54ad065a19 100644 --- a/avm/res/signal-r-service/web-pub-sub/main.bicep +++ b/avm/res/signal-r-service/web-pub-sub/main.bicep @@ -65,51 +65,92 @@ param networkAcls object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -var resourceLogConfiguration = [for configuration in resourceLogConfigurationsToEnable: { - name: configuration - enabled: 'true' -}] - -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } +var resourceLogConfiguration = [ + for configuration in resourceLogConfigurationsToEnable: { + name: configuration + enabled: 'true' + } +] -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? 'SystemAssigned' : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? 'SystemAssigned' + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : 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') - 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'SignalR AccessKey Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '04165923-9d83-45d5-8227-78b77b0a687e') - 'SignalR App Server': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '420fcaa2-552c-430f-98ca-3264be4806c7') - 'SignalR REST API Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fd53cd77-2268-407a-8f46-7e7863d0f521') - 'SignalR REST API Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ddde6b66-c0df-4114-a159-3618637b3035') - 'SignalR Service Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7e4f1700-ea5a-4f59-8f37-079cfe29dce3') - 'SignalR/Web PubSub Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8cf5e20a-e4b2-4e9d-b3a1-5ceb692c2761') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') - 'Web PubSub Service Owner (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12cf5a90-567b-43ae-8102-96cf46c7d9b4') - 'Web PubSub Service Reader (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'bfb1c7d2-fb1a-466b-b2ba-aee63b92deaf') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'SignalR AccessKey Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '04165923-9d83-45d5-8227-78b77b0a687e' + ) + 'SignalR App Server': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '420fcaa2-552c-430f-98ca-3264be4806c7' + ) + 'SignalR REST API Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'fd53cd77-2268-407a-8f46-7e7863d0f521' + ) + 'SignalR REST API Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'ddde6b66-c0df-4114-a159-3618637b3035' + ) + 'SignalR Service Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7e4f1700-ea5a-4f59-8f37-079cfe29dce3' + ) + 'SignalR/Web PubSub Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '8cf5e20a-e4b2-4e9d-b3a1-5ceb692c2761' + ) + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) + 'Web PubSub Service Owner (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12cf5a90-567b-43ae-8102-96cf46c7d9b4' + ) + 'Web PubSub Service Reader (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'bfb1c7d2-fb1a-466b-b2ba-aee63b92deaf' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.signalrservice-webpubsub.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.signalrservice-webpubsub.${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 webPubSub 'Microsoft.SignalRService/webPubSub@2021-10-01' = { name: name @@ -125,7 +166,9 @@ resource webPubSub 'Microsoft.SignalRService/webPubSub@2021-10-01' = { disableAadAuth: disableAadAuth disableLocalAuth: disableLocalAuth networkACLs: networkAcls - publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) : (!empty(privateEndpoints) && empty(networkAcls) ? 'Disabled' : null) + publicNetworkAccess: !empty(publicNetworkAccess) + ? any(publicNetworkAccess) + : (!empty(privateEndpoints) && empty(networkAcls) ? 'Disabled' : null) resourceLogConfiguration: { categories: resourceLogConfiguration } @@ -135,70 +178,89 @@ resource webPubSub 'Microsoft.SignalRService/webPubSub@2021-10-01' = { } } -module webPubSub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-webPubSub-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(webPubSub.id, '/'))}-${privateEndpoint.?service ?? 'webpubsub'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(webPubSub.id, '/'))}-${privateEndpoint.?service ?? 'webpubsub'}-${index}' - properties: { - privateLinkServiceId: webPubSub.id - groupIds: [ - privateEndpoint.?service ?? 'webpubsub' +module webPubSub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-webPubSub-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(webPubSub.id, '/'))}-${privateEndpoint.?service ?? 'webpubsub'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(webPubSub.id, '/'))}-${privateEndpoint.?service ?? 'webpubsub'}-${index}' + properties: { + privateLinkServiceId: webPubSub.id + groupIds: [ + privateEndpoint.?service ?? 'webpubsub' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(webPubSub.id, '/'))}-${privateEndpoint.?service ?? 'webpubsub'}-${index}' - properties: { - privateLinkServiceId: webPubSub.id - groupIds: [ - privateEndpoint.?service ?? 'webpubsub' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(webPubSub.id, '/'))}-${privateEndpoint.?service ?? 'webpubsub'}-${index}' + properties: { + privateLinkServiceId: webPubSub.id + groupIds: [ + privateEndpoint.?service ?? 'webpubsub' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] -resource webPubSub_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.' +resource webPubSub_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: webPubSub } - scope: webPubSub -} -resource webPubSub_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(webPubSub.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 +resource webPubSub_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(webPubSub.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: webPubSub } - scope: webPubSub -}] +] @description('The Web PubSub name.') output name string = webPubSub.name diff --git a/avm/res/signal-r-service/web-pub-sub/main.json b/avm/res/signal-r-service/web-pub-sub/main.json index 02b172406c..f222512801 100644 --- a/avm/res/signal-r-service/web-pub-sub/main.json +++ b/avm/res/signal-r-service/web-pub-sub/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11458194827556582454" + "version": "0.26.54.24096", + "templateHash": "14787195010509136653" }, "name": "SignalR Web PubSub Services", "description": "This module deploys a SignalR Web PubSub Service.", diff --git a/avm/res/signal-r-service/web-pub-sub/tests/e2e/defaults/main.test.bicep b/avm/res/signal-r-service/web-pub-sub/tests/e2e/defaults/main.test.bicep index 036f4788c4..14e02cb21f 100644 --- a/avm/res/signal-r-service/web-pub-sub/tests/e2e/defaults/main.test.bicep +++ b/avm/res/signal-r-service/web-pub-sub/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/signal-r-service/web-pub-sub/tests/e2e/max/main.test.bicep b/avm/res/signal-r-service/web-pub-sub/tests/e2e/max/main.test.bicep index 6d921659a0..9d4e07833f 100644 --- a/avm/res/signal-r-service/web-pub-sub/tests/e2e/max/main.test.bicep +++ b/avm/res/signal-r-service/web-pub-sub/tests/e2e/max/main.test.bicep @@ -46,88 +46,93 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - capacity: 2 - clientCertEnabled: false - disableAadAuth: false - disableLocalAuth: true - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - networkAcls: { - defaultAction: 'Allow' - privateEndpoints: [ - { +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 + capacity: 2 + clientCertEnabled: false + disableAadAuth: false + disableLocalAuth: true + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + networkAcls: { + defaultAction: 'Allow' + privateEndpoints: [ + { + allow: [] + deny: [ + 'ServerConnection' + 'Trace' + ] + name: 'pe-${namePrefix}-${serviceShort}-001' + } + ] + publicNetwork: { allow: [] deny: [ - 'ServerConnection' + 'RESTAPI' 'Trace' ] - name: 'pe-${namePrefix}-${serviceShort}-001' } - ] - publicNetwork: { - allow: [] - deny: [ - 'RESTAPI' - 'Trace' - ] } - } - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'webpubsub' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'webpubsub' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + resourceLogConfigurationsToEnable: [ + 'ConnectivityLogs' + ] + 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' + } + ] + sku: 'Standard_S1' + managedIdentities: { + systemAssigned: true } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - resourceLogConfigurationsToEnable: [ - 'ConnectivityLogs' - ] - 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' } - ] - sku: 'Standard_S1' - managedIdentities: { - systemAssigned: true - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] diff --git a/avm/res/signal-r-service/web-pub-sub/tests/e2e/waf-aligned/main.test.bicep b/avm/res/signal-r-service/web-pub-sub/tests/e2e/waf-aligned/main.test.bicep index 1504efe931..a1ba316a76 100644 --- a/avm/res/signal-r-service/web-pub-sub/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/signal-r-service/web-pub-sub/tests/e2e/waf-aligned/main.test.bicep @@ -45,61 +45,63 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - capacity: 2 - clientCertEnabled: false - disableAadAuth: false - disableLocalAuth: true - networkAcls: { - defaultAction: 'Allow' - privateEndpoints: [ - { +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 + capacity: 2 + clientCertEnabled: false + disableAadAuth: false + disableLocalAuth: true + networkAcls: { + defaultAction: 'Allow' + privateEndpoints: [ + { + allow: [] + deny: [ + 'ServerConnection' + 'Trace' + ] + name: 'pe-${namePrefix}-${serviceShort}-001' + } + ] + publicNetwork: { allow: [] deny: [ - 'ServerConnection' + 'RESTAPI' 'Trace' ] - name: 'pe-${namePrefix}-${serviceShort}-001' } - ] - publicNetwork: { - allow: [] - deny: [ - 'RESTAPI' - 'Trace' - ] } - } - privateEndpoints: [ - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'webpubsub' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'webpubsub' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } + ] + resourceLogConfigurationsToEnable: [ + 'ConnectivityLogs' + ] + sku: 'Standard_S1' + managedIdentities: { + systemAssigned: true + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - resourceLogConfigurationsToEnable: [ - 'ConnectivityLogs' - ] - sku: 'Standard_S1' - managedIdentities: { - systemAssigned: true - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } -}] +] 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 f40030f6d4..b73eaff15f 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.25.53.49325", - "templateHash": "17376471861428793697" + "version": "0.26.54.24096", + "templateHash": "13590495271621282724" }, "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 0aea9d0e91..6ba3e2d233 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.25.53.49325", - "templateHash": "16471212899981632790" + "version": "0.26.54.24096", + "templateHash": "11085405057722780022" }, "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 9a8b4f4a67..f6bc48609e 100644 --- a/avm/res/sql/server/database/main.bicep +++ b/avm/res/sql/server/database/main.bicep @@ -122,16 +122,25 @@ param backupLongTermRetentionPolicy object = {} // The SKU object must be built in a variable // The alternative, 'null' as default values, leads to non-terminating deployments -var skuVar = union({ +var skuVar = union( + { name: skuName tier: skuTier - }, (skuCapacity != null) ? { - capacity: skuCapacity - } : !empty(skuFamily) ? { - family: skuFamily - } : !empty(skuSize) ? { - size: skuSize - } : {}) + }, + (skuCapacity != null) + ? { + capacity: skuCapacity + } + : !empty(skuFamily) + ? { + family: skuFamily + } + : !empty(skuSize) + ? { + size: skuSize + } + : {} +) resource server 'Microsoft.Sql/servers@2022-05-01-preview' existing = { name: serverName @@ -160,42 +169,54 @@ resource database 'Microsoft.Sql/servers/databases@2022-05-01-preview' = { createMode: createMode sourceDatabaseId: !empty(sourceDatabaseResourceId) ? sourceDatabaseResourceId : null sourceDatabaseDeletionDate: !empty(sourceDatabaseDeletionDate) ? sourceDatabaseDeletionDate : null - recoveryServicesRecoveryPointId: !empty(recoveryServicesRecoveryPointResourceId) ? recoveryServicesRecoveryPointResourceId : null + recoveryServicesRecoveryPointId: !empty(recoveryServicesRecoveryPointResourceId) + ? recoveryServicesRecoveryPointResourceId + : null restorePointInTime: !empty(restorePointInTime) ? restorePointInTime : null } sku: skuVar } -resource database_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 - 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 +resource database_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 + 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 + } + scope: database } - scope: database -}] +] module database_backupShortTermRetentionPolicy 'backup-short-term-retention-policy/main.bicep' = { name: '${uniqueString(deployment().name, location)}-${name}-shBakRetPol' params: { serverName: serverName databaseName: database.name - diffBackupIntervalInHours: contains(backupShortTermRetentionPolicy, 'diffBackupIntervalInHours') ? backupShortTermRetentionPolicy.diffBackupIntervalInHours : 24 - retentionDays: contains(backupShortTermRetentionPolicy, 'retentionDays') ? backupShortTermRetentionPolicy.retentionDays : 7 + diffBackupIntervalInHours: contains(backupShortTermRetentionPolicy, 'diffBackupIntervalInHours') + ? backupShortTermRetentionPolicy.diffBackupIntervalInHours + : 24 + retentionDays: contains(backupShortTermRetentionPolicy, 'retentionDays') + ? backupShortTermRetentionPolicy.retentionDays + : 7 } } @@ -204,9 +225,15 @@ module database_backupLongTermRetentionPolicy 'backup-long-term-retention-policy params: { serverName: serverName databaseName: database.name - weeklyRetention: contains(backupLongTermRetentionPolicy, 'weeklyRetention') ? backupLongTermRetentionPolicy.weeklyRetention : '' - monthlyRetention: contains(backupLongTermRetentionPolicy, 'monthlyRetention') ? backupLongTermRetentionPolicy.monthlyRetention : '' - yearlyRetention: contains(backupLongTermRetentionPolicy, 'yearlyRetention') ? backupLongTermRetentionPolicy.yearlyRetention : '' + weeklyRetention: contains(backupLongTermRetentionPolicy, 'weeklyRetention') + ? backupLongTermRetentionPolicy.weeklyRetention + : '' + monthlyRetention: contains(backupLongTermRetentionPolicy, 'monthlyRetention') + ? backupLongTermRetentionPolicy.monthlyRetention + : '' + yearlyRetention: contains(backupLongTermRetentionPolicy, 'yearlyRetention') + ? backupLongTermRetentionPolicy.yearlyRetention + : '' weekOfYear: contains(backupLongTermRetentionPolicy, 'weekOfYear') ? backupLongTermRetentionPolicy.weekOfYear : 1 } } diff --git a/avm/res/sql/server/database/main.json b/avm/res/sql/server/database/main.json index e1a6b24ba4..b275733ac7 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.25.53.49325", - "templateHash": "745610238423132217" + "version": "0.26.54.24096", + "templateHash": "17545579739827867089" }, "name": "SQL Server Database", "description": "This module deploys an Azure SQL Server Database.", @@ -483,8 +483,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16471212899981632790" + "version": "0.26.54.24096", + "templateHash": "11085405057722780022" }, "name": "Azure SQL Server Database Short Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Short-Term Backup Retention Policy.", @@ -585,8 +585,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17376471861428793697" + "version": "0.26.54.24096", + "templateHash": "13590495271621282724" }, "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 04f10a84af..cc1804c480 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.25.53.49325", - "templateHash": "3404184459089621320" + "version": "0.26.54.24096", + "templateHash": "16839451417800355426" }, "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 2c6ab81141..c14369f9cc 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.25.53.49325", - "templateHash": "16485430925993626206" + "version": "0.26.54.24096", + "templateHash": "15754842645553898915" }, "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 211a03cd92..4f9b66749f 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.25.53.49325", - "templateHash": "6782455844016435325" + "version": "0.26.54.24096", + "templateHash": "11554996903169567204" }, "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.bicep b/avm/res/sql/server/key/main.bicep index 402a634b33..46ccaacaf4 100644 --- a/avm/res/sql/server/key/main.bicep +++ b/avm/res/sql/server/key/main.bicep @@ -22,7 +22,9 @@ var splittedKeyUri = split(uri, '/') // if serverManaged, use serverManaged, if uri provided use concated uri value // MUST match the pattern '__' -var serverKeyName = empty(uri) ? 'ServiceManaged' : '${split(splittedKeyUri[2], '.')[0]}_${splittedKeyUri[4]}_${splittedKeyUri[5]}' +var serverKeyName = empty(uri) + ? 'ServiceManaged' + : '${split(splittedKeyUri[2], '.')[0]}_${splittedKeyUri[4]}_${splittedKeyUri[5]}' resource server 'Microsoft.Sql/servers@2022-05-01-preview' existing = { name: serverName diff --git a/avm/res/sql/server/key/main.json b/avm/res/sql/server/key/main.json index f248bb2978..9d55f7c760 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.25.53.49325", - "templateHash": "8993850940520323522" + "version": "0.26.54.24096", + "templateHash": "5370214401001222813" }, "name": "Azure SQL Server Keys", "description": "This module deploys an Azure SQL Server Key.", diff --git a/avm/res/sql/server/main.bicep b/avm/res/sql/server/main.bicep index 26f63c5646..b9243fc751 100644 --- a/avm/res/sql/server/main.bicep +++ b/avm/res/sql/server/main.bicep @@ -81,12 +81,20 @@ param publicNetworkAccess string = '' ]) param restrictOutboundNetworkAccess string = '' -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null @description('Optional. The encryption protection configuration.') param encryptionProtectorObj object = {} @@ -98,34 +106,62 @@ 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') - 'Reservation Purchaser': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689') - 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'SQL DB Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9b7fa17d-e63e-47b0-bb0a-15c516ac86ec') - 'SQL Managed Instance Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d') - 'SQL Security Manager': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3') - 'SQL Server Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6d8ee4ec-f05a-4a1d-8b00-a9b17e38b437') - 'SqlDb Migration Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '189207d4-bb67-4208-a635-b06afe8b2c57') - 'SqlMI Migration Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1d335eef-eee1-47fe-a9e0-53214eba8872') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Reservation Purchaser': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f7b75c60-3036-4b75-91c3-6b41c27c1689' + ) + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'SQL DB Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '9b7fa17d-e63e-47b0-bb0a-15c516ac86ec' + ) + 'SQL Managed Instance Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d' + ) + 'SQL Security Manager': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '056cd41c-7e88-42e1-933e-88ba6a50c9c3' + ) + 'SQL Server Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '6d8ee4ec-f05a-4a1d-8b00-a9b17e38b437' + ) + 'SqlDb Migration Role': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '189207d4-bb67-4208-a635-b06afe8b2c57' + ) + 'SqlMI Migration Role': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '1d335eef-eee1-47fe-a9e0-53214eba8872' + ) + '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.sql-server.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.sql-server.${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 server 'Microsoft.Sql/servers@2022-05-01-preview' = { location: location @@ -135,221 +171,297 @@ resource server 'Microsoft.Sql/servers@2022-05-01-preview' = { properties: { administratorLogin: !empty(administratorLogin) ? administratorLogin : null administratorLoginPassword: !empty(administratorLoginPassword) ? administratorLoginPassword : null - administrators: !empty(administrators) ? { - administratorType: 'ActiveDirectory' - azureADOnlyAuthentication: administrators.azureADOnlyAuthentication - login: administrators.login - principalType: administrators.principalType - sid: administrators.sid - tenantId: administrators.?tenantId ?? tenant().tenantId - } : null + administrators: !empty(administrators) + ? { + administratorType: 'ActiveDirectory' + azureADOnlyAuthentication: administrators.azureADOnlyAuthentication + login: administrators.login + principalType: administrators.principalType + sid: administrators.sid + tenantId: administrators.?tenantId ?? tenant().tenantId + } + : null version: '12.0' minimalTlsVersion: minimalTlsVersion primaryUserAssignedIdentityId: !empty(primaryUserAssignedIdentityId) ? primaryUserAssignedIdentityId : null - publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) : (!empty(privateEndpoints) && empty(firewallRules) && empty(virtualNetworkRules) ? 'Disabled' : null) + publicNetworkAccess: !empty(publicNetworkAccess) + ? any(publicNetworkAccess) + : (!empty(privateEndpoints) && empty(firewallRules) && empty(virtualNetworkRules) ? 'Disabled' : null) restrictOutboundNetworkAccess: !empty(restrictOutboundNetworkAccess) ? restrictOutboundNetworkAccess : null } } -resource server_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.' +resource server_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: server } - scope: server -} -resource server_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(server.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 +resource server_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(server.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: server } - scope: server -}] - -module server_databases 'database/main.bicep' = [for (database, index) in databases: { - name: '${uniqueString(deployment().name, location)}-Sql-DB-${index}' - params: { - name: database.name - serverName: server.name - skuTier: contains(database, 'skuTier') ? database.skuTier : 'GeneralPurpose' - skuName: contains(database, 'skuName') ? database.skuName : 'GP_Gen5_2' - skuCapacity: database.?skuCapacity - skuFamily: contains(database, 'skuFamily') ? database.skuFamily : '' - skuSize: contains(database, 'skuSize') ? database.skuSize : '' - collation: contains(database, 'collation') ? database.collation : 'SQL_Latin1_General_CP1_CI_AS' - maxSizeBytes: contains(database, 'maxSizeBytes') ? database.maxSizeBytes : 34359738368 - autoPauseDelay: contains(database, 'autoPauseDelay') ? database.autoPauseDelay : 0 - diagnosticSettings: database.?diagnosticSettings - isLedgerOn: contains(database, 'isLedgerOn') ? database.isLedgerOn : false - location: location - licenseType: contains(database, 'licenseType') ? database.licenseType : '' - maintenanceConfigurationId: contains(database, 'maintenanceConfigurationId') ? database.maintenanceConfigurationId : '' - minCapacity: contains(database, 'minCapacity') ? database.minCapacity : '' - highAvailabilityReplicaCount: contains(database, 'highAvailabilityReplicaCount') ? database.highAvailabilityReplicaCount : 0 - readScale: contains(database, 'readScale') ? database.readScale : 'Disabled' - requestedBackupStorageRedundancy: contains(database, 'requestedBackupStorageRedundancy') ? database.requestedBackupStorageRedundancy : '' - sampleName: contains(database, 'sampleName') ? database.sampleName : '' - tags: database.?tags ?? tags - zoneRedundant: contains(database, 'zoneRedundant') ? database.zoneRedundant : false - elasticPoolId: contains(database, 'elasticPoolId') ? database.elasticPoolId : '' - backupShortTermRetentionPolicy: contains(database, 'backupShortTermRetentionPolicy') ? database.backupShortTermRetentionPolicy : {} - backupLongTermRetentionPolicy: contains(database, 'backupLongTermRetentionPolicy') ? database.backupLongTermRetentionPolicy : {} - createMode: contains(database, 'createMode') ? database.createMode : 'Default' - sourceDatabaseResourceId: contains(database, 'sourceDatabaseResourceId') ? database.sourceDatabaseResourceId : '' - sourceDatabaseDeletionDate: contains(database, 'sourceDatabaseDeletionDate') ? database.sourceDatabaseDeletionDate : '' - recoveryServicesRecoveryPointResourceId: contains(database, 'recoveryServicesRecoveryPointResourceId') ? database.recoveryServicesRecoveryPointResourceId : '' - restorePointInTime: contains(database, 'restorePointInTime') ? database.restorePointInTime : '' +] + +module server_databases 'database/main.bicep' = [ + for (database, index) in databases: { + name: '${uniqueString(deployment().name, location)}-Sql-DB-${index}' + params: { + name: database.name + serverName: server.name + skuTier: contains(database, 'skuTier') ? database.skuTier : 'GeneralPurpose' + skuName: contains(database, 'skuName') ? database.skuName : 'GP_Gen5_2' + skuCapacity: database.?skuCapacity + skuFamily: contains(database, 'skuFamily') ? database.skuFamily : '' + skuSize: contains(database, 'skuSize') ? database.skuSize : '' + collation: contains(database, 'collation') ? database.collation : 'SQL_Latin1_General_CP1_CI_AS' + maxSizeBytes: contains(database, 'maxSizeBytes') ? database.maxSizeBytes : 34359738368 + autoPauseDelay: contains(database, 'autoPauseDelay') ? database.autoPauseDelay : 0 + diagnosticSettings: database.?diagnosticSettings + isLedgerOn: contains(database, 'isLedgerOn') ? database.isLedgerOn : false + location: location + licenseType: contains(database, 'licenseType') ? database.licenseType : '' + maintenanceConfigurationId: contains(database, 'maintenanceConfigurationId') + ? database.maintenanceConfigurationId + : '' + minCapacity: contains(database, 'minCapacity') ? database.minCapacity : '' + highAvailabilityReplicaCount: contains(database, 'highAvailabilityReplicaCount') + ? database.highAvailabilityReplicaCount + : 0 + readScale: contains(database, 'readScale') ? database.readScale : 'Disabled' + requestedBackupStorageRedundancy: contains(database, 'requestedBackupStorageRedundancy') + ? database.requestedBackupStorageRedundancy + : '' + sampleName: contains(database, 'sampleName') ? database.sampleName : '' + tags: database.?tags ?? tags + zoneRedundant: contains(database, 'zoneRedundant') ? database.zoneRedundant : false + elasticPoolId: contains(database, 'elasticPoolId') ? database.elasticPoolId : '' + backupShortTermRetentionPolicy: contains(database, 'backupShortTermRetentionPolicy') + ? database.backupShortTermRetentionPolicy + : {} + backupLongTermRetentionPolicy: contains(database, 'backupLongTermRetentionPolicy') + ? database.backupLongTermRetentionPolicy + : {} + createMode: contains(database, 'createMode') ? database.createMode : 'Default' + sourceDatabaseResourceId: contains(database, 'sourceDatabaseResourceId') ? database.sourceDatabaseResourceId : '' + sourceDatabaseDeletionDate: contains(database, 'sourceDatabaseDeletionDate') + ? database.sourceDatabaseDeletionDate + : '' + recoveryServicesRecoveryPointResourceId: contains(database, 'recoveryServicesRecoveryPointResourceId') + ? database.recoveryServicesRecoveryPointResourceId + : '' + restorePointInTime: contains(database, 'restorePointInTime') ? database.restorePointInTime : '' + } + dependsOn: [ + server_elasticPools // Enables us to add databases to existing elastic pools + ] } - dependsOn: [ - server_elasticPools // Enables us to add databases to existing elastic pools - ] -}] - -module server_elasticPools 'elastic-pool/main.bicep' = [for (elasticPool, index) in elasticPools: { - name: '${uniqueString(deployment().name, location)}-SQLServer-ElasticPool-${index}' - params: { - name: elasticPool.name - serverName: server.name - databaseMaxCapacity: contains(elasticPool, 'databaseMaxCapacity') ? elasticPool.databaseMaxCapacity : 2 - databaseMinCapacity: contains(elasticPool, 'databaseMinCapacity') ? elasticPool.databaseMinCapacity : 0 - highAvailabilityReplicaCount: elasticPool.?highAvailabilityReplicaCount - licenseType: contains(elasticPool, 'licenseType') ? elasticPool.licenseType : 'LicenseIncluded' - maintenanceConfigurationId: contains(elasticPool, 'maintenanceConfigurationId') ? elasticPool.maintenanceConfigurationId : '' - maxSizeBytes: contains(elasticPool, 'maxSizeBytes') ? elasticPool.maxSizeBytes : 34359738368 - minCapacity: elasticPool.?minCapacity - skuCapacity: contains(elasticPool, 'skuCapacity') ? elasticPool.skuCapacity : 2 - skuName: contains(elasticPool, 'skuName') ? elasticPool.skuName : 'GP_Gen5' - skuTier: contains(elasticPool, 'skuTier') ? elasticPool.skuTier : 'GeneralPurpose' - zoneRedundant: contains(elasticPool, 'zoneRedundant') ? elasticPool.zoneRedundant : false - location: location - tags: elasticPool.?tags ?? tags +] + +module server_elasticPools 'elastic-pool/main.bicep' = [ + for (elasticPool, index) in elasticPools: { + name: '${uniqueString(deployment().name, location)}-SQLServer-ElasticPool-${index}' + params: { + name: elasticPool.name + serverName: server.name + databaseMaxCapacity: contains(elasticPool, 'databaseMaxCapacity') ? elasticPool.databaseMaxCapacity : 2 + databaseMinCapacity: contains(elasticPool, 'databaseMinCapacity') ? elasticPool.databaseMinCapacity : 0 + highAvailabilityReplicaCount: elasticPool.?highAvailabilityReplicaCount + licenseType: contains(elasticPool, 'licenseType') ? elasticPool.licenseType : 'LicenseIncluded' + maintenanceConfigurationId: contains(elasticPool, 'maintenanceConfigurationId') + ? elasticPool.maintenanceConfigurationId + : '' + maxSizeBytes: contains(elasticPool, 'maxSizeBytes') ? elasticPool.maxSizeBytes : 34359738368 + minCapacity: elasticPool.?minCapacity + skuCapacity: contains(elasticPool, 'skuCapacity') ? elasticPool.skuCapacity : 2 + skuName: contains(elasticPool, 'skuName') ? elasticPool.skuName : 'GP_Gen5' + skuTier: contains(elasticPool, 'skuTier') ? elasticPool.skuTier : 'GeneralPurpose' + zoneRedundant: contains(elasticPool, 'zoneRedundant') ? elasticPool.zoneRedundant : false + location: location + tags: elasticPool.?tags ?? tags + } } -}] - -module server_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Server-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(server.id, '/'))}-${privateEndpoint.?service ?? 'sqlServer'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(server.id, '/'))}-${privateEndpoint.?service ?? 'sqlServer'}-${index}' - properties: { - privateLinkServiceId: server.id - groupIds: [ - privateEndpoint.?service ?? 'sqlServer' +] + +module server_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Server-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(server.id, '/'))}-${privateEndpoint.?service ?? 'sqlServer'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(server.id, '/'))}-${privateEndpoint.?service ?? 'sqlServer'}-${index}' + properties: { + privateLinkServiceId: server.id + groupIds: [ + privateEndpoint.?service ?? 'sqlServer' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(server.id, '/'))}-${privateEndpoint.?service ?? 'sqlServer'}-${index}' - properties: { - privateLinkServiceId: server.id - groupIds: [ - privateEndpoint.?service ?? 'sqlServer' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(server.id, '/'))}-${privateEndpoint.?service ?? 'sqlServer'}-${index}' + properties: { + privateLinkServiceId: server.id + groupIds: [ + privateEndpoint.?service ?? 'sqlServer' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] - -module server_firewallRules 'firewall-rule/main.bicep' = [for (firewallRule, index) in firewallRules: { - name: '${uniqueString(deployment().name, location)}-Sql-FirewallRules-${index}' - params: { - name: firewallRule.name - serverName: server.name - endIpAddress: contains(firewallRule, 'endIpAddress') ? firewallRule.endIpAddress : '0.0.0.0' - startIpAddress: contains(firewallRule, 'startIpAddress') ? firewallRule.startIpAddress : '0.0.0.0' +] + +module server_firewallRules 'firewall-rule/main.bicep' = [ + for (firewallRule, index) in firewallRules: { + name: '${uniqueString(deployment().name, location)}-Sql-FirewallRules-${index}' + params: { + name: firewallRule.name + serverName: server.name + endIpAddress: contains(firewallRule, 'endIpAddress') ? firewallRule.endIpAddress : '0.0.0.0' + startIpAddress: contains(firewallRule, 'startIpAddress') ? firewallRule.startIpAddress : '0.0.0.0' + } } -}] - -module server_virtualNetworkRules 'virtual-network-rule/main.bicep' = [for (virtualNetworkRule, index) in virtualNetworkRules: { - name: '${uniqueString(deployment().name, location)}-Sql-VirtualNetworkRules-${index}' - params: { - name: virtualNetworkRule.name - serverName: server.name - ignoreMissingVnetServiceEndpoint: contains(virtualNetworkRule, 'ignoreMissingVnetServiceEndpoint') ? virtualNetworkRule.ignoreMissingVnetServiceEndpoint : false - virtualNetworkSubnetId: virtualNetworkRule.virtualNetworkSubnetId +] + +module server_virtualNetworkRules 'virtual-network-rule/main.bicep' = [ + for (virtualNetworkRule, index) in virtualNetworkRules: { + name: '${uniqueString(deployment().name, location)}-Sql-VirtualNetworkRules-${index}' + params: { + name: virtualNetworkRule.name + serverName: server.name + ignoreMissingVnetServiceEndpoint: contains(virtualNetworkRule, 'ignoreMissingVnetServiceEndpoint') + ? virtualNetworkRule.ignoreMissingVnetServiceEndpoint + : false + virtualNetworkSubnetId: virtualNetworkRule.virtualNetworkSubnetId + } } -}] - -module server_securityAlertPolicies 'security-alert-policy/main.bicep' = [for (securityAlertPolicy, index) in securityAlertPolicies: { - name: '${uniqueString(deployment().name, location)}-Sql-SecAlertPolicy-${index}' - params: { - name: securityAlertPolicy.name - serverName: server.name - disabledAlerts: contains(securityAlertPolicy, 'disabledAlerts') ? securityAlertPolicy.disabledAlerts : [] - emailAccountAdmins: contains(securityAlertPolicy, 'emailAccountAdmins') ? securityAlertPolicy.emailAccountAdmins : false - emailAddresses: contains(securityAlertPolicy, 'emailAddresses') ? securityAlertPolicy.emailAddresses : [] - retentionDays: contains(securityAlertPolicy, 'retentionDays') ? securityAlertPolicy.retentionDays : 0 - state: contains(securityAlertPolicy, 'state') ? securityAlertPolicy.state : 'Disabled' - storageAccountAccessKey: contains(securityAlertPolicy, 'storageAccountAccessKey') ? securityAlertPolicy.storageAccountAccessKey : '' - storageEndpoint: contains(securityAlertPolicy, 'storageEndpoint') ? securityAlertPolicy.storageEndpoint : '' +] + +module server_securityAlertPolicies 'security-alert-policy/main.bicep' = [ + for (securityAlertPolicy, index) in securityAlertPolicies: { + name: '${uniqueString(deployment().name, location)}-Sql-SecAlertPolicy-${index}' + params: { + name: securityAlertPolicy.name + serverName: server.name + disabledAlerts: contains(securityAlertPolicy, 'disabledAlerts') ? securityAlertPolicy.disabledAlerts : [] + emailAccountAdmins: contains(securityAlertPolicy, 'emailAccountAdmins') + ? securityAlertPolicy.emailAccountAdmins + : false + emailAddresses: contains(securityAlertPolicy, 'emailAddresses') ? securityAlertPolicy.emailAddresses : [] + retentionDays: contains(securityAlertPolicy, 'retentionDays') ? securityAlertPolicy.retentionDays : 0 + state: contains(securityAlertPolicy, 'state') ? securityAlertPolicy.state : 'Disabled' + storageAccountAccessKey: contains(securityAlertPolicy, 'storageAccountAccessKey') + ? securityAlertPolicy.storageAccountAccessKey + : '' + storageEndpoint: contains(securityAlertPolicy, 'storageEndpoint') ? securityAlertPolicy.storageEndpoint : '' + } } -}] - -module server_vulnerabilityAssessment 'vulnerability-assessment/main.bicep' = if (!empty(vulnerabilityAssessmentsObj)) { - name: '${uniqueString(deployment().name, location)}-Sql-VulnAssessm' - params: { - serverName: server.name - name: vulnerabilityAssessmentsObj.name - recurringScansEmails: contains(vulnerabilityAssessmentsObj, 'recurringScansEmails') ? vulnerabilityAssessmentsObj.recurringScansEmails : [] - recurringScansEmailSubscriptionAdmins: contains(vulnerabilityAssessmentsObj, 'recurringScansEmailSubscriptionAdmins') ? vulnerabilityAssessmentsObj.recurringScansEmailSubscriptionAdmins : false - recurringScansIsEnabled: contains(vulnerabilityAssessmentsObj, 'recurringScansIsEnabled') ? vulnerabilityAssessmentsObj.recurringScansIsEnabled : false - storageAccountResourceId: vulnerabilityAssessmentsObj.storageAccountResourceId - useStorageAccountAccessKey: contains(vulnerabilityAssessmentsObj, 'useStorageAccountAccessKey') ? vulnerabilityAssessmentsObj.useStorageAccountAccessKey : false - createStorageRoleAssignment: contains(vulnerabilityAssessmentsObj, 'createStorageRoleAssignment') ? vulnerabilityAssessmentsObj.createStorageRoleAssignment : true +] + +module server_vulnerabilityAssessment 'vulnerability-assessment/main.bicep' = + if (!empty(vulnerabilityAssessmentsObj)) { + name: '${uniqueString(deployment().name, location)}-Sql-VulnAssessm' + params: { + serverName: server.name + name: vulnerabilityAssessmentsObj.name + recurringScansEmails: contains(vulnerabilityAssessmentsObj, 'recurringScansEmails') + ? vulnerabilityAssessmentsObj.recurringScansEmails + : [] + recurringScansEmailSubscriptionAdmins: contains( + vulnerabilityAssessmentsObj, + 'recurringScansEmailSubscriptionAdmins' + ) + ? vulnerabilityAssessmentsObj.recurringScansEmailSubscriptionAdmins + : false + recurringScansIsEnabled: contains(vulnerabilityAssessmentsObj, 'recurringScansIsEnabled') + ? vulnerabilityAssessmentsObj.recurringScansIsEnabled + : false + storageAccountResourceId: vulnerabilityAssessmentsObj.storageAccountResourceId + useStorageAccountAccessKey: contains(vulnerabilityAssessmentsObj, 'useStorageAccountAccessKey') + ? vulnerabilityAssessmentsObj.useStorageAccountAccessKey + : false + createStorageRoleAssignment: contains(vulnerabilityAssessmentsObj, 'createStorageRoleAssignment') + ? vulnerabilityAssessmentsObj.createStorageRoleAssignment + : true + } + dependsOn: [ + server_securityAlertPolicies + ] } - dependsOn: [ - server_securityAlertPolicies - ] -} -module server_keys 'key/main.bicep' = [for (key, index) in keys: { - name: '${uniqueString(deployment().name, location)}-Sql-Key-${index}' - params: { - name: key.?name - serverName: server.name - serverKeyType: contains(key, 'serverKeyType') ? key.serverKeyType : 'ServiceManaged' - uri: contains(key, 'uri') ? key.uri : '' +module server_keys 'key/main.bicep' = [ + for (key, index) in keys: { + name: '${uniqueString(deployment().name, location)}-Sql-Key-${index}' + params: { + name: key.?name + serverName: server.name + serverKeyType: contains(key, 'serverKeyType') ? key.serverKeyType : 'ServiceManaged' + uri: contains(key, 'uri') ? key.uri : '' + } } -}] - -module server_encryptionProtector 'encryption-protector/main.bicep' = if (!empty(encryptionProtectorObj)) { - name: '${uniqueString(deployment().name, location)}-Sql-EncryProtector' - params: { - sqlServerName: server.name - serverKeyName: encryptionProtectorObj.serverKeyName - serverKeyType: contains(encryptionProtectorObj, 'serverKeyType') ? encryptionProtectorObj.serverKeyType : 'ServiceManaged' - autoRotationEnabled: contains(encryptionProtectorObj, 'autoRotationEnabled') ? encryptionProtectorObj.autoRotationEnabled : true +] + +module server_encryptionProtector 'encryption-protector/main.bicep' = + if (!empty(encryptionProtectorObj)) { + name: '${uniqueString(deployment().name, location)}-Sql-EncryProtector' + params: { + sqlServerName: server.name + serverKeyName: encryptionProtectorObj.serverKeyName + serverKeyType: contains(encryptionProtectorObj, 'serverKeyType') + ? encryptionProtectorObj.serverKeyType + : 'ServiceManaged' + autoRotationEnabled: contains(encryptionProtectorObj, 'autoRotationEnabled') + ? encryptionProtectorObj.autoRotationEnabled + : true + } + dependsOn: [ + server_keys + ] } - dependsOn: [ - server_keys - ] -} @description('The name of the deployed SQL server.') output name string = server.name diff --git a/avm/res/sql/server/main.json b/avm/res/sql/server/main.json index 5373bb5ebe..1323c000f0 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.25.53.49325", - "templateHash": "6171976598584344196" + "version": "0.26.54.24096", + "templateHash": "1498326047864414566" }, "name": "Azure SQL Servers", "description": "This module deploys an Azure SQL Server.", @@ -641,8 +641,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "745610238423132217" + "version": "0.26.54.24096", + "templateHash": "17545579739827867089" }, "name": "SQL Server Database", "description": "This module deploys an Azure SQL Server Database.", @@ -1119,8 +1119,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16471212899981632790" + "version": "0.26.54.24096", + "templateHash": "11085405057722780022" }, "name": "Azure SQL Server Database Short Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Short-Term Backup Retention Policy.", @@ -1221,8 +1221,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17376471861428793697" + "version": "0.26.54.24096", + "templateHash": "13590495271621282724" }, "name": "SQL Server Database Long Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Long-Term Backup Retention Policy.", @@ -1399,8 +1399,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3404184459089621320" + "version": "0.26.54.24096", + "templateHash": "16839451417800355426" }, "name": "SQL Server Elastic Pool", "description": "This module deploys an Azure SQL Server Elastic Pool.", @@ -2276,8 +2276,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6782455844016435325" + "version": "0.26.54.24096", + "templateHash": "11554996903169567204" }, "name": "Azure SQL Server Firewall Rule", "description": "This module deploys an Azure SQL Server Firewall Rule.", @@ -2382,8 +2382,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16350137843713909320" + "version": "0.26.54.24096", + "templateHash": "16468636891412424894" }, "name": "Azure SQL Server Virtual Network Rules", "description": "This module deploys an Azure SQL Server Virtual Network Rule.", @@ -2490,8 +2490,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12316453108388638438" + "version": "0.26.54.24096", + "templateHash": "4552154846289317547" }, "name": "Azure SQL Server Security Alert Policies", "description": "This module deploys an Azure SQL Server Security Alert Policy.", @@ -2641,8 +2641,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11132162611657015619" + "version": "0.26.54.24096", + "templateHash": "5720200901996028671" }, "name": "Azure SQL Server Vulnerability Assessments", "description": "This module deploys an Azure SQL Server Vulnerability Assessment.", @@ -2744,8 +2744,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7342984307461208675" + "version": "0.26.54.24096", + "templateHash": "13552747005956537738" } }, "parameters": { @@ -2833,8 +2833,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8993850940520323522" + "version": "0.26.54.24096", + "templateHash": "5370214401001222813" }, "name": "Azure SQL Server Keys", "description": "This module deploys an Azure SQL Server Key.", @@ -2952,8 +2952,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16485430925993626206" + "version": "0.26.54.24096", + "templateHash": "15754842645553898915" }, "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 c0350da7f4..0041bd7154 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.25.53.49325", - "templateHash": "12316453108388638438" + "version": "0.26.54.24096", + "templateHash": "4552154846289317547" }, "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/tests/e2e/defaults/main.test.bicep b/avm/res/sql/server/tests/e2e/defaults/main.test.bicep index b2b9f5c769..a6bb47978f 100644 --- a/avm/res/sql/server/tests/e2e/defaults/main.test.bicep +++ b/avm/res/sql/server/tests/e2e/defaults/main.test.bicep @@ -42,13 +42,15 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 - administratorLogin: 'adminUserName' - administratorLoginPassword: password +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 + administratorLogin: 'adminUserName' + administratorLoginPassword: password + } } -}] +] diff --git a/avm/res/sql/server/tests/e2e/max/dependencies.bicep b/avm/res/sql/server/tests/e2e/max/dependencies.bicep index 5f68856202..3698ac0ac5 100644 --- a/avm/res/sql/server/tests/e2e/max/dependencies.bicep +++ b/avm/res/sql/server/tests/e2e/max/dependencies.bicep @@ -26,12 +26,15 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { addressPrefix ] } - subnets: map(range(0, 2), i => { + subnets: map( + range(0, 2), + i => { name: 'subnet-${i}' properties: { addressPrefix: cidrSubnet(addressPrefix, 24, i) } - }) + } + ) } } @@ -81,7 +84,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: keyVault::key properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6') // Key Vault Crypto Service Encryption User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'e147488a-f6f5-4113-8e2d-b22465e65bf6' + ) // Key Vault Crypto Service Encryption User principalType: 'ServicePrincipal' } } diff --git a/avm/res/sql/server/tests/e2e/max/main.test.bicep b/avm/res/sql/server/tests/e2e/max/main.test.bicep index 01ea249410..92abcc0971 100644 --- a/avm/res/sql/server/tests/e2e/max/main.test.bicep +++ b/avm/res/sql/server/tests/e2e/max/main.test.bicep @@ -89,7 +89,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/sql/server/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/sql/server/tests/e2e/waf-aligned/dependencies.bicep index 5f68856202..3698ac0ac5 100644 --- a/avm/res/sql/server/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/sql/server/tests/e2e/waf-aligned/dependencies.bicep @@ -26,12 +26,15 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { addressPrefix ] } - subnets: map(range(0, 2), i => { + subnets: map( + range(0, 2), + i => { name: 'subnet-${i}' properties: { addressPrefix: cidrSubnet(addressPrefix, 24, i) } - }) + } + ) } } @@ -81,7 +84,10 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: keyVault::key properties: { principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6') // Key Vault Crypto Service Encryption User + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'e147488a-f6f5-4113-8e2d-b22465e65bf6' + ) // Key Vault Crypto Service Encryption User principalType: 'ServicePrincipal' } } diff --git a/avm/res/sql/server/virtual-network-rule/main.json b/avm/res/sql/server/virtual-network-rule/main.json index 1520ebf1a8..6ab064ab7c 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.25.53.49325", - "templateHash": "16350137843713909320" + "version": "0.26.54.24096", + "templateHash": "16468636891412424894" }, "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.bicep b/avm/res/sql/server/vulnerability-assessment/main.bicep index 519123f228..5156556584 100644 --- a/avm/res/sql/server/vulnerability-assessment/main.bicep +++ b/avm/res/sql/server/vulnerability-assessment/main.bicep @@ -31,21 +31,24 @@ resource server 'Microsoft.Sql/servers@2022-05-01-preview' existing = { } // Assign SQL Server MSI access to storage account -module storageAccount_sbdc_rbac 'modules/nested_storageRoleAssignment.bicep' = if (!useStorageAccountAccessKey && createStorageRoleAssignment) { - name: '${server.name}-sbdc-rbac' - scope: resourceGroup(split(storageAccountResourceId, '/')[2], split(storageAccountResourceId, '/')[4]) - params: { - storageAccountName: last(split(storageAccountResourceId, '/')) - managedInstanceIdentityPrincipalId: server.identity.principalId +module storageAccount_sbdc_rbac 'modules/nested_storageRoleAssignment.bicep' = + if (!useStorageAccountAccessKey && createStorageRoleAssignment) { + name: '${server.name}-sbdc-rbac' + scope: resourceGroup(split(storageAccountResourceId, '/')[2], split(storageAccountResourceId, '/')[4]) + params: { + storageAccountName: last(split(storageAccountResourceId, '/')) + managedInstanceIdentityPrincipalId: server.identity.principalId + } } -} resource vulnerabilityAssessment 'Microsoft.Sql/servers/vulnerabilityAssessments@2022-05-01-preview' = { name: name parent: server properties: { storageContainerPath: 'https://${last(split(storageAccountResourceId, '/'))}.blob.${environment().suffixes.storage}/vulnerability-assessment/' - storageAccountAccessKey: useStorageAccountAccessKey ? listKeys(storageAccountResourceId, '2019-06-01').keys[0].value : any(null) + storageAccountAccessKey: useStorageAccountAccessKey + ? listKeys(storageAccountResourceId, '2019-06-01').keys[0].value + : any(null) recurringScans: { isEnabled: recurringScansIsEnabled emailSubscriptionAdmins: recurringScansEmailSubscriptionAdmins diff --git a/avm/res/sql/server/vulnerability-assessment/main.json b/avm/res/sql/server/vulnerability-assessment/main.json index 8dfe8d48a8..1aad66da11 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.25.53.49325", - "templateHash": "11132162611657015619" + "version": "0.26.54.24096", + "templateHash": "5720200901996028671" }, "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.25.53.49325", - "templateHash": "7342984307461208675" + "version": "0.26.54.24096", + "templateHash": "13552747005956537738" } }, "parameters": { 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 ac3bd2c129..91a31edc0d 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.25.53.49325", - "templateHash": "10329548264889228160" + "version": "0.26.54.24096", + "templateHash": "2429139364933838439" }, "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 3f3a51ac90..a41cc7b8ce 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.25.53.49325", - "templateHash": "11351273351916968732" + "version": "0.26.54.24096", + "templateHash": "3297137219061666309" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container.", @@ -274,8 +274,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10329548264889228160" + "version": "0.26.54.24096", + "templateHash": "2429139364933838439" }, "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.json b/avm/res/storage/storage-account/blob-service/main.json index 46429e3bb4..2ac6992281 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.25.53.49325", - "templateHash": "4746835745355709536" + "version": "0.26.54.24096", + "templateHash": "12175020972967228537" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service.", @@ -403,8 +403,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "11351273351916968732" + "version": "0.26.54.24096", + "templateHash": "3297137219061666309" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container.", @@ -672,8 +672,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10329548264889228160" + "version": "0.26.54.24096", + "templateHash": "2429139364933838439" }, "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/main.json b/avm/res/storage/storage-account/file-service/main.json index b2d1773a8a..38dcbcb7c7 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.25.53.49325", - "templateHash": "5288106279947156711" + "version": "0.26.54.24096", + "templateHash": "13860799899517512764" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service.", @@ -286,8 +286,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2026482374148202879" + "version": "0.26.54.24096", + "templateHash": "18405917853511220559" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share.", @@ -486,8 +486,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15595600813016932186" + "version": "0.26.54.24096", + "templateHash": "16221226236637657314" } }, "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 4d6e95dba4..813cd74fbd 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.25.53.49325", - "templateHash": "2026482374148202879" + "version": "0.26.54.24096", + "templateHash": "18405917853511220559" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share.", @@ -205,8 +205,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "15595600813016932186" + "version": "0.26.54.24096", + "templateHash": "16221226236637657314" } }, "parameters": { diff --git a/avm/res/storage/storage-account/local-user/main.json b/avm/res/storage/storage-account/local-user/main.json index 5044c80422..07d5ea2520 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.25.53.49325", - "templateHash": "17117452291389534361" + "version": "0.26.54.24096", + "templateHash": "3388645117303533667" }, "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 f95b1f1f23..1b4437ab21 100644 --- a/avm/res/storage/storage-account/main.bicep +++ b/avm/res/storage/storage-account/main.bicep @@ -95,12 +95,14 @@ param customDomainUseSubDomainName bool = false param dnsEndpointType string = '' @description('Optional. Blob service and containers to deploy.') -param blobServices object = kind != 'FileStorage' ? { - containerDeleteRetentionPolicyEnabled: true - containerDeleteRetentionPolicyDays: 7 - deleteRetentionPolicyEnabled: true - deleteRetentionPolicyDays: 6 -} : {} +param blobServices object = kind != 'FileStorage' + ? { + containerDeleteRetentionPolicyEnabled: true + containerDeleteRetentionPolicyDays: 7 + deleteRetentionPolicyEnabled: true + deleteRetentionPolicyDays: 6 + } + : {} @description('Optional. File service and shares to deploy.') param fileServices object = {} @@ -177,69 +179,144 @@ param sasExpirationPeriod string = '' var supportsBlobService = kind == 'BlockBlobStorage' || kind == 'BlobStorage' || kind == 'StorageV2' || kind == 'Storage' var supportsFileService = kind == 'FileStorage' || kind == 'StorageV2' || kind == 'Storage' -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : 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') - 'Reader and Data Access': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349') - 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'Storage Account Backup Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1') - 'Storage Account Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab') - 'Storage Account Key Operator Service Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12') - 'Storage Blob Data Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe') - 'Storage Blob Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b') - 'Storage Blob Data Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1') - 'Storage Blob Delegator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db58b8e5-c6ad-4a2a-8342-4190687cbf4a') - 'Storage File Data SMB Share Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb') - 'Storage File Data SMB Share Elevated Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7264617-510b-434b-a828-9731dc254ea7') - 'Storage File Data SMB Share Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aba4ae5f-2193-4029-9191-0cb91df5e314') - 'Storage Queue Data Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88') - 'Storage Queue Data Message Processor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8a0f0c08-91a1-4084-bc3d-661d67233fed') - 'Storage Queue Data Message Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a') - 'Storage Queue Data Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '19e7f393-937e-4f77-808e-94535e297925') - 'Storage Table Data Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3') - 'Storage Table Data Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76199698-9eea-4c19-bc75-cec21354c6b6') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Reader and Data Access': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'c12c1c16-33a1-487b-954d-41c89c60f349' + ) + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'Storage Account Backup Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1' + ) + 'Storage Account Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '17d1049b-9a84-46fb-8f53-869881c3d3ab' + ) + 'Storage Account Key Operator Service Role': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '81a9662b-bebf-436f-a333-f67b29880f12' + ) + 'Storage Blob Data Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' + ) + 'Storage Blob Data Owner': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b' + ) + 'Storage Blob Data Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' + ) + 'Storage Blob Delegator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'db58b8e5-c6ad-4a2a-8342-4190687cbf4a' + ) + 'Storage File Data SMB Share Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb' + ) + 'Storage File Data SMB Share Elevated Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'a7264617-510b-434b-a828-9731dc254ea7' + ) + 'Storage File Data SMB Share Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'aba4ae5f-2193-4029-9191-0cb91df5e314' + ) + 'Storage Queue Data Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '974c5e8b-45b9-4653-ba55-5f855dd0fb88' + ) + 'Storage Queue Data Message Processor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '8a0f0c08-91a1-4084-bc3d-661d67233fed' + ) + 'Storage Queue Data Message Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a' + ) + 'Storage Queue Data Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '19e7f393-937e-4f77-808e-94535e297925' + ) + 'Storage Table Data Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3' + ) + 'Storage Table Data Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '76199698-9eea-4c19-bc75-cec21354c6b6' + ) + '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.storage-storageaccount.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.storage-storageaccount.${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 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 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 storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { name: name @@ -261,15 +338,20 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { } dnsEndpointType: !empty(dnsEndpointType) ? dnsEndpointType : null isLocalUserEnabled: isLocalUserEnabled - encryption: union({ + encryption: union( + { keySource: !empty(customerManagedKey) ? 'Microsoft.Keyvault' : 'Microsoft.Storage' services: { - blob: supportsBlobService ? { - enabled: true - } : null - file: supportsFileService ? { - enabled: true - } : null + blob: supportsBlobService + ? { + enabled: true + } + : null + file: supportsFileService + ? { + enabled: true + } + : null table: { enabled: true } @@ -277,207 +359,255 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { 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 + 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 + userAssignedIdentity: !empty(customerManagedKey.?userAssignedIdentityResourceId) + ? cMKUserAssignedIdentity.id + : null } - }, (requireInfrastructureEncryption ? { - requireInfrastructureEncryption: kind != 'Storage' ? requireInfrastructureEncryption : null - } : {})) + }, + (requireInfrastructureEncryption + ? { + requireInfrastructureEncryption: kind != 'Storage' ? requireInfrastructureEncryption : null + } + : {}) + ) accessTier: (kind != 'Storage' && kind != 'BlockBlobStorage') ? accessTier : null - sasPolicy: !empty(sasExpirationPeriod) ? { - expirationAction: 'Log' - sasExpirationPeriod: sasExpirationPeriod - } : null + sasPolicy: !empty(sasExpirationPeriod) + ? { + expirationAction: 'Log' + sasExpirationPeriod: sasExpirationPeriod + } + : null supportsHttpsTrafficOnly: supportsHttpsTrafficOnly isHnsEnabled: enableHierarchicalNamespace ? enableHierarchicalNamespace : null isSftpEnabled: enableSftp isNfsV3Enabled: enableNfsV3 ? enableNfsV3 : any('') largeFileSharesState: (skuName == 'Standard_LRS') || (skuName == 'Standard_ZRS') ? largeFileSharesState : null minimumTlsVersion: minimumTlsVersion - networkAcls: !empty(networkAcls) ? { - resourceAccessRules: networkAcls.?resourceAccessRules - bypass: networkAcls.?bypass - defaultAction: networkAcls.?defaultAction - virtualNetworkRules: networkAcls.?virtualNetworkRules - ipRules: networkAcls.?ipRules - } : null + networkAcls: !empty(networkAcls) + ? { + resourceAccessRules: networkAcls.?resourceAccessRules + bypass: networkAcls.?bypass + defaultAction: networkAcls.?defaultAction + virtualNetworkRules: networkAcls.?virtualNetworkRules + ipRules: networkAcls.?ipRules + } + : null allowBlobPublicAccess: allowBlobPublicAccess - publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) : (!empty(privateEndpoints) && empty(networkAcls) ? 'Disabled' : null) - azureFilesIdentityBasedAuthentication: !empty(azureFilesIdentityBasedAuthentication) ? azureFilesIdentityBasedAuthentication : null + publicNetworkAccess: !empty(publicNetworkAccess) + ? any(publicNetworkAccess) + : (!empty(privateEndpoints) && empty(networkAcls) ? 'Disabled' : null) + azureFilesIdentityBasedAuthentication: !empty(azureFilesIdentityBasedAuthentication) + ? azureFilesIdentityBasedAuthentication + : null } } -resource storageAccount_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 - metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { - category: group.category - enabled: group.?enabled ?? true - timeGrain: null - }] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType +resource storageAccount_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 + metrics: [ + for group in (diagnosticSetting.?metricCategories ?? [{ category: 'AllMetrics' }]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: storageAccount } - scope: storageAccount -}] +] -resource storageAccount_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.' +resource storageAccount_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: storageAccount } - scope: storageAccount -} -resource storageAccount_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(storageAccount.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 +resource storageAccount_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(storageAccount.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: storageAccount } - scope: storageAccount -}] - -module storageAccount_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-StorageAccount-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}' - properties: { - privateLinkServiceId: storageAccount.id - groupIds: [ - privateEndpoint.service +] + +module storageAccount_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-StorageAccount-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}' + properties: { + privateLinkServiceId: storageAccount.id + groupIds: [ + privateEndpoint.service + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}' - properties: { - privateLinkServiceId: storageAccount.id - groupIds: [ - privateEndpoint.service + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}' + properties: { + privateLinkServiceId: storageAccount.id + groupIds: [ + privateEndpoint.service + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] // Lifecycle Policy -module storageAccount_managementPolicies 'management-policy/main.bicep' = if (!empty(managementPolicyRules ?? [])) { - name: '${uniqueString(deployment().name, location)}-Storage-ManagementPolicies' - params: { - storageAccountName: storageAccount.name - rules: managementPolicyRules ?? [] +module storageAccount_managementPolicies 'management-policy/main.bicep' = + if (!empty(managementPolicyRules ?? [])) { + name: '${uniqueString(deployment().name, location)}-Storage-ManagementPolicies' + params: { + storageAccountName: storageAccount.name + rules: managementPolicyRules ?? [] + } + dependsOn: [ + storageAccount_blobServices // To ensure the lastAccessTimeTrackingPolicy is set first (if used in rule) + ] } - dependsOn: [ - storageAccount_blobServices // To ensure the lastAccessTimeTrackingPolicy is set first (if used in rule) - ] -} // SFTP user settings -module storageAccount_localUsers 'local-user/main.bicep' = [for (localUser, index) in localUsers: { - name: '${uniqueString(deployment().name, location)}-Storage-LocalUsers-${index}' - params: { - storageAccountName: storageAccount.name - name: localUser.name - hasSshKey: localUser.hasSshKey - hasSshPassword: localUser.hasSshPassword - permissionScopes: localUser.permissionScopes - hasSharedKey: localUser.?hasSharedKey - homeDirectory: localUser.?homeDirectory - sshAuthorizedKeys: localUser.?sshAuthorizedKeys +module storageAccount_localUsers 'local-user/main.bicep' = [ + for (localUser, index) in localUsers: { + name: '${uniqueString(deployment().name, location)}-Storage-LocalUsers-${index}' + params: { + storageAccountName: storageAccount.name + name: localUser.name + hasSshKey: localUser.hasSshKey + hasSshPassword: localUser.hasSshPassword + permissionScopes: localUser.permissionScopes + hasSharedKey: localUser.?hasSharedKey + homeDirectory: localUser.?homeDirectory + sshAuthorizedKeys: localUser.?sshAuthorizedKeys + } } -}] +] // Containers -module storageAccount_blobServices 'blob-service/main.bicep' = if (!empty(blobServices)) { - name: '${uniqueString(deployment().name, location)}-Storage-BlobServices' - params: { - storageAccountName: storageAccount.name - containers: blobServices.?containers - automaticSnapshotPolicyEnabled: blobServices.?automaticSnapshotPolicyEnabled - changeFeedEnabled: blobServices.?changeFeedEnabled - changeFeedRetentionInDays: blobServices.?changeFeedRetentionInDays - containerDeleteRetentionPolicyEnabled: blobServices.?containerDeleteRetentionPolicyEnabled - containerDeleteRetentionPolicyDays: blobServices.?containerDeleteRetentionPolicyDays - containerDeleteRetentionPolicyAllowPermanentDelete: blobServices.?containerDeleteRetentionPolicyAllowPermanentDelete - corsRules: blobServices.?corsRules - defaultServiceVersion: blobServices.?defaultServiceVersion - deleteRetentionPolicyAllowPermanentDelete: blobServices.?deleteRetentionPolicyAllowPermanentDelete - deleteRetentionPolicyEnabled: blobServices.?deleteRetentionPolicyEnabled - deleteRetentionPolicyDays: blobServices.?deleteRetentionPolicyDays - isVersioningEnabled: blobServices.?isVersioningEnabled - lastAccessTimeTrackingPolicyEnabled: blobServices.?lastAccessTimeTrackingPolicyEnabled - restorePolicyEnabled: blobServices.?restorePolicyEnabled - restorePolicyDays: blobServices.?restorePolicyDays - diagnosticSettings: blobServices.?diagnosticSettings +module storageAccount_blobServices 'blob-service/main.bicep' = + if (!empty(blobServices)) { + name: '${uniqueString(deployment().name, location)}-Storage-BlobServices' + params: { + storageAccountName: storageAccount.name + containers: blobServices.?containers + automaticSnapshotPolicyEnabled: blobServices.?automaticSnapshotPolicyEnabled + changeFeedEnabled: blobServices.?changeFeedEnabled + changeFeedRetentionInDays: blobServices.?changeFeedRetentionInDays + containerDeleteRetentionPolicyEnabled: blobServices.?containerDeleteRetentionPolicyEnabled + containerDeleteRetentionPolicyDays: blobServices.?containerDeleteRetentionPolicyDays + containerDeleteRetentionPolicyAllowPermanentDelete: blobServices.?containerDeleteRetentionPolicyAllowPermanentDelete + corsRules: blobServices.?corsRules + defaultServiceVersion: blobServices.?defaultServiceVersion + deleteRetentionPolicyAllowPermanentDelete: blobServices.?deleteRetentionPolicyAllowPermanentDelete + deleteRetentionPolicyEnabled: blobServices.?deleteRetentionPolicyEnabled + deleteRetentionPolicyDays: blobServices.?deleteRetentionPolicyDays + isVersioningEnabled: blobServices.?isVersioningEnabled + lastAccessTimeTrackingPolicyEnabled: blobServices.?lastAccessTimeTrackingPolicyEnabled + restorePolicyEnabled: blobServices.?restorePolicyEnabled + restorePolicyDays: blobServices.?restorePolicyDays + diagnosticSettings: blobServices.?diagnosticSettings + } } -} // File Shares -module storageAccount_fileServices 'file-service/main.bicep' = if (!empty(fileServices)) { - name: '${uniqueString(deployment().name, location)}-Storage-FileServices' - params: { - storageAccountName: storageAccount.name - diagnosticSettings: fileServices.?diagnosticSettings - protocolSettings: fileServices.?protocolSettings - shareDeleteRetentionPolicy: fileServices.?shareDeleteRetentionPolicy - shares: fileServices.?shares +module storageAccount_fileServices 'file-service/main.bicep' = + if (!empty(fileServices)) { + name: '${uniqueString(deployment().name, location)}-Storage-FileServices' + params: { + storageAccountName: storageAccount.name + diagnosticSettings: fileServices.?diagnosticSettings + protocolSettings: fileServices.?protocolSettings + shareDeleteRetentionPolicy: fileServices.?shareDeleteRetentionPolicy + shares: fileServices.?shares + } } -} // Queue -module storageAccount_queueServices 'queue-service/main.bicep' = if (!empty(queueServices)) { - name: '${uniqueString(deployment().name, location)}-Storage-QueueServices' - params: { - storageAccountName: storageAccount.name - diagnosticSettings: queueServices.?diagnosticSettings - queues: queueServices.?queues +module storageAccount_queueServices 'queue-service/main.bicep' = + if (!empty(queueServices)) { + name: '${uniqueString(deployment().name, location)}-Storage-QueueServices' + params: { + storageAccountName: storageAccount.name + diagnosticSettings: queueServices.?diagnosticSettings + queues: queueServices.?queues + } } -} // Table -module storageAccount_tableServices 'table-service/main.bicep' = if (!empty(tableServices)) { - name: '${uniqueString(deployment().name, location)}-Storage-TableServices' - params: { - storageAccountName: storageAccount.name - diagnosticSettings: tableServices.?diagnosticSettings - tables: tableServices.?tables +module storageAccount_tableServices 'table-service/main.bicep' = + if (!empty(tableServices)) { + name: '${uniqueString(deployment().name, location)}-Storage-TableServices' + params: { + storageAccountName: storageAccount.name + diagnosticSettings: tableServices.?diagnosticSettings + tables: tableServices.?tables + } } -} @description('The resource ID of the deployed storage account.') output resourceId string = storageAccount.id @@ -489,7 +619,9 @@ output name string = storageAccount.name output resourceGroupName string = resourceGroup().name @description('The primary blob endpoint reference if blob services are deployed.') -output primaryBlobEndpoint string = !empty(blobServices) && contains(blobServices, 'containers') ? reference('Microsoft.Storage/storageAccounts/${storageAccount.name}', '2019-04-01').primaryEndpoints.blob : '' +output primaryBlobEndpoint string = !empty(blobServices) && contains(blobServices, 'containers') + ? reference('Microsoft.Storage/storageAccounts/${storageAccount.name}', '2019-04-01').primaryEndpoints.blob + : '' @description('The principal ID of the system assigned identity.') output systemAssignedMIPrincipalId string = storageAccount.?identity.?principalId ?? '' @@ -551,7 +683,15 @@ type networkAclsType = { }[]? @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') + bypass: ( + | 'None' + | 'AzureServices' + | 'Logging' + | 'Metrics' + | 'AzureServices, Logging' + | 'AzureServices, Metrics' + | 'AzureServices, Logging, Metrics' + | 'Logging, Metrics') @description('Optional. Sets the virtual network rules.') virtualNetworkRules: array? @@ -561,7 +701,7 @@ type networkAclsType = { @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.') diff --git a/avm/res/storage/storage-account/management-policy/main.json b/avm/res/storage/storage-account/management-policy/main.json index 3e1730f09b..323df90a49 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.25.53.49325", - "templateHash": "774635646248081518" + "version": "0.26.54.24096", + "templateHash": "14052382142427178929" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy.", diff --git a/avm/res/storage/storage-account/queue-service/main.json b/avm/res/storage/storage-account/queue-service/main.json index aae35c5012..ea2dd644a3 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.25.53.49325", - "templateHash": "14446905482734328346" + "version": "0.26.54.24096", + "templateHash": "13677013226831946461" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service.", @@ -250,8 +250,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12411465246702614738" + "version": "0.26.54.24096", + "templateHash": "17219066722763101567" }, "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 6ad5c15435..981f57b5d0 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.25.53.49325", - "templateHash": "12411465246702614738" + "version": "0.26.54.24096", + "templateHash": "17219066722763101567" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue.", diff --git a/avm/res/storage/storage-account/table-service/main.json b/avm/res/storage/storage-account/table-service/main.json index 4b2089447c..bb058e623a 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.25.53.49325", - "templateHash": "14471460242481977546" + "version": "0.26.54.24096", + "templateHash": "17373442840517371502" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service.", @@ -247,8 +247,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8824223095963877860" + "version": "0.26.54.24096", + "templateHash": "10226619499666007193" }, "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 c87d417e99..1ba6eab43d 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.25.53.49325", - "templateHash": "8824223095963877860" + "version": "0.26.54.24096", + "templateHash": "10226619499666007193" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table.", diff --git a/avm/res/storage/storage-account/tests/e2e/defaults/main.test.bicep b/avm/res/storage/storage-account/tests/e2e/defaults/main.test.bicep index db5eb11bf1..31e888a7ff 100644 --- a/avm/res/storage/storage-account/tests/e2e/defaults/main.test.bicep +++ b/avm/res/storage/storage-account/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,18 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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' - allowBlobPublicAccess: false +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + allowBlobPublicAccess: false + location: resourceLocation + networkAcls: { + defaultAction: 'Allow' + bypass: 'AzureServices' + } + } } -}] +] diff --git a/avm/res/synapse/private-link-hub/main.bicep b/avm/res/synapse/private-link-hub/main.bicep index 22d0d278ce..dd36ffbce2 100644 --- a/avm/res/synapse/private-link-hub/main.bicep +++ b/avm/res/synapse/private-link-hub/main.bicep @@ -27,27 +27,34 @@ 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') + '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 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 @@ -56,72 +63,91 @@ resource privateLinkHub 'Microsoft.Synapse/privateLinkHubs@2021-06-01' = { } // 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.' +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 } - 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 +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 } - scope: privateLinkHub -}] +] // Private Endpoints -module privateLinkHub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-PrivateLinkHub-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(privateLinkHub.id, '/'))}-${privateEndpoint.?service ?? 'web'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(privateLinkHub.id, '/'))}-${privateEndpoint.?service ?? 'web'}-${index}' - properties: { - privateLinkServiceId: privateLinkHub.id - groupIds: [ - privateEndpoint.?service ?? 'web' +module privateLinkHub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-PrivateLinkHub-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(privateLinkHub.id, '/'))}-${privateEndpoint.?service ?? 'web'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(privateLinkHub.id, '/'))}-${privateEndpoint.?service ?? 'web'}-${index}' + properties: { + privateLinkServiceId: privateLinkHub.id + groupIds: [ + privateEndpoint.?service ?? 'web' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(privateLinkHub.id, '/'))}-${privateEndpoint.?service ?? 'web'}-${index}' - properties: { - privateLinkServiceId: privateLinkHub.id - groupIds: [ - privateEndpoint.?service ?? 'web' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(privateLinkHub.id, '/'))}-${privateEndpoint.?service ?? 'web'}-${index}' + properties: { + privateLinkServiceId: privateLinkHub.id + groupIds: [ + privateEndpoint.?service ?? 'web' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] @description('The resource ID of the deployed Synapse Private Link Hub.') output resourceId string = privateLinkHub.id diff --git a/avm/res/synapse/private-link-hub/main.json b/avm/res/synapse/private-link-hub/main.json index d0134ae735..4f2a9e3f8d 100644 --- a/avm/res/synapse/private-link-hub/main.json +++ b/avm/res/synapse/private-link-hub/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16624127378809450653" + "version": "0.26.54.24096", + "templateHash": "1037376719472164263" }, "name": "Azure Synapse Analytics", "description": "This module deploys an Azure Synapse Analytics (Private Link Hub).", 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 index c726100b1d..6287d99a6c 100644 --- 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 @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/main.test.bicep b/avm/res/synapse/private-link-hub/tests/e2e/max/main.test.bicep index 26749a1732..314df85fbd 100644 --- 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 @@ -47,54 +47,56 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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' } - { - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' - principalType: 'ServicePrincipal' + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] 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 index d7fa917088..6f194062be 100644 --- 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 @@ -61,4 +61,3 @@ 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 index 7a5577e6b5..bbbdccf99e 100644 --- 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 @@ -46,33 +46,35 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' +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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/synapse/workspace/integration-runtime/main.bicep b/avm/res/synapse/workspace/integration-runtime/main.bicep index 2734626027..081805a6ba 100644 --- a/avm/res/synapse/workspace/integration-runtime/main.bicep +++ b/avm/res/synapse/workspace/integration-runtime/main.bicep @@ -25,16 +25,18 @@ resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' existing = { 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 - } + 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.') diff --git a/avm/res/synapse/workspace/integration-runtime/main.json b/avm/res/synapse/workspace/integration-runtime/main.json index 97a5e64866..6ed516e1b3 100644 --- a/avm/res/synapse/workspace/integration-runtime/main.json +++ b/avm/res/synapse/workspace/integration-runtime/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7739107907804712060" + "version": "0.26.54.24096", + "templateHash": "3692817517911366371" }, "name": "Synapse Workspace Integration Runtimes", "description": "This module deploys a Synapse Workspace Integration Runtime.", diff --git a/avm/res/synapse/workspace/key/main.json b/avm/res/synapse/workspace/key/main.json index b966f02678..bd04f8389c 100644 --- a/avm/res/synapse/workspace/key/main.json +++ b/avm/res/synapse/workspace/key/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "29131182338463302" + "version": "0.26.54.24096", + "templateHash": "4754954307876642999" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep index 13c505992a..137294985f 100644 --- a/avm/res/synapse/workspace/main.bicep +++ b/avm/res/synapse/workspace/main.bicep @@ -93,11 +93,19 @@ param diagnosticSettings diagnosticSettingType // Variables -var cmkUserAssignedIdentityAsArray = !empty(customerManagedKey.?userAssignedIdentityResourceId ?? []) ? [ customerManagedKey.?userAssignedIdentityResourceId ] : [] +var cmkUserAssignedIdentityAsArray = !empty(customerManagedKey.?userAssignedIdentityResourceId ?? []) + ? [customerManagedKey.?userAssignedIdentityResourceId] + : [] -var userAssignedIdentitiesUnion = !empty(managedIdentities) ? union(managedIdentities.?userAssignedResourceIds ?? [], cmkUserAssignedIdentityAsArray) : cmkUserAssignedIdentityAsArray +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 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' @@ -108,42 +116,61 @@ 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 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 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 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 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 @@ -152,39 +179,49 @@ resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' = { tags: tags properties: { azureADOnlyAuthentication: azureADOnlyAuthentication ? azureADOnlyAuthentication : null - cspWorkspaceAdminProperties: !empty(initialWorkspaceAdminObjectID) ? { - initialWorkspaceAdminObjectId: initialWorkspaceAdminObjectID - } : 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 + 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 + : null managedResourceGroupName: !empty(managedResourceGroupName) ? managedResourceGroupName : null managedVirtualNetwork: managedVirtualNetwork ? 'default' : null - managedVirtualNetworkSettings: managedVirtualNetwork ? { - allowedAadTenantIdsForLinking: allowedAadTenantIdsForLinking - linkedAccessCheckOnTargetResource: linkedAccessCheckOnTargetResource - preventDataExfiltration: preventDataExfiltration - } : null + managedVirtualNetworkSettings: managedVirtualNetwork + ? { + allowedAadTenantIdsForLinking: allowedAadTenantIdsForLinking + linkedAccessCheckOnTargetResource: linkedAccessCheckOnTargetResource + preventDataExfiltration: preventDataExfiltration + } + : null publicNetworkAccess: managedVirtualNetwork ? publicNetworkAccess : null - purviewConfiguration: !empty(purviewResourceID) ? { - purviewResourceId: purviewResourceID - } : null + purviewConfiguration: !empty(purviewResourceID) + ? { + purviewResourceId: purviewResourceID + } + : null sqlAdministratorLogin: sqlAdministratorLogin sqlAdministratorLoginPassword: !empty(sqlAdministratorLoginPassword) ? sqlAdministratorLoginPassword : null workspaceRepositoryConfiguration: workspaceRepositoryConfiguration @@ -192,129 +229,161 @@ resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' = { } // 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 : {} +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 +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() } - 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 +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 + ] } - 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.' +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 } - 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 +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 } - scope: workspace -}] +] // Endpoints -module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-workspace-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.service}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.service}-${index}' - properties: { - privateLinkServiceId: workspace.id - groupIds: [ - privateEndpoint.service +module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-workspace-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.service}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.service}-${index}' + properties: { + privateLinkServiceId: workspace.id + groupIds: [ + privateEndpoint.service + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.service}-${index}' - properties: { - privateLinkServiceId: workspace.id - groupIds: [ - privateEndpoint.service + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(workspace.id, '/'))}-${privateEndpoint.service}-${index}' + properties: { + privateLinkServiceId: workspace.id + groupIds: [ + privateEndpoint.service + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] // 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 +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 } - scope: workspace -}] +] @description('The resource ID of the deployed Synapse Workspace.') output resourceID string = workspace.id diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json index 102e84b052..0e1f785400 100644 --- a/avm/res/synapse/workspace/main.json +++ b/avm/res/synapse/workspace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "199483993688319459" + "version": "0.26.54.24096", + "templateHash": "12255523377827341539" }, "name": "Synapse Workspaces", "description": "This module deploys a Synapse Workspace.", @@ -797,8 +797,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "7739107907804712060" + "version": "0.26.54.24096", + "templateHash": "3692817517911366371" }, "name": "Synapse Workspace Integration Runtimes", "description": "This module deploys a Synapse Workspace Integration Runtime.", @@ -895,8 +895,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "16862202180408198277" + "version": "0.26.54.24096", + "templateHash": "11661011043333744116" } }, "parameters": { @@ -983,8 +983,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "29131182338463302" + "version": "0.26.54.24096", + "templateHash": "4754954307876642999" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", diff --git a/avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep index b057b0b981..11a476b1e7 100644 --- a/avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep @@ -5,23 +5,23 @@ param location string = resourceGroup().location param storageAccountName string resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { - name: storageAccountName - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' - properties: { - isHnsEnabled: true - } + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } - resource blobService 'blobServices@2022-09-01' = { - name: 'default' + resource blobService 'blobServices@2022-09-01' = { + name: 'default' - resource container 'containers@2022-09-01' = { - name: 'synapsews' - } + resource container 'containers@2022-09-01' = { + name: 'synapsews' } + } } @description('The resource ID of the created Storage Account.') diff --git a/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep index 5b96756401..50adf1a478 100644 --- a/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep @@ -45,17 +45,19 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' +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' + } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep index ef593e0e43..6d7a736f40 100644 --- a/avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep +++ b/avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep @@ -8,49 +8,49 @@ param keyVaultName string 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: [] + 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 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 - } + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } - resource blobService 'blobServices@2022-09-01' = { - name: 'default' + resource blobService 'blobServices@2022-09-01' = { + name: 'default' - resource container 'containers@2022-09-01' = { - name: 'synapsews' - } + resource container 'containers@2022-09-01' = { + name: 'synapsews' } + } } @description('The resource ID of the created Key Vault.') diff --git a/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep index 1099ded9b2..4f63a039ef 100644 --- a/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep @@ -50,22 +50,24 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 +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 } - encryptionActivateWorkspace: true - location: resourceLocation + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep index 6faa37afac..04f775602e 100644 --- a/avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep +++ b/avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep @@ -11,64 +11,67 @@ param keyVaultName string param storageAccountName string 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 - softDeleteRetentionInDays: 7 - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: true - accessPolicies: [] + 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 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' - } + 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 - } + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } - resource blobService 'blobServices@2022-09-01' = { - name: 'default' + resource blobService 'blobServices@2022-09-01' = { + name: 'default' - resource container 'containers@2022-09-01' = { - name: 'synapsews' - } + resource container 'containers@2022-09-01' = { + name: 'synapsews' } + } } @description('The resource ID of the created Managed Identity.') diff --git a/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep index b1905e7fd0..373831bb01 100644 --- a/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep @@ -51,22 +51,24 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 +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 + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep index b057b0b981..11a476b1e7 100644 --- a/avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep +++ b/avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep @@ -5,23 +5,23 @@ param location string = resourceGroup().location param storageAccountName string resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { - name: storageAccountName - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' - properties: { - isHnsEnabled: true - } + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } - resource blobService 'blobServices@2022-09-01' = { - name: 'default' + resource blobService 'blobServices@2022-09-01' = { + name: 'default' - resource container 'containers@2022-09-01' = { - name: 'synapsews' - } + resource container 'containers@2022-09-01' = { + name: 'synapsews' } + } } @description('The resource ID of the created Storage Account.') diff --git a/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep index 4cbe44aa95..1ae5fd451d 100644 --- a/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep @@ -45,22 +45,24 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 +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 + ] + } + dependsOn: [ + nestedDependencies ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep index b798023efb..682ca135f8 100644 --- a/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep @@ -61,110 +61,115 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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 +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 ] - service: 'SQL' - subnetResourceId: nestedDependencies.outputs.customSubnet1ResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'SQL' - subnetResourceId: nestedDependencies.outputs.customSubnet2ResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'SqlOnDemand' - subnetResourceId: nestedDependencies.outputs.customSubnet1ResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' } - } - { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - service: 'Dev' - subnetResourceId: nestedDependencies.outputs.customSubnet1ResourceId - } - ] - managedVirtualNetwork: true - integrationRuntimes: [ - { - type: 'SelfHosted' - name: 'shir01' - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - logCategoriesAndGroups: [ - { - category: 'SynapseRbacOperations' + { + 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.customSubnet1ResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - category: 'SynapseLinkEvent' + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'SQL' + subnetResourceId: nestedDependencies.outputs.customSubnet2ResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'SqlOnDemand' + subnetResourceId: nestedDependencies.outputs.customSubnet1ResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'Dev' + subnetResourceId: nestedDependencies.outputs.customSubnet1ResourceId + } + ] + 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 + } + ] + } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] 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 index f47275aa9e..d6a7bc47fb 100644 --- a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -60,61 +60,63 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' +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' } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + 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' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/virtual-machine-images/image-template/main.bicep b/avm/res/virtual-machine-images/image-template/main.bicep index d7a74cd99f..4c46be1680 100644 --- a/avm/res/virtual-machine-images/image-template/main.bicep +++ b/avm/res/virtual-machine-images/image-template/main.bicep @@ -60,34 +60,45 @@ 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}': {} } + 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') + '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 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 @@ -101,68 +112,92 @@ resource imageTemplate 'Microsoft.VirtualMachineImages/imageTemplates@2022-02-14 vmSize: vmSize osDiskSizeGB: osDiskSizeGB userAssignedIdentities: vmUserAssignedIdentities - vnetConfig: !empty(subnetResourceId) ? { - subnetId: subnetResourceId - } : null + 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' - } : {}) - )] + 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.' +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 } - 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 +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 } - scope: imageTemplate -}] +] @description('The resource ID of the image template.') output resourceId string = imageTemplate.id @@ -226,7 +261,6 @@ type managedIdentitiesType = { 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? @@ -253,7 +287,6 @@ type sharedImageDistributionType = { } type unManagedDistributionType = { - @description('Required. The type of distribution.') type: 'VHD' @@ -268,7 +301,6 @@ type unManagedDistributionType = { } type managedImageDistributionType = { - @description('Required. The type of distribution.') type: 'ManagedImage' diff --git a/avm/res/virtual-machine-images/image-template/main.json b/avm/res/virtual-machine-images/image-template/main.json index cbc35f7506..e2bef8c3df 100644 --- a/avm/res/virtual-machine-images/image-template/main.json +++ b/avm/res/virtual-machine-images/image-template/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "13080829112167347263" + "version": "0.26.54.24096", + "templateHash": "4620280027037163005" }, "name": "Virtual Machine Image Templates", "description": "This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB).", 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 index 5de1a5cc92..1808563dfe 100644 --- 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 @@ -12,7 +12,10 @@ resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018- 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 + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor principalId: managedIdentity.properties.principalId principalType: 'ServicePrincipal' } 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 index 3333148724..036e72fb96 100644 --- 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 @@ -190,7 +190,11 @@ resource imageManagedIdentityOperatorRbac 'Microsoft.Authorization/roleAssignmen // 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) + name: guid( + assetsStorageAccount::blobService::container.id, + storageBlobDataContributorRole.id, + imageManagedIdentity.id + ) scope: assetsStorageAccount::blobService::container properties: { roleDefinitionId: storageBlobDataContributorRole.id @@ -226,7 +230,13 @@ resource dsStorageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = { { // 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) + id: resourceId( + subscription().subscriptionId, + resourceGroup().name, + 'Microsoft.Network/virtualNetworks/subnets', + virtualNetwork.name, + deploymentScriptSubnetName + ) } ] } @@ -278,7 +288,13 @@ resource assetsStorageAccount_upload 'Microsoft.Resources/deploymentScripts@2023 containerSettings: { subnetIds: [ { - id: resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Network/virtualNetworks/subnets', virtualNetwork.name, deploymentScriptSubnetName) + id: resourceId( + subscription().subscriptionId, + resourceGroup().name, + 'Microsoft.Network/virtualNetworks/subnets', + virtualNetwork.name, + deploymentScriptSubnetName + ) } ] } 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 index 8de9388d3d..2bd4869dd5 100644 --- 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 @@ -134,7 +134,10 @@ module testDeployment '../../../main.bicep' = { principalType: 'ServicePrincipal' } { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } diff --git a/avm/res/web/serverfarm/main.bicep b/avm/res/web/serverfarm/main.bicep index 89ca6b812f..7cff682e16 100644 --- a/avm/res/web/serverfarm/main.bicep +++ b/avm/res/web/serverfarm/main.bicep @@ -9,7 +9,7 @@ param name string @description('Required. Defines the name, tier, size, family and capacity of the App Service Plan.') @metadata({ - example: ''' + example: ''' { name: 'P1v3' tier: 'Premium' @@ -18,8 +18,7 @@ param name string capacity: 3 } ''' - } -) +}) param sku object @description('Optional. Location for all resources.') @@ -83,29 +82,42 @@ 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': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') - 'Web Plan Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b') - 'Website Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'de139f84-1756-47ae-9be6-808fbbe84772') + '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' + ) + 'Web Plan Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b' + ) + 'Website Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'de139f84-1756-47ae-9be6-808fbbe84772' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.web-serverfarm.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.web-serverfarm.${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 appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = { name: name @@ -115,9 +127,11 @@ resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = { sku: sku properties: { workerTierName: workerTierName - hostingEnvironmentProfile: !empty(appServiceEnvironmentId) ? { - id: appServiceEnvironmentId - } : null + hostingEnvironmentProfile: !empty(appServiceEnvironmentId) + ? { + id: appServiceEnvironmentId + } + : null perSiteScaling: perSiteScaling maximumElasticWorkerCount: maximumElasticWorkerCount reserved: reserved @@ -127,46 +141,59 @@ resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = { } } -resource appServicePlan_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 - metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { - category: group.category - enabled: group.?enabled ?? true - timeGrain: null - }] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType +resource appServicePlan_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 + metrics: [ + for group in (diagnosticSetting.?metricCategories ?? [{ category: 'AllMetrics' }]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: appServicePlan } - scope: appServicePlan -}] - -resource appServicePlan_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.' +] + +resource appServicePlan_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: appServicePlan } - scope: appServicePlan -} -resource appServicePlan_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(appServicePlan.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 +resource appServicePlan_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(appServicePlan.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: appServicePlan } - scope: appServicePlan -}] +] @description('The resource group the app service plan was deployed into.') output resourceGroupName string = resourceGroup().name diff --git a/avm/res/web/serverfarm/main.json b/avm/res/web/serverfarm/main.json index 6ccd7bb609..bf40400bed 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.25.53.49325", - "templateHash": "14257048735375797880" + "version": "0.26.54.24096", + "templateHash": "12495804892051718765" }, "name": "App Service Plan", "description": "This module deploys an App Service Plan.", diff --git a/avm/res/web/serverfarm/tests/e2e/defaults/main.test.bicep b/avm/res/web/serverfarm/tests/e2e/defaults/main.test.bicep index 01e3c49e5a..9f2ffe8e94 100644 --- a/avm/res/web/serverfarm/tests/e2e/defaults/main.test.bicep +++ b/avm/res/web/serverfarm/tests/e2e/defaults/main.test.bicep @@ -39,18 +39,20 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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: tempLocation - sku: { - name: 'P1v3' - tier: 'Premium' - size: 'P1v3' - family: 'P' - capacity: 3 +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: tempLocation + sku: { + name: 'P1v3' + tier: 'Premium' + size: 'P1v3' + family: 'P' + capacity: 3 + } } } -}] +] diff --git a/avm/res/web/serverfarm/tests/e2e/max/main.test.bicep b/avm/res/web/serverfarm/tests/e2e/max/main.test.bicep index 6a48f83bc9..5451356bd1 100644 --- a/avm/res/web/serverfarm/tests/e2e/max/main.test.bicep +++ b/avm/res/web/serverfarm/tests/e2e/max/main.test.bicep @@ -60,61 +60,66 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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: tempLocation - sku: { - name: 'P1v3' - tier: 'Premium' - size: 'P1v3' - family: 'P' - capacity: 3 - } - perSiteScaling: true - zoneRedundant: true - kind: 'App' - lock: { - name: 'lock' - kind: 'CanNotDelete' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +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: tempLocation + sku: { + name: 'P1v3' + tier: 'Premium' + size: 'P1v3' + family: 'P' + capacity: 3 } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + perSiteScaling: true + zoneRedundant: true + kind: 'App' + lock: { + name: 'lock' + kind: 'CanNotDelete' } - { - 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' } - ] - diagnosticSettings: [ - { - name: 'customSetting${serviceShort}' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - 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' + } + ] + diagnosticSettings: [ + { + name: 'customSetting${serviceShort}' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } } -}] +] diff --git a/avm/res/web/serverfarm/tests/e2e/waf-aligned/main.test.bicep b/avm/res/web/serverfarm/tests/e2e/waf-aligned/main.test.bicep index 0cf59b787c..5cd23e57c9 100644 --- a/avm/res/web/serverfarm/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/web/serverfarm/tests/e2e/waf-aligned/main.test.bicep @@ -51,43 +51,45 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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: tempLocation - sku: { - name: 'P1v3' - tier: 'Premium' - size: 'P1v3' - family: 'P' - capacity: 3 - } - zoneRedundant: true - kind: 'App' - lock: { - name: 'lock' - kind: 'CanNotDelete' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - diagnosticSettings: [ - { - name: 'customSetting${serviceShort}' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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: tempLocation + sku: { + name: 'P1v3' + tier: 'Premium' + size: 'P1v3' + family: 'P' + capacity: 3 + } + zoneRedundant: true + kind: 'App' + lock: { + name: 'lock' + kind: 'CanNotDelete' } - ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + diagnosticSettings: [ + { + name: 'customSetting${serviceShort}' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } } -}] +] diff --git a/avm/res/web/site/README.md b/avm/res/web/site/README.md index 150a304f80..a1d528472c 100644 --- a/avm/res/web/site/README.md +++ b/avm/res/web/site/README.md @@ -664,7 +664,6 @@ module site 'br/public:avm/res/web/site:' = { healthCheckPath: '/healthz' } } - } ``` @@ -1164,7 +1163,7 @@ This instance deploys the module as a Linux Web App with the minimum set of requ ```bicep module site 'br/public:avm/res/web/site:' = { - name: '${uniqueString(deployment().name, resourceLocation)}-test-wswalmin' + name: 'siteDeployment' params: { // Required parameters kind: 'app,linux' @@ -1220,7 +1219,7 @@ This instance deploys the module asa Linux Web App with most of its features ena ```bicep module site 'br/public:avm/res/web/site:' = { - name: '${uniqueString(deployment().name, resourceLocation)}-test-wswalmax' + name: 'siteDeployment' params: { // Required parameters kind: 'app,linux' diff --git a/avm/res/web/site/config--appsettings/main.bicep b/avm/res/web/site/config--appsettings/main.bicep index 573c274a95..bb782168aa 100644 --- a/avm/res/web/site/config--appsettings/main.bicep +++ b/avm/res/web/site/config--appsettings/main.bicep @@ -28,16 +28,22 @@ param appInsightResourceId string? @description('Optional. The app settings key-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING.') param appSettingsKeyValuePairs object? -var azureWebJobsValues = !empty(storageAccountResourceId) && !(storageAccountUseIdentityAuthentication) ? { - AzureWebJobsStorage: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};' -} : !empty(storageAccountResourceId) && storageAccountUseIdentityAuthentication ? union( - { AzureWebJobsStorage__accountName: storageAccount.name }, - { AzureWebJobsStorage__blobServiceUri: storageAccount.properties.primaryEndpoints.blob } -) : {} - -var appInsightsValues = !empty(appInsightResourceId) ? { - APPLICATIONINSIGHTS_CONNECTION_STRING: appInsight.properties.ConnectionString -} : {} +var azureWebJobsValues = !empty(storageAccountResourceId) && !(storageAccountUseIdentityAuthentication) + ? { + AzureWebJobsStorage: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};' + } + : !empty(storageAccountResourceId) && storageAccountUseIdentityAuthentication + ? union( + { AzureWebJobsStorage__accountName: storageAccount.name }, + { AzureWebJobsStorage__blobServiceUri: storageAccount.properties.primaryEndpoints.blob } + ) + : {} + +var appInsightsValues = !empty(appInsightResourceId) + ? { + APPLICATIONINSIGHTS_CONNECTION_STRING: appInsight.properties.ConnectionString + } + : {} var expandedAppSettings = union(appSettingsKeyValuePairs ?? {}, azureWebJobsValues, appInsightsValues) @@ -45,15 +51,20 @@ resource app 'Microsoft.Web/sites@2022-09-01' existing = { name: appName } -resource appInsight 'Microsoft.Insights/components@2020-02-02' existing = if (!empty(appInsightResourceId)) { - name: last(split(appInsightResourceId ?? 'dummyName', '/')) - scope: resourceGroup(split(appInsightResourceId ?? '//', '/')[2], split(appInsightResourceId ?? '////', '/')[4]) -} - -resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = if (!empty(storageAccountResourceId)) { - name: last(split(storageAccountResourceId ?? 'dummyName', '/')) - scope: resourceGroup(split(storageAccountResourceId ?? '//', '/')[2], split(storageAccountResourceId ?? '////', '/')[4]) -} +resource appInsight 'Microsoft.Insights/components@2020-02-02' existing = + if (!empty(appInsightResourceId)) { + name: last(split(appInsightResourceId ?? 'dummyName', '/')) + scope: resourceGroup(split(appInsightResourceId ?? '//', '/')[2], split(appInsightResourceId ?? '////', '/')[4]) + } + +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = + if (!empty(storageAccountResourceId)) { + name: last(split(storageAccountResourceId ?? 'dummyName', '/')) + scope: resourceGroup( + split(storageAccountResourceId ?? '//', '/')[2], + split(storageAccountResourceId ?? '////', '/')[4] + ) + } resource appSettings 'Microsoft.Web/sites/config@2022-09-01' = { name: 'appsettings' diff --git a/avm/res/web/site/hybrid-connection-namespace/relay/main.bicep b/avm/res/web/site/hybrid-connection-namespace/relay/main.bicep index 7b6a7f1182..7b64d67dc9 100644 --- a/avm/res/web/site/hybrid-connection-namespace/relay/main.bicep +++ b/avm/res/web/site/hybrid-connection-namespace/relay/main.bicep @@ -28,7 +28,13 @@ resource hybridConnectionRelay 'Microsoft.Web/sites/hybridConnectionNamespaces/r name: '${appName}/${namespace.name}/${namespace::hybridConnection.name}' properties: { serviceBusNamespace: namespace.name - serviceBusSuffix: split(substring(namespace.properties.serviceBusEndpoint, indexOf(namespace.properties.serviceBusEndpoint, '.servicebus')), ':')[0] + serviceBusSuffix: split( + substring( + namespace.properties.serviceBusEndpoint, + indexOf(namespace.properties.serviceBusEndpoint, '.servicebus') + ), + ':' + )[0] relayName: namespace::hybridConnection.name relayArmUri: namespace::hybridConnection.id hostname: split(json(namespace::hybridConnection.properties.userMetadata)[0].value, ':')[0] diff --git a/avm/res/web/site/main.bicep b/avm/res/web/site/main.bicep index a4a63bc236..c0571f9765 100644 --- a/avm/res/web/site/main.bicep +++ b/avm/res/web/site/main.bicep @@ -157,41 +157,65 @@ param hybridConnectionRelays array? ]) param publicNetworkAccess string? -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - 'App Compliance Automation Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f37683f-2463-46b6-9ce7-9b788b988ba2') + 'App Compliance Automation Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0f37683f-2463-46b6-9ce7-9b788b988ba2' + ) 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') - 'Web Plan Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b') - 'Website Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'de139f84-1756-47ae-9be6-808fbbe84772') + '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' + ) + 'Web Plan Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b' + ) + 'Website Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'de139f84-1756-47ae-9be6-808fbbe84772' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.web-site.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.web-site.${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 app 'Microsoft.Web/sites@2022-09-01' = { name: name @@ -203,9 +227,11 @@ resource app 'Microsoft.Web/sites@2022-09-01' = { serverFarmId: serverFarmResourceId clientAffinityEnabled: clientAffinityEnabled httpsOnly: httpsOnly - hostingEnvironmentProfile: !empty(appServiceEnvironmentResourceId) ? { - id: appServiceEnvironmentResourceId - } : null + hostingEnvironmentProfile: !empty(appServiceEnvironmentResourceId) + ? { + id: appServiceEnvironmentResourceId + } + : null storageAccountRequired: storageAccountRequired keyVaultReferenceIdentity: keyVaultAccessIdentityResourceId virtualNetworkSubnetId: virtualNetworkSubnetId @@ -221,7 +247,9 @@ resource app 'Microsoft.Web/sites@2022-09-01' = { hostNameSslStates: hostNameSslStates hyperV: hyperV redundancyMode: redundancyMode - publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) : (!empty(privateEndpoints) ? 'Disabled' : 'Enabled') + publicNetworkAccess: !empty(publicNetworkAccess) + ? any(publicNetworkAccess) + : (!empty(privateEndpoints) ? 'Disabled' : 'Enabled') vnetContentShareEnabled: vnetContentShareEnabled vnetImagePullEnabled: vnetImagePullEnabled vnetRouteAllEnabled: vnetRouteAllEnabled @@ -229,181 +257,216 @@ resource app 'Microsoft.Web/sites@2022-09-01' = { } } -module app_appsettings 'config--appsettings/main.bicep' = if (!empty(appSettingsKeyValuePairs)) { - name: '${uniqueString(deployment().name, location)}-Site-Config-AppSettings' - params: { - appName: app.name - kind: kind - storageAccountResourceId: storageAccountResourceId - storageAccountUseIdentityAuthentication: storageAccountUseIdentityAuthentication - appInsightResourceId: appInsightResourceId - appSettingsKeyValuePairs: appSettingsKeyValuePairs +module app_appsettings 'config--appsettings/main.bicep' = + if (!empty(appSettingsKeyValuePairs)) { + name: '${uniqueString(deployment().name, location)}-Site-Config-AppSettings' + params: { + appName: app.name + kind: kind + storageAccountResourceId: storageAccountResourceId + storageAccountUseIdentityAuthentication: storageAccountUseIdentityAuthentication + appInsightResourceId: appInsightResourceId + appSettingsKeyValuePairs: appSettingsKeyValuePairs + } } -} -module app_authsettingsv2 'config--authsettingsv2/main.bicep' = if (!empty(authSettingV2Configuration)) { - name: '${uniqueString(deployment().name, location)}-Site-Config-AuthSettingsV2' - params: { - appName: app.name - kind: kind - authSettingV2Configuration: authSettingV2Configuration ?? {} +module app_authsettingsv2 'config--authsettingsv2/main.bicep' = + if (!empty(authSettingV2Configuration)) { + name: '${uniqueString(deployment().name, location)}-Site-Config-AuthSettingsV2' + params: { + appName: app.name + kind: kind + authSettingV2Configuration: authSettingV2Configuration ?? {} + } } -} @batchSize(1) -module app_slots 'slot/main.bicep' = [for (slot, index) in (slots ?? []): { - name: '${uniqueString(deployment().name, location)}-Slot-${slot.name}' - params: { - name: slot.name - appName: app.name - location: location - kind: kind - serverFarmResourceId: serverFarmResourceId - httpsOnly: slot.?httpsOnly ?? httpsOnly - appServiceEnvironmentResourceId: appServiceEnvironmentResourceId - clientAffinityEnabled: slot.?clientAffinityEnabled ?? clientAffinityEnabled - managedIdentities: slot.?managedIdentities ?? managedIdentities - keyVaultAccessIdentityResourceId: slot.?keyVaultAccessIdentityResourceId ?? keyVaultAccessIdentityResourceId - storageAccountRequired: slot.?storageAccountRequired ?? storageAccountRequired - virtualNetworkSubnetId: slot.?virtualNetworkSubnetId ?? virtualNetworkSubnetId - siteConfig: slot.?siteConfig ?? siteConfig - storageAccountResourceId: slot.?storageAccountResourceId ?? storageAccountResourceId - storageAccountUseIdentityAuthentication: slot.?storageAccountUseIdentityAuthentication ?? storageAccountUseIdentityAuthentication - appInsightResourceId: slot.?appInsightResourceId ?? appInsightResourceId - authSettingV2Configuration: slot.?authSettingV2Configuration ?? authSettingV2Configuration - diagnosticSettings: slot.?diagnosticSettings - roleAssignments: slot.?roleAssignments ?? roleAssignments - appSettingsKeyValuePairs: slot.?appSettingsKeyValuePairs ?? appSettingsKeyValuePairs - basicPublishingCredentialsPolicies: slot.?basicPublishingCredentialsPolicies ?? basicPublishingCredentialsPolicies - lock: slot.?lock ?? lock - privateEndpoints: slot.?privateEndpoints ?? [] - tags: slot.?tags ?? tags - clientCertEnabled: slot.?clientCertEnabled - clientCertExclusionPaths: slot.?clientCertExclusionPaths - clientCertMode: slot.?clientCertMode - cloningInfo: slot.?cloningInfo - containerSize: slot.?containerSize - customDomainVerificationId: slot.?customDomainVerificationId - dailyMemoryTimeQuota: slot.?dailyMemoryTimeQuota - enabled: slot.?enabled - enableTelemetry: slot.?enableTelemetry ?? enableTelemetry - hostNameSslStates: slot.?hostNameSslStates - hyperV: slot.?hyperV - publicNetworkAccess: slot.?publicNetworkAccess ?? ((!empty(slot.?privateEndpoints) || !empty(privateEndpoints)) ? 'Disabled' : 'Enabled') - redundancyMode: slot.?redundancyMode - vnetContentShareEnabled: slot.?vnetContentShareEnabled - vnetImagePullEnabled: slot.?vnetImagePullEnabled - vnetRouteAllEnabled: slot.?vnetRouteAllEnabled - hybridConnectionRelays: slot.?hybridConnectionRelays +module app_slots 'slot/main.bicep' = [ + for (slot, index) in (slots ?? []): { + name: '${uniqueString(deployment().name, location)}-Slot-${slot.name}' + params: { + name: slot.name + appName: app.name + location: location + kind: kind + serverFarmResourceId: serverFarmResourceId + httpsOnly: slot.?httpsOnly ?? httpsOnly + appServiceEnvironmentResourceId: appServiceEnvironmentResourceId + clientAffinityEnabled: slot.?clientAffinityEnabled ?? clientAffinityEnabled + managedIdentities: slot.?managedIdentities ?? managedIdentities + keyVaultAccessIdentityResourceId: slot.?keyVaultAccessIdentityResourceId ?? keyVaultAccessIdentityResourceId + storageAccountRequired: slot.?storageAccountRequired ?? storageAccountRequired + virtualNetworkSubnetId: slot.?virtualNetworkSubnetId ?? virtualNetworkSubnetId + siteConfig: slot.?siteConfig ?? siteConfig + storageAccountResourceId: slot.?storageAccountResourceId ?? storageAccountResourceId + storageAccountUseIdentityAuthentication: slot.?storageAccountUseIdentityAuthentication ?? storageAccountUseIdentityAuthentication + appInsightResourceId: slot.?appInsightResourceId ?? appInsightResourceId + authSettingV2Configuration: slot.?authSettingV2Configuration ?? authSettingV2Configuration + diagnosticSettings: slot.?diagnosticSettings + roleAssignments: slot.?roleAssignments ?? roleAssignments + appSettingsKeyValuePairs: slot.?appSettingsKeyValuePairs ?? appSettingsKeyValuePairs + basicPublishingCredentialsPolicies: slot.?basicPublishingCredentialsPolicies ?? basicPublishingCredentialsPolicies + lock: slot.?lock ?? lock + privateEndpoints: slot.?privateEndpoints ?? [] + tags: slot.?tags ?? tags + clientCertEnabled: slot.?clientCertEnabled + clientCertExclusionPaths: slot.?clientCertExclusionPaths + clientCertMode: slot.?clientCertMode + cloningInfo: slot.?cloningInfo + containerSize: slot.?containerSize + customDomainVerificationId: slot.?customDomainVerificationId + dailyMemoryTimeQuota: slot.?dailyMemoryTimeQuota + enabled: slot.?enabled + enableTelemetry: slot.?enableTelemetry ?? enableTelemetry + hostNameSslStates: slot.?hostNameSslStates + hyperV: slot.?hyperV + publicNetworkAccess: slot.?publicNetworkAccess ?? ((!empty(slot.?privateEndpoints) || !empty(privateEndpoints)) + ? 'Disabled' + : 'Enabled') + redundancyMode: slot.?redundancyMode + vnetContentShareEnabled: slot.?vnetContentShareEnabled + vnetImagePullEnabled: slot.?vnetImagePullEnabled + vnetRouteAllEnabled: slot.?vnetRouteAllEnabled + hybridConnectionRelays: slot.?hybridConnectionRelays + } } -}] - -module app_basicPublishingCredentialsPolicies 'basic-publishing-credentials-policy/main.bicep' = [for (basicPublishingCredentialsPolicy, index) in (basicPublishingCredentialsPolicies ?? []): { - name: '${uniqueString(deployment().name, location)}-Site-Publish-Cred-${index}' - params: { - webAppName: app.name - name: basicPublishingCredentialsPolicy.name - allow: basicPublishingCredentialsPolicy.?allow - location: location +] + +module app_basicPublishingCredentialsPolicies 'basic-publishing-credentials-policy/main.bicep' = [ + for (basicPublishingCredentialsPolicy, index) in (basicPublishingCredentialsPolicies ?? []): { + name: '${uniqueString(deployment().name, location)}-Site-Publish-Cred-${index}' + params: { + webAppName: app.name + name: basicPublishingCredentialsPolicy.name + allow: basicPublishingCredentialsPolicy.?allow + location: location + } } -}] - -module app_hybridConnectionRelays 'hybrid-connection-namespace/relay/main.bicep' = [for (hybridConnectionRelay, index) in (hybridConnectionRelays ?? []): { - name: '${uniqueString(deployment().name, location)}-HybridConnectionRelay-${index}' - params: { - hybridConnectionResourceId: hybridConnectionRelay.resourceId - appName: app.name - sendKeyName: hybridConnectionRelay.?sendKeyName +] + +module app_hybridConnectionRelays 'hybrid-connection-namespace/relay/main.bicep' = [ + for (hybridConnectionRelay, index) in (hybridConnectionRelays ?? []): { + name: '${uniqueString(deployment().name, location)}-HybridConnectionRelay-${index}' + params: { + hybridConnectionResourceId: hybridConnectionRelay.resourceId + appName: app.name + sendKeyName: hybridConnectionRelay.?sendKeyName + } } -}] +] -resource app_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.' +resource app_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: app } - scope: app -} -resource app_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 - 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 +resource app_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 + 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 + } + scope: app } - scope: app -}] +] -resource app_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(app.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 +resource app_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(app.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: app } - scope: app -}] - -module app_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-App-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites'}-${index}' - properties: { - privateLinkServiceId: app.id - groupIds: [ - privateEndpoint.?service ?? 'sites' +] + +module app_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-App-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites'}-${index}' + properties: { + privateLinkServiceId: app.id + groupIds: [ + privateEndpoint.?service ?? 'sites' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites'}-${index}' - properties: { - privateLinkServiceId: app.id - groupIds: [ - privateEndpoint.?service ?? 'sites' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites'}-${index}' + properties: { + privateLinkServiceId: app.id + groupIds: [ + privateEndpoint.?service ?? 'sites' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] @description('The name of the site.') output name string = app.name @@ -424,7 +487,9 @@ output resourceGroupName string = resourceGroup().name output systemAssignedMIPrincipalId string = app.?identity.?principalId ?? '' @description('The principal ID of the system assigned identity of slots.') -output slotSystemAssignedMIPrincipalIds array = [for (slot, index) in (slots ?? []): app_slots[index].outputs.systemAssignedMIPrincipalId] +output slotSystemAssignedMIPrincipalIds array = [ + for (slot, index) in (slots ?? []): app_slots[index].outputs.systemAssignedMIPrincipalId +] @description('The location the resource was deployed into.') output location string = app.location diff --git a/avm/res/web/site/slot/config--appsettings/main.bicep b/avm/res/web/site/slot/config--appsettings/main.bicep index 6572451c58..679037db56 100644 --- a/avm/res/web/site/slot/config--appsettings/main.bicep +++ b/avm/res/web/site/slot/config--appsettings/main.bicep @@ -31,16 +31,22 @@ param appInsightResourceId string? @description('Optional. The app settings key-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING.') param appSettingsKeyValuePairs object? -var azureWebJobsValues = !empty(storageAccountResourceId) && !(storageAccountUseIdentityAuthentication) ? { - AzureWebJobsStorage: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};' -} : !empty(storageAccountResourceId) && storageAccountUseIdentityAuthentication ? union( - { AzureWebJobsStorage__accountName: storageAccount.name }, - { AzureWebJobsStorage__blobServiceUri: storageAccount.properties.primaryEndpoints.blob } -) : {} - -var appInsightsValues = !empty(appInsightResourceId) ? { - APPLICATIONINSIGHTS_CONNECTION_STRING: appInsight.properties.ConnectionString -} : {} +var azureWebJobsValues = !empty(storageAccountResourceId) && !(storageAccountUseIdentityAuthentication) + ? { + AzureWebJobsStorage: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};' + } + : !empty(storageAccountResourceId) && storageAccountUseIdentityAuthentication + ? union( + { AzureWebJobsStorage__accountName: storageAccount.name }, + { AzureWebJobsStorage__blobServiceUri: storageAccount.properties.primaryEndpoints.blob } + ) + : {} + +var appInsightsValues = !empty(appInsightResourceId) + ? { + APPLICATIONINSIGHTS_CONNECTION_STRING: appInsight.properties.ConnectionString + } + : {} var expandedAppSettings = union(appSettingsKeyValuePairs ?? {}, azureWebJobsValues, appInsightsValues) @@ -52,15 +58,20 @@ resource app 'Microsoft.Web/sites@2022-09-01' existing = { } } -resource appInsight 'Microsoft.Insights/components@2020-02-02' existing = if (!empty(appInsightResourceId)) { - name: last(split(appInsightResourceId ?? 'dummyName', '/')) - scope: resourceGroup(split(appInsightResourceId ?? '//', '/')[2], split(appInsightResourceId ?? '////', '/')[4]) -} +resource appInsight 'Microsoft.Insights/components@2020-02-02' existing = + if (!empty(appInsightResourceId)) { + name: last(split(appInsightResourceId ?? 'dummyName', '/')) + scope: resourceGroup(split(appInsightResourceId ?? '//', '/')[2], split(appInsightResourceId ?? '////', '/')[4]) + } -resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = if (!empty(storageAccountResourceId)) { - name: last(split(storageAccountResourceId ?? 'dummyName', '/'))! - scope: resourceGroup(split(storageAccountResourceId ?? '//', '/')[2], split(storageAccountResourceId ?? '////', '/')[4]) -} +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = + if (!empty(storageAccountResourceId)) { + name: last(split(storageAccountResourceId ?? 'dummyName', '/'))! + scope: resourceGroup( + split(storageAccountResourceId ?? '//', '/')[2], + split(storageAccountResourceId ?? '////', '/')[4] + ) + } resource slotSettings 'Microsoft.Web/sites/slots/config@2022-09-01' = { name: 'appsettings' diff --git a/avm/res/web/site/slot/hybrid-connection-namespace/relay/main.bicep b/avm/res/web/site/slot/hybrid-connection-namespace/relay/main.bicep index 5ffc44a797..6e85a49f08 100644 --- a/avm/res/web/site/slot/hybrid-connection-namespace/relay/main.bicep +++ b/avm/res/web/site/slot/hybrid-connection-namespace/relay/main.bicep @@ -31,7 +31,13 @@ resource hybridConnectionRelay 'Microsoft.Web/sites/slots/hybridConnectionNamesp name: '${appName}/${slotName}/${namespace.name}/${namespace::hybridConnection.name}' properties: { serviceBusNamespace: namespace.name - serviceBusSuffix: split(substring(namespace.properties.serviceBusEndpoint, indexOf(namespace.properties.serviceBusEndpoint, '.servicebus')), ':')[0] + serviceBusSuffix: split( + substring( + namespace.properties.serviceBusEndpoint, + indexOf(namespace.properties.serviceBusEndpoint, '.servicebus') + ), + ':' + )[0] relayName: namespace::hybridConnection.name relayArmUri: namespace::hybridConnection.id hostname: split(json(namespace::hybridConnection.properties.userMetadata)[0].value, ':')[0] diff --git a/avm/res/web/site/slot/main.bicep b/avm/res/web/site/slot/main.bicep index b5b5cf1354..209954c101 100644 --- a/avm/res/web/site/slot/main.bicep +++ b/avm/res/web/site/slot/main.bicep @@ -149,22 +149,45 @@ param vnetRouteAllEnabled bool = false @description('Optional. Names of hybrid connection relays to connect app with.') param hybridConnectionRelays array? -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null var builtInRoleNames = { - 'App Compliance Automation Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f37683f-2463-46b6-9ce7-9b788b988ba2') + 'App Compliance Automation Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0f37683f-2463-46b6-9ce7-9b788b988ba2' + ) 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') - 'Web Plan Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b') - 'Website Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'de139f84-1756-47ae-9be6-808fbbe84772') + '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' + ) + 'Web Plan Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b' + ) + 'Website Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'de139f84-1756-47ae-9be6-808fbbe84772' + ) } resource app 'Microsoft.Web/sites@2021-03-01' existing = { @@ -182,9 +205,11 @@ resource slot 'Microsoft.Web/sites/slots@2022-09-01' = { serverFarmId: serverFarmResourceId clientAffinityEnabled: clientAffinityEnabled httpsOnly: httpsOnly - hostingEnvironmentProfile: !empty(appServiceEnvironmentResourceId) ? { - id: appServiceEnvironmentResourceId - } : null + hostingEnvironmentProfile: !empty(appServiceEnvironmentResourceId) + ? { + id: appServiceEnvironmentResourceId + } + : null storageAccountRequired: storageAccountRequired keyVaultReferenceIdentity: keyVaultAccessIdentityResourceId virtualNetworkSubnetId: virtualNetworkSubnetId @@ -207,136 +232,167 @@ resource slot 'Microsoft.Web/sites/slots@2022-09-01' = { } } -module slot_appsettings 'config--appsettings/main.bicep' = if (!empty(appSettingsKeyValuePairs)) { - name: '${uniqueString(deployment().name, location)}-Slot-${name}-Config-AppSettings' - params: { - slotName: slot.name - appName: app.name - kind: kind - storageAccountResourceId: storageAccountResourceId - storageAccountUseIdentityAuthentication: storageAccountUseIdentityAuthentication - appInsightResourceId: appInsightResourceId - appSettingsKeyValuePairs: appSettingsKeyValuePairs +module slot_appsettings 'config--appsettings/main.bicep' = + if (!empty(appSettingsKeyValuePairs)) { + name: '${uniqueString(deployment().name, location)}-Slot-${name}-Config-AppSettings' + params: { + slotName: slot.name + appName: app.name + kind: kind + storageAccountResourceId: storageAccountResourceId + storageAccountUseIdentityAuthentication: storageAccountUseIdentityAuthentication + appInsightResourceId: appInsightResourceId + appSettingsKeyValuePairs: appSettingsKeyValuePairs + } } -} -module slot_authsettingsv2 'config--authsettingsv2/main.bicep' = if (!empty(authSettingV2Configuration)) { - name: '${uniqueString(deployment().name, location)}-Slot-${name}-Config-AuthSettingsV2' - params: { - slotName: slot.name - appName: app.name - kind: kind - authSettingV2Configuration: authSettingV2Configuration ?? {} +module slot_authsettingsv2 'config--authsettingsv2/main.bicep' = + if (!empty(authSettingV2Configuration)) { + name: '${uniqueString(deployment().name, location)}-Slot-${name}-Config-AuthSettingsV2' + params: { + slotName: slot.name + appName: app.name + kind: kind + authSettingV2Configuration: authSettingV2Configuration ?? {} + } } -} -module slot_basicPublishingCredentialsPolicies 'basic-publishing-credentials-policy/main.bicep' = [for (basicPublishingCredentialsPolicy, index) in (basicPublishingCredentialsPolicies ?? []): { - name: '${uniqueString(deployment().name, location)}-Slot-Publish-Cred-${index}' - params: { - appName: app.name - slotName: slot.name - name: basicPublishingCredentialsPolicy.name - allow: basicPublishingCredentialsPolicy.?allow - location: location +module slot_basicPublishingCredentialsPolicies 'basic-publishing-credentials-policy/main.bicep' = [ + for (basicPublishingCredentialsPolicy, index) in (basicPublishingCredentialsPolicies ?? []): { + name: '${uniqueString(deployment().name, location)}-Slot-Publish-Cred-${index}' + params: { + appName: app.name + slotName: slot.name + name: basicPublishingCredentialsPolicy.name + allow: basicPublishingCredentialsPolicy.?allow + location: location + } } -}] -module slot_hybridConnectionRelays 'hybrid-connection-namespace/relay/main.bicep' = [for (hybridConnectionRelay, index) in (hybridConnectionRelays ?? []): { - name: '${uniqueString(deployment().name, location)}-Slot-HybridConnectionRelay-${index}' - params: { - hybridConnectionResourceId: hybridConnectionRelay.resourceId - appName: app.name - slotName: slot.name - sendKeyName: hybridConnectionRelay.?sendKeyName +] +module slot_hybridConnectionRelays 'hybrid-connection-namespace/relay/main.bicep' = [ + for (hybridConnectionRelay, index) in (hybridConnectionRelays ?? []): { + name: '${uniqueString(deployment().name, location)}-Slot-HybridConnectionRelay-${index}' + params: { + hybridConnectionResourceId: hybridConnectionRelay.resourceId + appName: app.name + slotName: slot.name + sendKeyName: hybridConnectionRelay.?sendKeyName + } } -}] +] -resource slot_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.' +resource slot_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: slot } - scope: slot -} -resource slot_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 - 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 +resource slot_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 + 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 + } + scope: slot } - scope: slot -}] +] -resource slot_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(slot.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 +resource slot_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(slot.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: slot } - scope: slot -}] - -module slot_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Slot-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(app.id, '/'))}-${name}-${privateEndpoint.?service ?? 'sites-${slot.name}'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites-${slot.name}'}-${index}' - properties: { - privateLinkServiceId: app.id // Must be set on the WebApp and not the slot - groupIds: [ - privateEndpoint.?service ?? 'sites-${slot.name}' // The required syntax to create the private endpoint for a specific slot +] + +module slot_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-Slot-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(app.id, '/'))}-${name}-${privateEndpoint.?service ?? 'sites-${slot.name}'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites-${slot.name}'}-${index}' + properties: { + privateLinkServiceId: app.id // Must be set on the WebApp and not the slot + groupIds: [ + privateEndpoint.?service ?? 'sites-${slot.name}' // The required syntax to create the private endpoint for a specific slot + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites-${slot.name}'}-${index}' - properties: { - privateLinkServiceId: app.id // Must be set on the WebApp and not the slot - groupIds: [ - privateEndpoint.?service ?? 'sites-${slot.name}' // The required syntax to create the private endpoint for a specific slot + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites-${slot.name}'}-${index}' + properties: { + privateLinkServiceId: app.id // Must be set on the WebApp and not the slot + groupIds: [ + privateEndpoint.?service ?? 'sites-${slot.name}' // The required syntax to create the private endpoint for a specific slot + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] @description('The name of the slot.') output name string = slot.name diff --git a/avm/res/web/site/tests/e2e/functionApp.defaults/dependencies.bicep b/avm/res/web/site/tests/e2e/functionApp.defaults/dependencies.bicep index cd93e7ed3f..dd34e10b1c 100644 --- a/avm/res/web/site/tests/e2e/functionApp.defaults/dependencies.bicep +++ b/avm/res/web/site/tests/e2e/functionApp.defaults/dependencies.bicep @@ -5,16 +5,16 @@ param location string = resourceGroup().location param serverFarmName string resource serverFarm 'Microsoft.Web/serverfarms@2022-03-01' = { - name: serverFarmName - location: location - sku: { - name: 'S1' - tier: 'Standard' - size: 'S1' - family: 'S' - capacity: 1 - } - properties: {} + name: serverFarmName + location: location + sku: { + name: 'S1' + tier: 'Standard' + size: 'S1' + family: 'S' + capacity: 1 + } + properties: {} } @description('The resource ID of the created Server Farm.') diff --git a/avm/res/web/site/tests/e2e/functionApp.defaults/main.test.bicep b/avm/res/web/site/tests/e2e/functionApp.defaults/main.test.bicep index a9d3e90e3a..49f241e3f0 100644 --- a/avm/res/web/site/tests/e2e/functionApp.defaults/main.test.bicep +++ b/avm/res/web/site/tests/e2e/functionApp.defaults/main.test.bicep @@ -45,19 +45,21 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - kind: 'functionapp' - serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId - siteConfig: { - alwaysOn: true +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 + kind: 'functionapp' + serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId + siteConfig: { + alwaysOn: true + } } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/web/site/tests/e2e/functionApp.max/main.test.bicep b/avm/res/web/site/tests/e2e/functionApp.max/main.test.bicep index c336ca84ad..4ec82011d0 100644 --- a/avm/res/web/site/tests/e2e/functionApp.max/main.test.bicep +++ b/avm/res/web/site/tests/e2e/functionApp.max/main.test.bicep @@ -65,169 +65,174 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // // For the below test case, please consider the guidelines described here: https://github.com/Azure/ResourceModules/wiki/Getting%20started%20-%20Scenario%202%20Onboard%20module%20library%20and%20CI%20environment#microsoftwebsites @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 - kind: 'functionapp' - serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId - appInsightResourceId: nestedDependencies.outputs.applicationInsightsResourceId - appSettingsKeyValuePairs: { - AzureFunctionsJobHost__logging__logLevel__default: 'Trace' - EASYAUTH_SECRET: 'https://${namePrefix}-KeyVault${environment().suffixes.keyvaultDns}/secrets/Modules-Test-SP-Password' - FUNCTIONS_EXTENSION_VERSION: '~4' - FUNCTIONS_WORKER_RUNTIME: 'dotnet' - } - authSettingV2Configuration: { - globalValidation: { - requireAuthentication: true - unauthenticatedClientAction: 'Return401' +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 + kind: 'functionapp' + serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId + appInsightResourceId: nestedDependencies.outputs.applicationInsightsResourceId + appSettingsKeyValuePairs: { + AzureFunctionsJobHost__logging__logLevel__default: 'Trace' + EASYAUTH_SECRET: 'https://${namePrefix}-KeyVault${environment().suffixes.keyvaultDns}/secrets/Modules-Test-SP-Password' + FUNCTIONS_EXTENSION_VERSION: '~4' + FUNCTIONS_WORKER_RUNTIME: 'dotnet' } - httpSettings: { - forwardProxy: { - convention: 'NoProxy' - } - requireHttps: true - routes: { - apiPrefix: '/.auth' + authSettingV2Configuration: { + globalValidation: { + requireAuthentication: true + unauthenticatedClientAction: 'Return401' } - } - identityProviders: { - azureActiveDirectory: { - enabled: true - login: { - disableWWWAuthenticate: false + httpSettings: { + forwardProxy: { + convention: 'NoProxy' } - registration: { - clientId: 'd874dd2f-2032-4db1-a053-f0ec243685aa' - clientSecretSettingName: 'EASYAUTH_SECRET' - openIdIssuer: 'https://sts.windows.net/${tenant().tenantId}/v2.0/' + requireHttps: true + routes: { + apiPrefix: '/.auth' } - validation: { - allowedAudiences: [ - 'api://d874dd2f-2032-4db1-a053-f0ec243685aa' - ] - defaultAuthorizationPolicy: { - allowedPrincipals: {} + } + identityProviders: { + azureActiveDirectory: { + enabled: true + login: { + disableWWWAuthenticate: false + } + registration: { + clientId: 'd874dd2f-2032-4db1-a053-f0ec243685aa' + clientSecretSettingName: 'EASYAUTH_SECRET' + openIdIssuer: 'https://sts.windows.net/${tenant().tenantId}/v2.0/' + } + validation: { + allowedAudiences: [ + 'api://d874dd2f-2032-4db1-a053-f0ec243685aa' + ] + defaultAuthorizationPolicy: { + allowedPrincipals: {} + } + jwtClaimChecks: {} } - jwtClaimChecks: {} } } - } - login: { - allowedExternalRedirectUrls: [ - 'string' - ] - cookieExpiration: { - convention: 'FixedTime' - timeToExpiration: '08:00:00' - } - nonce: { - nonceExpirationInterval: '00:05:00' - validateNonce: true + login: { + allowedExternalRedirectUrls: [ + 'string' + ] + cookieExpiration: { + convention: 'FixedTime' + timeToExpiration: '08:00:00' + } + nonce: { + nonceExpirationInterval: '00:05:00' + validateNonce: true + } + preserveUrlFragmentsForLogins: false + routes: {} + tokenStore: { + azureBlobStorage: {} + enabled: true + fileSystem: {} + tokenRefreshExtensionHours: 72 + } } - preserveUrlFragmentsForLogins: false - routes: {} - tokenStore: { - azureBlobStorage: {} + platform: { enabled: true - fileSystem: {} - tokenRefreshExtensionHours: 72 + runtimeVersion: '~1' } } - platform: { - enabled: true - runtimeVersion: '~1' - } - } - basicPublishingCredentialsPolicies: [ - { - name: 'ftp' - allow: false - } - { - name: 'scm' - allow: false + basicPublishingCredentialsPolicies: [ + { + name: 'ftp' + allow: false + } + { + name: 'scm' + allow: false + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + } + ] + 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' + } + ] + keyVaultAccessIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + siteConfig: { + alwaysOn: true + use32BitWorkerProcess: false } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId + storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + storageAccountUseIdentityAuthentication: true + managedIdentities: { + systemAssigned: true + 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' - } - ] - keyVaultAccessIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId - siteConfig: { - alwaysOn: true - use32BitWorkerProcess: false - } - storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - storageAccountUseIdentityAuthentication: true - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId + hybridConnectionRelays: [ + { + resourceId: nestedDependencies.outputs.hybridConnectionResourceId + sendKeyName: 'defaultSender' + } ] } - hybridConnectionRelays: [ - { - resourceId: nestedDependencies.outputs.hybridConnectionResourceId - sendKeyName: 'defaultSender' - } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/web/site/tests/e2e/waf-aligned/main.test.bicep b/avm/res/web/site/tests/e2e/waf-aligned/main.test.bicep index 118c87cf79..cce9097635 100644 --- a/avm/res/web/site/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/web/site/tests/e2e/waf-aligned/main.test.bicep @@ -58,51 +58,53 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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 - kind: 'app' - serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + kind: 'app' + serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + httpsOnly: true + siteConfig: { + healthCheckPath: '/healthz' + alwaysOn: true + metadata: [ + { + name: 'CURRENT_STACK' + value: 'dotnetcore' + } + ] } - ] - httpsOnly: true - siteConfig: { - healthCheckPath: '/healthz' - alwaysOn: true - metadata: [ + basicPublishingCredentialsPolicies: [ + { + name: 'ftp' + allow: false + } { - name: 'CURRENT_STACK' - value: 'dotnetcore' + name: 'scm' + allow: false } ] + scmSiteAlsoStopped: true + vnetContentShareEnabled: true + vnetImagePullEnabled: true + vnetRouteAllEnabled: true + publicNetworkAccess: 'Disabled' } - basicPublishingCredentialsPolicies: [ - { - name: 'ftp' - allow: false - } - { - name: 'scm' - allow: false - } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] - scmSiteAlsoStopped: true - vnetContentShareEnabled: true - vnetImagePullEnabled: true - vnetRouteAllEnabled: true - publicNetworkAccess: 'Disabled' } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/web/site/tests/e2e/webApp.defaults/dependencies.bicep b/avm/res/web/site/tests/e2e/webApp.defaults/dependencies.bicep index cd93e7ed3f..dd34e10b1c 100644 --- a/avm/res/web/site/tests/e2e/webApp.defaults/dependencies.bicep +++ b/avm/res/web/site/tests/e2e/webApp.defaults/dependencies.bicep @@ -5,16 +5,16 @@ param location string = resourceGroup().location param serverFarmName string resource serverFarm 'Microsoft.Web/serverfarms@2022-03-01' = { - name: serverFarmName - location: location - sku: { - name: 'S1' - tier: 'Standard' - size: 'S1' - family: 'S' - capacity: 1 - } - properties: {} + name: serverFarmName + location: location + sku: { + name: 'S1' + tier: 'Standard' + size: 'S1' + family: 'S' + capacity: 1 + } + properties: {} } @description('The resource ID of the created Server Farm.') diff --git a/avm/res/web/site/tests/e2e/webApp.defaults/main.test.bicep b/avm/res/web/site/tests/e2e/webApp.defaults/main.test.bicep index baecb8fbaf..c4b0bce825 100644 --- a/avm/res/web/site/tests/e2e/webApp.defaults/main.test.bicep +++ b/avm/res/web/site/tests/e2e/webApp.defaults/main.test.bicep @@ -45,21 +45,23 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - kind: 'app' - serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId - siteConfig: { - healthCheckPath: '/healthz' - alwaysOn: true +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 + kind: 'app' + serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId + siteConfig: { + healthCheckPath: '/healthz' + alwaysOn: true + } } + + dependsOn: [ + nestedDependencies + ] } - - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/web/site/tests/e2e/webApp.max/main.test.bicep b/avm/res/web/site/tests/e2e/webApp.max/main.test.bicep index 07b3cf2548..434166b1e2 100644 --- a/avm/res/web/site/tests/e2e/webApp.max/main.test.bicep +++ b/avm/res/web/site/tests/e2e/webApp.max/main.test.bicep @@ -63,196 +63,203 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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 - kind: 'app' - serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + kind: 'app' + serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + httpsOnly: true + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - httpsOnly: true - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - slots: [ - { - name: 'slot1' - diagnosticSettings: [ - { - name: 'customSetting' - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + slots: [ + { + name: 'slot1' + diagnosticSettings: [ + { + name: 'customSetting' + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - service: 'sites-slot1' - } - ] - basicPublishingCredentialsPolicies: [ - { - name: 'ftp' - allow: false - } - { - name: 'scm' - allow: false - } - ] - 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: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + service: 'sites-slot1' + } + ] + basicPublishingCredentialsPolicies: [ + { + name: 'ftp' + allow: false + } + { + name: 'scm' + allow: false + } + ] + 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' + } + ] + siteConfig: { + alwaysOn: true + metadata: [ + { + name: 'CURRENT_STACK' + value: 'dotnetcore' + } + ] } - ] - siteConfig: { - alwaysOn: true - metadata: [ + storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + storageAccountUseIdentityAuthentication: true + hybridConnectionRelays: [ { - name: 'CURRENT_STACK' - value: 'dotnetcore' + resourceId: nestedDependencies.outputs.hybridConnectionResourceId + sendKeyName: 'defaultSender' } ] } - storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - storageAccountUseIdentityAuthentication: true - hybridConnectionRelays: [ - { - resourceId: nestedDependencies.outputs.hybridConnectionResourceId - sendKeyName: 'defaultSender' - } - ] - } - { - name: 'slot2' - basicPublishingCredentialsPolicies: [ - { - name: 'ftp' + { + name: 'slot2' + basicPublishingCredentialsPolicies: [ + { + name: 'ftp' + } + { + name: 'scm' + } + ] + storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + storageAccountUseIdentityAuthentication: true + } + ] + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } + } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + } + ] + 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' + } + ] + siteConfig: { + alwaysOn: true + metadata: [ { - name: 'scm' + name: 'CURRENT_STACK' + value: 'dotnetcore' } ] - storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - storageAccountUseIdentityAuthentication: true - } - ] - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId + storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + storageAccountUseIdentityAuthentication: true + managedIdentities: { + systemAssigned: true + 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' - } - ] - siteConfig: { - alwaysOn: true - metadata: [ + basicPublishingCredentialsPolicies: [ + { + name: 'ftp' + allow: false + } { - name: 'CURRENT_STACK' - value: 'dotnetcore' + name: 'scm' + allow: false } ] - } - storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - storageAccountUseIdentityAuthentication: true - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId + hybridConnectionRelays: [ + { + resourceId: nestedDependencies.outputs.hybridConnectionResourceId + sendKeyName: 'defaultSender' + } ] + scmSiteAlsoStopped: true + vnetContentShareEnabled: true + vnetImagePullEnabled: true + vnetRouteAllEnabled: true + publicNetworkAccess: 'Disabled' } - basicPublishingCredentialsPolicies: [ - { - name: 'ftp' - allow: false - } - { - name: 'scm' - allow: false - } - - ] - hybridConnectionRelays: [ - { - resourceId: nestedDependencies.outputs.hybridConnectionResourceId - sendKeyName: 'defaultSender' - } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] - scmSiteAlsoStopped: true - vnetContentShareEnabled: true - vnetImagePullEnabled: true - vnetRouteAllEnabled: true - publicNetworkAccess: 'Disabled' } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/web/site/tests/e2e/webAppLinux.defaults/dependencies.bicep b/avm/res/web/site/tests/e2e/webAppLinux.defaults/dependencies.bicep index cc8e14c136..25017acf7b 100644 --- a/avm/res/web/site/tests/e2e/webAppLinux.defaults/dependencies.bicep +++ b/avm/res/web/site/tests/e2e/webAppLinux.defaults/dependencies.bicep @@ -5,18 +5,18 @@ param location string = resourceGroup().location param serverFarmName string resource serverFarm 'Microsoft.Web/serverfarms@2022-03-01' = { - name: serverFarmName - location: location - sku: { - name: 'S1' - tier: 'Standard' - size: 'S1' - family: 'S' - capacity: 1 - } - properties: { - reserved: true - } + name: serverFarmName + location: location + sku: { + name: 'S1' + tier: 'Standard' + size: 'S1' + family: 'S' + capacity: 1 + } + properties: { + reserved: true + } } @description('The resource ID of the created Server Farm.') diff --git a/avm/res/web/site/tests/e2e/webAppLinux.defaults/main.test.bicep b/avm/res/web/site/tests/e2e/webAppLinux.defaults/main.test.bicep index 61de2c7c89..d61b339989 100644 --- a/avm/res/web/site/tests/e2e/webAppLinux.defaults/main.test.bicep +++ b/avm/res/web/site/tests/e2e/webAppLinux.defaults/main.test.bicep @@ -45,16 +45,18 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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 - kind: 'app,linux' - serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId +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 + kind: 'app,linux' + serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId + } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/web/site/tests/e2e/webAppLinux.max/main.test.bicep b/avm/res/web/site/tests/e2e/webAppLinux.max/main.test.bicep index 41754c557b..ab31f0adb6 100644 --- a/avm/res/web/site/tests/e2e/webAppLinux.max/main.test.bicep +++ b/avm/res/web/site/tests/e2e/webAppLinux.max/main.test.bicep @@ -63,196 +63,203 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // 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 - kind: 'app,linux' - serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId +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 + kind: 'app,linux' + serverFarmResourceId: nestedDependencies.outputs.serverFarmResourceId + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + httpsOnly: true + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - ] - httpsOnly: true - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - slots: [ - { - name: 'slot1' - diagnosticSettings: [ - { - name: 'customSetting' - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + slots: [ + { + name: 'slot1' + diagnosticSettings: [ + { + name: 'customSetting' + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - service: 'sites-slot1' - } - ] - basicPublishingCredentialsPolicies: [ - { - name: 'ftp' - allow: false - } - { - name: 'scm' - allow: false - } - ] - 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: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + service: 'sites-slot1' + } + ] + basicPublishingCredentialsPolicies: [ + { + name: 'ftp' + allow: false + } + { + name: 'scm' + allow: false + } + ] + 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' + } + ] + siteConfig: { + alwaysOn: true + metadata: [ + { + name: 'CURRENT_STACK' + value: 'dotnetcore' + } + ] } - ] - siteConfig: { - alwaysOn: true - metadata: [ + storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + storageAccountUseIdentityAuthentication: true + hybridConnectionRelays: [ { - name: 'CURRENT_STACK' - value: 'dotnetcore' + resourceId: nestedDependencies.outputs.hybridConnectionResourceId + sendKeyName: 'defaultSender' } ] } - storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - storageAccountUseIdentityAuthentication: true - hybridConnectionRelays: [ - { - resourceId: nestedDependencies.outputs.hybridConnectionResourceId - sendKeyName: 'defaultSender' - } - ] - } - { - name: 'slot2' - basicPublishingCredentialsPolicies: [ - { - name: 'ftp' + { + name: 'slot2' + basicPublishingCredentialsPolicies: [ + { + name: 'ftp' + } + { + name: 'scm' + } + ] + storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + storageAccountUseIdentityAuthentication: true + } + ] + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } + } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + } + ] + 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' + } + ] + siteConfig: { + alwaysOn: true + metadata: [ { - name: 'scm' + name: 'CURRENT_STACK' + value: 'dotnetcore' } ] - storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - storageAccountUseIdentityAuthentication: true - } - ] - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId + storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + storageAccountUseIdentityAuthentication: true + managedIdentities: { + systemAssigned: true + 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' - } - ] - siteConfig: { - alwaysOn: true - metadata: [ + basicPublishingCredentialsPolicies: [ + { + name: 'ftp' + allow: false + } { - name: 'CURRENT_STACK' - value: 'dotnetcore' + name: 'scm' + allow: false } ] - } - storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId - storageAccountUseIdentityAuthentication: true - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId + hybridConnectionRelays: [ + { + resourceId: nestedDependencies.outputs.hybridConnectionResourceId + sendKeyName: 'defaultSender' + } ] + scmSiteAlsoStopped: true + vnetContentShareEnabled: true + vnetImagePullEnabled: true + vnetRouteAllEnabled: true + publicNetworkAccess: 'Disabled' } - basicPublishingCredentialsPolicies: [ - { - name: 'ftp' - allow: false - } - { - name: 'scm' - allow: false - } - - ] - hybridConnectionRelays: [ - { - resourceId: nestedDependencies.outputs.hybridConnectionResourceId - sendKeyName: 'defaultSender' - } + dependsOn: [ + nestedDependencies + diagnosticDependencies ] - scmSiteAlsoStopped: true - vnetContentShareEnabled: true - vnetImagePullEnabled: true - vnetRouteAllEnabled: true - publicNetworkAccess: 'Disabled' } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/web/static-site/config/main.json b/avm/res/web/static-site/config/main.json index 63676de877..9e22c932e8 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.25.53.49325", - "templateHash": "17053065769415076723" + "version": "0.26.54.24096", + "templateHash": "4029344815380998105" }, "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 c208b7bc10..c2215009ab 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.25.53.49325", - "templateHash": "3581008276102913900" + "version": "0.26.54.24096", + "templateHash": "9170296310450777701" }, "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 6a5aba4615..5a49c3bbe7 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.25.53.49325", - "templateHash": "3673239578041396478" + "version": "0.26.54.24096", + "templateHash": "15307923419105312167" }, "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.bicep b/avm/res/web/static-site/main.bicep index 92bb14bee0..9ba884ce25 100644 --- a/avm/res/web/static-site/main.bicep +++ b/avm/res/web/static-site/main.bicep @@ -85,40 +85,61 @@ param functionAppSettings object = {} @description('Optional. The custom domains associated with this static site. The deployment will fail as long as the validation records are not present.') param customDomains array = [] -var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } - -var identity = !empty(managedIdentities) ? { - type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) - userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null -} : null +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : 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') - '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') - 'Web Plan Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b') - 'Website Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'de139f84-1756-47ae-9be6-808fbbe84772') + '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' + ) + 'Web Plan Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b' + ) + 'Website Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'de139f84-1756-47ae-9be6-808fbbe84772' + ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.web-staticSite.${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.res.web-staticSite.${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 staticSite 'Microsoft.Web/staticSites@2021-03-01' = { name: name @@ -142,106 +163,132 @@ resource staticSite 'Microsoft.Web/staticSites@2021-03-01' = { } } -module staticSite_linkedBackend 'linked-backend/main.bicep' = if (!empty(linkedBackend)) { - name: '${uniqueString(deployment().name, location)}-StaticSite-UserDefinedFunction' - params: { - staticSiteName: staticSite.name - backendResourceId: linkedBackend.resourceId - region: contains(linkedBackend, 'location') ? linkedBackend.location : location +module staticSite_linkedBackend 'linked-backend/main.bicep' = + if (!empty(linkedBackend)) { + name: '${uniqueString(deployment().name, location)}-StaticSite-UserDefinedFunction' + params: { + staticSiteName: staticSite.name + backendResourceId: linkedBackend.resourceId + region: contains(linkedBackend, 'location') ? linkedBackend.location : location + } } -} -module staticSite_appSettings 'config/main.bicep' = if (!empty(appSettings)) { - name: '${uniqueString(deployment().name, location)}-StaticSite-appSettings' - params: { - kind: 'appsettings' - staticSiteName: staticSite.name - properties: appSettings +module staticSite_appSettings 'config/main.bicep' = + if (!empty(appSettings)) { + name: '${uniqueString(deployment().name, location)}-StaticSite-appSettings' + params: { + kind: 'appsettings' + staticSiteName: staticSite.name + properties: appSettings + } } -} -module staticSite_functionAppSettings 'config/main.bicep' = if (!empty(functionAppSettings)) { - name: '${uniqueString(deployment().name, location)}-StaticSite-functionAppSettings' - params: { - kind: 'functionappsettings' - staticSiteName: staticSite.name - properties: functionAppSettings +module staticSite_functionAppSettings 'config/main.bicep' = + if (!empty(functionAppSettings)) { + name: '${uniqueString(deployment().name, location)}-StaticSite-functionAppSettings' + params: { + kind: 'functionappsettings' + staticSiteName: staticSite.name + properties: functionAppSettings + } } -} -module staticSite_customDomains 'custom-domain/main.bicep' = [for (customDomain, index) in customDomains: { - name: '${uniqueString(deployment().name, location)}-StaticSite-customDomains-${index}' - params: { - name: customDomain - staticSiteName: staticSite.name - validationMethod: indexOf(customDomain, '.') == lastIndexOf(customDomain, '.') ? 'dns-txt-token' : 'cname-delegation' +module staticSite_customDomains 'custom-domain/main.bicep' = [ + for (customDomain, index) in customDomains: { + name: '${uniqueString(deployment().name, location)}-StaticSite-customDomains-${index}' + params: { + name: customDomain + staticSiteName: staticSite.name + validationMethod: indexOf(customDomain, '.') == lastIndexOf(customDomain, '.') + ? 'dns-txt-token' + : 'cname-delegation' + } } -}] +] -resource staticSite_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.' +resource staticSite_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: staticSite } - scope: staticSite -} -resource staticSite_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(staticSite.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 +resource staticSite_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(staticSite.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: staticSite } - scope: staticSite -}] - -module staticSite_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-StaticSite-PrivateEndpoint-${index}' - params: { - name: privateEndpoint.?name ?? 'pep-${last(split(staticSite.id, '/'))}-${privateEndpoint.?service ?? 'staticSites'}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(staticSite.id, '/'))}-${privateEndpoint.?service ?? 'staticSites'}-${index}' - properties: { - privateLinkServiceId: staticSite.id - groupIds: [ - privateEndpoint.?service ?? 'staticSites' +] + +module staticSite_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ + for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-StaticSite-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(staticSite.id, '/'))}-${privateEndpoint.?service ?? 'staticSites'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(staticSite.id, '/'))}-${privateEndpoint.?service ?? 'staticSites'}-${index}' + properties: { + privateLinkServiceId: staticSite.id + groupIds: [ + privateEndpoint.?service ?? 'staticSites' + ] + } + } ] - } - } - ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ - { - name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(staticSite.id, '/'))}-${privateEndpoint.?service ?? 'staticSites'}-${index}' - properties: { - privateLinkServiceId: staticSite.id - groupIds: [ - privateEndpoint.?service ?? 'staticSites' + : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(staticSite.id, '/'))}-${privateEndpoint.?service ?? 'staticSites'}-${index}' + properties: { + privateLinkServiceId: staticSite.id + groupIds: [ + privateEndpoint.?service ?? 'staticSites' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } ] - requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' - } - } - ] : null - 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 - customDnsConfigs: privateEndpoint.?customDnsConfigs - ipConfigurations: privateEndpoint.?ipConfigurations - applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds - customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + : null + 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 + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } } -}] +] @description('The name of the static site.') output name string = staticSite.name diff --git a/avm/res/web/static-site/main.json b/avm/res/web/static-site/main.json index 6d473d52c2..49bae2b6a6 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.25.53.49325", - "templateHash": "18245734514085730321" + "version": "0.26.54.24096", + "templateHash": "7529430437285380768" }, "name": "Static Web Apps", "description": "This module deploys a Static Web App.", @@ -596,8 +596,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3673239578041396478" + "version": "0.26.54.24096", + "templateHash": "15307923419105312167" }, "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.", @@ -698,8 +698,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17053065769415076723" + "version": "0.26.54.24096", + "templateHash": "4029344815380998105" }, "name": "Static Web App Site Config", "description": "This module deploys a Static Web App Site Config.", @@ -793,8 +793,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17053065769415076723" + "version": "0.26.54.24096", + "templateHash": "4029344815380998105" }, "name": "Static Web App Site Config", "description": "This module deploys a Static Web App Site Config.", @@ -889,8 +889,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3581008276102913900" + "version": "0.26.54.24096", + "templateHash": "9170296310450777701" }, "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/tests/e2e/defaults/main.test.bicep b/avm/res/web/static-site/tests/e2e/defaults/main.test.bicep index 750c86d508..255a33dba4 100644 --- a/avm/res/web/static-site/tests/e2e/defaults/main.test.bicep +++ b/avm/res/web/static-site/tests/e2e/defaults/main.test.bicep @@ -36,11 +36,13 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @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 +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/web/static-site/tests/e2e/max/main.test.bicep b/avm/res/web/static-site/tests/e2e/max/main.test.bicep index 4db79418e9..45de7cf720 100644 --- a/avm/res/web/static-site/tests/e2e/max/main.test.bicep +++ b/avm/res/web/static-site/tests/e2e/max/main.test.bicep @@ -48,80 +48,85 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - allowConfigFileUpdates: true - enterpriseGradeCdnStatus: 'Disabled' - location: resourceLocation - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + allowConfigFileUpdates: true + enterpriseGradeCdnStatus: 'Disabled' + location: resourceLocation + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' } - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + } + ] + 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' + } + ] + sku: 'Standard' + stagingEnvironmentPolicy: 'Enabled' + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId ] } - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + appSettings: { + foo: 'bar' + setting: 1 } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + functionAppSettings: { + foo: 'bar' + setting: 1 } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' + linkedBackend: { + resourceId: nestedDependencies.outputs.siteResourceId + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - sku: 'Standard' - stagingEnvironmentPolicy: 'Enabled' - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - appSettings: { - foo: 'bar' - setting: 1 - } - functionAppSettings: { - foo: 'bar' - setting: 1 - } - linkedBackend: { - resourceId: nestedDependencies.outputs.siteResourceId - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/res/web/static-site/tests/e2e/waf-aligned/main.test.bicep b/avm/res/web/static-site/tests/e2e/waf-aligned/main.test.bicep index e95bd5db2b..77c04b71b2 100644 --- a/avm/res/web/static-site/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/web/static-site/tests/e2e/waf-aligned/main.test.bicep @@ -47,51 +47,53 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // @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' - allowConfigFileUpdates: true - enterpriseGradeCdnStatus: 'Disabled' - location: resourceLocation - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - privateEndpoints: [ - { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + allowConfigFileUpdates: true + enterpriseGradeCdnStatus: 'Disabled' + location: resourceLocation + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } + ] + sku: 'Standard' + stagingEnvironmentPolicy: 'Enabled' + appSettings: { + foo: 'bar' + setting: 1 + } + functionAppSettings: { + foo: 'bar' + setting: 1 + } + linkedBackend: { + resourceId: nestedDependencies.outputs.siteResourceId + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - sku: 'Standard' - stagingEnvironmentPolicy: 'Enabled' - appSettings: { - foo: 'bar' - setting: 1 - } - functionAppSettings: { - foo: 'bar' - setting: 1 - } - linkedBackend: { - resourceId: nestedDependencies.outputs.siteResourceId - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + ] } - dependsOn: [ - nestedDependencies - ] -}] +] diff --git a/avm/utilities/tools/helper/src/src.main.bicep b/avm/utilities/tools/helper/src/src.main.bicep index 88066209d3..7d14192161 100644 --- a/avm/utilities/tools/helper/src/src.main.bicep +++ b/avm/utilities/tools/helper/src/src.main.bicep @@ -19,23 +19,24 @@ param enableTelemetry bool = true // Resources // // ============== // -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.[[REPLACE WITH TELEMETRY IDENTIFIER]].${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 avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = + if (enableTelemetry) { + name: '46d3xbcp.[[REPLACE WITH TELEMETRY IDENTIFIER]].${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' + } } } } } -} // // Add your resources here diff --git a/avm/utilities/tools/helper/src/src.main.test.bicep b/avm/utilities/tools/helper/src/src.main.test.bicep index 4bcc560ab0..0e8b537041 100644 --- a/avm/utilities/tools/helper/src/src.main.test.bicep +++ b/avm/utilities/tools/helper/src/src.main.test.bicep @@ -35,12 +35,14 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - // You parameters go here - name: '${namePrefix}${serviceShort}001' - location: resourceLocation +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + // You parameters go here + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + } } -}] +]