Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adding publicNetworkAccess support #4481

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9dab7b7
Updated resource API to latest preview version to add support for pub…
hundredacres Feb 12, 2025
d144b87
Removing unnecessary depends
hundredacres Feb 12, 2025
8432e4a
Running Set-AVMModule
hundredacres Feb 12, 2025
afe7ae8
Adding new test for publicNetworkAccess
hundredacres Feb 12, 2025
bcc19e2
Making loganalytics optional
hundredacres Feb 13, 2025
fe16ea7
Updated resource API to latest preview version to add support for pub…
hundredacres Feb 12, 2025
61108d9
Removing unnecessary depends
hundredacres Feb 12, 2025
56da6ed
Running Set-AVMModule
hundredacres Feb 12, 2025
03bce0f
Adding new test for publicNetworkAccess
hundredacres Feb 12, 2025
1f848c4
Making loganalytics optional
hundredacres Feb 13, 2025
6ead251
Merge branch 'feat/issues/4387' of https://github.com/hundredacres/bi…
hundredacres Feb 13, 2025
0e5433d
Removing loganalytics from default test
hundredacres Feb 13, 2025
3330b54
Updating logic for loganalytics
hundredacres Feb 13, 2025
8b211b4
Updating logic for loganalytics
hundredacres Feb 13, 2025
588d535
Let logsDestination be nullable
hundredacres Feb 13, 2025
1335a76
Need to nullify logAnalyticsConfiguration if logsDestination is not l…
hundredacres Feb 13, 2025
3cd9d43
Removing logAnalytics from public-access test
hundredacres Feb 13, 2025
eff8f8e
Adding missing logsDestination param to tests
hundredacres Feb 14, 2025
e672e3b
Adding support for public access
hundredacres Feb 20, 2025
9b274c5
Bumping version
hundredacres Feb 20, 2025
dfd8905
Cleaning up changes
hundredacres Feb 20, 2025
d9e5d4c
Renaming test
hundredacres Feb 21, 2025
fe090c7
Merge branch 'main' into feat/issues/4387
hundredacres Feb 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 156 additions & 4 deletions avm/res/app/managed-environment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ This module deploys an App Managed Environment (also known as a Container App En

| Resource Type | API Version |
| :-- | :-- |
| `Microsoft.App/managedEnvironments` | [2024-02-02-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.App/2024-02-02-preview/managedEnvironments) |
| `Microsoft.App/managedEnvironments/storages` | [2024-02-02-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.App/2024-02-02-preview/managedEnvironments/storages) |
| `Microsoft.App/managedEnvironments` | [2024-10-02-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.App/2024-10-02-preview/managedEnvironments) |
| `Microsoft.App/managedEnvironments/storages` | [2024-10-02-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.App/2024-10-02-preview/managedEnvironments/storages) |
| `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) |

Expand All @@ -29,7 +29,8 @@ The following section provides usage examples for the module, which were used to

- [Using only defaults](#example-1-using-only-defaults)
- [Using large parameter set](#example-2-using-large-parameter-set)
- [WAF-aligned](#example-3-waf-aligned)
- [Enable public access](#example-3-enable-public-access)
- [WAF-aligned](#example-4-waf-aligned)

### Example 1: _Using only defaults_

Expand Down Expand Up @@ -188,6 +189,7 @@ module managedEnvironment 'br/public:avm/res/app/managed-environment:<version>'
kind: 'CanNotDelete'
name: 'myCustomLockName'
}
logsDestination: 'log-analytics'
managedIdentities: {
systemAssigned: true
userAssignedResourceIds: [
Expand Down Expand Up @@ -311,6 +313,9 @@ module managedEnvironment 'br/public:avm/res/app/managed-environment:<version>'
"name": "myCustomLockName"
}
},
"logsDestination": {
"value": "log-analytics"
},
"managedIdentities": {
"value": {
"systemAssigned": true,
Expand Down Expand Up @@ -428,6 +433,7 @@ param lock = {
kind: 'CanNotDelete'
name: 'myCustomLockName'
}
param logsDestination = 'log-analytics'
param managedIdentities = {
systemAssigned: true
userAssignedResourceIds: [
Expand Down Expand Up @@ -499,7 +505,132 @@ param workloadProfiles = [
</details>
<p>

### Example 3: _WAF-aligned_
### Example 3: _Enable public access_

This instance deploys the module with public access enabled.


<details>

<summary>via Bicep module</summary>

```bicep
module managedEnvironment 'br/public:avm/res/app/managed-environment:<version>' = {
name: 'managedEnvironmentDeployment'
params: {
// Required parameters
logAnalyticsWorkspaceResourceId: '<logAnalyticsWorkspaceResourceId>'
name: 'amepa001'
// Non-required parameters
dockerBridgeCidr: '172.16.0.1/28'
infrastructureResourceGroupName: '<infrastructureResourceGroupName>'
infrastructureSubnetId: '<infrastructureSubnetId>'
location: '<location>'
platformReservedCidr: '172.17.17.0/24'
platformReservedDnsIP: '172.17.17.17'
publicNetworkAccess: 'Enabled'
workloadProfiles: [
{
maximumCount: 3
minimumCount: 0
name: 'CAW01'
workloadProfileType: 'D4'
}
]
}
}
```

</details>
<p>

<details>

<summary>via JSON parameters file</summary>

```json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
// Required parameters
"logAnalyticsWorkspaceResourceId": {
"value": "<logAnalyticsWorkspaceResourceId>"
},
"name": {
"value": "amepa001"
},
// Non-required parameters
"dockerBridgeCidr": {
"value": "172.16.0.1/28"
},
"infrastructureResourceGroupName": {
"value": "<infrastructureResourceGroupName>"
},
"infrastructureSubnetId": {
"value": "<infrastructureSubnetId>"
},
"location": {
"value": "<location>"
},
"platformReservedCidr": {
"value": "172.17.17.0/24"
},
"platformReservedDnsIP": {
"value": "172.17.17.17"
},
"publicNetworkAccess": {
"value": "Enabled"
},
"workloadProfiles": {
"value": [
{
"maximumCount": 3,
"minimumCount": 0,
"name": "CAW01",
"workloadProfileType": "D4"
}
]
}
}
}
```

</details>
<p>

<details>

<summary>via Bicep parameters file</summary>

```bicep-params
using 'br/public:avm/res/app/managed-environment:<version>'

