Skip to content

Commit

Permalink
feat: Container-App - Add logic to disable ingress entirely (#2723)
Browse files Browse the repository at this point in the history
## Description

Adds the ability to completely disable ingress traffic for the container
apps.

Closes #2205


## Pipeline Reference

<!-- Insert your Pipeline Status Badge below -->

| Pipeline |
| -------- |
|
[![avm.res.app.container-app](https://github.com/oZakari/bicep-registry-modules/actions/workflows/avm.res.app.container-app.yml/badge.svg?branch=feat-disable-ingress)](https://github.com/oZakari/bicep-registry-modules/actions/workflows/avm.res.app.container-app.yml)
|

## Type of Change

<!-- Use the checkboxes [x] on the options that are relevant. -->

- [ ] Update to CI Environment or utilities (Non-module affecting
changes)
- [x] Azure Verified Module updates:
- [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT
bumped the MAJOR or MINOR version in `version.json`:
- [ ] Someone has opened a bug report issue, and I have included "Closes
#{bug_report_issue_number}" in the PR description.
- [ ] The bug was found by the module author, and no one has opened an
issue to report it yet.
- [x] Feature update backwards compatible feature updates, and I have
bumped the MINOR version in `version.json`.
- [ ] Breaking changes and I have bumped the MAJOR version in
`version.json`.
  - [ ] Update to documentation

## Checklist

- [x] I'm sure there are no other open Pull Requests for the same
update/change
- [x] I have run `Set-AVMModule` locally to generate the supporting
module files.
- [ ] My corresponding pipelines / checks run clean and green without
any errors or warnings

<!-- Please keep up to date with the contribution guide at
https://aka.ms/avm/contribute/bicep -->

---------

Co-authored-by: Alexander Sehr <[email protected]>
  • Loading branch information
oZakari and AlexanderSehr authored Jul 17, 2024
1 parent 59c21dc commit c4f07b4
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 29 deletions.
96 changes: 92 additions & 4 deletions avm/res/app/container-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ 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/res/app/container-app:<version>`.
- [Using only defaults](#example-1-using-only-defaults)
- [Using large parameter set](#example-2-using-large-parameter-set)
- [WAF-aligned](#example-3-waf-aligned)
- [Without ingress enabled](#example-2-without-ingress-enabled)
- [Using large parameter set](#example-3-using-large-parameter-set)
- [WAF-aligned](#example-4-waf-aligned)

### Example 1: _Using only defaults_

Expand Down Expand Up @@ -105,7 +106,85 @@ module containerApp 'br/public:avm/res/app/container-app:<version>' = {
</details>
<p>

### Example 2: _Using large parameter set_
### Example 2: _Without ingress enabled_

This instance deploys the module with ingress traffic completely disabled.


<details>

<summary>via Bicep module</summary>

```bicep
module containerApp 'br/public:avm/res/app/container-app:<version>' = {
name: 'containerAppDeployment'
params: {
// Required parameters
containers: [
{
image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'
name: 'simple-hello-world-container'
resources: {
cpu: '<cpu>'
memory: '0.5Gi'
}
}
]
environmentId: '<environmentId>'
name: 'acapriv001'
// Non-required parameters
disableIngress: true
location: '<location>'
}
}
```

</details>
<p>

<details>

<summary>via JSON Parameter file</summary>

```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": "<cpu>",
"memory": "0.5Gi"
}
}
]
},
"environmentId": {
"value": "<environmentId>"
},
"name": {
"value": "acapriv001"
},
// Non-required parameters
"disableIngress": {
"value": true
},
"location": {
"value": "<location>"
}
}
}
```

</details>
<p>

### Example 3: _Using large parameter set_

This instance deploys the module with most of its features enabled.

Expand Down Expand Up @@ -299,7 +378,7 @@ module containerApp 'br/public:avm/res/app/container-app:<version>' = {
</details>
<p>

### Example 3: _WAF-aligned_
### Example 4: _WAF-aligned_

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

Expand Down Expand Up @@ -465,6 +544,7 @@ module containerApp 'br/public:avm/res/app/container-app:<version>' = {
| [`activeRevisionsMode`](#parameter-activerevisionsmode) | string | 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. |
| [`disableIngress`](#parameter-disableingress) | bool | Bool to disable all ingress traffic for the container app. |
| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. |
| [`exposedPort`](#parameter-exposedport) | int | Exposed Port in containers for TCP traffic from ingress. |
| [`ingressAllowInsecure`](#parameter-ingressallowinsecure) | bool | Bool indicating if HTTP connections to is allowed. If set to false HTTP connections are automatically redirected to HTTPS connections. |
Expand Down Expand Up @@ -876,6 +956,14 @@ Dapr configuration for the Container App.
- Type: object
- Default: `{}`

### Parameter: `disableIngress`

Bool to disable all ingress traffic for the container app.

- Required: No
- Type: bool
- Default: `False`

### Parameter: `enableTelemetry`

Enable/Disable usage telemetry for module.
Expand Down
7 changes: 5 additions & 2 deletions avm/res/app/container-app/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ param name string
@description('Optional. Location for all Resources.')
param location string = resourceGroup().location

@description('Optional. Bool to disable all ingress traffic for the container app.')
param disableIngress bool = false

@description('Optional. Bool indicating if the App exposes an external HTTP endpoint.')
param ingressExternal bool = true

Expand Down Expand Up @@ -180,7 +183,7 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
configuration: {
activeRevisionsMode: activeRevisionsMode
dapr: !empty(dapr) ? dapr : null
ingress: {
ingress: disableIngress ? null : {
allowInsecure: ingressAllowInsecure
customDomains: !empty(customDomains) ? customDomains : null
exposedPort: exposedPort
Expand Down Expand Up @@ -254,7 +257,7 @@ resource containerApp_roleAssignments 'Microsoft.Authorization/roleAssignments@2
output resourceId string = containerApp.id

@description('The configuration of ingress fqdn.')
output fqdn string = containerApp.properties.configuration.ingress.fqdn
output fqdn string = disableIngress ? 'IngressDisabled' : containerApp.properties.configuration.ingress.fqdn

@description('The name of the resource group the Container App was deployed into.')
output resourceGroupName string = resourceGroup().name
Expand Down
32 changes: 10 additions & 22 deletions avm/res/app/container-app/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"_generator": {
"name": "bicep",
"version": "0.28.1.47646",
"templateHash": "8728217426108975166"
"templateHash": "17800459642895019722"
},
"name": "Container Apps",
"description": "This module deploys a Container App.",
Expand Down Expand Up @@ -430,6 +430,13 @@
"description": "Optional. Location for all Resources."
}
},
"disableIngress": {
"type": "bool",
"defaultValue": false,
"metadata": {
"description": "Optional. Bool to disable all ingress traffic for the container app."
}
},
"ingressExternal": {
"type": "bool",
"defaultValue": true,
Expand Down Expand Up @@ -706,26 +713,7 @@
"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')]",
"stickySessions": {
"affinity": "[parameters('stickySessionsAffinity')]"
},
"traffic": [
{
"label": "[parameters('trafficLabel')]",
"latestRevision": "[parameters('trafficLatestRevision')]",
"revisionName": "[parameters('trafficRevisionName')]",
"weight": "[parameters('trafficWeight')]"
}
],
"transport": "[parameters('ingressTransport')]"
},
"ingress": "[if(parameters('disableIngress'), null(), createObject('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'), 'stickySessions', createObject('affinity', parameters('stickySessionsAffinity')), 'traffic', createArray(createObject('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')]"
Expand Down Expand Up @@ -794,7 +782,7 @@
"metadata": {
"description": "The configuration of ingress fqdn."
},
"value": "[reference('containerApp').configuration.ingress.fqdn]"
"value": "[if(parameters('disableIngress'), 'IngressDisabled', reference('containerApp').configuration.ingress.fqdn)]"
},
"resourceGroupName": {
"type": "string",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@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@2023-05-01' = {
name: managedEnvironmentName
location: location
properties: {}
}

@description('The resource ID of the created Managed Environment.')
output managedEnvironmentResourceId string = managedEnvironment.id
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
targetScope = 'subscription'

metadata name = 'Without ingress enabled'
metadata description = 'This instance deploys the module with ingress traffic completely disabled.'

// ========== //
// 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 resourceLocation string = deployment().location

@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.')
param serviceShort string = 'acapriv'

@description('Optional. A token to inject into the name of each resource.')
param namePrefix string = '#_namePrefix_#'

// =========== //
// Deployments //
// =========== //

// General resources
// =================
resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = {
name: resourceGroupName
location: resourceLocation
}

module nestedDependencies 'dependencies.bicep' = {
scope: resourceGroup
name: '${uniqueString(deployment().name, resourceLocation)}-paramNested'
params: {
location: resourceLocation
managedEnvironmentName: 'dep-${namePrefix}-menv-${serviceShort}'
}
}

// ============== //
// Test Execution //
// ============== //

@batchSize(1)
module testDeployment '../../../main.bicep' = [
for iteration in ['init', 'idem']: {
scope: resourceGroup
name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}'
params: {
name: '${namePrefix}${serviceShort}001'
environmentId: nestedDependencies.outputs.managedEnvironmentResourceId
location: resourceLocation
disableIngress: true
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'
}
}
]
}
}
]
2 changes: 1 addition & 1 deletion avm/res/app/container-app/version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://aka.ms/bicep-registry-module-version-file-schema#",
"version": "0.4",
"version": "0.5",
"pathFilters": [
"./main.json"
]
Expand Down

0 comments on commit c4f07b4

Please sign in to comment.