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

Check that Container Apps have a minimum number of replicas #2790 #2792

Merged
merged 3 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 19 additions & 9 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

## Unreleased

What's changed since v1.35.0:

- New rules:
- Container App:
- Check that Container Apps have a minimum number of replicas by @BernieWhite.
[#2790](https://github.com/Azure/PSRule.Rules.Azure/issues/2790)
- General improvements:
- Quality updates to documentation by @lukemurraynz.
[#2789](https://github.com/Azure/PSRule.Rules.Azure/pull/2789)

## v1.35.0

What's changed since v1.34.2:
Expand Down Expand Up @@ -851,14 +861,6 @@ What's changed since v1.29.0:
- Includes rules released before or during September 2023.
- Marked `Azure.GA_2023_06` and `Azure.Preview_2023_06` baselines as obsolete.
- New rules:
- Azure Container Apps:
- Check that Container Apps uses a supported API version by @BenjaminEngeset.
[#2398](https://github.com/Azure/PSRule.Rules.Azure/issues/2398)
- Azure Container Registry:
- Check that Container Registries restricts network access by @BenjaminEngeset.
[#2423](https://github.com/Azure/PSRule.Rules.Azure/issues/2423)
- Check that Container Registries disables anonymous pull access by @BenjaminEngeset.
[#2422](https://github.com/Azure/PSRule.Rules.Azure/issues/2422)
- Azure Database for MySQL:
- Check that Azure AD-only authentication is configured for Azure Database for MySQL databases by @BenjaminEngeset.
[#2227](https://github.com/Azure/PSRule.Rules.Azure/issues/2227)
Expand All @@ -868,6 +870,14 @@ What's changed since v1.29.0:
- Backup vault:
- Check that immutability is configured for Backup vaults by @BenjaminEngeset.
[#2387](https://github.com/Azure/PSRule.Rules.Azure/issues/2387)
- Container App:
- Check that Container Apps uses a supported API version by @BenjaminEngeset.
[#2398](https://github.com/Azure/PSRule.Rules.Azure/issues/2398)
- Container Registry:
- Check that Container Registries restricts network access by @BenjaminEngeset.
[#2423](https://github.com/Azure/PSRule.Rules.Azure/issues/2423)
- Check that Container Registries disables anonymous pull access by @BenjaminEngeset.
[#2422](https://github.com/Azure/PSRule.Rules.Azure/issues/2422)
- Front Door:
- Check that managed identity for Azure Front Door instances are configured by @BenjaminEngeset.
[#2378](https://github.com/Azure/PSRule.Rules.Azure/issues/2378)
Expand Down Expand Up @@ -1014,7 +1024,7 @@ What's changed since pre-release v1.30.0-B0026:
What's changed since pre-release v1.30.0-B0011:

- New rules:
- Azure Container Apps:
- Container App:
- Check that Container Apps uses a supported API version by @BenjaminEngeset.
[#2398](https://github.com/Azure/PSRule.Rules.Azure/issues/2398)
- Bug fixes:
Expand Down
132 changes: 132 additions & 0 deletions docs/en/rules/Azure.ContainerApp.MinReplicas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
---
reviewed: 2024-04-02
severity: Important
pillar: Reliability
category: RE:05 Redundancy
resource: Container App
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ContainerApp.MinReplicas/
---

# Use a minimum number of replicas

## SYNOPSIS

Use multiple replicas to remove a single point of failure.

## DESCRIPTION

When a Container App is deployed Azure create one or more instances or replicas of the application.
The number of replicas is configurable and can be automatically scaled up or down based on demand using scaling rules.

When a single instance of the application is deployed, in the event of a failure Azure will replace the instance.
However, this can lead to downtime while the instance is replaced with this single point of failure.

To ensure that the application is highly available, it is recommended to configure a minimum number of replicas.
The minimum number of replicas required will depend on the criticality of the application and the expected demand.

For a production application, consider configuring a minimum of two (2) replicas.
When zone redundancy is configured, use a minimum of three (3) replicas to spread the replicas across all availability zones.

## RECOMMENDATION

Consider configuring a minimum number of replicas for the Container App to remove a single point of failure on a single instance.

## EXAMPLES

### Configure with Azure template

To deploy Container Apps that pass this rule:

- Set the `properties.template.scale.minReplicas` property to a minimum of `2`.

For example:

```json
{
"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"
}
}
}
},
"dependsOn": [
"[resourceId('Microsoft.App/managedEnvironments', parameters('envName'))]"
]
}
```

### Configure with Bicep

To deploy Container Apps that pass this rule:

- Set the `properties.template.scale.minReplicas` property to a minimum of `2`.

For example:

```bicep
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'
}
}
}
}
}
```

<!-- external:avm avm/res/app/container-app scaleMinReplicas -->

### Configure with Azure CLI

```bash
az containerapp update -n '<name>' -g '<resource_group>' --min-replicas 2 --max-replicas 10
```

### Configure with Azure PowerShell

```powershell
Update-AzContainerApp -Name '<name>' -ResourceGroupName '<resource_group>' -ScaleMinReplica 2 -ScaleMaxReplica 10
```

## LINKS

- [RE:05 Redundancy](https://learn.microsoft.com/azure/well-architected/reliability/redundancy)
- [Reliability in Azure Container Apps](https://learn.microsoft.com/azure/reliability/reliability-azure-container-apps#availability-zone-support)
- [Set scaling rules in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/scale-app)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.app/containerapps)
4 changes: 4 additions & 0 deletions docs/examples-containerapp.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ resource containerEnv 'Microsoft.App/managedEnvironments@2023-05-01' = {
sharedKey: workspace.listKeys().primarySharedKey
}
}
zoneRedundant: true
}
}

Expand All @@ -60,6 +61,9 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
template: {
revisionSuffix: revision
containers: containers
scale: {
minReplicas: 2
}
}
configuration: {
ingress: {
Expand Down
12 changes: 8 additions & 4 deletions docs/examples-containerapp.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.21.1.54444",
"templateHash": "14295091017114091018"
"version": "0.26.54.24096",
"templateHash": "13273570990713004075"
}
},
"parameters": {
Expand Down Expand Up @@ -66,7 +66,8 @@
"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
}
},
{
Expand All @@ -81,7 +82,10 @@
"environmentId": "[resourceId('Microsoft.App/managedEnvironments', parameters('envName'))]",
"template": {
"revisionSuffix": "[parameters('revision')]",
"containers": "[variables('containers')]"
"containers": "[variables('containers')]",
"scale": {
"minReplicas": 2
}
},
"configuration": {
"ingress": {
Expand Down
18 changes: 18 additions & 0 deletions src/PSRule.Rules.Azure/rules/Azure.ContainerApp.Rule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,24 @@ spec:
- 2022-06-01-preview
- 2022-11-01-preview

---
# Synopsis: Use multiple replicas to remove a single point of failure.
apiVersion: github.com/microsoft/PSRule/v1
kind: Rule
metadata:
name: Azure.ContainerApp.MinReplicas
ref: AZR-000413
tags:
release: GA
ruleSet: 2024_06
Azure.WAF/pillar: Reliability
spec:
type:
- Microsoft.App/containerApps
condition:
field: properties.template.scale.minReplicas
greaterOrEquals: 2

#endregion Rules

#region Selectors
Expand Down
15 changes: 15 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/Azure.ContainerApp.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,21 @@ Describe 'Azure.ContainerApp' -Tag 'ContainerApp' {
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'capp-C', 'capp-D';
}

It 'Azure.ContainerApp.MinReplicas' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.ContainerApp.MinReplicas' };

# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'capp-A', 'capp-B';
$ruleResult.Detail.Reason.Path | Should -BeIn 'properties.template.scale.minReplicas';

# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'capp-C', 'capp-D';
}
}

Context 'Resource name - Azure.ContainerApp.Name' {
Expand Down
3 changes: 3 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/Resources.ContainerApp.json
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@
}
],
"scale": {
"minReplicas": 1,
"maxReplicas": 10
},
"volumes": []
Expand Down Expand Up @@ -368,6 +369,7 @@
}
],
"scale": {
"minReplicas": 3,
"maxReplicas": 10
},
"volumes": [
Expand Down Expand Up @@ -465,6 +467,7 @@
}
],
"scale": {
"minReplicas": 2,
"maxReplicas": 10
},
"volumes": [
Expand Down
Loading