// Required parameters
param logAnalyticsWorkspaceResourceId = '<logAnalyticsWorkspaceResourceId>'
param name = 'amepa001'
// Non-required parameters
param dockerBridgeCidr = '172.16.0.1/28'
param infrastructureResourceGroupName = '<infrastructureResourceGroupName>'
param infrastructureSubnetId = '<infrastructureSubnetId>'
param location = '<location>'
param platformReservedCidr = '172.17.17.0/24'
param platformReservedDnsIP = '172.17.17.17'
param publicNetworkAccess = 'Enabled'
param workloadProfiles = [
{
maximumCount: 3
minimumCount: 0
name: 'CAW01'
workloadProfileType: 'D4'
}
]
```

</details>
<p>

### Example 4: _WAF-aligned_

This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.

Expand All @@ -525,6 +656,7 @@ module managedEnvironment 'br/public:avm/res/app/managed-environment:<version>'
kind: 'CanNotDelete'
name: 'myCustomLockName'
}
logsDestination: 'log-analytics'
platformReservedCidr: '172.17.17.0/24'
platformReservedDnsIP: '172.17.17.17'
roleAssignments: [
Expand Down Expand Up @@ -601,6 +733,9 @@ module managedEnvironment 'br/public:avm/res/app/managed-environment:<version>'
"name": "myCustomLockName"
}
},
"logsDestination": {
"value": "log-analytics"
},
"platformReservedCidr": {
"value": "172.17.17.0/24"
},
Expand Down Expand Up @@ -669,6 +804,7 @@ param lock = {
kind: 'CanNotDelete'
name: 'myCustomLockName'
}
param logsDestination = 'log-analytics'
param platformReservedCidr = '172.17.17.0/24'
param platformReservedDnsIP = '172.17.17.17'
param roleAssignments = [
Expand Down Expand Up @@ -744,6 +880,7 @@ param workloadProfiles = [
| [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. |
| [`openTelemetryConfiguration`](#parameter-opentelemetryconfiguration) | object | Open Telemetry configuration. |
| [`peerTrafficEncryption`](#parameter-peertrafficencryption) | bool | Whether or not to encrypt peer traffic. |
| [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | Whether to allow or block all public traffic. |
| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. |
| [`storages`](#parameter-storages) | array | The list of storages to mount on the environment. |
| [`tags`](#parameter-tags) | object | Tags of the resource. |
Expand Down Expand Up @@ -999,6 +1136,21 @@ Whether or not to encrypt peer traffic.
- Type: bool
- Default: `True`

### Parameter: `publicNetworkAccess`

Whether to allow or block all public traffic.

- Required: No
- Type: string
- Default: `'Disabled'`
- Allowed:
```Bicep
[
'Disabled'
'Enabled'
]
```

### Parameter: `roleAssignments`

Array of role assignments to create.
Expand Down
10 changes: 9 additions & 1 deletion avm/res/app/managed-environment/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ param platformReservedDnsIP string = ''
@description('Optional. Whether or not to encrypt peer traffic.')
param peerTrafficEncryption bool = true

@allowed([
'Enabled'
'Disabled'
])
@description('Optional. Whether to allow or block all public traffic.')
param publicNetworkAccess string = 'Disabled'

@description('Optional. Whether or not this Managed Environment is zone-redundant.')
param zoneRedundant bool = true

Expand Down Expand Up @@ -151,7 +158,7 @@ resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09
scope: resourceGroup(split(logAnalyticsWorkspaceResourceId, '/')[2], split(logAnalyticsWorkspaceResourceId, '/')[4])
}

resource managedEnvironment 'Microsoft.App/managedEnvironments@2024-02-02-preview' = {
resource managedEnvironment 'Microsoft.App/managedEnvironments@2024-10-02-preview' = {
name: name
location: location
tags: tags
Expand Down Expand Up @@ -186,6 +193,7 @@ resource managedEnvironment 'Microsoft.App/managedEnvironments@2024-02-02-previe
enabled: peerTrafficEncryption
}
}
publicNetworkAccess: publicNetworkAccess
vnetConfiguration: {
internal: internal
infrastructureSubnetId: !empty(infrastructureSubnetId) ? infrastructureSubnetId : null
Expand Down
24 changes: 18 additions & 6 deletions avm/res/app/managed-environment/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.33.13.18514",
"templateHash": "4503904336969657185"
"version": "0.33.93.31351",
"templateHash": "16135611596956127909"
},
"name": "App ManagedEnvironments",
"description": "This module deploys an App Managed Environment (also known as a Container App Environment)."
Expand Down Expand Up @@ -309,6 +309,17 @@
"description": "Optional. Whether or not to encrypt peer traffic."
}
},
"publicNetworkAccess": {
"type": "string",
"defaultValue": "Disabled",
"allowedValues": [
"Enabled",
"Disabled"
],
"metadata": {
"description": "Optional. Whether to allow or block all public traffic."
}
},
"zoneRedundant": {
"type": "bool",
"defaultValue": true,
Expand Down Expand Up @@ -402,7 +413,7 @@
"count": "[length(coalesce(parameters('storages'), createArray()))]"
},
"type": "Microsoft.App/managedEnvironments/storages",
"apiVersion": "2024-02-02-preview",
"apiVersion": "2024-10-02-preview",
"name": "[format('{0}/{1}', parameters('name'), coalesce(parameters('storages'), createArray())[copyIndex()].shareName)]",
"properties": {
"nfsAzureFile": "[if(equals(coalesce(parameters('storages'), createArray())[copyIndex()].kind, 'NFS'), createObject('accessMode', coalesce(parameters('storages'), createArray())[copyIndex()].accessMode, 'server', format('{0}.file.{1}', coalesce(parameters('storages'), createArray())[copyIndex()].storageAccountName, environment().suffixes.storage), 'shareName', format('/{0}/{1}', coalesce(parameters('storages'), createArray())[copyIndex()].storageAccountName, coalesce(parameters('storages'), createArray())[copyIndex()].shareName)), null())]",
Expand Down Expand Up @@ -443,7 +454,7 @@
},
"managedEnvironment": {
"type": "Microsoft.App/managedEnvironments",
"apiVersion": "2024-02-02-preview",
"apiVersion": "2024-10-02-preview",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"tags": "[parameters('tags')]",
Expand Down Expand Up @@ -473,6 +484,7 @@
"enabled": "[parameters('peerTrafficEncryption')]"
}
},
"publicNetworkAccess": "[parameters('publicNetworkAccess')]",
"vnetConfiguration": {
"internal": "[parameters('internal')]",
"infrastructureSubnetId": "[if(not(empty(parameters('infrastructureSubnetId'))), parameters('infrastructureSubnetId'), null())]",
Expand Down Expand Up @@ -538,7 +550,7 @@
"metadata": {
"description": "The location the resource was deployed into."
},
"value": "[reference('managedEnvironment', '2024-02-02-preview', 'full').location]"
"value": "[reference('managedEnvironment', '2024-10-02-preview', 'full').location]"
},
"name": {
"type": "string",
Expand All @@ -560,7 +572,7 @@
"metadata": {
"description": "The principal ID of the system assigned identity."
},
"value": "[tryGet(tryGet(reference('managedEnvironment', '2024-02-02-preview', 'full'), 'identity'), 'principalId')]"
"value": "[tryGet(tryGet(reference('managedEnvironment', '2024-10-02-preview', 'full'), 'identity'), 'principalId')]"
},
"defaultDomain": {
"type": "string",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,5 @@ module testDeployment '../../../main.bicep' = [
infrastructureSubnetId: nestedDependencies.outputs.subnetResourceId
infrastructureResourceGroupName: 'me-${resourceGroupName}'
}
dependsOn: [
nestedDependencies
]
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ module testDeployment '../../../main.bicep' = [
name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}'
params: {
name: '${namePrefix}${serviceShort}001'
logsDestination: 'log-analytics'
logAnalyticsWorkspaceResourceId: nestedDependencies.outputs.logAnalyticsWorkspaceResourceId
location: resourceLocation
appInsightsConnectionString: nestedDependencies.outputs.appInsightsConnectionString
Expand Down Expand Up @@ -141,8 +142,5 @@ module testDeployment '../../../main.bicep' = [
Env: 'test'
}
}
dependsOn: [
nestedDependencies
]
}
]
Loading