diff --git a/.vscode/settings.json b/.vscode/settings.json index af9dcd57d2..5951349864 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -50,7 +50,7 @@ "agentpool", "APIM", "apiserver", - "APIVERSION", + "apiVersion", "APPGW", "Architected", "AUDITIFNOTEXISTS", @@ -62,7 +62,7 @@ "bicepparam", "cmdlet", "cmdlets", - "CODEOWNERS", + "codeowners", "Concat", "CONTAINERAPPS", "Contoso", @@ -90,6 +90,7 @@ "LESSOREQUAL", "LESSOREQUALS", "lifecycle", + "maxpods", "MCSB", "Newtonsoft", "nics", diff --git a/docs/CHANGELOG-v1.md b/docs/CHANGELOG-v1.md index 0aee2d634d..8aa7f5222e 100644 --- a/docs/CHANGELOG-v1.md +++ b/docs/CHANGELOG-v1.md @@ -14,14 +14,14 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers - Issue #741: `Could not load file or assembly YamlDotNet`. See [troubleshooting guide] for a workaround to this issue. -- The configuration option `Azure_AKSMinimumVersion` is replaced with `AZURE_AKS_CLUSTER_MINIMUM_VERSION`. - If you have this option configured, please update it to `AZURE_AKS_CLUSTER_MINIMUM_VERSION`. - Support for `Azure_AKSMinimumVersion` will be removed in v2. - See [upgrade notes][1] for more information. -- The configuration option `Azure_AllowedRegions` is replaced with `AZURE_RESOURCE_ALLOWED_LOCATIONS`. - If you have this option configured, please update it to `AZURE_RESOURCE_ALLOWED_LOCATIONS`. - Support for `Azure_AllowedRegions` will be removed in v2. +- The following configuration options are deprecated and have been replaced with alternative options. + If you have these options configured, please update them to the replacement. + Support for the old names will be removed in v2. See [upgrade notes][1] for more information. + - `Azure_AKSMinimumVersion` is replaced with `AZURE_AKS_CLUSTER_MINIMUM_VERSION`. + - `Azure_AKSNodeMinimumMaxPods` is replaced with `AZURE_AKS_POOL_MINIMUM_MAXPODS`. + - `Azure_AllowedRegions` is replaced with `AZURE_RESOURCE_ALLOWED_LOCATIONS`. + - `Azure_MinimumCertificateLifetime` is replaced with `AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME`. - The `SupportsTag` PowerShell function has been replaced with the `Azure.Resource.SupportsTags` selector. Update PowerShell rules to use the `Azure.Resource.SupportsTags` selector instead. Support for the `SupportsTag` function will be removed in v2. @@ -35,6 +35,23 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers [#432](https://github.com/Azure/PSRule.Rules.Azure/issues/432) - Verify that availability set members are in a backend pool by @BenjaminEngeset. [#67](https://github.com/Azure/PSRule.Rules.Azure/issues/67) +- General improvements: + - **Important change:** Replaced the `Azure_AKSNodeMinimumMaxPods` option with `AZURE_AKS_POOL_MINIMUM_MAXPODS` by @BernieWhite. + [#941](https://github.com/Azure/PSRule.Rules.Azure/issues/941) + - For compatibility, if `Azure_AKSNodeMinimumMaxPods` is set it will be used instead of `AZURE_AKS_POOL_MINIMUM_MAXPODS`. + - If only `AZURE_AKS_POOL_MINIMUM_MAXPODS` is set, this value will be used. + - The default will be used neither options are configured. + - If `Azure_AKSNodeMinimumMaxPods` is set a warning will be generated until the configuration is removed. + - Support for `Azure_AKSNodeMinimumMaxPods` is deprecated and will be removed in v2. + - See [upgrade notes][1] for details. + - **Important change:** Replaced the `Azure_MinimumCertificateLifetime` option with `AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME` by @BernieWhite. + [#941](https://github.com/Azure/PSRule.Rules.Azure/issues/941) + - For compatibility, if `Azure_MinimumCertificateLifetime` is set it will be used instead of `AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME`. + - If only `AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME` is set, this value will be used. + - The default will be used neither options are configured. + - If `Azure_MinimumCertificateLifetime` is set a warning will be generated until the configuration is removed. + - Support for `Azure_MinimumCertificateLifetime` is deprecated and will be removed in v2. + - See [upgrade notes][1] for details. - Bug fixed: - Fixed `Azure.AppService.AvailabilityZone` only detects premium by tier property @BenjaminEngeset. [#3034](https://github.com/Azure/PSRule.Rules.Azure/issues/3034) @@ -1455,7 +1472,7 @@ What's changed since v1.29.0: - Promoted `Azure.ContainerApp.DisableAffinity` to GA rule set by @BernieWhite. [#2455](https://github.com/Azure/PSRule.Rules.Azure/issues/2455) - General improvements: - - **Important change:** Replaced the `Azure_AllowedRegions` option with `AZURE_RESOURCE_ALLOWED_LOCATIONS`. + - **Important change:** Replaced the `Azure_AllowedRegions` option with `AZURE_RESOURCE_ALLOWED_LOCATIONS` by @BernieWhite. [#941](https://github.com/Azure/PSRule.Rules.Azure/issues/941) - For compatibility, if `Azure_AllowedRegions` is set it will be used instead of `AZURE_RESOURCE_ALLOWED_LOCATIONS`. - If only `AZURE_RESOURCE_ALLOWED_LOCATIONS` is set, this value will be used. @@ -1542,7 +1559,7 @@ What's changed since pre-release v1.30.0-B0080: What's changed since pre-release v1.30.0-B0047: - General improvements: - - **Important change:** Replaced the `Azure_AllowedRegions` option with `AZURE_RESOURCE_ALLOWED_LOCATIONS`. + - **Important change:** Replaced the `Azure_AllowedRegions` option with `AZURE_RESOURCE_ALLOWED_LOCATIONS` by @BernieWhite. [#941](https://github.com/Azure/PSRule.Rules.Azure/issues/941) - For compatibility, if `Azure_AllowedRegions` is set it will be used instead of `AZURE_RESOURCE_ALLOWED_LOCATIONS`. - If only `AZURE_RESOURCE_ALLOWED_LOCATIONS` is set, this value will be used. diff --git a/docs/concepts/about_PSRule_Azure_Configuration.md b/docs/concepts/about_PSRule_Azure_Configuration.md index 1dcc4b9746..b7bfaba4aa 100644 --- a/docs/concepts/about_PSRule_Azure_Configuration.md +++ b/docs/concepts/about_PSRule_Azure_Configuration.md @@ -18,9 +18,9 @@ For details of setting configuration options see [PSRule options][1]. The following configurations options are available for use: - [AZURE_AKS_CLUSTER_MINIMUM_VERSION](#azure_aks_cluster_minimum_version) -- [Azure_AKSNodeMinimumMaxPods](#azure_aksnodeminimummaxpods) -- [Azure_AllowedRegions](#azure_allowedregions) -- [Azure_MinimumCertificateLifetime](#azure_minimumcertificatelifetime) +- [AZURE_AKS_POOL_MINIMUM_MAXPODS](#azure_aks_pool_minimum_maxpods) +- [AZURE_RESOURCE_ALLOWED_LOCATIONS](#azure_resource_allowed_locations) +- [AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME](#azure_apim_minimum_certificate_lifetime) - [AZURE_PARAMETER_FILE_EXPANSION](#azure_parameter_file_expansion) - [AZURE_POLICY_WAIVER_MAX_EXPIRY](#azure_policy_waiver_max_expiry) - [AZURE_RESOURCE_GROUP](#azure_resource_group) @@ -42,87 +42,88 @@ Syntax: ```yaml configuration: - Azure_AKSMinimumVersion: string # A version string + AZURE_AKS_CLUSTER_MINIMUM_VERSION: string # A version string ``` Default: ```yaml -# YAML: The default Azure_AKSMinimumVersion configuration option +# YAML: The default AZURE_AKS_CLUSTER_MINIMUM_VERSION configuration option configuration: - Azure_AKSMinimumVersion: 1.20.5 + AZURE_AKS_CLUSTER_MINIMUM_VERSION: 1.20.5 ``` Example: ```yaml -# YAML: Set the Azure_AKSMinimumVersion configuration option to 1.19.7 +# YAML: Set the AZURE_AKS_CLUSTER_MINIMUM_VERSION configuration option to 1.19.7 configuration: - Azure_AKSMinimumVersion: 1.19.7 + AZURE_AKS_CLUSTER_MINIMUM_VERSION: 1.19.7 ``` -### Azure_AKSNodeMinimumMaxPods +### AZURE_AKS_POOL_MINIMUM_MAXPODS This configuration option determines the minimum allowed max pods setting per node pool. -When an AKS cluster node pool is created, a `maxPods` option is used to determine the maximum number of pods for each node in the node pool. +When an AKS cluster node pool is created, +a `maxPods` option is used to determine the maximum number of pods for each node in the node pool. Syntax: ```yaml configuration: - Azure_AKSNodeMinimumMaxPods: integer + AZURE_AKS_POOL_MINIMUM_MAXPODS: integer ``` Default: ```yaml -# YAML: The default Azure_AKSNodeMinimumMaxPods configuration option +# YAML: The default AZURE_AKS_POOL_MINIMUM_MAXPODS configuration option configuration: - Azure_AKSNodeMinimumMaxPods: 50 + AZURE_AKS_POOL_MINIMUM_MAXPODS: 50 ``` Example: ```yaml -# YAML: Set the Azure_AKSNodeMinimumMaxPods configuration option to 30 +# YAML: Set the AZURE_AKS_POOL_MINIMUM_MAXPODS configuration option to 30 configuration: - Azure_AKSNodeMinimumMaxPods: 30 + AZURE_AKS_POOL_MINIMUM_MAXPODS: 30 ``` -### Azure_AllowedRegions +### AZURE_RESOURCE_ALLOWED_LOCATIONS This configuration option specifies a list of allowed locations that resources can be deployed to. Rules that check the location of Azure resources fail when a resource or resource group is created in a different region. -By default, `Azure_AllowedRegions` is not configured. +By default, `AZURE_RESOURCE_ALLOWED_LOCATIONS` is not configured. The rule `Azure.Resource.AllowedRegions` is skipped when no allowed locations are configured. Syntax: ```yaml configuration: - Azure_AllowedRegions: array # An array of regions + AZURE_RESOURCE_ALLOWED_LOCATIONS: array # An array of regions ``` Default: ```yaml -# YAML: The default Azure_AllowedRegions configuration option +# YAML: The default AZURE_RESOURCE_ALLOWED_LOCATIONS configuration option configuration: - Azure_AllowedRegions: [] + AZURE_RESOURCE_ALLOWED_LOCATIONS: [] ``` Example: ```yaml -# YAML: Set the Azure_AllowedRegions configuration option to Australia East, Australia South East +# YAML: Set the AZURE_RESOURCE_ALLOWED_LOCATIONS configuration option to Australia East, Australia South East configuration: - Azure_AllowedRegions: + AZURE_RESOURCE_ALLOWED_LOCATIONS: - 'australiaeast' - 'australiasoutheast' ``` -### Azure_MinimumCertificateLifetime +### AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME This configuration option determines the minimum number of days allowed before certificate expiry. Rules that check certificate lifetime fail when the days remaining before expiry drop below this number. @@ -131,23 +132,23 @@ Syntax: ```yaml configuration: - Azure_MinimumCertificateLifetime: integer + AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME: integer ``` Default: ```yaml -# YAML: The default Azure_MinimumCertificateLifetime configuration option +# YAML: The default AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME configuration option configuration: - Azure_MinimumCertificateLifetime: 30 + AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME: 30 ``` Example: ```yaml -# YAML: Set the Azure_MinimumCertificateLifetime configuration option to 90 +# YAML: Set the AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME configuration option to 90 configuration: - Azure_MinimumCertificateLifetime: 90 + AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME: 90 ``` ### AZURE_PARAMETER_FILE_EXPANSION diff --git a/docs/deprecations.md b/docs/deprecations.md index 4fa2f1f6cf..38b1d5501a 100644 --- a/docs/deprecations.md +++ b/docs/deprecations.md @@ -19,9 +19,9 @@ Until v2, the old option names are still work and will take precedence if new an New name | Old name | Available from -------- | -------- | -------------- `AZURE_AKS_CLUSTER_MINIMUM_VERSION` | `Azure_AKSMinimumVersion` | :octicons-milestone-24: v1.12.0 -`AZURE_AKS_POOL_MINIMUM_MAXPODS` | `Azure_AKSNodeMinimumMaxPods` | _TBA - not available_ +`AZURE_AKS_POOL_MINIMUM_MAXPODS` | `Azure_AKSNodeMinimumMaxPods` | :octicons-milestone-24: v1.39.0 `AZURE_RESOURCE_ALLOWED_LOCATIONS` | `Azure_AllowedRegions` | :octicons-milestone-24: v1.30.0 -`AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME` | `Azure_MinimumCertificateLifetime` | _TBA - not available_ +`AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME` | `Azure_MinimumCertificateLifetime` | :octicons-milestone-24: v1.39.0 !!! Note Configuration options marked _TBA_ are not available yet. diff --git a/docs/en/rules/Azure.AKS.NodeMinPods.md b/docs/en/rules/Azure.AKS.NodeMinPods.md index d62de1446a..473a55f428 100644 --- a/docs/en/rules/Azure.AKS.NodeMinPods.md +++ b/docs/en/rules/Azure.AKS.NodeMinPods.md @@ -234,10 +234,10 @@ resource clusterWithPools 'Microsoft.ContainerService/managedClusters@2023-11-01 ### Rule configuration - + By default, this rule fails when node pools have `maxPods` set to less than 50. -To configure this rule override the `Azure_AKSNodeMinimumMaxPods` configuration value with the minimum maxPods. +To configure this rule, override the `AZURE_AKS_POOL_MINIMUM_MAXPODS` configuration value with the minimum maxPods. ## LINKS diff --git a/docs/en/rules/Azure.APIM.CertificateExpiry.md b/docs/en/rules/Azure.APIM.CertificateExpiry.md index d7a48ee337..b5958786bc 100644 --- a/docs/en/rules/Azure.APIM.CertificateExpiry.md +++ b/docs/en/rules/Azure.APIM.CertificateExpiry.md @@ -28,9 +28,13 @@ Consider renewing certificates before expiry to prevent service issues. By default, this rule fails when certificates have less than 30 days remaining before expiry. -To configure this rule: +### Rule configuration -- Override the `Azure_MinimumCertificateLifetime` configuration value with the minimum number of days until expiry. + + +By default, this rule fails if the days before a configured certificate expires is less than 30 days. +To configure this rule, +override the `AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME` configuration value with the minimum number of days until expiry. ## LINKS diff --git a/docs/setup/configuring-rules.md b/docs/setup/configuring-rules.md index ac84a69eba..1d02723051 100644 --- a/docs/setup/configuring-rules.md +++ b/docs/setup/configuring-rules.md @@ -245,9 +245,10 @@ configuration: - AllMetrics ``` -### Set the minimum MaxPods for a node pool +### AZURE_AKS_POOL_MINIMUM_MAXPODS - + + This configuration option determines the minimum allowed max pods setting per node pool. When an AKS cluster node pool is created, a `maxPods` option is used to determine the maximum number of pods for each node in the node pool. @@ -261,23 +262,23 @@ Syntax: ```yaml title="ps-rule.yaml" configuration: - Azure_AKSNodeMinimumMaxPods: integer + AZURE_AKS_POOL_MINIMUM_MAXPODS: integer ``` Default: ```yaml title="ps-rule.yaml" -# YAML: The default Azure_AKSNodeMinimumMaxPods configuration option +# YAML: The default AZURE_AKS_POOL_MINIMUM_MAXPODS configuration option configuration: - Azure_AKSNodeMinimumMaxPods: 50 + AZURE_AKS_POOL_MINIMUM_MAXPODS: 50 ``` Example: ```yaml title="ps-rule.yaml" -# YAML: Set the Azure_AKSNodeMinimumMaxPods configuration option to 30 +# YAML: Set the AZURE_AKS_POOL_MINIMUM_MAXPODS configuration option to 30 configuration: - Azure_AKSNodeMinimumMaxPods: 30 + AZURE_AKS_POOL_MINIMUM_MAXPODS: 30 ``` ### AZURE_AKS_CLUSTER_USER_POOL_MINIMUM_NODES @@ -579,7 +580,10 @@ configuration: location: australiaeast ``` -### Azure_MinimumCertificateLifetime +### AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME + + + This configuration option determines the minimum number of days allowed before certificate expiry. Rules that check certificate lifetime fail when the days remaining before expiry drop below this number. @@ -588,23 +592,23 @@ Syntax: ```yaml title="ps-rule.yaml" configuration: - Azure_MinimumCertificateLifetime: integer + AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME: integer ``` Default: ```yaml -# YAML: The default Azure_MinimumCertificateLifetime configuration option +# YAML: The default AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME configuration option configuration: - Azure_MinimumCertificateLifetime: 30 + AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME: 30 ``` Example: ```yaml title="ps-rule.yaml" -# YAML: Set the Azure_MinimumCertificateLifetime configuration option to 90 +# YAML: Set the AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME configuration option to 90 configuration: - Azure_MinimumCertificateLifetime: 90 + AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME: 90 ``` ### AZURE_LINUX_OS_OFFERS diff --git a/docs/upgrade-notes.md b/docs/upgrade-notes.md index 3bad9a040b..bd32d0ce98 100644 --- a/docs/upgrade-notes.md +++ b/docs/upgrade-notes.md @@ -30,7 +30,9 @@ To locate any configurations, search for the old option names within your Infras New name | Old name | Available from -------- | -------- | -------------- `AZURE_AKS_CLUSTER_MINIMUM_VERSION` | `Azure_AKSMinimumVersion` | :octicons-milestone-24: v1.12.0 +`AZURE_AKS_POOL_MINIMUM_MAXPODS` | `Azure_AKSNodeMinimumMaxPods` | :octicons-milestone-24: v1.39.0 `AZURE_RESOURCE_ALLOWED_LOCATIONS` | `Azure_AllowedRegions` | :octicons-milestone-24: v1.30.0 +`AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME` | `Azure_MinimumCertificateLifetime` | :octicons-milestone-24: v1.39.0 To update your configuration, use the new name instead. diff --git a/src/PSRule.Rules.Azure/en/PSRule-rules.psd1 b/src/PSRule.Rules.Azure/en/PSRule-rules.psd1 index f274a65ffb..d2b6e542f2 100644 --- a/src/PSRule.Rules.Azure/en/PSRule-rules.psd1 +++ b/src/PSRule.Rules.Azure/en/PSRule-rules.psd1 @@ -66,7 +66,9 @@ PremiumRedisCacheAvailabilityZone = "The premium redis cache ({0}) deployed to region ({1}) should use a minimum of two availability zones from the following [{2}]." EnterpriseRedisCacheAvailabilityZone = "The enterprise redis cache ({0}) deployed to region ({1}) should be zone-redundant." AKSMinimumVersionReplace = "The configuration option 'Azure_AKSMinimumVersion' has been replaced with 'AZURE_AKS_CLUSTER_MINIMUM_VERSION'. The option 'Azure_AKSMinimumVersion' is deprecated and will no longer work in the next major version. Please update your configuration to the new name. See https://aka.ms/ps-rule-azure/upgrade." + AKSNodeMinimumMaxPodsReplace = "The configuration option 'Azure_AKSNodeMinimumMaxPods' has been replaced with 'AZURE_AKS_POOL_MINIMUM_MAXPODS'. The option 'Azure_AKSNodeMinimumMaxPods' is deprecated and will no longer work in the next major version. Please update your configuration to the new name. See https://aka.ms/ps-rule-azure/upgrade." AzureAllowedRegionsReplace = "The configuration option 'Azure_AllowedRegions' has been replaced with 'AZURE_RESOURCE_ALLOWED_LOCATIONS'. The option 'Azure_AllowedRegions' is deprecated and will no longer work in the next major version. Please update your configuration to the new name. See https://aka.ms/ps-rule-azure/upgrade." + APIMMinimumCertificateLifetimeReplace = "The configuration option 'Azure_MinimumCertificateLifetime' has been replaced with 'AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME'. The option 'Azure_MinimumCertificateLifetime' is deprecated and will no longer work in the next major version. Please update your configuration to the new name. See https://aka.ms/ps-rule-azure/upgrade." # DeprecatedSupportsTags = "The 'SupportsTags' PowerShell function has been replaced with the selector 'Azure.Resource.SupportsTags'. The 'SupportsTags' function is deprecated and will no longer work in the next major version. Please update your PowerShell rules to the selector instead. See https://aka.ms/ps-rule-azure/upgrade." KeyVaultAutoRotationPolicy = "The key ({0}) should enable a auto-rotation policy." ReplicaNotFound = "A replica was not found." @@ -122,4 +124,4 @@ VMSSPublicIPAttached = "The virtual machine scale set instances should not have public IP addresses directly attached to their network interfaces." VMMultiTenantHostingRights = "The Windows 0S installed on the virtual machine ({0}) should use multi-tenant hosting rights." VMAvailabilitySetDistributeTraffic = "The availability set member ({0}) should be a part of a backend pool." -} \ No newline at end of file +} diff --git a/src/PSRule.Rules.Azure/rules/Azure.AKS.Rule.ps1 b/src/PSRule.Rules.Azure/rules/Azure.AKS.Rule.ps1 index 148e69cd0b..d3f6d7505e 100644 --- a/src/PSRule.Rules.Azure/rules/Azure.AKS.Rule.ps1 +++ b/src/PSRule.Rules.Azure/rules/Azure.AKS.Rule.ps1 @@ -56,14 +56,15 @@ Rule 'Azure.AKS.PoolScaleSet' -Ref 'AZR-000017' -Type 'Microsoft.ContainerServic # Synopsis: AKS nodes should use a minimum number of pods Rule 'Azure.AKS.NodeMinPods' -Ref 'AZR-000018' -Type 'Microsoft.ContainerService/managedClusters', 'Microsoft.ContainerService/managedClusters/agentPools' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Performance Efficiency'; } { + $minMaxPods = $Configuration.GetValueOrDefault('Azure_AKSNodeMinimumMaxPods', $Configuration.AZURE_AKS_POOL_MINIMUM_MAXPODS); $agentPools = @(GetAgentPoolProfiles); if ($agentPools.Length -eq 0) { return $Assert.Pass(); } foreach ($agentPool in $agentPools) { - $Assert.GreaterOrEqual($agentPool, 'maxPods', $Configuration.Azure_AKSNodeMinimumMaxPods); + $Assert.GreaterOrEqual($agentPool, 'maxPods', $minMaxPods); } -} -Configure @{ Azure_AKSNodeMinimumMaxPods = 50 } +} # Synopsis: Use Autoscaling to ensure AKS cluster is running efficiently with the right number of nodes for the workloads present. Rule 'Azure.AKS.AutoScaling' -Ref 'AZR-000019' -Type 'Microsoft.ContainerService/managedClusters', 'Microsoft.ContainerService/managedClusters/agentPools' -Tag @{ release = 'GA'; ruleSet = '2021_09'; 'Azure.WAF/pillar' = 'Performance Efficiency'; } { diff --git a/src/PSRule.Rules.Azure/rules/Azure.APIM.Rule.ps1 b/src/PSRule.Rules.Azure/rules/Azure.APIM.Rule.ps1 index e330a3685a..e9085024d1 100644 --- a/src/PSRule.Rules.Azure/rules/Azure.APIM.Rule.ps1 +++ b/src/PSRule.Rules.Azure/rules/Azure.APIM.Rule.ps1 @@ -179,8 +179,9 @@ Rule 'Azure.APIM.ProductTerms' -Ref 'AZR-000050' -Type 'Microsoft.ApiManagement/ # Synopsis: Renew expired certificates Rule 'Azure.APIM.CertificateExpiry' -Ref 'AZR-000051' -Type 'Microsoft.ApiManagement/service' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } -Labels @{ 'Azure.MCSB.v1/control' = 'DP-7' } { + $minDays = $Configuration.GetValueOrDefault('Azure_MinimumCertificateLifetime', $Configuration.AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME); $configurations = @($TargetObject.Properties.hostnameConfigurations | Where-Object { - $Null -ne $_.certificate + $Null -ne $_.certificate.expiry }) if ($configurations.Length -eq 0) { return $Assert.Pass(); @@ -188,10 +189,10 @@ Rule 'Azure.APIM.CertificateExpiry' -Ref 'AZR-000051' -Type 'Microsoft.ApiManage foreach ($configuration in $configurations) { $remaining = ($configuration.certificate.expiry - [DateTime]::Now).Days; $Assert. - GreaterOrEqual($remaining, '.', $Configuration.Azure_MinimumCertificateLifetime). + GreaterOrEqual($remaining, '.', $minDays). WithReason(($LocalizedData.APIMCertificateExpiry -f $configuration.hostName, $configuration.certificate.expiry.ToString('yyyy/MM/dd')), $True); } -} -Configure @{ Azure_MinimumCertificateLifetime = 30 } +} # Synopsis: API Management instances should use availability zones in supported regions for high availability. Rule 'Azure.APIM.AvailabilityZone' -Ref 'AZR-000052' -Type 'Microsoft.ApiManagement/service' -Tag @{ release = 'GA'; ruleSet = '2024_06'; 'Azure.WAF/pillar' = 'Reliability'; } { diff --git a/src/PSRule.Rules.Azure/rules/Config.Rule.yaml b/src/PSRule.Rules.Azure/rules/Config.Rule.yaml index bcd5231779..f502edd41e 100644 --- a/src/PSRule.Rules.Azure/rules/Config.Rule.yaml +++ b/src/PSRule.Rules.Azure/rules/Config.Rule.yaml @@ -39,9 +39,12 @@ spec: AZURE_BICEP_MINIMUM_VERSION: '0.4.451' AZURE_BICEP_CHECK_TOOL: false - # Configure minimum AKS cluster version. + # Configures minimum AKS cluster version. AZURE_AKS_CLUSTER_MINIMUM_VERSION: '1.28.9' + # Configures the minimum allowed max pods setting per node pool. + AZURE_AKS_POOL_MINIMUM_MAXPODS: 50 + # Configures the minimum number of nodes across all system node pools. AZURE_AKS_CLUSTER_MINIMUM_SYSTEM_NODES: 3 @@ -51,6 +54,9 @@ spec: # Configures user pools that are excluded from checking for minimum nodes. AZURE_AKS_CLUSTER_USER_POOL_EXCLUDED_FROM_MINIMUM_NODES: [] + # Configures minimum number of days allowed before certificate expiry. + AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME: 30 + AZURE_DEPLOYMENT_SENSITIVE_PROPERTY_NAMES: - adminUsername - administratorLogin diff --git a/src/PSRule.Rules.Azure/rules/Conventions.Rule.ps1 b/src/PSRule.Rules.Azure/rules/Conventions.Rule.ps1 index 054ac578b4..de501198df 100644 --- a/src/PSRule.Rules.Azure/rules/Conventions.Rule.ps1 +++ b/src/PSRule.Rules.Azure/rules/Conventions.Rule.ps1 @@ -12,10 +12,20 @@ Export-PSRuleConvention 'Azure.DeprecatedOptions' -Initialize { Write-Warning -Message $LocalizedData.AKSMinimumVersionReplace; } + $aksMinimumMaxPods = $Configuration.GetValueOrDefault('Azure_AKSNodeMinimumMaxPods', $Null); + if ($Null -ne $aksMinimumMaxPods) { + Write-Warning -Message $LocalizedData.AKSNodeMinimumMaxPodsReplace; + } + $allowedRegions = $Configuration.GetValueOrDefault('Azure_AllowedRegions', $Null); if ($Null -ne $allowedRegions) { Write-Warning -Message $LocalizedData.AzureAllowedRegionsReplace; } + + $apimMinDays = $Configuration.GetValueOrDefault('Azure_MinimumCertificateLifetime', $Null); + if ($Null -ne $apimMinDays) { + Write-Warning -Message $LocalizedData.APIMMinimumCertificateLifetimeReplace; + } } # Synopsis: Create a context singleton. diff --git a/tests/PSRule.Rules.Azure.Tests/Azure.AKS.Tests.ps1 b/tests/PSRule.Rules.Azure.Tests/Azure.AKS.Tests.ps1 index e6372de65c..ce3b869fb5 100644 --- a/tests/PSRule.Rules.Azure.Tests/Azure.AKS.Tests.ps1 +++ b/tests/PSRule.Rules.Azure.Tests/Azure.AKS.Tests.ps1 @@ -733,14 +733,14 @@ Describe 'Azure.AKS' -Tag AKS { # Fail $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' }); $ruleResult | Should -Not -BeNullOrEmpty; - $ruleResult.Length | Should -Be 1; - $ruleResult.TargetName | Should -Be 'clusterA'; + $ruleResult.Length | Should -Be 2; + $ruleResult.TargetName | Should -BeIn 'clusterA', 'clusterF'; # Pass $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); $ruleResult | Should -Not -BeNullOrEmpty; - $ruleResult.Length | Should -Be 6; - $ruleResult.TargetName | Should -BeIn 'clusterB', 'clusterC/agentpool3', 'clusterC/agentpool4', 'clusterD', 'clusterE', 'clusterF'; + $ruleResult.Length | Should -Be 5; + $ruleResult.TargetName | Should -BeIn 'clusterB', 'clusterC/agentpool3', 'clusterC/agentpool4', 'clusterD', 'clusterE'; } It 'Azure.AKS.MinUserPoolNodes' { @@ -1219,6 +1219,27 @@ Describe 'Azure.AKS' -Tag AKS { $ruleResult.TargetName | Should -BeIn 'cluster-A', 'cluster-B', 'cluster-D'; } + It 'Azure.AKS.NodeMinPods - HashTable option' { + $option = @{ + 'Configuration.AZURE_AKS_POOL_MINIMUM_MAXPODS' = 30 + } + + $result = Invoke-PSRule @invokeParams -InputPath $dataPath -Option $option + $filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.AKS.NodeMinPods' }; + + # Fail + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' }); + $ruleResult | Should -Not -BeNullOrEmpty; + $ruleResult.Length | Should -Be 1; + $ruleResult.TargetName | Should -BeIn 'cluster-B'; + + # Pass + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); + $ruleResult | Should -Not -BeNullOrEmpty; + $ruleResult.Length | Should -Be 11; + $ruleResult.TargetName | Should -BeIn 'cluster-A', 'cluster-C', 'cluster-D', 'cluster-F', 'cluster-G', 'cluster-H', 'cluster-I', 'cluster-J', 'cluster-K', 'cluster-L', 'system'; + } + It 'Azure.AKS.PlatformLogs - HashTable option - Excluding metrics category' { $option = @{ 'Configuration.AZURE_AKS_ENABLED_PLATFORM_LOG_CATEGORIES_LIST' = @( diff --git a/tests/PSRule.Rules.Azure.Tests/Azure.APIM.Tests.ps1 b/tests/PSRule.Rules.Azure.Tests/Azure.APIM.Tests.ps1 index 3033d290ef..20448a1acf 100644 --- a/tests/PSRule.Rules.Azure.Tests/Azure.APIM.Tests.ps1 +++ b/tests/PSRule.Rules.Azure.Tests/Azure.APIM.Tests.ps1 @@ -276,8 +276,8 @@ Describe 'Azure.APIM' -Tag 'APIM' { # Fail $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' }); $ruleResult | Should -Not -BeNullOrEmpty; - $ruleResult.Length | Should -Be 14; - $ruleResult.TargetName | Should -Be 'apim-C', 'apim-D', 'apim-E', 'apim-F', 'apim-G', 'apim-H', 'apim-I', 'apim-J', 'apim-K', 'apim-L', 'apim-M', 'apim-N', 'apim-O', 'apim-P'; + $ruleResult.Length | Should -Be 13; + $ruleResult.TargetName | Should -Be 'apim-C', 'apim-D', 'apim-E', 'apim-F', 'apim-G', 'apim-H', 'apim-I', 'apim-J', 'apim-K', 'apim-L', 'apim-M', 'apim-N', 'apim-O'; $ruleResult[0].Reason | Should -Not -BeNullOrEmpty; $ruleResult[0].Reason | Should -BeExactly "The certificate for host name 'api.contoso.com' expires or expired on '2020/01/01'."; @@ -285,8 +285,8 @@ Describe 'Azure.APIM' -Tag 'APIM' { # Pass $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); $ruleResult | Should -Not -BeNullOrEmpty; - $ruleResult.Length | Should -Be 2; - $ruleResult.TargetName | Should -BeIn 'apim-B', 'apim-A'; + $ruleResult.Length | Should -Be 3; + $ruleResult.TargetName | Should -BeIn 'apim-B', 'apim-A', 'apim-P'; } It 'Azure.APIM.Name' { @@ -627,6 +627,26 @@ Describe 'Azure.APIM' -Tag 'APIM' { $ruleResult.TargetName | Should -BeIn 'apim-M', 'apim-N', 'apim-O'; } + It 'Azure.APIM.CertificateExpiry - HashTable option' { + $option = @{ + 'Configuration.AZURE_APIM_MINIMUM_CERTIFICATE_LIFETIME' = 356 + } + $result = Invoke-PSRule @invokeParams -InputPath $dataPath -Option $option -Outcome All; + $filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.APIM.CertificateExpiry' -and $_.TargetType -eq 'Microsoft.ApiManagement/service' }; + + # Fail + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' }); + $ruleResult | Should -Not -BeNullOrEmpty; + $ruleResult.Length | Should -Be 14; + $ruleResult.TargetName | Should -Be 'apim-C', 'apim-D', 'apim-E', 'apim-F', 'apim-G', 'apim-H', 'apim-I', 'apim-J', 'apim-K', 'apim-L', 'apim-M', 'apim-N', 'apim-O', 'apim-P'; + + # Pass + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); + $ruleResult | Should -Not -BeNullOrEmpty; + $ruleResult.Length | Should -Be 2; + $ruleResult.TargetName | Should -BeIn 'apim-B', 'apim-A'; + } + It 'Azure.APIM.AvailabilityZone - YAML file option' { $result = Invoke-PSRule @invokeParams -InputPath $dataPath -Option $configPath -Outcome All; $filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.APIM.AvailabilityZone' -and $_.TargetType -eq 'Microsoft.ApiManagement/service' }; diff --git a/tests/PSRule.Rules.Azure.Tests/Resources.AKS.Template.json b/tests/PSRule.Rules.Azure.Tests/Resources.AKS.Template.json index c0891cff1b..6046504324 100644 --- a/tests/PSRule.Rules.Azure.Tests/Resources.AKS.Template.json +++ b/tests/PSRule.Rules.Azure.Tests/Resources.AKS.Template.json @@ -840,7 +840,7 @@ "vmSize": "Standard_B2ms", "osDiskSizeGB": 100, "vnetSubnetID": "[concat(parameters('vnetId'), '/subnets/subnet-01')]", - "maxPods": 50, + "maxPods": 20, "type": "VirtualMachineScaleSets", "osType": "Linux", "enableAutoScaling": true, diff --git a/tests/PSRule.Rules.Azure.Tests/Resources.AKS.json b/tests/PSRule.Rules.Azure.Tests/Resources.AKS.json index 78a1c9d9e5..b344a498c8 100644 --- a/tests/PSRule.Rules.Azure.Tests/Resources.AKS.json +++ b/tests/PSRule.Rules.Azure.Tests/Resources.AKS.json @@ -82,7 +82,7 @@ "vmSize": "Standard_F2s_v2", "osDiskSizeGB": 30, "vnetSubnetID": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-A/subnets/subnet-A", - "maxPods": 30, + "maxPods": 20, "type": "AvailabilitySet", "orchestratorVersion": "1.11.4", "osType": "Linux", diff --git a/tests/PSRule.Rules.Azure.Tests/Resources.APIM.json b/tests/PSRule.Rules.Azure.Tests/Resources.APIM.json index 2b1dc3c575..afebb43ede 100644 --- a/tests/PSRule.Rules.Azure.Tests/Resources.APIM.json +++ b/tests/PSRule.Rules.Azure.Tests/Resources.APIM.json @@ -3061,7 +3061,7 @@ "certificatePassword": null, "negotiateClientCertificate": false, "certificate": { - "expiry": "2020-01-01T12:00:00+00:00", + "expiry": "2025-09-01T12:00:00+00:00", "thumbprint": "0000000000000000000000000000000000000000", "subject": "CN=api.contoso.com, OU=A, O=O, L=L, S=S, C=C" },