зеркало из
1
0
Форкнуть 0

Check that Container App environments are zone redundant #2791 (#2805)

* Check that Container App environments are zone redundant #2791

* Fix
This commit is contained in:
Bernie White 2024-04-07 03:11:06 +10:00 коммит произвёл GitHub
Родитель 90e253fefd
Коммит 09b283d6e2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
14 изменённых файлов: 396 добавлений и 49 удалений

Просмотреть файл

@ -38,6 +38,8 @@ What's changed since v1.35.1:
- Container App:
- Check that Container Apps have a minimum number of replicas by @BernieWhite.
[#2790](https://github.com/Azure/PSRule.Rules.Azure/issues/2790)
- Check that Container App environments are zone redundant by @BernieWhite.
[#2791](https://github.com/Azure/PSRule.Rules.Azure/issues/2791)
- General improvements:
- Quality updates to documentation by @lukemurraynz.
[#2789](https://github.com/Azure/PSRule.Rules.Azure/pull/2789)

Просмотреть файл

@ -0,0 +1,107 @@
---
reviewed: 2024-04-07
severity: Important
pillar: Reliability
category: RE:05 Regions and availability zones
resource: Container App
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ContainerApp.AvailabilityZone/
---
# Use zone redundant Container App environments
## SYNOPSIS
Use Container Apps environments that are zone redundant to improve reliability.
## DESCRIPTION
Container App environments can be configured to be zone redundant in regions that support availability zones.
When configured, replicas of each Container App are spread across availability zones automatically.
A Container App must have multiple replicas to be zone redundant.
For example, if a Container App has three replicas, each replica is placed in a different availability zone.
## RECOMMENDATION
Consider configuring Container App environments to be zone redundant to improve reliability.
## EXAMPLES
### Configure with Azure template
To deploy Container App environments that pass this rule:
- Set the `properties.zoneRedundant` property to `true`.
For example:
```json
{
"type": "Microsoft.App/managedEnvironments",
"apiVersion": "2023-05-01",
"name": "[parameters('envName')]",
"location": "[parameters('location')]",
"properties": {
"appLogsConfiguration": {
"destination": "log-analytics",
"logAnalyticsConfiguration": {
"customerId": "[reference(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceId')), '2022-10-01').customerId]",
"sharedKey": "[listKeys(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceId')), '2022-10-01').primarySharedKey]"
}
},
"zoneRedundant": true,
"workloadProfiles": [
{
"name": "Consumption",
"workloadProfileType": "Consumption"
}
],
"vnetConfiguration": {
"infrastructureSubnetId": "[parameters('subnetId')]",
"internal": true
}
}
}
```
### Configure with Bicep
To deploy Container App environments that pass this rule:
- Set the `properties.zoneRedundant` property to `true`.
For example:
```bicep
resource containerEnv 'Microsoft.App/managedEnvironments@2023-05-01' = {
name: envName
location: location
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: workspace.properties.customerId
sharedKey: workspace.listKeys().primarySharedKey
}
}
zoneRedundant: true
workloadProfiles: [
{
name: 'Consumption'
workloadProfileType: 'Consumption'
}
]
vnetConfiguration: {
infrastructureSubnetId: subnetId
internal: true
}
}
}
```
## LINKS
- [RE:05 Regions and availability zones](https://learn.microsoft.com/azure/well-architected/reliability/regions-availability-zones)
- [Reliability in Azure Container Apps](https://learn.microsoft.com/azure/reliability/reliability-azure-container-apps#availability-zone-support)
- [What are availability zones?](https://learn.microsoft.com/azure/reliability/availability-zones-overview)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.app/containerapps)

Просмотреть файл

@ -1,8 +1,8 @@
---
reviewed: 2023-10-01
reviewed: 2024-04-07
severity: Important
pillar: Performance Efficiency
category: Design for performance efficiency
category: PE:05 Scaling and partitioning
resource: Container App
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ContainerApp.DisableAffinity/
---
@ -50,7 +50,10 @@ For example:
"environmentId": "[resourceId('Microsoft.App/managedEnvironments', parameters('envName'))]",
"template": {
"revisionSuffix": "[parameters('revision')]",
"containers": "[variables('containers')]"
"containers": "[variables('containers')]",
"scale": {
"minReplicas": 2
}
},
"configuration": {
"ingress": {
@ -87,6 +90,9 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
template: {
revisionSuffix: revision
containers: containers
scale: {
minReplicas: 2
}
}
configuration: {
ingress: {
@ -106,7 +112,6 @@ This rule may generate false positive results for stateful applications.
## LINKS
- [Avoid a requirement to store server-side session state](https://learn.microsoft.com/azure/well-architected/scalability/performance-efficiency#implementation)
- [Session affinity](https://learn.microsoft.com/azure/well-architected/scalability/design-efficiency#improve-performance-with-session-affinity)
- [PE:05 Scaling and partitioning](https://learn.microsoft.com/azure/well-architected/performance-efficiency/scale-partition)
- [Session Affinity in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/sticky-sessions)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.app/containerapps#ingressstickysessions)

Просмотреть файл

@ -1,7 +1,8 @@
---
reviewed: 2024-04-07
severity: Important
pillar: Security
category: Network security and containment
category: SE:06 Network controls
resource: Container App
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ContainerApp.ExternalIngress/
---
@ -14,14 +15,15 @@ Limit inbound communication for Container Apps is limited to callers within the
## DESCRIPTION
Container apps allows you to expose your container app to the Internet, your VNET, or to other container apps within the same environment by enabling ingress.
Inbound access to a Container App is configured by enabling ingress.
Container Apps can be configured to allow external ingress or not.
External ingress permits communication outside the Container App environment from a private VNET or the Internet.
To restrict communication to a private VNET your Container App Environment must be:
- Configured with a custom VNET.
- Configured with an internal load balancer.
When inbound access to the app is required, configure the ingress.
Applications that do batch processing or consume events may not require ingress to be enabled.
When external ingress is configured, communication outside the container apps environment is enabled from your private VNET or the Internet.
To restrict communication to a private VNET your Container App Environment must be deployed on a custom VNET with an Internal load balancer.
If communication outside your Container Apps Environment is not required, disable external ingress.
## RECOMMENDATION
@ -41,25 +43,34 @@ For example:
```json
{
"type": "Microsoft.App/containerApps",
"apiVersion": "2022-10-01",
"apiVersion": "2023-05-01",
"name": "[parameters('appName')]",
"location": "[parameters('location')]",
"identity": {
"type": "SystemAssigned",
"userAssignedIdentities": {}
"type": "SystemAssigned"
},
"properties": {
"environmentId": "[parameters('environmentId')]",
"template": {
"revisionSuffix": "",
"containers": "[variables('containers')]"
},
"configuration": {
"ingress": {
"external": false
}
"environmentId": "[resourceId('Microsoft.App/managedEnvironments', parameters('envName'))]",
"template": {
"revisionSuffix": "[parameters('revision')]",
"containers": "[variables('containers')]",
"scale": {
"minReplicas": 2
}
},
"configuration": {
"ingress": {
"external": false,
"allowInsecure": false,
"stickySessions": {
"affinity": "none"
}
}
}
},
"dependsOn": [
"[resourceId('Microsoft.App/managedEnvironments', parameters('envName'))]"
]
}
```
@ -72,22 +83,28 @@ To deploy Container Apps that pass this rule:
For example:
```bicep
resource containerApp 'Microsoft.App/containerApps@2022-10-01' = {
resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
name: appName
location: location
identity: {
type: 'SystemAssigned'
userAssignedIdentities: {}
}
properties: {
environmentId: environmentId
properties: {
environmentId: containerEnv.id
template: {
revisionSuffix: ''
revisionSuffix: revision
containers: containers
scale: {
minReplicas: 2
}
}
configuration: {
ingress: {
external: false
allowInsecure: false
stickySessions: {
affinity: 'none'
}
}
}
}
@ -103,6 +120,7 @@ If you don't need external ingress, enable this rule by:
## LINKS
- [Networking architecture in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/networking)
- [Set up HTTPS or TCP ingress in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/ingress)
- [SE:06 Network controls](https://learn.microsoft.com/azure/well-architected/security/networking)
- [Networking in Azure Container Apps environment](https://learn.microsoft.com/azure/container-apps/networking)
- [Ingress in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/ingress-overview)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.app/containerapps#ingress)

Просмотреть файл

@ -48,7 +48,10 @@ For example:
"environmentId": "[resourceId('Microsoft.App/managedEnvironments', parameters('envName'))]",
"template": {
"revisionSuffix": "[parameters('revision')]",
"containers": "[variables('containers')]"
"containers": "[variables('containers')]",
"scale": {
"minReplicas": 2
}
},
"configuration": {
"ingress": {
@ -85,6 +88,9 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
template: {
revisionSuffix: revision
containers: containers
scale: {
minReplicas: 2
}
}
configuration: {
ingress: {

Просмотреть файл

@ -54,7 +54,10 @@ For example:
"environmentId": "[resourceId('Microsoft.App/managedEnvironments', parameters('envName'))]",
"template": {
"revisionSuffix": "[parameters('revision')]",
"containers": "[variables('containers')]"
"containers": "[variables('containers')]",
"scale": {
"minReplicas": 2
}
},
"configuration": {
"ingress": {
@ -92,6 +95,9 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
template: {
revisionSuffix: revision
containers: containers
scale: {
minReplicas: 2
}
}
configuration: {
ingress: {

Просмотреть файл

@ -1,7 +1,7 @@
---
severity: Awareness
pillar: Operational Excellence
category: Repeatable infrastructure
category: OE:04 Tools and processes
resource: Container App
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ContainerApp.Name/
---
@ -23,15 +23,157 @@ The requirements for container app names are:
## RECOMMENDATION
Consider using container app names thas meets naming requirements.
Consider using container app names that meets naming requirements.
Additionally consider naming resources with a standard naming convention.
## EXAMPLES
### Configure with Azure template
To deploy Container Apps that pass this rule:
- Configuring a `minLength` and `maxLength` constraint for the resource name parameter.
- Optionally, you could also use a `uniqueString()` function to generate a unique name.
For example:
```json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"envName": {
"type": "string",
"metadata": {
"description": "The name of the app environment."
}
},
"appName": {
"type": "string",
"minLength": 2,
"maxLength": 32,
"metadata": {
"description": "The name of the container app."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "The location resources will be deployed."
}
},
"workspaceId": {
"type": "string",
"metadata": {
"description": "The name of a Log Analytics workspace"
}
},
"subnetId": {
"type": "string",
"metadata": {
"description": "The resource ID of a VNET subnet."
}
},
"revision": {
"type": "string",
"metadata": {
"description": "The revision of the container app."
}
}
},
"variables": {
"containers": [
{
"name": "simple-hello-world-container",
"image": "mcr.microsoft.com/azuredocs/containerapps-helloworld:latest",
"resources": {
"cpu": "[json('0.25')]",
"memory": ".5Gi"
}
}
]
},
"resources": [
{
"type": "Microsoft.App/containerApps",
"apiVersion": "2023-05-01",
"name": "[parameters('appName')]",
"location": "[parameters('location')]",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"environmentId": "[resourceId('Microsoft.App/managedEnvironments', parameters('envName'))]",
"template": {
"revisionSuffix": "[parameters('revision')]",
"containers": "[variables('containers')]",
"scale": {
"minReplicas": 2
}
},
"configuration": {
"ingress": {
"allowInsecure": false,
"stickySessions": {
"affinity": "none"
}
}
}
}
}
]
}
```
### Configure with Bicep
To deploy Container Apps that pass this rule:
- Configuring a `minLength` and `maxLength` constraint for the resource name parameter.
- Optionally, you could also use a `uniqueString()` function to generate a unique name.
For example:
```bicep
@minLength(2)
@maxLength(32)
@description('The name of the container app.')
param appName string
resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
name: appName
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
environmentId: containerEnv.id
template: {
revisionSuffix: revision
containers: containers
scale: {
minReplicas: 2
}
}
configuration: {
ingress: {
allowInsecure: false
stickySessions: {
affinity: 'none'
}
}
}
}
}
```
## NOTES
This rule does not check if container app names are unique.
## LINKS
- [Repeatable infrastructure](https://learn.microsoft.com/azure/architecture/framework/devops/automation-infrastructure)
- [OE:04 Tools and processes](https://learn.microsoft.com/azure/well-architected/operational-excellence/tools-processes)
- [Naming rules and restrictions for container app resource](https://learn.microsoft.com/azure/azure-resource-manager/management/resource-name-rules#microsoftapp)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.app/containerapps)

Просмотреть файл

@ -1,7 +1,7 @@
---
severity: Important
pillar: Security
category: Application endpoints
category: SE:06 Network controls
resource: Container App
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ContainerApp.PublicAccess/
---
@ -87,6 +87,6 @@ resource containerAppEnv 'Microsoft.App/managedEnvironments@2022-10-01' = {
## LINKS
- [Best practices for endpoint security on Azure](https://learn.microsoft.com/azure/architecture/framework/security/design-network-endpoints)
- [Networking architecture in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/networking)
- [SE:06 Network controls](https://learn.microsoft.com/azure/well-architected/security/networking)
- [Networking in Azure Container Apps environment](https://learn.microsoft.com/azure/container-apps/networking)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.app/managedenvironments#vnetconfiguration)

Просмотреть файл

@ -1,7 +1,7 @@
---
severity: Important
pillar: Security
category: Network security and containment
category: SE:06 Network controls
resource: Container App
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ContainerApp.RestrictIngress/
---
@ -133,8 +133,8 @@ If no rules are defined at all, the rule will not pass as it expects at least on
## LINKS
- [Network security and containment](https://learn.microsoft.com/azure/well-architected/security/design-network)
- [Networking architecture in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/networking)
- [SE:06 Network controls](https://learn.microsoft.com/azure/well-architected/security/networking)
- [Networking in Azure Container Apps environment](https://learn.microsoft.com/azure/container-apps/networking)
- [IP restrictions](https://learn.microsoft.com/azure/container-apps/ingress-overview#ip-restrictions)
- [Set up IP ingress restrictions in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/ip-restrictions)
- [Azure security baseline for Azure Container Apps](https://learn.microsoft.com/security/benchmark/azure/baselines/azure-container-apps-security-baseline)

Просмотреть файл

@ -6,6 +6,8 @@
@description('The name of the app environment.')
param envName string
@minLength(2)
@maxLength(32)
@description('The name of the container app.')
param appName string
@ -15,6 +17,9 @@ param location string = resourceGroup().location
@description('The name of a Log Analytics workspace')
param workspaceId string
@description('The resource ID of a VNET subnet.')
param subnetId string
@description('The revision of the container app.')
param revision string
@ -33,7 +38,7 @@ var containers = [
}
]
// An example App Environment
// An example App Environment configured with a consumption workload profile.
resource containerEnv 'Microsoft.App/managedEnvironments@2023-05-01' = {
name: envName
location: location
@ -46,10 +51,20 @@ resource containerEnv 'Microsoft.App/managedEnvironments@2023-05-01' = {
}
}
zoneRedundant: true
workloadProfiles: [
{
name: 'Consumption'
workloadProfileType: 'Consumption'
}
]
vnetConfiguration: {
infrastructureSubnetId: subnetId
internal: true
}
}
}
// An example Container App
// An example Container App using a minimum of 2 replicas.
resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
name: appName
location: location

Просмотреть файл

@ -5,7 +5,7 @@
"_generator": {
"name": "bicep",
"version": "0.26.54.24096",
"templateHash": "13273570990713004075"
"templateHash": "3735352956667233547"
}
},
"parameters": {
@ -17,6 +17,8 @@
},
"appName": {
"type": "string",
"minLength": 2,
"maxLength": 32,
"metadata": {
"description": "The name of the container app."
}
@ -34,6 +36,12 @@
"description": "The name of a Log Analytics workspace"
}
},
"subnetId": {
"type": "string",
"metadata": {
"description": "The resource ID of a VNET subnet."
}
},
"revision": {
"type": "string",
"metadata": {
@ -67,7 +75,17 @@
"sharedKey": "[listKeys(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceId')), '2022-10-01').primarySharedKey]"
}
},
"zoneRedundant": true
"zoneRedundant": true,
"workloadProfiles": [
{
"name": "Consumption",
"workloadProfileType": "Consumption"
}
],
"vnetConfiguration": {
"infrastructureSubnetId": "[parameters('subnetId')]",
"internal": true
}
}
},
{

Просмотреть файл

@ -18,6 +18,20 @@ Rule 'Azure.ContainerApp.RestrictIngress' -Ref 'AZR-000380' -Type 'Microsoft.App
}
}
# Synopsis: Use Container Apps environments that are zone redundant to improve reliability.
Rule 'Azure.ContainerApp.AvailabilityZone' -Ref 'AZR-000414' -Type 'Microsoft.App/managedEnvironments' -Tag @{ release = 'GA'; ruleSet = '2024_06'; 'Azure.WAF/pillar' = 'Reliability'; } {
# Check for availability zones based on Compute, because it is not exposed through the provider for container apps.
$provider = [PSRule.Rules.Azure.Runtime.Helper]::GetResourceType('Microsoft.Compute', 'virtualMachineScaleSets');
$availabilityZones = GetAvailabilityZone -Location $TargetObject.Location -Zone $provider.ZoneMappings;
# Don't flag if the region does not support AZ.
if (-not $availabilityZones) {
return $Assert.Pass();
}
$Assert.HasFieldValue($TargetObject, 'properties.zoneRedundant', $True);
}
#endregion Rules
#region Helper functions

Просмотреть файл

@ -189,6 +189,21 @@ Describe 'Azure.ContainerApp' -Tag 'ContainerApp' {
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'capp-C', 'capp-D';
}
It 'Azure.ContainerApp.AvailabilityZone' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.ContainerApp.AvailabilityZone' };
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'capp-env-A', 'capp-env-B';
$ruleResult.Detail.Reason.Path | Should -BeIn 'properties.zoneRedundant';
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -BeIn 'capp-env-C';
}
}
Context 'Resource name - Azure.ContainerApp.Name' {

Просмотреть файл

@ -87,8 +87,7 @@
"minimumCount": null,
"workloadProfileType": null
}
],
"zoneRedundant": false
]
},
"ResourceGroupName": "test-rg",
"Type": "Microsoft.App/managedEnvironments",
@ -143,7 +142,7 @@
"workloadProfileType": null
}
],
"zoneRedundant": false
"zoneRedundant": true
},
"ResourceGroupName": "test-rg",
"Type": "Microsoft.App/managedEnvironments",