From 0e62948be32813b42296aa7376d059c1aeb975f9 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 12 Dec 2023 15:04:20 -0600 Subject: [PATCH 01/42] Initial copy from CARML --- avm/res/app/container-app/README.md | 900 ++++++++++++++++++ avm/res/app/container-app/main.bicep | 267 ++++++ avm/res/app/container-app/main.json | 510 ++++++++++ .../tests/e2e/defaults/dependencies.bicep | 17 + .../tests/e2e/defaults/main.test.bicep | 75 ++ .../tests/e2e/max/dependencies.bicep | 28 + .../tests/e2e/max/main.test.bicep | 110 +++ .../tests/e2e/waf-aligned/dependencies.bicep | 28 + .../tests/e2e/waf-aligned/main.test.bicep | 110 +++ avm/res/app/container-app/version.json | 7 + 10 files changed, 2052 insertions(+) create mode 100644 avm/res/app/container-app/README.md create mode 100644 avm/res/app/container-app/main.bicep create mode 100644 avm/res/app/container-app/main.json create mode 100644 avm/res/app/container-app/tests/e2e/defaults/dependencies.bicep create mode 100644 avm/res/app/container-app/tests/e2e/defaults/main.test.bicep create mode 100644 avm/res/app/container-app/tests/e2e/max/dependencies.bicep create mode 100644 avm/res/app/container-app/tests/e2e/max/main.test.bicep create mode 100644 avm/res/app/container-app/tests/e2e/waf-aligned/dependencies.bicep create mode 100644 avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep create mode 100644 avm/res/app/container-app/version.json diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md new file mode 100644 index 0000000000..3c53161686 --- /dev/null +++ b/avm/res/app/container-app/README.md @@ -0,0 +1,900 @@ +# Container Apps `[Microsoft.App/containerApps]` + +This module deploys a Container App. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.App/containerApps` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.App/2022-10-01/containerApps) | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br:bicep/modules/app.container-app:1.0.0`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +
+ +via Bicep module + +```bicep +module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { + name: '${uniqueString(deployment().name, location)}-test-mcappmin' + params: { + // Required parameters + containers: [ + { + image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' + name: 'simple-hello-world-container' + resources: { + cpu: '' + memory: '0.5Gi' + } + } + ] + environmentId: '' + name: 'mcappmin001' + // Non-required parameters + enableDefaultTelemetry: '' + location: '' + tags: { + Env: 'test' + 'hidden-title': 'This is visible in the resource name' + } + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "containers": { + "value": [ + { + "image": "mcr.microsoft.com/azuredocs/containerapps-helloworld:latest", + "name": "simple-hello-world-container", + "resources": { + "cpu": "", + "memory": "0.5Gi" + } + } + ] + }, + "environmentId": { + "value": "" + }, + "name": { + "value": "mcappmin001" + }, + // Non-required parameters + "enableDefaultTelemetry": { + "value": "" + }, + "location": { + "value": "" + }, + "tags": { + "value": { + "Env": "test", + "hidden-title": "This is visible in the resource name" + } + } + } +} +``` + +
+

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

+ +via Bicep module + +```bicep +module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { + name: '${uniqueString(deployment().name, location)}-test-mcappmax' + params: { + // Required parameters + containers: [ + { + image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' + name: 'simple-hello-world-container' + probes: [ + { + httpGet: { + httpHeaders: [ + { + name: 'Custom-Header' + value: 'Awesome' + } + ] + path: '/health' + port: 8080 + } + initialDelaySeconds: 3 + periodSeconds: 3 + type: 'Liveness' + } + ] + resources: { + cpu: '' + memory: '0.5Gi' + } + } + ] + environmentId: '' + name: 'mcappmax001' + // Non-required parameters + enableDefaultTelemetry: '' + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + userAssignedResourceIds: [ + '' + ] + } + secrets: { + secureList: [ + { + name: 'customtest' + value: '' + } + ] + } + tags: { + Env: 'test' + 'hidden-title': 'This is visible in the resource name' + } + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "containers": { + "value": [ + { + "image": "mcr.microsoft.com/azuredocs/containerapps-helloworld:latest", + "name": "simple-hello-world-container", + "probes": [ + { + "httpGet": { + "httpHeaders": [ + { + "name": "Custom-Header", + "value": "Awesome" + } + ], + "path": "/health", + "port": 8080 + }, + "initialDelaySeconds": 3, + "periodSeconds": 3, + "type": "Liveness" + } + ], + "resources": { + "cpu": "", + "memory": "0.5Gi" + } + } + ] + }, + "environmentId": { + "value": "" + }, + "name": { + "value": "mcappmax001" + }, + // Non-required parameters + "enableDefaultTelemetry": { + "value": "" + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "managedIdentities": { + "value": { + "userAssignedResourceIds": [ + "" + ] + } + }, + "secrets": { + "value": { + "secureList": [ + { + "name": "customtest", + "value": "" + } + ] + } + }, + "tags": { + "value": { + "Env": "test", + "hidden-title": "This is visible in the resource name" + } + } + } +} +``` + +
+

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

+ +via Bicep module + +```bicep +module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { + name: '${uniqueString(deployment().name, location)}-test-mcappwaf' + params: { + // Required parameters + containers: [ + { + image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' + name: 'simple-hello-world-container' + probes: [ + { + httpGet: { + httpHeaders: [ + { + name: 'Custom-Header' + value: 'Awesome' + } + ] + path: '/health' + port: 8080 + } + initialDelaySeconds: 3 + periodSeconds: 3 + type: 'Liveness' + } + ] + resources: { + cpu: '' + memory: '0.5Gi' + } + } + ] + environmentId: '' + name: 'mcappwaf001' + // Non-required parameters + enableDefaultTelemetry: '' + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + userAssignedResourceIds: [ + '' + ] + } + secrets: { + secureList: [ + { + name: 'customtest' + value: '' + } + ] + } + tags: { + Env: 'test' + 'hidden-title': 'This is visible in the resource name' + } + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "containers": { + "value": [ + { + "image": "mcr.microsoft.com/azuredocs/containerapps-helloworld:latest", + "name": "simple-hello-world-container", + "probes": [ + { + "httpGet": { + "httpHeaders": [ + { + "name": "Custom-Header", + "value": "Awesome" + } + ], + "path": "/health", + "port": 8080 + }, + "initialDelaySeconds": 3, + "periodSeconds": 3, + "type": "Liveness" + } + ], + "resources": { + "cpu": "", + "memory": "0.5Gi" + } + } + ] + }, + "environmentId": { + "value": "" + }, + "name": { + "value": "mcappwaf001" + }, + // Non-required parameters + "enableDefaultTelemetry": { + "value": "" + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "managedIdentities": { + "value": { + "userAssignedResourceIds": [ + "" + ] + } + }, + "secrets": { + "value": { + "secureList": [ + { + "name": "customtest", + "value": "" + } + ] + } + }, + "tags": { + "value": { + "Env": "test", + "hidden-title": "This is visible in the resource name" + } + } + } +} +``` + +
+

+ + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`containers`](#parameter-containers) | array | List of container definitions for the Container App. | +| [`environmentId`](#parameter-environmentid) | string | Resource ID of environment. | +| [`name`](#parameter-name) | string | Name of the Container App. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`activeRevisionsMode`](#parameter-activerevisionsmode) | string | ActiveRevisionsMode controls how active revisions are handled for the Container app. | +| [`customDomains`](#parameter-customdomains) | array | Custom domain bindings for Container App hostnames. | +| [`dapr`](#parameter-dapr) | object | Dapr configuration for the Container App. | +| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`exposedPort`](#parameter-exposedport) | int | Exposed Port in containers for TCP traffic from ingress. | +| [`ingressAllowInsecure`](#parameter-ingressallowinsecure) | bool | Bool indicating if HTTP connections to is allowed. If set to false HTTP connections are automatically redirected to HTTPS connections. | +| [`ingressExternal`](#parameter-ingressexternal) | bool | Bool indicating if app exposes an external http endpoint. | +| [`ingressTargetPort`](#parameter-ingresstargetport) | int | Target Port in containers for traffic from ingress. | +| [`ingressTransport`](#parameter-ingresstransport) | string | Ingress transport protocol. | +| [`initContainersTemplate`](#parameter-initcontainerstemplate) | array | List of specialized containers that run before app containers. | +| [`ipSecurityRestrictions`](#parameter-ipsecurityrestrictions) | array | Rules to restrict incoming IP address. | +| [`location`](#parameter-location) | string | Location for all Resources. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. | +| [`maxInactiveRevisions`](#parameter-maxinactiverevisions) | int | Max inactive revisions a Container App can have. | +| [`registries`](#parameter-registries) | array | Collection of private container registry credentials for containers used by the Container app. | +| [`revisionSuffix`](#parameter-revisionsuffix) | string | User friendly suffix that is appended to the revision name. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute. | +| [`scaleMaxReplicas`](#parameter-scalemaxreplicas) | int | Maximum number of container replicas. Defaults to 10 if not set. | +| [`scaleMinReplicas`](#parameter-scaleminreplicas) | int | Minimum number of container replicas. | +| [`scaleRules`](#parameter-scalerules) | array | Scaling rules. | +| [`secrets`](#parameter-secrets) | secureObject | The secrets of the Container App. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`trafficLabel`](#parameter-trafficlabel) | string | Associates a traffic label with a revision. Label name should be consist of lower case alphanumeric characters or dashes. | +| [`trafficLatestRevision`](#parameter-trafficlatestrevision) | bool | Indicates that the traffic weight belongs to a latest stable revision. | +| [`trafficRevisionName`](#parameter-trafficrevisionname) | string | Name of a revision. | +| [`trafficWeight`](#parameter-trafficweight) | int | Traffic weight assigned to a revision. | +| [`volumes`](#parameter-volumes) | array | List of volume definitions for the Container App. | +| [`workloadProfileType`](#parameter-workloadprofiletype) | string | Workload profile type to pin for container app execution. | + +### Parameter: `containers` + +List of container definitions for the Container App. + +- Required: Yes +- Type: array + +### Parameter: `environmentId` + +Resource ID of environment. + +- Required: Yes +- Type: string + +### Parameter: `name` + +Name of the Container App. + +- Required: Yes +- Type: string + +### Parameter: `activeRevisionsMode` + +ActiveRevisionsMode controls how active revisions are handled for the Container app. + +- Required: No +- Type: string +- Default: `'Single'` +- Allowed: + ```Bicep + [ + 'Multiple' + 'Single' + ] + ``` + +### Parameter: `customDomains` + +Custom domain bindings for Container App hostnames. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `dapr` + +Dapr configuration for the Container App. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `enableDefaultTelemetry` + +Enable telemetry via a Globally Unique Identifier (GUID). + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `exposedPort` + +Exposed Port in containers for TCP traffic from ingress. + +- Required: No +- Type: int +- Default: `0` + +### Parameter: `ingressAllowInsecure` + +Bool indicating if HTTP connections to is allowed. If set to false HTTP connections are automatically redirected to HTTPS connections. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `ingressExternal` + +Bool indicating if app exposes an external http endpoint. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `ingressTargetPort` + +Target Port in containers for traffic from ingress. + +- Required: No +- Type: int +- Default: `80` + +### Parameter: `ingressTransport` + +Ingress transport protocol. + +- Required: No +- Type: string +- Default: `'auto'` +- Allowed: + ```Bicep + [ + 'auto' + 'http' + 'http2' + 'tcp' + ] + ``` + +### Parameter: `initContainersTemplate` + +List of specialized containers that run before app containers. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `ipSecurityRestrictions` + +Rules to restrict incoming IP address. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `location` + +Location for all Resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `managedIdentities` + +The managed identity definition for this resource. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`systemAssigned`](#parameter-managedidentitiessystemassigned) | bool | Enables system assigned managed identity on the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. | + +### Parameter: `managedIdentities.systemAssigned` + +Enables system assigned managed identity on the resource. + +- Required: No +- Type: bool + +### Parameter: `managedIdentities.userAssignedResourceIds` + +The resource ID(s) to assign to the resource. + +- Required: No +- Type: array + +### Parameter: `maxInactiveRevisions` + +Max inactive revisions a Container App can have. + +- Required: No +- Type: int +- Default: `0` + +### Parameter: `registries` + +Collection of private container registry credentials for containers used by the Container app. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `revisionSuffix` + +User friendly suffix that is appended to the revision name. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `roleAssignments` + +Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `scaleMaxReplicas` + +Maximum number of container replicas. Defaults to 10 if not set. + +- Required: No +- Type: int +- Default: `1` + +### Parameter: `scaleMinReplicas` + +Minimum number of container replicas. + +- Required: No +- Type: int +- Default: `0` + +### Parameter: `scaleRules` + +Scaling rules. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `secrets` + +The secrets of the Container App. + +- Required: No +- Type: secureObject +- Default: `{}` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `trafficLabel` + +Associates a traffic label with a revision. Label name should be consist of lower case alphanumeric characters or dashes. + +- Required: No +- Type: string +- Default: `'label-1'` + +### Parameter: `trafficLatestRevision` + +Indicates that the traffic weight belongs to a latest stable revision. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `trafficRevisionName` + +Name of a revision. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `trafficWeight` + +Traffic weight assigned to a revision. + +- Required: No +- Type: int +- Default: `100` + +### Parameter: `volumes` + +List of volume definitions for the Container App. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `workloadProfileType` + +Workload profile type to pin for container app execution. + +- Required: No +- Type: string +- Default: `''` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the Container App. | +| `resourceGroupName` | string | The name of the resource group the Container App was deployed into. | +| `resourceId` | string | The resource ID of the Container App. | +| `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | + +## Cross-referenced modules + +_None_ diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep new file mode 100644 index 0000000000..939f2bed5c --- /dev/null +++ b/avm/res/app/container-app/main.bicep @@ -0,0 +1,267 @@ +metadata name = 'Container Apps' +metadata description = 'This module deploys a Container App.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Name of the Container App.') +param name string + +@description('Optional. Location for all Resources.') +param location string = resourceGroup().location + +@description('Optional. Bool indicating if app exposes an external http endpoint.') +param ingressExternal bool = true + +@allowed([ + 'auto' + 'http' + 'http2' + 'tcp' +]) +@description('Optional. Ingress transport protocol.') +param ingressTransport string = 'auto' + +@description('Optional. Bool indicating if HTTP connections to is allowed. If set to false HTTP connections are automatically redirected to HTTPS connections.') +param ingressAllowInsecure bool = true + +@description('Optional. Target Port in containers for traffic from ingress.') +param ingressTargetPort int = 80 + +@description('Optional. Maximum number of container replicas. Defaults to 10 if not set.') +param scaleMaxReplicas int = 1 + +@description('Optional. Minimum number of container replicas.') +param scaleMinReplicas int = 0 + +@description('Optional. Scaling rules.') +param scaleRules array = [] + +@allowed([ + 'Multiple' + 'Single' +]) +@description('Optional. ActiveRevisionsMode controls how active revisions are handled for the Container app.') +param activeRevisionsMode string = 'Single' + +@description('Required. Resource ID of environment.') +param environmentId string + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Optional. Collection of private container registry credentials for containers used by the Container app.') +param registries array = [] + +@description('Optional. The managed identity definition for this resource.') +param managedIdentities managedIdentitiesType + +@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute.') +param roleAssignments roleAssignmentType + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. Custom domain bindings for Container App hostnames.') +param customDomains array = [] + +@description('Optional. Exposed Port in containers for TCP traffic from ingress.') +param exposedPort int = 0 + +@description('Optional. Rules to restrict incoming IP address.') +param ipSecurityRestrictions array = [] + +@description('Optional. Associates a traffic label with a revision. Label name should be consist of lower case alphanumeric characters or dashes.') +param trafficLabel string = 'label-1' + +@description('Optional. Indicates that the traffic weight belongs to a latest stable revision.') +param trafficLatestRevision bool = true + +@description('Optional. Name of a revision.') +param trafficRevisionName string = '' + +@description('Optional. Traffic weight assigned to a revision.') +param trafficWeight int = 100 + +@description('Optional. Dapr configuration for the Container App.') +param dapr object = {} + +@description('Optional. Max inactive revisions a Container App can have.') +param maxInactiveRevisions int = 0 + +@description('Required. List of container definitions for the Container App.') +param containers array + +@description('Optional. List of specialized containers that run before app containers.') +param initContainersTemplate array = [] + +@description('Optional. The secrets of the Container App.') +@secure() +param secrets object = {} + +@description('Optional. User friendly suffix that is appended to the revision name.') +param revisionSuffix string = '' + +@description('Optional. List of volume definitions for the Container App.') +param volumes array = [] + +@description('Optional. Workload profile type to pin for container app execution.') +param workloadProfileType string = '' + +var secretList = !empty(secrets) ? secrets.secureList : [] + +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 = { + 'ContainerApp Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ad2dd5fb-cd4b-4fd4-a9b6-4fed3630980b') + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { + name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + } + } +} + +resource containerApp 'Microsoft.App/containerApps@2022-10-01' = { + name: name + tags: tags + location: location + identity: identity + properties: { + environmentId: environmentId + configuration: { + activeRevisionsMode: activeRevisionsMode + dapr: !empty(dapr) ? dapr : null + ingress: { + allowInsecure: ingressAllowInsecure + customDomains: !empty(customDomains) ? customDomains : null + exposedPort: exposedPort + external: ingressExternal + ipSecurityRestrictions: !empty(ipSecurityRestrictions) ? ipSecurityRestrictions : null + targetPort: ingressTargetPort + traffic: [ + { + label: trafficLabel + latestRevision: trafficLatestRevision + revisionName: trafficRevisionName + weight: trafficWeight + } + ] + transport: ingressTransport + } + maxInactiveRevisions: maxInactiveRevisions + registries: !empty(registries) ? registries : null + secrets: secretList + } + template: { + containers: containers + initContainers: !empty(initContainersTemplate) ? initContainersTemplate : null + revisionSuffix: revisionSuffix + scale: { + maxReplicas: scaleMaxReplicas + minReplicas: scaleMinReplicas + rules: !empty(scaleRules) ? scaleRules : null + } + volumes: !empty(volumes) ? volumes : null + } + workloadProfileType: workloadProfileType + } +} + +resource containerApp_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: containerApp +} + +resource containerApp_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(containerApp.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: containerApp +}] + +@description('The resource ID of the Container App.') +output resourceId string = containerApp.id + +@description('The name of the resource group the Container App was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The name of the Container App.') +output name string = containerApp.name + +@description('The principal ID of the system assigned identity.') +output systemAssignedMIPrincipalId string = (managedIdentities.?systemAssigned ?? false) && contains(containerApp.identity, 'principalId') ? containerApp.identity.principalId : '' + +@description('The location the resource was deployed into.') +output location string = containerApp.location + +// =============== // +// Definitions // +// =============== // + +type managedIdentitiesType = { + @description('Optional. Enables system assigned managed identity on the resource.') + systemAssigned: bool? + + @description('Optional. The resource ID(s) to assign to the resource.') + userAssignedResourceIds: string[]? +}? + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container"') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json new file mode 100644 index 0000000000..151294bb80 --- /dev/null +++ b/avm/res/app/container-app/main.json @@ -0,0 +1,510 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "3664175856787955387" + }, + "name": "Container Apps", + "description": "This module deploys a Container App.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the Container App." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "ingressExternal": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Bool indicating if app exposes an external http endpoint." + } + }, + "ingressTransport": { + "type": "string", + "defaultValue": "auto", + "allowedValues": [ + "auto", + "http", + "http2", + "tcp" + ], + "metadata": { + "description": "Optional. Ingress transport protocol." + } + }, + "ingressAllowInsecure": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Bool indicating if HTTP connections to is allowed. If set to false HTTP connections are automatically redirected to HTTPS connections." + } + }, + "ingressTargetPort": { + "type": "int", + "defaultValue": 80, + "metadata": { + "description": "Optional. Target Port in containers for traffic from ingress." + } + }, + "scaleMaxReplicas": { + "type": "int", + "defaultValue": 1, + "metadata": { + "description": "Optional. Maximum number of container replicas. Defaults to 10 if not set." + } + }, + "scaleMinReplicas": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Optional. Minimum number of container replicas." + } + }, + "scaleRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Scaling rules." + } + }, + "activeRevisionsMode": { + "type": "string", + "defaultValue": "Single", + "allowedValues": [ + "Multiple", + "Single" + ], + "metadata": { + "description": "Optional. ActiveRevisionsMode controls how active revisions are handled for the Container app." + } + }, + "environmentId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of environment." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "registries": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Collection of private container registry credentials for containers used by the Container app." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "customDomains": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Custom domain bindings for Container App hostnames." + } + }, + "exposedPort": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Optional. Exposed Port in containers for TCP traffic from ingress." + } + }, + "ipSecurityRestrictions": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Rules to restrict incoming IP address." + } + }, + "trafficLabel": { + "type": "string", + "defaultValue": "label-1", + "metadata": { + "description": "Optional. Associates a traffic label with a revision. Label name should be consist of lower case alphanumeric characters or dashes." + } + }, + "trafficLatestRevision": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Indicates that the traffic weight belongs to a latest stable revision." + } + }, + "trafficRevisionName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Name of a revision." + } + }, + "trafficWeight": { + "type": "int", + "defaultValue": 100, + "metadata": { + "description": "Optional. Traffic weight assigned to a revision." + } + }, + "dapr": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Dapr configuration for the Container App." + } + }, + "maxInactiveRevisions": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Optional. Max inactive revisions a Container App can have." + } + }, + "containers": { + "type": "array", + "metadata": { + "description": "Required. List of container definitions for the Container App." + } + }, + "initContainersTemplate": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of specialized containers that run before app containers." + } + }, + "secrets": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. The secrets of the Container App." + } + }, + "revisionSuffix": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. User friendly suffix that is appended to the revision name." + } + }, + "volumes": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of volume definitions for the Container App." + } + }, + "workloadProfileType": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Workload profile type to pin for container app execution." + } + } + }, + "variables": { + "secretList": "[if(not(empty(parameters('secrets'))), parameters('secrets').secureList, createArray())]", + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "builtInRoleNames": { + "ContainerApp Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ad2dd5fb-cd4b-4fd4-a9b6-4fed3630980b')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "containerApp": { + "type": "Microsoft.App/containerApps", + "apiVersion": "2022-10-01", + "name": "[parameters('name')]", + "tags": "[parameters('tags')]", + "location": "[parameters('location')]", + "identity": "[variables('identity')]", + "properties": { + "environmentId": "[parameters('environmentId')]", + "configuration": { + "activeRevisionsMode": "[parameters('activeRevisionsMode')]", + "dapr": "[if(not(empty(parameters('dapr'))), parameters('dapr'), null())]", + "ingress": { + "allowInsecure": "[parameters('ingressAllowInsecure')]", + "customDomains": "[if(not(empty(parameters('customDomains'))), parameters('customDomains'), null())]", + "exposedPort": "[parameters('exposedPort')]", + "external": "[parameters('ingressExternal')]", + "ipSecurityRestrictions": "[if(not(empty(parameters('ipSecurityRestrictions'))), parameters('ipSecurityRestrictions'), null())]", + "targetPort": "[parameters('ingressTargetPort')]", + "traffic": [ + { + "label": "[parameters('trafficLabel')]", + "latestRevision": "[parameters('trafficLatestRevision')]", + "revisionName": "[parameters('trafficRevisionName')]", + "weight": "[parameters('trafficWeight')]" + } + ], + "transport": "[parameters('ingressTransport')]" + }, + "maxInactiveRevisions": "[parameters('maxInactiveRevisions')]", + "registries": "[if(not(empty(parameters('registries'))), parameters('registries'), null())]", + "secrets": "[variables('secretList')]" + }, + "template": { + "containers": "[parameters('containers')]", + "initContainers": "[if(not(empty(parameters('initContainersTemplate'))), parameters('initContainersTemplate'), null())]", + "revisionSuffix": "[parameters('revisionSuffix')]", + "scale": { + "maxReplicas": "[parameters('scaleMaxReplicas')]", + "minReplicas": "[parameters('scaleMinReplicas')]", + "rules": "[if(not(empty(parameters('scaleRules'))), parameters('scaleRules'), null())]" + }, + "volumes": "[if(not(empty(parameters('volumes'))), parameters('volumes'), null())]" + }, + "workloadProfileType": "[parameters('workloadProfileType')]" + } + }, + "containerApp_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.App/containerApps/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "containerApp" + ] + }, + "containerApp_roleAssignments": { + "copy": { + "name": "containerApp_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.App/containerApps/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.App/containerApps', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "containerApp" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Container App." + }, + "value": "[resourceId('Microsoft.App/containerApps', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the Container App was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the Container App." + }, + "value": "[parameters('name')]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[if(and(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), contains(reference('containerApp', '2022-10-01', 'full').identity, 'principalId')), reference('containerApp', '2022-10-01', 'full').identity.principalId, '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('containerApp', '2022-10-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/app/container-app/tests/e2e/defaults/dependencies.bicep b/avm/res/app/container-app/tests/e2e/defaults/dependencies.bicep new file mode 100644 index 0000000000..edf4adee4b --- /dev/null +++ b/avm/res/app/container-app/tests/e2e/defaults/dependencies.bicep @@ -0,0 +1,17 @@ +@description('Required. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Environment to create.') +param managedEnvironmentName string + +resource managedEnvironment 'Microsoft.App/managedEnvironments@2022-10-01' = { + name: managedEnvironmentName + location: location + sku: { + name: 'Consumption' + } + properties: {} +} + +@description('The resource ID of the created Managed Environment.') +output managedEnvironmentResourceId string = managedEnvironment.id diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..b00bf36743 --- /dev/null +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,75 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-app.containerApps-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location 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 = 'mcappmin' + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '[[namePrefix]]' + +// =========== // +// Deployments // +// =========== // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-paramNested' + params: { + location: location + managedEnvironmentName: 'dep-${namePrefix}-menv-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + tags: { + 'hidden-title': 'This is visible in the resource name' + Env: 'test' + } + enableDefaultTelemetry: enableDefaultTelemetry + environmentId: nestedDependencies.outputs.managedEnvironmentResourceId + location: location + containers: [ + { + name: 'simple-hello-world-container' + image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' + resources: { + // workaround as 'float' values are not supported in Bicep, yet the resource providers expects them. Related issue: https://github.com/Azure/bicep/issues/1386 + cpu: json('0.25') + memory: '0.5Gi' + } + } + ] + } +}] diff --git a/avm/res/app/container-app/tests/e2e/max/dependencies.bicep b/avm/res/app/container-app/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..a6700c9d60 --- /dev/null +++ b/avm/res/app/container-app/tests/e2e/max/dependencies.bicep @@ -0,0 +1,28 @@ +@description('Required. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Environment for Container Apps to create.') +param managedEnvironmentName string + +@description('Required. The name of the managed identity to create.') +param managedIdentityName string + +resource managedEnvironment 'Microsoft.App/managedEnvironments@2022-10-01' = { + name: managedEnvironmentName + location: location + sku: { + name: 'Consumption' + } + properties: {} +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2022-01-31-preview' = { + name: managedIdentityName + location: location +} + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Managed Environment.') +output managedEnvironmentResourceId string = managedEnvironment.id diff --git a/avm/res/app/container-app/tests/e2e/max/main.test.bicep b/avm/res/app/container-app/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..a9397c8777 --- /dev/null +++ b/avm/res/app/container-app/tests/e2e/max/main.test.bicep @@ -0,0 +1,110 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-app.containerApps-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location 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 = 'mcappmax' + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '[[namePrefix]]' + +// =========== // +// Deployments // +// =========== // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-paramNested' + params: { + location: location + managedEnvironmentName: 'dep-${namePrefix}-menv-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + tags: { + 'hidden-title': 'This is visible in the resource name' + Env: 'test' + } + enableDefaultTelemetry: enableDefaultTelemetry + environmentId: nestedDependencies.outputs.managedEnvironmentResourceId + location: location + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + secrets: { + secureList: [ + { + name: 'customtest' + value: guid(deployment().name) + } + ] + } + containers: [ + { + name: 'simple-hello-world-container' + image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' + resources: { + // workaround as 'float' values are not supported in Bicep, yet the resource providers expects them. Related issue: https://github.com/Azure/bicep/issues/1386 + cpu: json('0.25') + memory: '0.5Gi' + } + probes: [ + { + type: 'Liveness' + httpGet: { + path: '/health' + port: 8080 + httpHeaders: [ + { + name: 'Custom-Header' + value: 'Awesome' + } + ] + } + initialDelaySeconds: 3 + periodSeconds: 3 + } + ] + } + ] + } +}] diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..a6700c9d60 --- /dev/null +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,28 @@ +@description('Required. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Environment for Container Apps to create.') +param managedEnvironmentName string + +@description('Required. The name of the managed identity to create.') +param managedIdentityName string + +resource managedEnvironment 'Microsoft.App/managedEnvironments@2022-10-01' = { + name: managedEnvironmentName + location: location + sku: { + name: 'Consumption' + } + properties: {} +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2022-01-31-preview' = { + name: managedIdentityName + location: location +} + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Managed Environment.') +output managedEnvironmentResourceId string = managedEnvironment.id diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..f7be7ad1bc --- /dev/null +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,110 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-app.containerApps-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location 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 = 'mcappwaf' + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '[[namePrefix]]' + +// =========== // +// Deployments // +// =========== // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-paramNested' + params: { + location: location + managedEnvironmentName: 'dep-${namePrefix}-menv-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + tags: { + 'hidden-title': 'This is visible in the resource name' + Env: 'test' + } + enableDefaultTelemetry: enableDefaultTelemetry + environmentId: nestedDependencies.outputs.managedEnvironmentResourceId + location: location + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + secrets: { + secureList: [ + { + name: 'customtest' + value: guid(deployment().name) + } + ] + } + containers: [ + { + name: 'simple-hello-world-container' + image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' + resources: { + // workaround as 'float' values are not supported in Bicep, yet the resource providers expects them. Related issue: https://github.com/Azure/bicep/issues/1386 + cpu: json('0.25') + memory: '0.5Gi' + } + probes: [ + { + type: 'Liveness' + httpGet: { + path: '/health' + port: 8080 + httpHeaders: [ + { + name: 'Custom-Header' + value: 'Awesome' + } + ] + } + initialDelaySeconds: 3 + periodSeconds: 3 + } + ] + } + ] + } +}] diff --git a/avm/res/app/container-app/version.json b/avm/res/app/container-app/version.json new file mode 100644 index 0000000000..96236a61ba --- /dev/null +++ b/avm/res/app/container-app/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.4", + "pathFilters": [ + "./main.json" + ] +} From 7575352e4349700538f34a8c625ae6d4abe6faa6 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 12 Dec 2023 15:48:49 -0600 Subject: [PATCH 02/42] Initial workflow for AVM container app --- .../workflows/avm.res.app.container-app.yml | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 .github/workflows/avm.res.app.container-app.yml diff --git a/.github/workflows/avm.res.app.container-app.yml b/.github/workflows/avm.res.app.container-app.yml new file mode 100644 index 0000000000..dc8b0ac12e --- /dev/null +++ b/.github/workflows/avm.res.app.container-app.yml @@ -0,0 +1,83 @@ +name: "avm.res.app.containerapp" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.app.container-app.yml" + - "avm/res/app/container-app/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/app/container-app" + workflowPath: ".github/workflows/avm.res.app.container-a.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-20.04 + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Module" + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit From 7a7d6fa29db10fe4c5e9d0c55d8d2242a85c9a26 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 12 Dec 2023 15:50:37 -0600 Subject: [PATCH 03/42] Fix container app references --- .github/workflows/avm.res.app.container-app.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/avm.res.app.container-app.yml b/.github/workflows/avm.res.app.container-app.yml index dc8b0ac12e..e3b58f30c1 100644 --- a/.github/workflows/avm.res.app.container-app.yml +++ b/.github/workflows/avm.res.app.container-app.yml @@ -1,4 +1,4 @@ -name: "avm.res.app.containerapp" +name: "avm.res.app.container-app" on: schedule: @@ -34,7 +34,7 @@ on: env: modulePath: "avm/res/app/container-app" - workflowPath: ".github/workflows/avm.res.app.container-a.yml" + workflowPath: ".github/workflows/avm.res.app.container-app.yml" concurrency: group: ${{ github.workflow }} From fcf14f6adcf5d3f2cf7644b43e11aa075960dfe4 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 12 Dec 2023 21:59:03 -0600 Subject: [PATCH 04/42] Changed [[namePrefix]] to #_namePrefix_# to avoid Bicep compilation issue --- avm/res/app/container-app/tests/e2e/defaults/main.test.bicep | 2 +- avm/res/app/container-app/tests/e2e/max/main.test.bicep | 2 +- avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index b00bf36743..ccffef83a7 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -21,7 +21,7 @@ param serviceShort string = 'mcappmin' param enableDefaultTelemetry bool = true @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '[[namePrefix]]' +param namePrefix string = '#_namePrefix_#' // =========== // // Deployments // diff --git a/avm/res/app/container-app/tests/e2e/max/main.test.bicep b/avm/res/app/container-app/tests/e2e/max/main.test.bicep index a9397c8777..125e198da4 100644 --- a/avm/res/app/container-app/tests/e2e/max/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/max/main.test.bicep @@ -21,7 +21,7 @@ param serviceShort string = 'mcappmax' param enableDefaultTelemetry bool = true @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '[[namePrefix]]' +param namePrefix string = '#_namePrefix_#' // =========== // // Deployments // diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index f7be7ad1bc..23a22e722e 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -21,7 +21,7 @@ param serviceShort string = 'mcappwaf' param enableDefaultTelemetry bool = true @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '[[namePrefix]]' +param namePrefix string = '#_namePrefix_#' // =========== // // Deployments // From 64d686b5dd0aede625a964681506f1484cf651ee Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 12 Dec 2023 22:11:46 -0600 Subject: [PATCH 05/42] Align serviceShort param with AVM --- avm/res/app/container-app/tests/e2e/defaults/main.test.bicep | 2 +- avm/res/app/container-app/tests/e2e/max/main.test.bicep | 2 +- avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index ccffef83a7..91bf32915d 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -15,7 +15,7 @@ param resourceGroupName string = 'dep-${namePrefix}-app.containerApps-${serviceS param location 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 = 'mcappmin' +param serviceShort string = 'acadef' @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') param enableDefaultTelemetry bool = true diff --git a/avm/res/app/container-app/tests/e2e/max/main.test.bicep b/avm/res/app/container-app/tests/e2e/max/main.test.bicep index 125e198da4..7ceb82c8fd 100644 --- a/avm/res/app/container-app/tests/e2e/max/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/max/main.test.bicep @@ -15,7 +15,7 @@ param resourceGroupName string = 'dep-${namePrefix}-app.containerApps-${serviceS param location 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 = 'mcappmax' +param serviceShort string = 'acamax' @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') param enableDefaultTelemetry bool = true diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index 23a22e722e..d70d0b5c0c 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -15,7 +15,7 @@ param resourceGroupName string = 'dep-${namePrefix}-app.containerApps-${serviceS param location 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 = 'mcappwaf' +param serviceShort string = 'acawaf' @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') param enableDefaultTelemetry bool = true From 400e1c063368be0ca2bded5677ffc721c3f87e34 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Wed, 13 Dec 2023 23:29:09 -0600 Subject: [PATCH 06/42] Add diagnostic settings to containr app --- avm/res/app/container-app/README.md | 153 ++++++++++++++++-- avm/res/app/container-app/main.bicep | 67 ++++++++ avm/res/app/container-app/main.json | 137 +++++++++++++++- .../tests/e2e/defaults/main.test.bicep | 22 +++ .../tests/e2e/max/main.test.bicep | 22 +++ .../tests/e2e/waf-aligned/main.test.bicep | 22 +++ 6 files changed, 410 insertions(+), 13 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index 3c53161686..a6274b6830 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -15,6 +15,7 @@ This module deploys a Container App. | Resource Type | API Version | | :-- | :-- | | `Microsoft.App/containerApps` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.App/2022-10-01/containerApps) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | @@ -40,8 +41,8 @@ This instance deploys the module with the minimum set of required parameters.

via Bicep module ```bicep -module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { - name: '${uniqueString(deployment().name, location)}-test-mcappmin' +module containerApp 'br:public:avm/res/app/container-app:' = { + name: '${uniqueString(deployment().name, location)}-test-acamin' params: { // Required parameters containers: [ @@ -55,7 +56,7 @@ module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { } ] environmentId: '' - name: 'mcappmin001' + name: 'acamin001' // Non-required parameters enableDefaultTelemetry: '' location: '' @@ -96,7 +97,7 @@ module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { "value": "" }, "name": { - "value": "mcappmin001" + "value": "acamin001" }, // Non-required parameters "enableDefaultTelemetry": { @@ -128,8 +129,8 @@ This instance deploys the module with most of its features enabled. via Bicep module ```bicep -module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { - name: '${uniqueString(deployment().name, location)}-test-mcappmax' +module containerApp 'br/public:avm/res/automation/automation-account:' = { + name: '${uniqueString(deployment().name, location)}-test-acamax' params: { // Required parameters containers: [ @@ -160,8 +161,16 @@ module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { } ] environmentId: '' - name: 'mcappmax001' + name: 'acamax001' // Non-required parameters + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] enableDefaultTelemetry: '' location: '' lock: { @@ -235,9 +244,19 @@ module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { "value": "" }, "name": { - "value": "mcappmax001" + "value": "acamax001" }, // Non-required parameters + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, "enableDefaultTelemetry": { "value": "" }, @@ -290,8 +309,8 @@ This instance deploys the module in alignment with the best-practices of the Azu via Bicep module ```bicep -module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { - name: '${uniqueString(deployment().name, location)}-test-mcappwaf' +module containerApp 'br/public:avm/res/automation/automation-account:' = { + name: '${uniqueString(deployment().name, location)}-test-acawaf' params: { // Required parameters containers: [ @@ -322,8 +341,16 @@ module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { } ] environmentId: '' - name: 'mcappwaf001' + name: 'acawaf001' // Non-required parameters + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] enableDefaultTelemetry: '' location: '' lock: { @@ -397,9 +424,19 @@ module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { "value": "" }, "name": { - "value": "mcappwaf001" + "value": "acawaf001" }, // Non-required parameters + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, "enableDefaultTelemetry": { "value": "" }, @@ -460,6 +497,7 @@ module containerApp 'br:bicep/modules/app.container-app:1.0.0' = { | [`activeRevisionsMode`](#parameter-activerevisionsmode) | string | ActiveRevisionsMode controls how active revisions are handled for the Container app. | | [`customDomains`](#parameter-customdomains) | array | Custom domain bindings for Container App hostnames. | | [`dapr`](#parameter-dapr) | object | Dapr configuration for the Container App. | +| [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | | [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | | [`exposedPort`](#parameter-exposedport) | int | Exposed Port in containers for TCP traffic from ingress. | | [`ingressAllowInsecure`](#parameter-ingressallowinsecure) | bool | Bool indicating if HTTP connections to is allowed. If set to false HTTP connections are automatically redirected to HTTPS connections. | @@ -539,6 +577,97 @@ Dapr configuration for the Container App. - Type: object - Default: `{}` +### Parameter: `diagnosticSettings` + +The diagnostic settings of the service. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | + +### Parameter: `diagnosticSettings.eventHubAuthorizationRuleResourceId` + +Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.eventHubName` + +Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logAnalyticsDestinationType` + +A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AzureDiagnostics' + 'Dedicated' + ] + ``` + +### Parameter: `diagnosticSettings.logCategoriesAndGroups` + +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. + +- Required: No +- Type: array + +### Parameter: `diagnosticSettings.marketplacePartnerResourceId` + +The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.metricCategories` + +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. + +- Required: No +- Type: array + +### Parameter: `diagnosticSettings.name` + +The name of diagnostic setting. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.storageAccountResourceId` + +Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.workspaceResourceId` + +Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + ### Parameter: `enableDefaultTelemetry` Enable telemetry via a Globally Unique Identifier (GUID). diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 939f2bed5c..9fdbeff0a6 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -54,6 +54,9 @@ param tags object? @description('Optional. Collection of private container registry credentials for containers used by the Container app.') param registries array = [] +@description('Optional. The diagnostic settings of the service.') +param diagnosticSettings diagnosticSettingType + @description('Optional. The managed identity definition for this resource.') param managedIdentities managedIdentitiesType @@ -185,6 +188,32 @@ resource containerApp 'Microsoft.App/containerApps@2022-10-01' = { } } +resource containerApp_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: diagnosticSetting.?metricCategories ?? [ + { + category: 'AllMetrics' + timeGrain: null + enabled: true + } + ] + logs: diagnosticSetting.?logCategoriesAndGroups ?? [ + { + categoryGroup: 'AllLogs' + enabled: true + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType +} +scope: containerApp +}] + resource containerApp_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { name: lock.?name ?? 'lock-${name}' properties: { @@ -227,6 +256,44 @@ output location string = containerApp.location // Definitions // // =============== // +type diagnosticSettingType = { + @description('Optional. The name of diagnostic setting.') + name: string? + + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + logCategoriesAndGroups: { + @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') + category: string? + + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + categoryGroup: string? + }[]? + + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + metricCategories: { + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + category: string + }[]? + + @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') + logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? + + @description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + workspaceResourceId: string? + + @description('Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + storageAccountResourceId: string? + + @description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') + eventHubAuthorizationRuleResourceId: string? + + @description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + eventHubName: string? + + @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') + marketplacePartnerResourceId: string? +}[]? + type managedIdentitiesType = { @description('Optional. Enables system assigned managed identity on the resource.') systemAssigned: bool? diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index 151294bb80..2a3862761b 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -6,13 +6,119 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "3664175856787955387" + "templateHash": "7167506561528624829" }, "name": "Container Apps", "description": "This module deploys a Container App.", "owner": "Azure/module-maintainers" }, "definitions": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, "managedIdentitiesType": { "type": "object", "properties": { @@ -234,6 +340,12 @@ "description": "Optional. Collection of private container registry credentials for containers used by the Container app." } }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, "managedIdentities": { "$ref": "#/definitions/managedIdentitiesType", "metadata": { @@ -433,6 +545,29 @@ "workloadProfileType": "[parameters('workloadProfileType')]" } }, + "containerApp_diagnosticSettings": { + "copy": { + "name": "containerApp_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.App/containerApps/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", + "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "containerApp" + ] + }, "containerApp_lock": { "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index 91bf32915d..ee6b815d5c 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -43,6 +43,20 @@ module nestedDependencies 'dependencies.bicep' = { } } +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' + location: location + } +} + // ============== // // Test Execution // // ============== // @@ -53,6 +67,14 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-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 + } + ] tags: { 'hidden-title': 'This is visible in the resource name' Env: 'test' diff --git a/avm/res/app/container-app/tests/e2e/max/main.test.bicep b/avm/res/app/container-app/tests/e2e/max/main.test.bicep index 7ceb82c8fd..ae414bc543 100644 --- a/avm/res/app/container-app/tests/e2e/max/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/max/main.test.bicep @@ -44,6 +44,20 @@ module nestedDependencies 'dependencies.bicep' = { } } +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' + location: location + } +} + // ============== // // Test Execution // // ============== // @@ -54,6 +68,14 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-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 + } + ] tags: { 'hidden-title': 'This is visible in the resource name' Env: 'test' diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index d70d0b5c0c..f1608b85c9 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -44,6 +44,20 @@ module nestedDependencies 'dependencies.bicep' = { } } +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' + location: location + } +} + // ============== // // Test Execution // // ============== // @@ -54,6 +68,14 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-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 + } + ] tags: { 'hidden-title': 'This is visible in the resource name' Env: 'test' From a79d00fc75040019e2f9e106b0837a6e40f63e8c Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Wed, 13 Dec 2023 23:56:36 -0600 Subject: [PATCH 07/42] Update api versions to latest --- avm/res/app/container-app/README.md | 4 ++-- avm/res/app/container-app/main.bicep | 8 ++++---- avm/res/app/container-app/main.json | 14 +++++++------- .../tests/e2e/defaults/dependencies.bicep | 5 +---- .../container-app/tests/e2e/max/dependencies.bicep | 5 +---- .../tests/e2e/waf-aligned/dependencies.bicep | 7 ++----- 6 files changed, 17 insertions(+), 26 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index a6274b6830..3d48aef25e 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -523,7 +523,7 @@ module containerApp 'br/public:avm/res/automation/automation-account:' | [`trafficRevisionName`](#parameter-trafficrevisionname) | string | Name of a revision. | | [`trafficWeight`](#parameter-trafficweight) | int | Traffic weight assigned to a revision. | | [`volumes`](#parameter-volumes) | array | List of volume definitions for the Container App. | -| [`workloadProfileType`](#parameter-workloadprofiletype) | string | Workload profile type to pin for container app execution. | +| [`workloadProfileName`](#parameter-workloadProfileName) | string | Workload profile type to pin for container app execution. | ### Parameter: `containers` @@ -1005,7 +1005,7 @@ List of volume definitions for the Container App. - Type: array - Default: `[]` -### Parameter: `workloadProfileType` +### Parameter: `workloadProfileName` Workload profile type to pin for container app execution. diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 9fdbeff0a6..932d614d46 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -109,8 +109,8 @@ param revisionSuffix string = '' @description('Optional. List of volume definitions for the Container App.') param volumes array = [] -@description('Optional. Workload profile type to pin for container app execution.') -param workloadProfileType string = '' +@description('Optional. Workload profile name to pin for container app execution.') +param workloadProfileName string = '' var secretList = !empty(secrets) ? secrets.secureList : [] @@ -142,7 +142,7 @@ resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (ena } } -resource containerApp 'Microsoft.App/containerApps@2022-10-01' = { +resource containerApp 'Microsoft.App/containerApps@2023-05-01' = { name: name tags: tags location: location @@ -184,7 +184,7 @@ resource containerApp 'Microsoft.App/containerApps@2022-10-01' = { } volumes: !empty(volumes) ? volumes : null } - workloadProfileType: workloadProfileType + workloadProfileName: workloadProfileName } } diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index 2a3862761b..b48e273362 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "7167506561528624829" + "templateHash": "10344651199371334726" }, "name": "Container Apps", "description": "This module deploys a Container App.", @@ -462,11 +462,11 @@ "description": "Optional. List of volume definitions for the Container App." } }, - "workloadProfileType": { + "workloadProfileName": { "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. Workload profile type to pin for container app execution." + "description": "Optional. Workload profile name to pin for container app execution." } } }, @@ -500,7 +500,7 @@ }, "containerApp": { "type": "Microsoft.App/containerApps", - "apiVersion": "2022-10-01", + "apiVersion": "2023-05-01", "name": "[parameters('name')]", "tags": "[parameters('tags')]", "location": "[parameters('location')]", @@ -542,7 +542,7 @@ }, "volumes": "[if(not(empty(parameters('volumes'))), parameters('volumes'), null())]" }, - "workloadProfileType": "[parameters('workloadProfileType')]" + "workloadProfileName": "[parameters('workloadProfileName')]" } }, "containerApp_diagnosticSettings": { @@ -632,14 +632,14 @@ "metadata": { "description": "The principal ID of the system assigned identity." }, - "value": "[if(and(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), contains(reference('containerApp', '2022-10-01', 'full').identity, 'principalId')), reference('containerApp', '2022-10-01', 'full').identity.principalId, '')]" + "value": "[if(and(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), contains(reference('containerApp', '2023-05-01', 'full').identity, 'principalId')), reference('containerApp', '2023-05-01', 'full').identity.principalId, '')]" }, "location": { "type": "string", "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('containerApp', '2022-10-01', 'full').location]" + "value": "[reference('containerApp', '2023-05-01', 'full').location]" } } } \ No newline at end of file diff --git a/avm/res/app/container-app/tests/e2e/defaults/dependencies.bicep b/avm/res/app/container-app/tests/e2e/defaults/dependencies.bicep index edf4adee4b..350d56b26f 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/dependencies.bicep @@ -4,12 +4,9 @@ param location string = resourceGroup().location @description('Required. The name of the Managed Environment to create.') param managedEnvironmentName string -resource managedEnvironment 'Microsoft.App/managedEnvironments@2022-10-01' = { +resource managedEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = { name: managedEnvironmentName location: location - sku: { - name: 'Consumption' - } properties: {} } diff --git a/avm/res/app/container-app/tests/e2e/max/dependencies.bicep b/avm/res/app/container-app/tests/e2e/max/dependencies.bicep index a6700c9d60..be547e344b 100644 --- a/avm/res/app/container-app/tests/e2e/max/dependencies.bicep +++ b/avm/res/app/container-app/tests/e2e/max/dependencies.bicep @@ -7,12 +7,9 @@ param managedEnvironmentName string @description('Required. The name of the managed identity to create.') param managedIdentityName string -resource managedEnvironment 'Microsoft.App/managedEnvironments@2022-10-01' = { +resource managedEnvironment 'Microsoft.App/managedEnvironments@2023-05-02-preview' = { name: managedEnvironmentName location: location - sku: { - name: 'Consumption' - } properties: {} } diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/dependencies.bicep index a6700c9d60..2070fb66c8 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/dependencies.bicep @@ -7,16 +7,13 @@ param managedEnvironmentName string @description('Required. The name of the managed identity to create.') param managedIdentityName string -resource managedEnvironment 'Microsoft.App/managedEnvironments@2022-10-01' = { +resource managedEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = { name: managedEnvironmentName location: location - sku: { - name: 'Consumption' - } properties: {} } -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2022-01-31-preview' = { +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: managedIdentityName location: location } From 0d6fd9df5e37ca37c9147ee7bbd54379b53db4b9 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 2 Jan 2024 14:39:16 -0600 Subject: [PATCH 08/42] Update api version of rg --- avm/res/app/container-app/tests/e2e/defaults/main.test.bicep | 2 +- avm/res/app/container-app/tests/e2e/max/main.test.bicep | 2 +- avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index ee6b815d5c..79514b90c7 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -29,7 +29,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { name: resourceGroupName location: location } diff --git a/avm/res/app/container-app/tests/e2e/max/main.test.bicep b/avm/res/app/container-app/tests/e2e/max/main.test.bicep index ae414bc543..f6f7eeaab6 100644 --- a/avm/res/app/container-app/tests/e2e/max/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/max/main.test.bicep @@ -29,7 +29,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { name: resourceGroupName location: location } diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index f1608b85c9..65317ecd56 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -29,7 +29,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { name: resourceGroupName location: location } From c89464e46131ac91dca299342092279570823a8c Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 2 Jan 2024 15:05:19 -0600 Subject: [PATCH 09/42] Updating various api versions --- avm/res/app/container-app/main.bicep | 2 +- avm/res/app/container-app/tests/e2e/max/dependencies.bicep | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 932d614d46..59e4ea8bc1 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -130,7 +130,7 @@ var builtInRoleNames = { 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') } -resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { +resource defaultTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableDefaultTelemetry) { name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' properties: { mode: 'Incremental' diff --git a/avm/res/app/container-app/tests/e2e/max/dependencies.bicep b/avm/res/app/container-app/tests/e2e/max/dependencies.bicep index be547e344b..2070fb66c8 100644 --- a/avm/res/app/container-app/tests/e2e/max/dependencies.bicep +++ b/avm/res/app/container-app/tests/e2e/max/dependencies.bicep @@ -7,13 +7,13 @@ param managedEnvironmentName string @description('Required. The name of the managed identity to create.') param managedIdentityName string -resource managedEnvironment 'Microsoft.App/managedEnvironments@2023-05-02-preview' = { +resource managedEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = { name: managedEnvironmentName location: location properties: {} } -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2022-01-31-preview' = { +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: managedIdentityName location: location } From 9930503aebf51483d98845a5f4cf64110bedd8e5 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 2 Jan 2024 20:43:13 -0600 Subject: [PATCH 10/42] Update readme.md and main.json --- avm/res/app/container-app/README.md | 30 +++++++++++++++++++++++------ avm/res/app/container-app/main.json | 6 +++--- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index 3d48aef25e..cfb770aa1b 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -14,10 +14,10 @@ This module deploys a Container App. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.App/containerApps` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.App/2022-10-01/containerApps) | -| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.App/containerApps` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.App/2023-05-01/containerApps) | | `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | ## Usage examples @@ -58,6 +58,14 @@ module containerApp 'br:public:avm/res/app/container-app:' = { environmentId: '' name: 'acamin001' // Non-required parameters + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] enableDefaultTelemetry: '' location: '' tags: { @@ -100,6 +108,16 @@ module containerApp 'br:public:avm/res/app/container-app:' = { "value": "acamin001" }, // Non-required parameters + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, "enableDefaultTelemetry": { "value": "" }, @@ -129,7 +147,7 @@ This instance deploys the module with most of its features enabled. via Bicep module ```bicep -module containerApp 'br/public:avm/res/automation/automation-account:' = { +module containerApp 'br:public:avm/res/app/container-app:' = { name: '${uniqueString(deployment().name, location)}-test-acamax' params: { // Required parameters @@ -309,7 +327,7 @@ This instance deploys the module in alignment with the best-practices of the Azu via Bicep module ```bicep -module containerApp 'br/public:avm/res/automation/automation-account:' = { +module containerApp 'br/public:AVM/bicep-registry-modules:' = { name: '${uniqueString(deployment().name, location)}-test-acawaf' params: { // Required parameters @@ -523,7 +541,7 @@ module containerApp 'br/public:avm/res/automation/automation-account:' | [`trafficRevisionName`](#parameter-trafficrevisionname) | string | Name of a revision. | | [`trafficWeight`](#parameter-trafficweight) | int | Traffic weight assigned to a revision. | | [`volumes`](#parameter-volumes) | array | List of volume definitions for the Container App. | -| [`workloadProfileName`](#parameter-workloadProfileName) | string | Workload profile type to pin for container app execution. | +| [`workloadProfileName`](#parameter-workloadprofilename) | string | Workload profile name to pin for container app execution. | ### Parameter: `containers` @@ -1007,7 +1025,7 @@ List of volume definitions for the Container App. ### Parameter: `workloadProfileName` -Workload profile type to pin for container app execution. +Workload profile name to pin for container app execution. - Required: No - Type: string diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index b48e273362..d5468a5e66 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "10344651199371334726" + "version": "0.21.1.54444", + "templateHash": "13143828735491157921" }, "name": "Container Apps", "description": "This module deploys a Container App.", @@ -487,7 +487,7 @@ "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", + "apiVersion": "2023-07-01", "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", "properties": { "mode": "Incremental", From b043a0e0e2b6cac84617ec76c36eb37a63d391ce Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 2 Jan 2024 21:03:38 -0600 Subject: [PATCH 11/42] Change enableDefaultTelemetry to enableTelemetry --- avm/res/app/container-app/README.md | 22 +++++++++---------- avm/res/app/container-app/main.bicep | 4 ++-- avm/res/app/container-app/main.json | 6 ++--- .../tests/e2e/defaults/main.test.bicep | 4 ++-- .../tests/e2e/max/main.test.bicep | 4 ++-- .../tests/e2e/waf-aligned/main.test.bicep | 4 ++-- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index cfb770aa1b..075ac32aaa 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -66,7 +66,7 @@ module containerApp 'br:public:avm/res/app/container-app:' = { workspaceResourceId: '' } ] - enableDefaultTelemetry: '' + enableTelemetry: '' location: '' tags: { Env: 'test' @@ -118,8 +118,8 @@ module containerApp 'br:public:avm/res/app/container-app:' = { } ] }, - "enableDefaultTelemetry": { - "value": "" + "enableTelemetry": { + "value": "" }, "location": { "value": "" @@ -189,7 +189,7 @@ module containerApp 'br:public:avm/res/app/container-app:' = { workspaceResourceId: '' } ] - enableDefaultTelemetry: '' + enableTelemetry: '' location: '' lock: { kind: 'CanNotDelete' @@ -275,8 +275,8 @@ module containerApp 'br:public:avm/res/app/container-app:' = { } ] }, - "enableDefaultTelemetry": { - "value": "" + "enableTelemetry": { + "value": "" }, "location": { "value": "" @@ -369,7 +369,7 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { workspaceResourceId: '' } ] - enableDefaultTelemetry: '' + enableTelemetry: '' location: '' lock: { kind: 'CanNotDelete' @@ -455,8 +455,8 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { } ] }, - "enableDefaultTelemetry": { - "value": "" + "enableTelemetry": { + "value": "" }, "location": { "value": "" @@ -516,7 +516,7 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { | [`customDomains`](#parameter-customdomains) | array | Custom domain bindings for Container App hostnames. | | [`dapr`](#parameter-dapr) | object | Dapr configuration for the Container App. | | [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | -| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`enableTelemetry`](#parameter-enableTelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | | [`exposedPort`](#parameter-exposedport) | int | Exposed Port in containers for TCP traffic from ingress. | | [`ingressAllowInsecure`](#parameter-ingressallowinsecure) | bool | Bool indicating if HTTP connections to is allowed. If set to false HTTP connections are automatically redirected to HTTPS connections. | | [`ingressExternal`](#parameter-ingressexternal) | bool | Bool indicating if app exposes an external http endpoint. | @@ -686,7 +686,7 @@ Resource ID of the diagnostic log analytics workspace. For security reasons, it - Required: No - Type: string -### Parameter: `enableDefaultTelemetry` +### Parameter: `enableTelemetry` Enable telemetry via a Globally Unique Identifier (GUID). diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 59e4ea8bc1..74391c2d82 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -64,7 +64,7 @@ param managedIdentities managedIdentitiesType param roleAssignments roleAssignmentType @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true +param enableTelemetry bool = true @description('Optional. Custom domain bindings for Container App hostnames.') param customDomains array = [] @@ -130,7 +130,7 @@ var builtInRoleNames = { 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') } -resource defaultTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableDefaultTelemetry) { +resource defaultTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' properties: { mode: 'Incremental' diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index d5468a5e66..a7b2e5bbef 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -358,7 +358,7 @@ "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute." } }, - "enableDefaultTelemetry": { + "enableTelemetry": { "type": "bool", "defaultValue": true, "metadata": { @@ -485,7 +485,7 @@ }, "resources": { "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", + "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2023-07-01", "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", @@ -642,4 +642,4 @@ "value": "[reference('containerApp', '2023-05-01', 'full').location]" } } -} \ No newline at end of file +} diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index 79514b90c7..3138416bfe 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -18,7 +18,7 @@ param location string = deployment().location param serviceShort string = 'acadef' @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true +param enableTelemetry bool = true @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' @@ -79,7 +79,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' 'hidden-title': 'This is visible in the resource name' Env: 'test' } - enableDefaultTelemetry: enableDefaultTelemetry + enableTelemetry: enableTelemetry environmentId: nestedDependencies.outputs.managedEnvironmentResourceId location: location containers: [ diff --git a/avm/res/app/container-app/tests/e2e/max/main.test.bicep b/avm/res/app/container-app/tests/e2e/max/main.test.bicep index f6f7eeaab6..efe5835088 100644 --- a/avm/res/app/container-app/tests/e2e/max/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/max/main.test.bicep @@ -18,7 +18,7 @@ param location string = deployment().location param serviceShort string = 'acamax' @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true +param enableTelemetry bool = true @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' @@ -80,7 +80,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' 'hidden-title': 'This is visible in the resource name' Env: 'test' } - enableDefaultTelemetry: enableDefaultTelemetry + enableTelemetry: enableTelemetry environmentId: nestedDependencies.outputs.managedEnvironmentResourceId location: location lock: { diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index 65317ecd56..1e1ee315ed 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -18,7 +18,7 @@ param location string = deployment().location param serviceShort string = 'acawaf' @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true +param enableTelemetry bool = true @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' @@ -80,7 +80,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' 'hidden-title': 'This is visible in the resource name' Env: 'test' } - enableDefaultTelemetry: enableDefaultTelemetry + enableTelemetry: enableTelemetry environmentId: nestedDependencies.outputs.managedEnvironmentResourceId location: location lock: { From 6b3e060ab8e86c6bf6df15074eacc05badaacc5b Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 2 Jan 2024 21:12:05 -0600 Subject: [PATCH 12/42] Fix serviceShort name for default test --- avm/res/app/container-app/main.json | 6 +++--- .../app/container-app/tests/e2e/defaults/main.test.bicep | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index a7b2e5bbef..821b0d105b 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.21.1.54444", - "templateHash": "13143828735491157921" + "version": "0.24.24.22086", + "templateHash": "15691555628767004491" }, "name": "Container Apps", "description": "This module deploys a Container App.", @@ -642,4 +642,4 @@ "value": "[reference('containerApp', '2023-05-01', 'full').location]" } } -} +} \ No newline at end of file diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index 3138416bfe..22110e5655 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -15,13 +15,13 @@ param resourceGroupName string = 'dep-${namePrefix}-app.containerApps-${serviceS param location 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 = 'acadef' +param serviceShort string = 'acamin' @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') param enableTelemetry bool = true @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '#_namePrefix_#' +param namePrefix string = 'avm' // =========== // // Deployments // From 4ab3582064fefea2d5a6a7d588ddb06715b18fb7 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 2 Jan 2024 21:34:37 -0600 Subject: [PATCH 13/42] Fix telemetry resource --- avm/res/app/container-app/main.bicep | 10 ++++++++-- avm/res/app/container-app/main.json | 14 ++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 74391c2d82..50b64b5329 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -130,14 +130,20 @@ var builtInRoleNames = { 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') } -resource defaultTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.app-container-app.${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' + } + } } } } diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index 821b0d105b..adf28242f5 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "15691555628767004491" + "templateHash": "2530373300582115367" }, "name": "Container Apps", "description": "This module deploys a Container App.", @@ -484,17 +484,23 @@ } }, "resources": { - "defaultTelemetry": { + "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2023-07-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "name": "[format('46d3xbcp.res.app-container-app.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", - "resources": [] + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } } } }, From d3127de48f8b9806b95dd9491c40a0f4484f1663 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Tue, 2 Jan 2024 21:51:59 -0600 Subject: [PATCH 14/42] Fix telemetry resource --- avm/res/app/container-app/main.bicep | 10 ++++++++-- avm/res/app/container-app/main.json | 14 ++++++++++---- .../tests/e2e/defaults/main.test.bicep | 2 +- avm/res/batch/batch-account/main.json | 4 ++-- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 74391c2d82..50b64b5329 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -130,14 +130,20 @@ var builtInRoleNames = { 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') } -resource defaultTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.app-container-app.${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' + } + } } } } diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index 821b0d105b..adf28242f5 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "15691555628767004491" + "templateHash": "2530373300582115367" }, "name": "Container Apps", "description": "This module deploys a Container App.", @@ -484,17 +484,23 @@ } }, "resources": { - "defaultTelemetry": { + "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2023-07-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "name": "[format('46d3xbcp.res.app-container-app.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", - "resources": [] + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } } } }, diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index 22110e5655..b6941277d8 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -21,7 +21,7 @@ param serviceShort string = 'acamin' param enableTelemetry bool = true @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = 'avm' +param namePrefix string = '#_namePrefix_#' // =========== // // Deployments // diff --git a/avm/res/batch/batch-account/main.json b/avm/res/batch/batch-account/main.json index 1e54643441..a467b138cd 100644 --- a/avm/res/batch/batch-account/main.json +++ b/avm/res/batch/batch-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "2440542999931048241" + "version": "0.24.24.22086", + "templateHash": "466422337829619419" }, "name": "Batch Accounts", "description": "This module deploys a Batch Account.", From f7ed1a0eaa1dac3d0831aa5715837655d30dd461 Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:59:29 -0600 Subject: [PATCH 15/42] Update avm/res/app/container-app/version.json Co-authored-by: Alexander Sehr --- avm/res/app/container-app/version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/app/container-app/version.json b/avm/res/app/container-app/version.json index 96236a61ba..7fa401bdf7 100644 --- a/avm/res/app/container-app/version.json +++ b/avm/res/app/container-app/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.4", + "version": "0.1", "pathFilters": [ "./main.json" ] From dae8768cabb06e431601943de524ad56aa8ce06c Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:03:51 -0600 Subject: [PATCH 16/42] Update avm/res/app/container-app/main.bicep Co-authored-by: Alexander Sehr --- avm/res/app/container-app/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 50b64b5329..f83e54e119 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -60,7 +60,7 @@ param diagnosticSettings diagnosticSettingType @description('Optional. The managed identity definition for this resource.') param managedIdentities managedIdentitiesType -@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute.') +@description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') From 908a4326b5dcb34f7b377e41a85088089fcc2c8e Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:04:09 -0600 Subject: [PATCH 17/42] Update avm/res/app/container-app/main.bicep Co-authored-by: Alexander Sehr --- avm/res/app/container-app/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index f83e54e119..2dd1809028 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -63,7 +63,7 @@ param managedIdentities managedIdentitiesType @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +@description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true @description('Optional. Custom domain bindings for Container App hostnames.') From 8a1af0da85d273ecdca287db1448baa3ef244547 Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:05:39 -0600 Subject: [PATCH 18/42] Update avm/res/app/container-app/main.bicep Co-authored-by: Alexander Sehr --- avm/res/app/container-app/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 2dd1809028..f65ce719cb 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -275,7 +275,7 @@ type diagnosticSettingType = { categoryGroup: string? }[]? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') category: string From 30dcf0005773bbeb4b5e57a19f23f0142eade9bc Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Fri, 19 Jan 2024 12:23:57 -0600 Subject: [PATCH 19/42] Undo unintentional change to batch account --- avm/res/batch/batch-account/main.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/batch/batch-account/main.json b/avm/res/batch/batch-account/main.json index 9caf25b6fd..fe9ce38a52 100644 --- a/avm/res/batch/batch-account/main.json +++ b/avm/res/batch/batch-account/main.json @@ -1486,4 +1486,4 @@ "value": "[if(and(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), contains(reference('batchAccount', '2022-06-01', 'full').identity, 'principalId')), reference('batchAccount', '2022-06-01', 'full').identity.principalId, '')]" } } -} +} \ No newline at end of file From 6443274b144cdfed64049c9a2ae24c0adf9cddf9 Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:25:29 -0600 Subject: [PATCH 20/42] Update avm/res/app/container-app/tests/e2e/defaults/main.test.bicep Co-authored-by: Alexander Sehr --- avm/res/app/container-app/tests/e2e/defaults/main.test.bicep | 3 --- 1 file changed, 3 deletions(-) diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index b6941277d8..bbe4a3e375 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -17,9 +17,6 @@ param location 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 = 'acamin' -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableTelemetry bool = true - @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' From a28f0e5d9ff90854e7dcd764da9f5520b99e9776 Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:25:47 -0600 Subject: [PATCH 21/42] Update avm/res/app/container-app/tests/e2e/defaults/main.test.bicep Co-authored-by: Alexander Sehr --- .../tests/e2e/defaults/main.test.bicep | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index bbe4a3e375..146cdb89e5 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -64,19 +64,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-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 - } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Env: 'test' - } - enableTelemetry: enableTelemetry environmentId: nestedDependencies.outputs.managedEnvironmentResourceId location: location containers: [ From b2d8ded43fd9ef1aea5fa3b2b31ffa5e9e20861e Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:25:58 -0600 Subject: [PATCH 22/42] Update avm/res/app/container-app/tests/e2e/max/main.test.bicep Co-authored-by: Alexander Sehr --- avm/res/app/container-app/tests/e2e/max/main.test.bicep | 3 --- 1 file changed, 3 deletions(-) diff --git a/avm/res/app/container-app/tests/e2e/max/main.test.bicep b/avm/res/app/container-app/tests/e2e/max/main.test.bicep index efe5835088..1d98a3b520 100644 --- a/avm/res/app/container-app/tests/e2e/max/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/max/main.test.bicep @@ -17,9 +17,6 @@ param location 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 = 'acamax' -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableTelemetry bool = true - @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' From ce170d9c3cfb6abbde3a027ac73a3e11f4022ca8 Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:26:21 -0600 Subject: [PATCH 23/42] Update avm/res/app/container-app/tests/e2e/max/main.test.bicep Co-authored-by: Alexander Sehr --- .../tests/e2e/max/main.test.bicep | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/avm/res/app/container-app/tests/e2e/max/main.test.bicep b/avm/res/app/container-app/tests/e2e/max/main.test.bicep index 1d98a3b520..6209db1b36 100644 --- a/avm/res/app/container-app/tests/e2e/max/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/max/main.test.bicep @@ -77,7 +77,23 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' 'hidden-title': 'This is visible in the resource name' Env: 'test' } - enableTelemetry: enableTelemetry + 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' + } + ] environmentId: nestedDependencies.outputs.managedEnvironmentResourceId location: location lock: { From d2aed9dd1c49981243f1ab9ff4f1ce2bc54fd7a6 Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:26:41 -0600 Subject: [PATCH 24/42] Update avm/res/app/container-app/tests/e2e/max/dependencies.bicep Co-authored-by: Alexander Sehr --- avm/res/app/container-app/tests/e2e/max/dependencies.bicep | 3 +++ 1 file changed, 3 insertions(+) diff --git a/avm/res/app/container-app/tests/e2e/max/dependencies.bicep b/avm/res/app/container-app/tests/e2e/max/dependencies.bicep index 2070fb66c8..634defb509 100644 --- a/avm/res/app/container-app/tests/e2e/max/dependencies.bicep +++ b/avm/res/app/container-app/tests/e2e/max/dependencies.bicep @@ -21,5 +21,8 @@ resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023- @description('The resource ID of the created Managed Identity.') output managedIdentityResourceId string = managedIdentity.id +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + @description('The resource ID of the created Managed Environment.') output managedEnvironmentResourceId string = managedEnvironment.id From cf49b4f2f5560fd9a594f1815459bd98f8b51f0e Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:27:01 -0600 Subject: [PATCH 25/42] Update avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep Co-authored-by: Alexander Sehr --- .../app/container-app/tests/e2e/waf-aligned/main.test.bicep | 3 --- 1 file changed, 3 deletions(-) diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index 1e1ee315ed..55f1152112 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -17,9 +17,6 @@ param location 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 = 'acawaf' -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableTelemetry bool = true - @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' From 908c93918e1e697e677e7a3e6ad8d4e75b119760 Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:27:14 -0600 Subject: [PATCH 26/42] Update avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep Co-authored-by: Alexander Sehr --- avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep | 1 - 1 file changed, 1 deletion(-) diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index 55f1152112..7348b376af 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -77,7 +77,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' 'hidden-title': 'This is visible in the resource name' Env: 'test' } - enableTelemetry: enableTelemetry environmentId: nestedDependencies.outputs.managedEnvironmentResourceId location: location lock: { From a6b19d531da14b8e153c4db0599819d5a5cf5b13 Mon Sep 17 00:00:00 2001 From: Zach Trocinski <30884663+oZakari@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:54:30 -0600 Subject: [PATCH 27/42] Update avm/res/app/container-app/main.bicep Co-authored-by: Alexander Sehr --- avm/res/app/container-app/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index f65ce719cb..3d5a98a256 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -253,7 +253,7 @@ output resourceGroupName string = resourceGroup().name output name string = containerApp.name @description('The principal ID of the system assigned identity.') -output systemAssignedMIPrincipalId string = (managedIdentities.?systemAssigned ?? false) && contains(containerApp.identity, 'principalId') ? containerApp.identity.principalId : '' +output systemAssignedMIPrincipalId string = containerApp.?identity.?principalId ?? '' @description('The location the resource was deployed into.') output location string = containerApp.location From fd464248660e144d4a36f134eb4690a08bcbebb3 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Fri, 19 Jan 2024 12:55:30 -0600 Subject: [PATCH 28/42] Uncommented line for container-app within codeowners --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c73d019d19..937da4c306 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,7 +6,7 @@ #/avm/res/aad/domain-service/ @Azure/avm-res-aad-domainservice-module-owners-bicep #/avm/res/analysis-services/server/ @Azure/avm-res-analysisservices-server-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/api-management/service/ @Azure/avm-res-apimanagement-service-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/app/container-app/ @Azure/avm-res-app-containerapp-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/app/container-app/ @Azure/avm-res-app-containerapp-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/app/managed-environment/ @Azure/avm-res-app-managedenvironment-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/app-configuration/configuration-store/ @Azure/avm-res-appconfiguration-configurationstore-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/authorization/lock/ @Azure/avm-res-authorization-lock-module-owners-bicep @Azure/avm-core-team-technical-bicep From eda69e5a1a6f43bb7b21536489a20edb2f52b3b6 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Fri, 19 Jan 2024 13:20:02 -0600 Subject: [PATCH 29/42] Switch pipeline agent to support latest ubuntu version --- .github/workflows/avm.res.app.container-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/avm.res.app.container-app.yml b/.github/workflows/avm.res.app.container-app.yml index e3b58f30c1..ce37875211 100644 --- a/.github/workflows/avm.res.app.container-app.yml +++ b/.github/workflows/avm.res.app.container-app.yml @@ -44,7 +44,7 @@ jobs: # Initialize pipeline # ########################### job_initialize_pipeline: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest name: "Initialize pipeline" steps: - name: "Checkout" From 255d96cc98ff4a39980a41107ff4820847805987 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Fri, 19 Jan 2024 13:33:48 -0600 Subject: [PATCH 30/42] Update readme and main.json --- avm/res/app/container-app/README.md | 93 +++++++++++++++-------------- avm/res/app/container-app/main.json | 12 ++-- 2 files changed, 53 insertions(+), 52 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index 075ac32aaa..64f36b6718 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -9,6 +9,7 @@ This module deploys a Container App. - [Parameters](#Parameters) - [Outputs](#Outputs) - [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) ## Resource Types @@ -58,20 +59,7 @@ module containerApp 'br:public:avm/res/app/container-app:' = { environmentId: '' name: 'acamin001' // Non-required parameters - diagnosticSettings: [ - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - storageAccountResourceId: '' - workspaceResourceId: '' - } - ] - enableTelemetry: '' location: '' - tags: { - Env: 'test' - 'hidden-title': 'This is visible in the resource name' - } } } ``` @@ -108,27 +96,8 @@ module containerApp 'br:public:avm/res/app/container-app:' = { "value": "acamin001" }, // Non-required parameters - "diagnosticSettings": { - "value": [ - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "storageAccountResourceId": "", - "workspaceResourceId": "" - } - ] - }, - "enableTelemetry": { - "value": "" - }, "location": { "value": "" - }, - "tags": { - "value": { - "Env": "test", - "hidden-title": "This is visible in the resource name" - } } } } @@ -189,7 +158,6 @@ module containerApp 'br:public:avm/res/app/container-app:' = { workspaceResourceId: '' } ] - enableTelemetry: '' location: '' lock: { kind: 'CanNotDelete' @@ -200,6 +168,23 @@ module containerApp 'br:public:avm/res/app/container-app:' = { '' ] } + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] secrets: { secureList: [ { @@ -275,9 +260,6 @@ module containerApp 'br:public:avm/res/app/container-app:' = { } ] }, - "enableTelemetry": { - "value": "" - }, "location": { "value": "" }, @@ -294,6 +276,25 @@ module containerApp 'br:public:avm/res/app/container-app:' = { ] } }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, "secrets": { "value": { "secureList": [ @@ -369,7 +370,6 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { workspaceResourceId: '' } ] - enableTelemetry: '' location: '' lock: { kind: 'CanNotDelete' @@ -455,9 +455,6 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { } ] }, - "enableTelemetry": { - "value": "" - }, "location": { "value": "" }, @@ -516,7 +513,7 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { | [`customDomains`](#parameter-customdomains) | array | Custom domain bindings for Container App hostnames. | | [`dapr`](#parameter-dapr) | object | Dapr configuration for the Container App. | | [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | -| [`enableTelemetry`](#parameter-enableTelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`exposedPort`](#parameter-exposedport) | int | Exposed Port in containers for TCP traffic from ingress. | | [`ingressAllowInsecure`](#parameter-ingressallowinsecure) | bool | Bool indicating if HTTP connections to is allowed. If set to false HTTP connections are automatically redirected to HTTPS connections. | | [`ingressExternal`](#parameter-ingressexternal) | bool | Bool indicating if app exposes an external http endpoint. | @@ -530,7 +527,7 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { | [`maxInactiveRevisions`](#parameter-maxinactiverevisions) | int | Max inactive revisions a Container App can have. | | [`registries`](#parameter-registries) | array | Collection of private container registry credentials for containers used by the Container app. | | [`revisionSuffix`](#parameter-revisionsuffix) | string | User friendly suffix that is appended to the revision name. | -| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | | [`scaleMaxReplicas`](#parameter-scalemaxreplicas) | int | Maximum number of container replicas. Defaults to 10 if not set. | | [`scaleMinReplicas`](#parameter-scaleminreplicas) | int | Minimum number of container replicas. | | [`scaleRules`](#parameter-scalerules) | array | Scaling rules. | @@ -611,7 +608,7 @@ The diagnostic settings of the service. | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | | [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -660,7 +657,7 @@ The full ARM resource ID of the Marketplace resource to which you would like to ### Parameter: `diagnosticSettings.metricCategories` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. - Required: No - Type: array @@ -688,7 +685,7 @@ Resource ID of the diagnostic log analytics workspace. For security reasons, it ### Parameter: `enableTelemetry` -Enable telemetry via a Globally Unique Identifier (GUID). +Enable/Disable usage telemetry for module. - Required: No - Type: bool @@ -857,7 +854,7 @@ User friendly suffix that is appended to the revision name. ### Parameter: `roleAssignments` -Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute. +Array of role assignments to create. - Required: No - Type: array @@ -1045,3 +1042,7 @@ Workload profile name to pin for container app execution. ## Cross-referenced modules _None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index adf28242f5..d04c694daa 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2530373300582115367" + "version": "0.21.1.54444", + "templateHash": "12570382725911183040" }, "name": "Container Apps", "description": "This module deploys a Container App.", @@ -66,7 +66,7 @@ }, "nullable": true, "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." } }, "logAnalyticsDestinationType": { @@ -355,14 +355,14 @@ "roleAssignments": { "$ref": "#/definitions/roleAssignmentType", "metadata": { - "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute." + "description": "Optional. Array of role assignments to create." } }, "enableTelemetry": { "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } }, "customDomains": { @@ -638,7 +638,7 @@ "metadata": { "description": "The principal ID of the system assigned identity." }, - "value": "[if(and(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), contains(reference('containerApp', '2023-05-01', 'full').identity, 'principalId')), reference('containerApp', '2023-05-01', 'full').identity.principalId, '')]" + "value": "[coalesce(tryGet(tryGet(reference('containerApp', '2023-05-01', 'full'), 'identity'), 'principalId'), '')]" }, "location": { "type": "string", From b78cba85583f315af97aacc8dd63a3565cdaa87e Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Fri, 19 Jan 2024 13:39:47 -0600 Subject: [PATCH 31/42] Update readme.md --- avm/res/app/container-app/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index 64f36b6718..0ba6a6562e 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -26,7 +26,7 @@ The following section provides usage examples for the module, which were used to >**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. ->**Note**: To reference the module, please use the following syntax `br:bicep/modules/app.container-app:1.0.0`. +>**Note**: To reference the module, please use the following syntax `br/public:AVM/bicep-registry-modules:`. - [Using only defaults](#example-1-using-only-defaults) - [Using large parameter set](#example-2-using-large-parameter-set) @@ -42,7 +42,7 @@ This instance deploys the module with the minimum set of required parameters. via Bicep module ```bicep -module containerApp 'br:public:avm/res/app/container-app:' = { +module containerApp 'br/public:AVM/bicep-registry-modules:' = { name: '${uniqueString(deployment().name, location)}-test-acamin' params: { // Required parameters @@ -116,7 +116,7 @@ This instance deploys the module with most of its features enabled. via Bicep module ```bicep -module containerApp 'br:public:avm/res/app/container-app:' = { +module containerApp 'br/public:AVM/bicep-registry-modules:' = { name: '${uniqueString(deployment().name, location)}-test-acamax' params: { // Required parameters From e446ad51e346bbf02b4bba80f2d72b09a3ffdd1d Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Fri, 19 Jan 2024 14:38:23 -0600 Subject: [PATCH 32/42] Add additional WAF poperties for test --- .../app/container-app/tests/e2e/waf-aligned/main.test.bicep | 3 +++ 1 file changed, 3 insertions(+) diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index 7348b376af..9915535dca 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -65,6 +65,9 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' + ingressExternal: false + ingressAllowInsecure: false + diagnosticSettings: [ { eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName From 0ed87325c037489ac5de837d631547b12bbfade8 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Fri, 19 Jan 2024 14:42:10 -0600 Subject: [PATCH 33/42] Update readme.md for waf additions --- avm/res/app/container-app/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index 0ba6a6562e..ba811d8a5f 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -370,6 +370,8 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { workspaceResourceId: '' } ] + ingressAllowInsecure: false + ingressExternal: false location: '' lock: { kind: 'CanNotDelete' @@ -455,6 +457,12 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { } ] }, + "ingressAllowInsecure": { + "value": false + }, + "ingressExternal": { + "value": false + }, "location": { "value": "" }, From 96817eb51594a25f9eca89dff748d77b65c640b7 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Fri, 19 Jan 2024 14:48:20 -0600 Subject: [PATCH 34/42] Removed secrets as not applicable for WAF --- avm/res/app/container-app/README.md | 18 ------------------ .../tests/e2e/waf-aligned/main.test.bicep | 8 -------- 2 files changed, 26 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index ba811d8a5f..65e4a54a91 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -382,14 +382,6 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { '' ] } - secrets: { - secureList: [ - { - name: 'customtest' - value: '' - } - ] - } tags: { Env: 'test' 'hidden-title': 'This is visible in the resource name' @@ -479,16 +471,6 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { ] } }, - "secrets": { - "value": { - "secureList": [ - { - "name": "customtest", - "value": "" - } - ] - } - }, "tags": { "value": { "Env": "test", diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index 9915535dca..213d206f8a 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -91,14 +91,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' nestedDependencies.outputs.managedIdentityResourceId ] } - secrets: { - secureList: [ - { - name: 'customtest' - value: guid(deployment().name) - } - ] - } containers: [ { name: 'simple-hello-world-container' From 1357cdf8a043d6a52d78ce1fd56f0f97ec051320 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Fri, 19 Jan 2024 16:46:49 -0600 Subject: [PATCH 35/42] Fix telemetry resource --- avm/res/app/container-app/main.bicep | 48 ++++++++++++++-------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 3d5a98a256..059d7cfdbf 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -131,7 +131,7 @@ var builtInRoleNames = { } resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.app-container-app.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + name: '46d3xbcp.res.app-containerapp.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' properties: { mode: 'Incremental' template: { @@ -195,29 +195,29 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = { } resource containerApp_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: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'AllLogs' - enabled: true - } - ] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType -} -scope: containerApp + name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' + properties: { + storageAccountId: diagnosticSetting.?storageAccountResourceId + workspaceId: diagnosticSetting.?workspaceResourceId + eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId + eventHubName: diagnosticSetting.?eventHubName + metrics: diagnosticSetting.?metricCategories ?? [ + { + category: 'AllMetrics' + timeGrain: null + enabled: true + } + ] + logs: diagnosticSetting.?logCategoriesAndGroups ?? [ + { + categoryGroup: 'AllLogs' + enabled: true + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: containerApp }] resource containerApp_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { From d477e0e013fa435b90d1a156fadf953dfc368270 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Fri, 19 Jan 2024 17:05:01 -0600 Subject: [PATCH 36/42] Fixed role assignment udt --- avm/res/app/container-app/README.md | 4 ++-- avm/res/app/container-app/main.bicep | 2 +- avm/res/app/container-app/main.json | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index 65e4a54a91..2ee1ef7815 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -860,7 +860,7 @@ Array of role assignments to create. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | | [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | | [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | | [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | @@ -882,7 +882,7 @@ The role to assign. You can provide either the display name of the role definiti ### Parameter: `roleAssignments.condition` -The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". - Required: No - Type: string diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 059d7cfdbf..d5a0372a76 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -329,7 +329,7 @@ type roleAssignmentType = { @description('Optional. The description of the role assignment.') description: string? - @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container"') + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') condition: string? @description('Optional. Version of the condition.') diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index d04c694daa..9305ed8815 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "12570382725911183040" + "templateHash": "9636517864951680672" }, "name": "Container Apps", "description": "This module deploys a Container App.", @@ -209,7 +209,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." } }, "conditionVersion": { @@ -488,7 +488,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.app-container-app.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.app-containerapp.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { From 000f11a6b62294d152fd083580e3351c16305559 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Mon, 22 Jan 2024 15:37:33 -0600 Subject: [PATCH 37/42] Attempt to fix readme.md --- avm/res/app/container-app/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index 2ee1ef7815..b1a6261487 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -26,7 +26,7 @@ The following section provides usage examples for the module, which were used to >**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. ->**Note**: To reference the module, please use the following syntax `br/public:AVM/bicep-registry-modules:`. +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/app/container-app:`. - [Using only defaults](#example-1-using-only-defaults) - [Using large parameter set](#example-2-using-large-parameter-set) @@ -42,7 +42,7 @@ This instance deploys the module with the minimum set of required parameters. via Bicep module ```bicep -module containerApp 'br/public:AVM/bicep-registry-modules:' = { +module containerApp 'br/public:avm/res/app/container-app:' = { name: '${uniqueString(deployment().name, location)}-test-acamin' params: { // Required parameters @@ -116,7 +116,7 @@ This instance deploys the module with most of its features enabled. via Bicep module ```bicep -module containerApp 'br/public:AVM/bicep-registry-modules:' = { +module containerApp 'br/public:avm/res/app/container-app:' = { name: '${uniqueString(deployment().name, location)}-test-acamax' params: { // Required parameters @@ -328,7 +328,7 @@ This instance deploys the module in alignment with the best-practices of the Azu via Bicep module ```bicep -module containerApp 'br/public:AVM/bicep-registry-modules:' = { +module containerApp 'br/public:avm/res/app/container-app:' = { name: '${uniqueString(deployment().name, location)}-test-acawaf' params: { // Required parameters From 11f450980e15986c9653560e0bca9517713d1bfc Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Mon, 22 Jan 2024 20:19:51 -0600 Subject: [PATCH 38/42] Remove extra line --- avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep | 1 - 1 file changed, 1 deletion(-) diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index 213d206f8a..a9800b6bda 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -67,7 +67,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${namePrefix}${serviceShort}001' ingressExternal: false ingressAllowInsecure: false - diagnosticSettings: [ { eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName From 0fa64f0ae8c5b46aac8c30815a424829ea28075d Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Mon, 22 Jan 2024 20:33:29 -0600 Subject: [PATCH 39/42] Adjust allLogs capitalization --- avm/res/app/container-app/main.bicep | 4 ++-- avm/res/app/container-app/main.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index d5a0372a76..1d8efd0d4b 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -210,7 +210,7 @@ resource containerApp_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@ ] logs: diagnosticSetting.?logCategoriesAndGroups ?? [ { - categoryGroup: 'AllLogs' + categoryGroup: 'allLogs' enabled: true } ] @@ -271,7 +271,7 @@ type diagnosticSettingType = { @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') category: string? - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'allLogs\' to collect all logs.') categoryGroup: string? }[]? diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index 9305ed8815..986bc715ab 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -41,7 +41,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'allLogs' to collect all logs." } } } @@ -566,7 +566,7 @@ "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", + "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())))]", "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, From 6113d9a53e2125fb74d7017462f2cd1f691f290c Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Mon, 22 Jan 2024 21:47:42 -0600 Subject: [PATCH 40/42] Remove diagnostic settings --- avm/res/app/container-app/README.md | 65 +++--------------- avm/res/app/container-app/main.bicep | 67 ------------------- .../tests/e2e/defaults/main.test.bicep | 14 ---- .../tests/e2e/max/dependencies.bicep | 6 +- .../tests/e2e/max/main.test.bicep | 22 ------ .../tests/e2e/waf-aligned/main.test.bicep | 22 ------ 6 files changed, 15 insertions(+), 181 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index b1a6261487..c2e0a4c238 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -26,23 +26,20 @@ The following section provides usage examples for the module, which were used to >**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. ->**Note**: To reference the module, please use the following syntax `br/public:avm/res/app/container-app:`. +>**Note**: To reference the module, please use the following syntax `br/public:AVM/bicep-registry-modules:`. -- [Using only defaults](#example-1-using-only-defaults) -- [Using large parameter set](#example-2-using-large-parameter-set) -- [WAF-aligned](#example-3-waf-aligned) - -### Example 1: _Using only defaults_ - -This instance deploys the module with the minimum set of required parameters. +- [Defaults](#example-1-defaults) +- [Max](#example-2-max) +- [Waf-Aligned](#example-3-waf-aligned) +### Example 1: _Defaults_
via Bicep module ```bicep -module containerApp 'br/public:avm/res/app/container-app:' = { +module containerApp 'br/public:AVM/bicep-registry-modules:' = { name: '${uniqueString(deployment().name, location)}-test-acamin' params: { // Required parameters @@ -106,17 +103,14 @@ module containerApp 'br/public:avm/res/app/container-app:' = {

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

via Bicep module ```bicep -module containerApp 'br/public:avm/res/app/container-app:' = { +module containerApp 'br/public:AVM/bicep-registry-modules:' = { name: '${uniqueString(deployment().name, location)}-test-acamax' params: { // Required parameters @@ -150,14 +144,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { environmentId: '' name: 'acamax001' // Non-required parameters - diagnosticSettings: [ - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - storageAccountResourceId: '' - workspaceResourceId: '' - } - ] location: '' lock: { kind: 'CanNotDelete' @@ -250,16 +236,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { "value": "acamax001" }, // Non-required parameters - "diagnosticSettings": { - "value": [ - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "storageAccountResourceId": "", - "workspaceResourceId": "" - } - ] - }, "location": { "value": "" }, @@ -318,17 +294,14 @@ module containerApp 'br/public:avm/res/app/container-app:' = {

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

via Bicep module ```bicep -module containerApp 'br/public:avm/res/app/container-app:' = { +module containerApp 'br/public:AVM/bicep-registry-modules:' = { name: '${uniqueString(deployment().name, location)}-test-acawaf' params: { // Required parameters @@ -362,14 +335,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { environmentId: '' name: 'acawaf001' // Non-required parameters - diagnosticSettings: [ - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - storageAccountResourceId: '' - workspaceResourceId: '' - } - ] ingressAllowInsecure: false ingressExternal: false location: '' @@ -439,16 +404,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { "value": "acawaf001" }, // Non-required parameters - "diagnosticSettings": { - "value": [ - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "storageAccountResourceId": "", - "workspaceResourceId": "" - } - ] - }, "ingressAllowInsecure": { "value": false }, diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 1d8efd0d4b..d7b7d34169 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -54,9 +54,6 @@ param tags object? @description('Optional. Collection of private container registry credentials for containers used by the Container app.') param registries array = [] -@description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType - @description('Optional. The managed identity definition for this resource.') param managedIdentities managedIdentitiesType @@ -194,32 +191,6 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = { } } -resource containerApp_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: diagnosticSetting.?metricCategories ?? [ - { - category: 'AllMetrics' - timeGrain: null - enabled: true - } - ] - logs: diagnosticSetting.?logCategoriesAndGroups ?? [ - { - categoryGroup: 'allLogs' - enabled: true - } - ] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType - } - scope: containerApp -}] - resource containerApp_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { name: lock.?name ?? 'lock-${name}' properties: { @@ -262,44 +233,6 @@ output location string = containerApp.location // Definitions // // =============== // -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'allLogs\' to collect all logs.') - categoryGroup: string? - }[]? - - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') - category: string - }[]? - - @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') - workspaceResourceId: string? - - @description('Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') - storageAccountResourceId: string? - - @description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') - eventHubAuthorizationRuleResourceId: string? - - @description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? - type managedIdentitiesType = { @description('Optional. Enables system assigned managed identity on the resource.') systemAssigned: bool? diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index 146cdb89e5..19ba7a0c5a 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -40,20 +40,6 @@ module nestedDependencies 'dependencies.bicep' = { } } -// Diagnostics -// =========== -module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { - scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' - params: { - storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' - logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' - eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' - eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' - location: location - } -} - // ============== // // Test Execution // // ============== // diff --git a/avm/res/app/container-app/tests/e2e/max/dependencies.bicep b/avm/res/app/container-app/tests/e2e/max/dependencies.bicep index 634defb509..0ca3555668 100644 --- a/avm/res/app/container-app/tests/e2e/max/dependencies.bicep +++ b/avm/res/app/container-app/tests/e2e/max/dependencies.bicep @@ -10,7 +10,11 @@ param managedIdentityName string resource managedEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = { name: managedEnvironmentName location: location - properties: {} + properties: { + appLogsConfiguration: { + destination: 'azure-monitor' + } + } } resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { diff --git a/avm/res/app/container-app/tests/e2e/max/main.test.bicep b/avm/res/app/container-app/tests/e2e/max/main.test.bicep index 6209db1b36..b7443708df 100644 --- a/avm/res/app/container-app/tests/e2e/max/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/max/main.test.bicep @@ -41,20 +41,6 @@ module nestedDependencies 'dependencies.bicep' = { } } -// Diagnostics -// =========== -module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { - scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' - params: { - storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' - logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' - eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' - eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' - location: location - } -} - // ============== // // Test Execution // // ============== // @@ -65,14 +51,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-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 - } - ] tags: { 'hidden-title': 'This is visible in the resource name' Env: 'test' diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index a9800b6bda..73446fb75e 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -41,20 +41,6 @@ module nestedDependencies 'dependencies.bicep' = { } } -// Diagnostics -// =========== -module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { - scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' - params: { - storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' - logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' - eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' - eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' - location: location - } -} - // ============== // // Test Execution // // ============== // @@ -67,14 +53,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${namePrefix}${serviceShort}001' ingressExternal: false ingressAllowInsecure: false - 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' Env: 'test' From 094f24ccf6f619b478e0c68e1f947af8ba21de06 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Mon, 22 Jan 2024 21:49:39 -0600 Subject: [PATCH 41/42] Update readme and main.json --- avm/res/app/container-app/README.md | 114 +++-------------------- avm/res/app/container-app/main.json | 137 +--------------------------- 2 files changed, 16 insertions(+), 235 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index c2e0a4c238..ca2ab2b832 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -18,7 +18,6 @@ This module deploys a Container App. | `Microsoft.App/containerApps` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.App/2023-05-01/containerApps) | | `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | -| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | ## Usage examples @@ -28,11 +27,14 @@ The following section provides usage examples for the module, which were used to >**Note**: To reference the module, please use the following syntax `br/public:AVM/bicep-registry-modules:`. -- [Defaults](#example-1-defaults) -- [Max](#example-2-max) -- [Waf-Aligned](#example-3-waf-aligned) +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. -### Example 1: _Defaults_
@@ -103,7 +105,10 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = {

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

@@ -294,7 +299,10 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = {

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

@@ -457,7 +465,6 @@ module containerApp 'br/public:AVM/bicep-registry-modules:' = { | [`activeRevisionsMode`](#parameter-activerevisionsmode) | string | ActiveRevisionsMode controls how active revisions are handled for the Container app. | | [`customDomains`](#parameter-customdomains) | array | Custom domain bindings for Container App hostnames. | | [`dapr`](#parameter-dapr) | object | Dapr configuration for the Container App. | -| [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`exposedPort`](#parameter-exposedport) | int | Exposed Port in containers for TCP traffic from ingress. | | [`ingressAllowInsecure`](#parameter-ingressallowinsecure) | bool | Bool indicating if HTTP connections to is allowed. If set to false HTTP connections are automatically redirected to HTTPS connections. | @@ -537,97 +544,6 @@ Dapr configuration for the Container App. - Type: object - Default: `{}` -### Parameter: `diagnosticSettings` - -The diagnostic settings of the service. - -- Required: No -- Type: array - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | -| [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | -| [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | -| [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | -| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. | -| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | -| [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | -| [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | - -### Parameter: `diagnosticSettings.eventHubAuthorizationRuleResourceId` - -Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. - -- Required: No -- Type: string - -### Parameter: `diagnosticSettings.eventHubName` - -Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. - -- Required: No -- Type: string - -### Parameter: `diagnosticSettings.logAnalyticsDestinationType` - -A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. - -- Required: No -- Type: string -- Allowed: - ```Bicep - [ - 'AzureDiagnostics' - 'Dedicated' - ] - ``` - -### Parameter: `diagnosticSettings.logCategoriesAndGroups` - -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. - -- Required: No -- Type: array - -### Parameter: `diagnosticSettings.marketplacePartnerResourceId` - -The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. - -- Required: No -- Type: string - -### Parameter: `diagnosticSettings.metricCategories` - -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to '' to disable metric collection. - -- Required: No -- Type: array - -### Parameter: `diagnosticSettings.name` - -The name of diagnostic setting. - -- Required: No -- Type: string - -### Parameter: `diagnosticSettings.storageAccountResourceId` - -Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. - -- Required: No -- Type: string - -### Parameter: `diagnosticSettings.workspaceResourceId` - -Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. - -- Required: No -- Type: string - ### Parameter: `enableTelemetry` Enable/Disable usage telemetry for module. diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index 986bc715ab..53b17db4fa 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -6,119 +6,13 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "9636517864951680672" + "templateHash": "7210670012885312812" }, "name": "Container Apps", "description": "This module deploys a Container App.", "owner": "Azure/module-maintainers" }, "definitions": { - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } - }, - "logCategoriesAndGroups": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." - } - }, - "categoryGroup": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'allLogs' to collect all logs." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." - } - }, - "metricCategories": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to 'AllMetrics' to collect all metrics." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to '' to disable metric collection." - } - }, - "logAnalyticsDestinationType": { - "type": "string", - "allowedValues": [ - "AzureDiagnostics", - "Dedicated" - ], - "nullable": true, - "metadata": { - "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." - } - }, - "workspaceResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "storageAccountResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "eventHubAuthorizationRuleResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." - } - }, - "eventHubName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "marketplacePartnerResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." - } - } - } - }, - "nullable": true - }, "managedIdentitiesType": { "type": "object", "properties": { @@ -340,12 +234,6 @@ "description": "Optional. Collection of private container registry credentials for containers used by the Container app." } }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", - "metadata": { - "description": "Optional. The diagnostic settings of the service." - } - }, "managedIdentities": { "$ref": "#/definitions/managedIdentitiesType", "metadata": { @@ -551,29 +439,6 @@ "workloadProfileName": "[parameters('workloadProfileName')]" } }, - "containerApp_diagnosticSettings": { - "copy": { - "name": "containerApp_diagnosticSettings", - "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" - }, - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.App/containerApps/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", - "properties": { - "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", - "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", - "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())))]", - "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", - "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" - }, - "dependsOn": [ - "containerApp" - ] - }, "containerApp_lock": { "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", From a25aabe28c7f86430d8a222b30104832ba21ef69 Mon Sep 17 00:00:00 2001 From: Zach Trocinski Date: Mon, 22 Jan 2024 21:57:48 -0600 Subject: [PATCH 42/42] Fix readme.md --- avm/res/app/container-app/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index ca2ab2b832..9e5568d7a9 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -25,7 +25,7 @@ The following section provides usage examples for the module, which were used to >**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. ->**Note**: To reference the module, please use the following syntax `br/public:AVM/bicep-registry-modules:`. +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/app/container-app:`. - [Using only defaults](#example-1-using-only-defaults) - [Using large parameter set](#example-2-using-large-parameter-set) @@ -41,7 +41,7 @@ This instance deploys the module with the minimum set of required parameters. via Bicep module ```bicep -module containerApp 'br/public:AVM/bicep-registry-modules:' = { +module containerApp 'br/public:avm/res/app/container-app:' = { name: '${uniqueString(deployment().name, location)}-test-acamin' params: { // Required parameters @@ -115,7 +115,7 @@ This instance deploys the module with most of its features enabled. via Bicep module ```bicep -module containerApp 'br/public:AVM/bicep-registry-modules:' = { +module containerApp 'br/public:avm/res/app/container-app:' = { name: '${uniqueString(deployment().name, location)}-test-acamax' params: { // Required parameters @@ -309,7 +309,7 @@ This instance deploys the module in alignment with the best-practices of the Azu via Bicep module ```bicep -module containerApp 'br/public:AVM/bicep-registry-modules:' = { +module containerApp 'br/public:avm/res/app/container-app:' = { name: '${uniqueString(deployment().name, location)}-test-acawaf' params: { // Required parameters