* Quality updates to rule #1772 * Fix
This commit is contained in:
Родитель
9259b3b622
Коммит
84e8c4893d
|
@ -34,6 +34,9 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers
|
|||
|
||||
What's changed since v1.32.1:
|
||||
|
||||
- General improvements:
|
||||
- Quality updates to rules and documentation by @BernieWhite.
|
||||
[#1772](https://github.com/Azure/PSRule.Rules.Azure/issues/1772)
|
||||
- Engineering:
|
||||
- Bump xunit to v2.6.4.
|
||||
[#2618](https://github.com/Azure/PSRule.Rules.Azure/pull/2618)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
reviewed: 2021/12/20
|
||||
reviewed: 2021-12-20
|
||||
severity: Important
|
||||
pillar: Operational Excellence
|
||||
category: Deployment
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
reviewed: 2022/09/21
|
||||
reviewed: 2022-09-21
|
||||
severity: Awareness
|
||||
pillar: Operational Excellence
|
||||
category: Repeatable infrastructure
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
reviewed: 2021/11/21
|
||||
reviewed: 2021-11-21
|
||||
severity: Awareness
|
||||
pillar: Operational Excellence
|
||||
category: Repeatable infrastructure
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
severity: Important
|
||||
pillar: Reliability
|
||||
category: Design
|
||||
category: RE:05 Redundancy
|
||||
resource: Virtual Network Gateway
|
||||
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.VNG.VPNAvailabilityZoneSKU/
|
||||
---
|
||||
|
@ -29,10 +29,6 @@ Deploying VPN gateways in Azure Availability Zones physically and logically sepa
|
|||
|
||||
Consider deploying VPN gateways with an availability zone SKU to improve reliability of virtual network gateways.
|
||||
|
||||
## NOTES
|
||||
|
||||
VPN gateway availability zones are managed via Public IP addresses, and are flagged separately under the `Azure.PublicIP.AvailabilityZone` rule.
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
### Configure with Azure template
|
||||
|
@ -51,37 +47,33 @@ For example:
|
|||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "2020-11-01",
|
||||
"name": "[parameters('name')]",
|
||||
"type": "Microsoft.Network/virtualNetworkGateways",
|
||||
"location": "[parameters('location')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', parameters('newPublicIpAddressName'))]"
|
||||
],
|
||||
"tags": {},
|
||||
"properties": {
|
||||
"gatewayType": "Vpn",
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "default",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"subnet": {
|
||||
"id": "[parameters('subnetId')]"
|
||||
},
|
||||
"publicIpAddress": {
|
||||
"id": "[resourceId('vpn-rg', 'Microsoft.Network/publicIPAddresses', parameters('newPublicIpAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"vpnType": "[parameters('vpnType')]",
|
||||
"vpnGatewayGeneration": "[parameters('vpnGatewayGeneration')]",
|
||||
"sku": {
|
||||
"name": "VpnGw1AZ",
|
||||
"tier": "VpnGw1AZ"
|
||||
"type": "Microsoft.Network/virtualNetworkGateways",
|
||||
"apiVersion": "2023-06-01",
|
||||
"name": "[parameters('name')]",
|
||||
"location": "[parameters('location')]",
|
||||
"properties": {
|
||||
"gatewayType": "Vpn",
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "default",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"subnet": {
|
||||
"id": "[parameters('subnetId')]"
|
||||
},
|
||||
"publicIPAddress": {
|
||||
"id": "[parameters('pipId')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"vpnType": "RouteBased",
|
||||
"vpnGatewayGeneration": "Generation2",
|
||||
"sku": {
|
||||
"name": "VpnGw1AZ",
|
||||
"tier": "VpnGw1AZ"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -100,10 +92,9 @@ To configure an AZ SKU for a VPN gateway:
|
|||
For example:
|
||||
|
||||
```bicep
|
||||
resource name_resource 'Microsoft.Network/virtualNetworkGateways@2020-11-01' = {
|
||||
resource vng 'Microsoft.Network/virtualNetworkGateways@2023-06-01' = {
|
||||
name: name
|
||||
location: location
|
||||
tags: {}
|
||||
properties: {
|
||||
gatewayType: 'Vpn'
|
||||
ipConfigurations: [
|
||||
|
@ -115,27 +106,29 @@ resource name_resource 'Microsoft.Network/virtualNetworkGateways@2020-11-01' = {
|
|||
id: subnetId
|
||||
}
|
||||
publicIPAddress: {
|
||||
id: resourceId('vpn-rg', 'Microsoft.Network/publicIPAddresses', newPublicIpAddressName)
|
||||
id: pipId
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
vpnType: vpnType
|
||||
vpnGatewayGeneration: vpnGatewayGeneration
|
||||
vpnType: 'RouteBased'
|
||||
vpnGatewayGeneration: 'Generation2'
|
||||
sku: {
|
||||
name: 'VpnGw1AZ'
|
||||
tier: 'VpnGw1AZ'
|
||||
}
|
||||
}
|
||||
dependsOn: [
|
||||
newPublicIpAddressName_resource
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## NOTES
|
||||
|
||||
VPN gateway availability zones are managed via Public IP addresses, and are flagged separately under the `Azure.PublicIP.AvailabilityZone` rule.
|
||||
|
||||
## LINKS
|
||||
|
||||
- [Azure deployment reference](https://docs.microsoft.com/azure/templates/microsoft.network/virtualnetworkgateways?tabs=json)
|
||||
- [About zone-redundant virtual network gateways in Azure Availability Zones](https://docs.microsoft.com/azure/vpn-gateway/about-zone-redundant-vnet-gateways)
|
||||
- [VPN gateway SKUs](https://docs.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpngateways#gwsku)
|
||||
- [Use zone-aware services](https://learn.microsoft.com/azure/architecture/framework/resiliency/design-best-practices#use-zone-aware-services)
|
||||
- [RE:05 Redundancy](https://learn.microsoft.com/azure/well-architected/reliability/redundancy)
|
||||
- [About zone-redundant virtual network gateway in Azure availability zones](https://learn.microsoft.com/azure/vpn-gateway/about-zone-redundant-vnet-gateways)
|
||||
- [VPN gateway SKUs](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpngateways#gwsku)
|
||||
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.network/virtualnetworkgateways)
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// Bicep documentation examples
|
||||
|
||||
@description('The name of the resource.')
|
||||
param name string
|
||||
|
||||
@description('The location resources will be deployed.')
|
||||
param location string = resourceGroup().location
|
||||
|
||||
@description('The resource ID for the subnet to connect to.')
|
||||
param subnetId string
|
||||
|
||||
@description('The resource ID of the public IP address to use.')
|
||||
param pipId string
|
||||
|
||||
// An example Virtual Network Gateway with availablity zone aware SKU.
|
||||
resource vng 'Microsoft.Network/virtualNetworkGateways@2023-06-01' = {
|
||||
name: name
|
||||
location: location
|
||||
properties: {
|
||||
gatewayType: 'Vpn'
|
||||
ipConfigurations: [
|
||||
{
|
||||
name: 'default'
|
||||
properties: {
|
||||
privateIPAllocationMethod: 'Dynamic'
|
||||
subnet: {
|
||||
id: subnetId
|
||||
}
|
||||
publicIPAddress: {
|
||||
id: pipId
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
vpnType: 'RouteBased'
|
||||
vpnGatewayGeneration: 'Generation2'
|
||||
sku: {
|
||||
name: 'VpnGw1AZ'
|
||||
tier: 'VpnGw1AZ'
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"metadata": {
|
||||
"_generator": {
|
||||
"name": "bicep",
|
||||
"version": "0.24.24.22086",
|
||||
"templateHash": "6204832215938608293"
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the resource."
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"defaultValue": "[resourceGroup().location]",
|
||||
"metadata": {
|
||||
"description": "The location resources will be deployed."
|
||||
}
|
||||
},
|
||||
"subnetId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The resource ID for the subnet to connect to."
|
||||
}
|
||||
},
|
||||
"pipId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The resource ID of the public IP address to use."
|
||||
}
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Network/virtualNetworkGateways",
|
||||
"apiVersion": "2023-06-01",
|
||||
"name": "[parameters('name')]",
|
||||
"location": "[parameters('location')]",
|
||||
"properties": {
|
||||
"gatewayType": "Vpn",
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "default",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"subnet": {
|
||||
"id": "[parameters('subnetId')]"
|
||||
},
|
||||
"publicIPAddress": {
|
||||
"id": "[parameters('pipId')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"vpnType": "RouteBased",
|
||||
"vpnGatewayGeneration": "Generation2",
|
||||
"sku": {
|
||||
"name": "VpnGw1AZ",
|
||||
"tier": "VpnGw1AZ"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -343,6 +343,7 @@ task Rules Dependencies, {
|
|||
OutputFormat = 'NUnit3'
|
||||
ErrorAction = 'Stop'
|
||||
As = 'Summary'
|
||||
Outcome = 'Problem'
|
||||
}
|
||||
Import-Module (Join-Path -Path $PWD -ChildPath out/modules/PSRule.Rules.Azure) -Force;
|
||||
Assert-PSRule @assertParams -InputPath $PWD -Module PSRule.Rules.MSFT.OSS -Format File -OutputPath reports/ps-rule-file.xml;
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
#
|
||||
|
||||
# Synopsis: Use ASEv3 as replacement for the classic app service environment versions ASEv1 and ASEv2.
|
||||
Rule 'Azure.ASE.MigrateV3' -Ref 'AZR-000319' -Type 'Microsoft.Web/hostingEnvironments' -Tag @{ release = 'GA'; ruleSet = '2022_12'; } {
|
||||
Rule 'Azure.ASE.MigrateV3' -Ref 'AZR-000319' -Type 'Microsoft.Web/hostingEnvironments' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$Assert.HasFieldValue($TargetObject, 'kind', 'ASEV3').Reason($LocalizedData.ClassicASEDeprecated, $PSRule.TargetName, $TargetObject.kind)
|
||||
}
|
||||
|
|
|
@ -15,8 +15,9 @@ metadata:
|
|||
name: Azure.AppGwWAF.Enabled
|
||||
ref: AZR-000309
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2022_09'
|
||||
release: GA
|
||||
ruleSet: 2022_09
|
||||
Azure.WAF/pillar: Security
|
||||
spec:
|
||||
type:
|
||||
- Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies
|
||||
|
@ -34,8 +35,9 @@ metadata:
|
|||
name: Azure.AppGwWAF.PreventionMode
|
||||
ref: AZR-000302
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2022_09'
|
||||
release: GA
|
||||
ruleSet: 2022_09
|
||||
Azure.WAF/pillar: Security
|
||||
spec:
|
||||
type:
|
||||
- Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies
|
||||
|
@ -54,8 +56,9 @@ metadata:
|
|||
name: Azure.AppGwWAF.Exclusions
|
||||
ref: AZR-000303
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2022_09'
|
||||
release: GA
|
||||
ruleSet: 2022_09
|
||||
Azure.WAF/pillar: Security
|
||||
spec:
|
||||
type:
|
||||
- Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies
|
||||
|
@ -76,8 +79,9 @@ metadata:
|
|||
name: Azure.AppGwWAF.RuleGroups
|
||||
ref: AZR-000304
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2022_09'
|
||||
release: GA
|
||||
ruleSet: 2022_09
|
||||
Azure.WAF/pillar: Security
|
||||
spec:
|
||||
type:
|
||||
- Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies
|
||||
|
|
|
@ -15,8 +15,9 @@ metadata:
|
|||
name: Azure.AppInsights.Workspace
|
||||
ref: AZR-000069
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2021_06'
|
||||
release: GA
|
||||
ruleSet: 2021_06
|
||||
Azure.WAF/pillar: Operational Excellence
|
||||
spec:
|
||||
type:
|
||||
- microsoft.insights/components
|
||||
|
@ -32,8 +33,9 @@ metadata:
|
|||
name: Azure.AppInsights.Name
|
||||
ref: AZR-000070
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2021_06'
|
||||
release: GA
|
||||
ruleSet: 2021_06
|
||||
Azure.WAF/pillar: Operational Excellence
|
||||
spec:
|
||||
type:
|
||||
- microsoft.insights/components
|
||||
|
|
|
@ -18,7 +18,7 @@ Rule 'Azure.Automation.EncryptVariables' -Ref 'AZR-000086' -Type 'Microsoft.Auto
|
|||
}
|
||||
|
||||
# Synopsis: Ensure webhook expiry is not longer than one year
|
||||
Rule 'Azure.Automation.WebHookExpiry' -Ref 'AZR-000087' -Type 'Microsoft.Automation/automationAccounts' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.Automation.WebHookExpiry' -Ref 'AZR-000087' -Type 'Microsoft.Automation/automationAccounts' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$webhooks = GetSubResources -ResourceType 'Microsoft.Automation/automationAccounts/webhooks';
|
||||
if ($webhooks.Length -eq 0) {
|
||||
return $Assert.Pass();
|
||||
|
@ -47,7 +47,7 @@ Rule 'Azure.Automation.AuditLogs' -Ref 'AZR-000088' -Type 'Microsoft.Automation/
|
|||
}
|
||||
|
||||
# Synopsis: Ensure automation account platform diagnostic logs are enabled.
|
||||
Rule 'Azure.Automation.PlatformLogs' -Ref 'AZR-000089' -Type 'Microsoft.Automation/automationAccounts' -Tag @{ release = 'GA'; ruleSet = '2021_12'; } {
|
||||
Rule 'Azure.Automation.PlatformLogs' -Ref 'AZR-000089' -Type 'Microsoft.Automation/automationAccounts' -Tag @{ release = 'GA'; ruleSet = '2021_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$configurationLogCategoriesList = $Configuration.GetStringValues('AZURE_AUTOMATIONACCOUNT_ENABLED_PLATFORM_LOG_CATEGORIES_LIST');
|
||||
|
||||
if ($configurationLogCategoriesList.Length -eq 0) {
|
||||
|
|
|
@ -39,7 +39,7 @@ Rule 'Azure.CDN.MinTLS' -Ref 'AZR-000092' -Type 'Microsoft.Cdn/profiles/endpoint
|
|||
}
|
||||
|
||||
# Synopsis: Use Azure Front Door Standard or Premium SKU to improve the performance of web pages with dynamic content and overall capabilities.
|
||||
Rule 'Azure.CDN.UseFrontDoor' -Ref 'AZR-000286' -Type 'Microsoft.Cdn/profiles' -If { IsStandard_MicrosoftSKU } -Tag @{ release = 'GA'; ruleSet = '2022_09' } {
|
||||
Rule 'Azure.CDN.UseFrontDoor' -Ref 'AZR-000286' -Type 'Microsoft.Cdn/profiles' -If { IsStandard_MicrosoftSKU } -Tag @{ release = 'GA'; ruleSet = '2022_09'; 'Azure.WAF/pillar' = 'Performance Efficiency'; } {
|
||||
$Assert.In($TargetObject, 'sku.name', @('Standard_AzureFrontDoor', 'Premium_AzureFrontDoor'));
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ metadata:
|
|||
name: Azure.Cosmos.DisableMetadataWrite
|
||||
ref: AZR-000095
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2021_09'
|
||||
Azure.WAF/pillar: 'Security'
|
||||
release: GA
|
||||
ruleSet: 2021_09
|
||||
Azure.WAF/pillar: Security
|
||||
labels:
|
||||
Azure.MCSB.v1/control: [ 'IM-1', 'IM-2' ]
|
||||
spec:
|
||||
|
@ -35,8 +35,9 @@ metadata:
|
|||
name: Azure.Cosmos.AccountName
|
||||
ref: AZR-000096
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2021_09'
|
||||
release: GA
|
||||
ruleSet: 2021_09
|
||||
Azure.WAF/pillar: Operational Excellence
|
||||
spec:
|
||||
type:
|
||||
- Microsoft.DocumentDb/databaseAccounts
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#region Rules
|
||||
|
||||
# Synopsis: Regularly remove unused resources to reduce costs.
|
||||
Rule 'Azure.EventHub.Usage' -Ref 'AZR-000101' -Type 'Microsoft.EventHub/namespaces' -If { IsExport } -Tag @{ release = 'GA'; ruleSet = '2022_03'; } {
|
||||
Rule 'Azure.EventHub.Usage' -Ref 'AZR-000101' -Type 'Microsoft.EventHub/namespaces' -If { IsExport } -Tag @{ release = 'GA'; ruleSet = '2022_03'; 'Azure.WAF/pillar' = 'Cost Optimization'; } {
|
||||
$items = @(GetSubResources -ResourceType 'Microsoft.EventHub/namespaces/eventhubs');
|
||||
$Assert.GreaterOrEqual($items, '.', 1);
|
||||
}
|
||||
|
|
|
@ -15,8 +15,9 @@ metadata:
|
|||
name: Azure.LB.Name
|
||||
ref: AZR-000129
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2020_06'
|
||||
release: GA
|
||||
ruleSet: 2020_06
|
||||
Azure.WAF/pillar: Operational Excellence
|
||||
spec:
|
||||
type:
|
||||
- Microsoft.Network/loadBalancers
|
||||
|
|
|
@ -15,8 +15,9 @@ metadata:
|
|||
name: Azure.NSG.Name
|
||||
ref: AZR-000141
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2020_06'
|
||||
release: GA
|
||||
ruleSet: 2020_06
|
||||
Azure.WAF/pillar: Operational Excellence
|
||||
spec:
|
||||
type:
|
||||
- Microsoft.Network/networkSecurityGroups
|
||||
|
@ -30,7 +31,7 @@ spec:
|
|||
match: '^[a-z0-9]([a-z0-9_.-]{0,78}[a-z0-9_])?$'
|
||||
|
||||
---
|
||||
|
||||
# Synopsis: Network Security Groups that are managed by AKS.
|
||||
apiVersion: github.com/microsoft/PSRule/v1
|
||||
kind: Selector
|
||||
metadata:
|
||||
|
@ -51,8 +52,9 @@ metadata:
|
|||
name: Azure.NSG.AKSRules
|
||||
ref: AZR-000292
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2022_09'
|
||||
release: GA
|
||||
ruleSet: 2022_09
|
||||
Azure.WAF/pillar: Operational Excellence
|
||||
spec:
|
||||
with:
|
||||
- Azure.NSG.AKSManaged
|
||||
|
|
|
@ -6,30 +6,30 @@
|
|||
#
|
||||
|
||||
# Synopsis: Policy and initiative definitions require a display name, description, and category.
|
||||
Rule 'Azure.Policy.Descriptors' -Ref 'AZR-000142' -Type 'Microsoft.Authorization/policyDefinitions', 'Microsoft.Authorization/policySetDefinitions' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.Policy.Descriptors' -Ref 'AZR-000142' -Type 'Microsoft.Authorization/policyDefinitions', 'Microsoft.Authorization/policySetDefinitions' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.displayName');
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.description');
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.metadata.category');
|
||||
}
|
||||
|
||||
# Synopsis: Policy assignments require a display name and description.
|
||||
Rule 'Azure.Policy.AssignmentDescriptors' -Ref 'AZR-000143' -Type 'Microsoft.Authorization/policyAssignments' -Tag @{ release = 'GA'; ruleSet = '2021_06'; } {
|
||||
Rule 'Azure.Policy.AssignmentDescriptors' -Ref 'AZR-000143' -Type 'Microsoft.Authorization/policyAssignments' -Tag @{ release = 'GA'; ruleSet = '2021_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.displayName');
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.description');
|
||||
}
|
||||
|
||||
# Synopsis: Policy assignments require assignedBy metadata.
|
||||
Rule 'Azure.Policy.AssignmentAssignedBy' -Ref 'AZR-000144' -Type 'Microsoft.Authorization/policyAssignments' -Tag @{ release = 'GA'; ruleSet = '2021_06'; } {
|
||||
Rule 'Azure.Policy.AssignmentAssignedBy' -Ref 'AZR-000144' -Type 'Microsoft.Authorization/policyAssignments' -Tag @{ release = 'GA'; ruleSet = '2021_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.metadata.assignedBy');
|
||||
}
|
||||
|
||||
# Synopsis: Policy exemptions require a display name, and description.
|
||||
Rule 'Azure.Policy.ExemptionDescriptors' -Ref 'AZR-000145' -Type 'Microsoft.Authorization/policyExemptions' -Tag @{ release = 'GA'; ruleSet = '2021_06'; } {
|
||||
Rule 'Azure.Policy.ExemptionDescriptors' -Ref 'AZR-000145' -Type 'Microsoft.Authorization/policyExemptions' -Tag @{ release = 'GA'; ruleSet = '2021_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.displayName');
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.description');
|
||||
}
|
||||
|
||||
# Synopsis: Policy exceptions must be less then 2 years.
|
||||
Rule 'Azure.Policy.WaiverExpiry' -Ref 'AZR-000146' -Type 'Microsoft.Authorization/policyExemptions' -With 'Azure.PolicyExemptionWaiver' -Tag @{ release = 'GA'; ruleSet = '2021_06' } {
|
||||
Rule 'Azure.Policy.WaiverExpiry' -Ref 'AZR-000146' -Type 'Microsoft.Authorization/policyExemptions' -With 'Azure.PolicyExemptionWaiver' -Tag @{ release = 'GA'; ruleSet = '2021_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$Assert.LessOrEqual($TargetObject, 'properties.expiresOn', $Configuration.AZURE_POLICY_WAIVER_MAX_EXPIRY);
|
||||
} -Configure @{ AZURE_POLICY_WAIVER_MAX_EXPIRY = 366 }
|
||||
|
|
|
@ -15,8 +15,9 @@ metadata:
|
|||
name: Azure.PrivateEndpoint.Name
|
||||
ref: AZR-000153
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2021_12'
|
||||
release: GA
|
||||
ruleSet: 2021_12
|
||||
Azure.WAF/pillar: Operational Excellence
|
||||
spec:
|
||||
type:
|
||||
- Microsoft.Network/privateEndpoints
|
||||
|
|
|
@ -14,14 +14,14 @@ Rule 'Azure.Resource.UseTags' -Ref 'AZR-000166' -With 'Azure.Resource.SupportsTa
|
|||
}
|
||||
|
||||
# Synopsis: Resources should be deployed to allowed regions.
|
||||
Rule 'Azure.Resource.AllowedRegions' -Ref 'AZR-000167' -If { (SupportsRegions) -and $PSRule.TargetType -ne 'Microsoft.Resources/deployments' -and $Assert.HasFieldValue($TargetObject, 'location').Result } -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.Resource.AllowedRegions' -Ref 'AZR-000167' -If { (SupportsRegions) -and $PSRule.TargetType -ne 'Microsoft.Resources/deployments' -and $Assert.HasFieldValue($TargetObject, 'location').Result } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$context = $PSRule.GetService('Azure.Context');
|
||||
$location = $TargetObject.location;
|
||||
$Assert.Create($context.IsAllowedLocation($location), $LocalizedData.LocationNotAllowed, $location);
|
||||
}
|
||||
|
||||
# Synopsis: Use Resource Group naming requirements
|
||||
Rule 'Azure.ResourceGroup.Name' -Ref 'AZR-000168' -Type 'Microsoft.Resources/resourceGroups' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.ResourceGroup.Name' -Ref 'AZR-000168' -Type 'Microsoft.Resources/resourceGroups' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftresources
|
||||
|
||||
# Between 1 and 90 characters long
|
||||
|
|
|
@ -15,8 +15,9 @@ metadata:
|
|||
name: Azure.Route.Name
|
||||
ref: AZR-000169
|
||||
tags:
|
||||
release: 'GA'
|
||||
ruleSet: '2020_06'
|
||||
release: GA
|
||||
ruleSet: 2020_06
|
||||
Azure.WAF/pillar: Operational Excellence
|
||||
spec:
|
||||
type:
|
||||
- Microsoft.Network/routeTables
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#region SQL Logical Server
|
||||
|
||||
# Synopsis: Determine if there is an excessive number of firewall rules
|
||||
Rule 'Azure.SQL.FirewallRuleCount' -Ref 'AZR-000183' -Type 'Microsoft.Sql/servers' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.SQL.FirewallRuleCount' -Ref 'AZR-000183' -Type 'Microsoft.Sql/servers' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$firewallRules = @(GetSubResources -ResourceType 'Microsoft.Sql/servers/firewallRules');
|
||||
$Assert.
|
||||
LessOrEqual($firewallRules, '.', 10).
|
||||
|
@ -16,7 +16,7 @@ Rule 'Azure.SQL.FirewallRuleCount' -Ref 'AZR-000183' -Type 'Microsoft.Sql/server
|
|||
}
|
||||
|
||||
# Synopsis: Determine if access from Azure services is required
|
||||
Rule 'Azure.SQL.AllowAzureAccess' -Ref 'AZR-000184' -Type 'Microsoft.Sql/servers' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.SQL.AllowAzureAccess' -Ref 'AZR-000184' -Type 'Microsoft.Sql/servers' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$firewallRules = @(GetSubResources -ResourceType 'Microsoft.Sql/servers/firewallRules' | Where-Object {
|
||||
$_.ResourceName -eq 'AllowAllWindowsAzureIps' -or
|
||||
($_.properties.StartIpAddress -eq '0.0.0.0' -and $_.properties.EndIpAddress -eq '0.0.0.0')
|
||||
|
@ -25,7 +25,7 @@ Rule 'Azure.SQL.AllowAzureAccess' -Ref 'AZR-000184' -Type 'Microsoft.Sql/servers
|
|||
}
|
||||
|
||||
# Synopsis: Determine if there is an excessive number of permitted IP addresses
|
||||
Rule 'Azure.SQL.FirewallIPRange' -Ref 'AZR-000185' -Type 'Microsoft.Sql/servers' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.SQL.FirewallIPRange' -Ref 'AZR-000185' -Type 'Microsoft.Sql/servers' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$summary = GetIPAddressSummary
|
||||
$Assert.
|
||||
LessOrEqual($summary, 'Public', 10).
|
||||
|
@ -44,7 +44,7 @@ Rule 'Azure.SQL.DefenderCloud' -Alias 'Azure.SQL.ThreatDetection' -Ref 'AZR-0001
|
|||
}
|
||||
|
||||
# Synopsis: Enable auditing for Azure SQL logical server
|
||||
Rule 'Azure.SQL.Auditing' -Ref 'AZR-000187' -Type 'Microsoft.Sql/servers' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.SQL.Auditing' -Ref 'AZR-000187' -Type 'Microsoft.Sql/servers' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$configs = @(GetSubResources -ResourceType 'Microsoft.Sql/servers/auditingSettings');
|
||||
if ($configs.Length -eq 0) {
|
||||
return $Assert.Fail($LocalizedData.SubResourceNotFound, 'Microsoft.Sql/servers/auditingSettings');
|
||||
|
@ -92,7 +92,7 @@ Rule 'Azure.SQL.ServerName' -Ref 'AZR-000190' -Type 'Microsoft.Sql/servers' -Tag
|
|||
}
|
||||
|
||||
# Synopsis: Ensure Azure AD-only authentication is enabled with Azure SQL Database.
|
||||
Rule 'Azure.SQL.AADOnly' -Ref 'AZR-000369' -Type 'Microsoft.Sql/servers', 'Microsoft.Sql/servers/azureADOnlyAuthentications' -Tag @{ release = 'GA'; ruleSet = '2023_03'; } {
|
||||
Rule 'Azure.SQL.AADOnly' -Ref 'AZR-000369' -Type 'Microsoft.Sql/servers', 'Microsoft.Sql/servers/azureADOnlyAuthentications' -Tag @{ release = 'GA'; ruleSet = '2023_03'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$types = 'Microsoft.Sql/servers', 'Microsoft.Sql/servers/azureADOnlyAuthentications'
|
||||
$enabledAADOnly = @(GetAzureSQLADOnlyAuthentication -ResourceType $types | Where-Object { $_ })
|
||||
$Assert.GreaterOrEqual($enabledAADOnly, '.', 1).Reason($LocalizedData.AzureADOnlyAuthentication)
|
||||
|
@ -125,7 +125,7 @@ Rule 'Azure.SQL.TDE' -Ref 'AZR-000191' -Type 'Microsoft.Sql/servers/databases',
|
|||
}
|
||||
|
||||
# Synopsis: Azure SQL Database names should meet naming requirements.
|
||||
Rule 'Azure.SQL.DBName' -Ref 'AZR-000192' -Type 'Microsoft.Sql/servers/databases' -If { !(IsExport) } -Tag @{ release = 'GA'; ruleSet = '2020_12'; } {
|
||||
Rule 'Azure.SQL.DBName' -Ref 'AZR-000192' -Type 'Microsoft.Sql/servers/databases' -If { !(IsExport) } -Tag @{ release = 'GA'; ruleSet = '2020_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/azure/azure-resource-manager/management/resource-name-rules#microsoftsql
|
||||
|
||||
$name = $PSRule.TargetName.Split('/', 2, [System.StringSplitOptions]::RemoveEmptyEntries)[-1];
|
||||
|
@ -147,7 +147,7 @@ Rule 'Azure.SQL.DBName' -Ref 'AZR-000192' -Type 'Microsoft.Sql/servers/databases
|
|||
#region Failover group
|
||||
|
||||
# Synopsis: Azure SQL failover group names should meet naming requirements.
|
||||
Rule 'Azure.SQL.FGName' -Ref 'AZR-000193' -Type 'Microsoft.Sql/servers/failoverGroups' -If { !(IsExport) } -Tag @{ release = 'GA'; ruleSet = '2020_12'; } {
|
||||
Rule 'Azure.SQL.FGName' -Ref 'AZR-000193' -Type 'Microsoft.Sql/servers/failoverGroups' -If { !(IsExport) } -Tag @{ release = 'GA'; ruleSet = '2020_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/azure/azure-resource-manager/management/resource-name-rules#microsoftsql
|
||||
|
||||
$name = $PSRule.TargetName.Split('/')[-1];
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#region SQL Managed Instance
|
||||
|
||||
# Synopsis: SQL Managed Instance names should meet naming requirements.
|
||||
Rule 'Azure.SQLMI.Name' -Ref 'AZR-000194' -Type 'Microsoft.Sql/managedInstances' -Tag @{ release = 'GA'; ruleSet = '2020_12'; } {
|
||||
Rule 'Azure.SQLMI.Name' -Ref 'AZR-000194' -Type 'Microsoft.Sql/managedInstances' -Tag @{ release = 'GA'; ruleSet = '2020_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/azure/azure-resource-manager/management/resource-name-rules#microsoftsql
|
||||
|
||||
# Between 1 and 63 characters long
|
||||
|
@ -21,7 +21,7 @@ Rule 'Azure.SQLMI.Name' -Ref 'AZR-000194' -Type 'Microsoft.Sql/managedInstances'
|
|||
}
|
||||
|
||||
# Synopsis: Ensure Azure AD-only authentication is enabled with Azure SQL Managed Instance.
|
||||
Rule 'Azure.SQLMI.AADOnly' -Ref 'AZR-000366' -Type 'Microsoft.Sql/managedInstances', 'Microsoft.Sql/managedInstances/azureADOnlyAuthentications' -Tag @{ release = 'GA'; ruleSet = '2023_03'; } {
|
||||
Rule 'Azure.SQLMI.AADOnly' -Ref 'AZR-000366' -Type 'Microsoft.Sql/managedInstances', 'Microsoft.Sql/managedInstances/azureADOnlyAuthentications' -Tag @{ release = 'GA'; ruleSet = '2023_03'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$types = 'Microsoft.Sql/managedInstances', 'Microsoft.Sql/managedInstances/azureADOnlyAuthentications'
|
||||
$enabledAADOnly = @(GetAzureSQLADOnlyAuthentication -ResourceType $types | Where-Object { $_ })
|
||||
$Assert.GreaterOrEqual($enabledAADOnly, '.', 1).Reason($LocalizedData.AzureADOnlyAuthentication)
|
||||
|
|
|
@ -8,18 +8,18 @@
|
|||
#region Rules
|
||||
|
||||
# Synopsis: Regularly remove unused resources to reduce costs.
|
||||
Rule 'Azure.ServiceBus.Usage' -Ref 'AZR-000177' -Type 'Microsoft.ServiceBus/namespaces' -If { IsExport } -Tag @{ release = 'GA'; ruleSet = '2022_03'; } {
|
||||
Rule 'Azure.ServiceBus.Usage' -Ref 'AZR-000177' -Type 'Microsoft.ServiceBus/namespaces' -If { IsExport } -Tag @{ release = 'GA'; ruleSet = '2022_03'; 'Azure.WAF/pillar' = 'Cost Optimization'; } {
|
||||
$items = @(GetSubResources -ResourceType 'Microsoft.ServiceBus/namespaces/topics', 'Microsoft.ServiceBus/namespaces/queues');
|
||||
$Assert.GreaterOrEqual($items, '.', 1);
|
||||
}
|
||||
|
||||
# Synopsis: Enforce namespaces to require that clients send and receive data with TLS 1.2 version.
|
||||
Rule 'Azure.ServiceBus.MinTLS' -Ref 'AZR-000315' -Type 'Microsoft.ServiceBus/namespaces' -Tag @{ release = 'GA'; ruleSet = '2022_12' } {
|
||||
Rule 'Azure.ServiceBus.MinTLS' -Ref 'AZR-000315' -Type 'Microsoft.ServiceBus/namespaces' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$Assert.HasFieldValue($TargetObject, 'Properties.minimumTlsVersion', '1.2').Reason($LocalizedData.ServiceBusMinTLS, $PSRule.TargetName)
|
||||
}
|
||||
|
||||
# Synopsis: Ensure namespaces audit diagnostic logs are enabled.
|
||||
Rule 'Azure.ServiceBus.AuditLogs' -Ref 'AZR-000358' -Type 'Microsoft.ServiceBus/namespaces' -With 'Azure.ServiceBus.IsPremium' -Tag @{ release = 'GA'; ruleSet = '2023_03'; } {
|
||||
Rule 'Azure.ServiceBus.AuditLogs' -Ref 'AZR-000358' -Type 'Microsoft.ServiceBus/namespaces' -With 'Azure.ServiceBus.IsPremium' -Tag @{ release = 'GA'; ruleSet = '2023_03'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$logCategoryGroups = 'audit', 'allLogs'
|
||||
$joinedLogCategoryGroups = $logCategoryGroups -join ', '
|
||||
$diagnostics = @(GetSubResources -ResourceType 'Microsoft.Insights/diagnosticSettings' |
|
||||
|
|
|
@ -17,7 +17,7 @@ metadata:
|
|||
tags:
|
||||
release: GA
|
||||
ruleSet: 2022_03
|
||||
Azure.WAF/pillar: 'Security'
|
||||
Azure.WAF/pillar: Security
|
||||
labels:
|
||||
Azure.MCSB.v1/control: 'IM-1'
|
||||
spec:
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#
|
||||
|
||||
# Synopsis: Use SignalR naming requirements
|
||||
Rule 'Azure.SignalR.Name' -Ref 'AZR-000180' -Type 'Microsoft.SignalRService/signalR' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.SignalR.Name' -Ref 'AZR-000180' -Type 'Microsoft.SignalRService/signalR' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftsignalrservice
|
||||
|
||||
# Between 3 and 63 characters long
|
||||
|
|
|
@ -39,6 +39,7 @@ metadata:
|
|||
tags:
|
||||
release: GA
|
||||
ruleSet: 2022_03
|
||||
Azure.WAF/pillar: Reliability
|
||||
spec:
|
||||
type:
|
||||
- Microsoft.SignalRService/signalR
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
#region Template
|
||||
|
||||
# Synopsis: Use ARM template file structure.
|
||||
Rule 'Azure.Template.TemplateFile' -Ref 'AZR-000212' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.Template.TemplateFile' -Ref 'AZR-000212' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject);
|
||||
$Assert.HasFields($jsonObject, @('$schema', 'contentVersion', 'resources'));
|
||||
$jsonObject.PSObject.Properties | Within 'Name' '$schema', 'contentVersion', 'metadata', 'parameters', 'functions', 'variables', 'resources', 'outputs';
|
||||
}
|
||||
|
||||
# Synopsis: Use a more recent version of the Azure template schema.
|
||||
Rule 'Azure.Template.TemplateSchema' -Ref 'AZR-000213' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; } {
|
||||
Rule 'Azure.Template.TemplateSchema' -Ref 'AZR-000213' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject);
|
||||
$Assert.HasJsonSchema($jsonObject, @(
|
||||
'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json'
|
||||
|
@ -26,13 +26,13 @@ Rule 'Azure.Template.TemplateSchema' -Ref 'AZR-000213' -Type '.json' -If { (IsTe
|
|||
}
|
||||
|
||||
# Synopsis: Use a Azure template schema with the https scheme.
|
||||
Rule 'Azure.Template.TemplateScheme' -Ref 'AZR-000214' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; } {
|
||||
Rule 'Azure.Template.TemplateScheme' -Ref 'AZR-000214' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject);
|
||||
$Assert.StartsWith($jsonObject, '$schema', 'https://');
|
||||
}
|
||||
|
||||
# Synopsis: Use template parameter descriptions.
|
||||
Rule 'Azure.Template.ParameterMetadata' -Ref 'AZR-000215' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09' } {
|
||||
Rule 'Azure.Template.ParameterMetadata' -Ref 'AZR-000215' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$parameters = @(GetTemplateParameters);
|
||||
if ($parameters.Length -eq 0) {
|
||||
return $Assert.Pass();
|
||||
|
@ -44,13 +44,13 @@ Rule 'Azure.Template.ParameterMetadata' -Ref 'AZR-000215' -Type '.json' -If { (I
|
|||
}
|
||||
|
||||
# Synopsis: ARM templates should include at least one resource.
|
||||
Rule 'Azure.Template.Resources' -Ref 'AZR-000216' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09' } {
|
||||
Rule 'Azure.Template.Resources' -Ref 'AZR-000216' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContent($TargetObject)[0];
|
||||
$Assert.GreaterOrEqual($jsonObject, 'resources', 1);
|
||||
}
|
||||
|
||||
# Synopsis: ARM template parameters should be used at least once.
|
||||
Rule 'Azure.Template.UseParameters' -Ref 'AZR-000217' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09' } {
|
||||
Rule 'Azure.Template.UseParameters' -Ref 'AZR-000217' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonContent = Get-Content -Path $TargetObject.FullName -Raw;
|
||||
$parameters = @(GetTemplateParameters);
|
||||
if ($parameters.Length -eq 0) {
|
||||
|
@ -63,13 +63,13 @@ Rule 'Azure.Template.UseParameters' -Ref 'AZR-000217' -Type '.json' -If { (IsTem
|
|||
}
|
||||
|
||||
# Synopsis: Each Azure Resource Manager (ARM) template file should contain a minimal number of parameters.
|
||||
Rule 'Azure.Template.DefineParameters' -Ref 'AZR-000218' -Type '.json' -If { (IsTemplateFile) -and !(IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } {
|
||||
Rule 'Azure.Template.DefineParameters' -Ref 'AZR-000218' -Type '.json' -If { (IsTemplateFile) -and !(IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$parameters = @(GetTemplateParameters);
|
||||
$Assert.GreaterOrEqual($parameters, '.', 1);
|
||||
}
|
||||
|
||||
# Synopsis: ARM template variables should be used at least once.
|
||||
Rule 'Azure.Template.UseVariables' -Ref 'AZR-000219' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09' } {
|
||||
Rule 'Azure.Template.UseVariables' -Ref 'AZR-000219' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContent($TargetObject)[0];
|
||||
$jsonContent = Get-Content -Path $TargetObject.FullName -Raw;
|
||||
$variableNames = @($jsonObject.variables.PSObject.Properties | Where-Object { $_.MemberType -eq 'NoteProperty' } | ForEach-Object {
|
||||
|
@ -93,7 +93,7 @@ Rule 'Azure.Template.UseVariables' -Ref 'AZR-000219' -Type '.json' -If { (IsTemp
|
|||
}
|
||||
|
||||
# Synopsis: Set the default value for location parameters within ARM template to the default value to `[resourceGroup().location]`.
|
||||
Rule 'Azure.Template.LocationDefault' -Ref 'AZR-000220' -Type '.json' -If { (HasLocationParameter) } -Tag @{ release = 'GA'; ruleSet = '2021_03' } {
|
||||
Rule 'Azure.Template.LocationDefault' -Ref 'AZR-000220' -Type '.json' -If { (HasLocationParameter) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; 'Azure.WAF/pillar' = 'Reliability'; } {
|
||||
# https://github.com/Azure/arm-ttk/blob/master/arm-ttk/testcases/deploymentTemplate/Location-Should-Not-Be-Hardcoded.test.ps1
|
||||
|
||||
$parameters = @(GetTemplateParameters -Name 'location');
|
||||
|
@ -110,7 +110,7 @@ Rule 'Azure.Template.LocationDefault' -Ref 'AZR-000220' -Type '.json' -If { (Has
|
|||
}
|
||||
|
||||
# Synopsis: Location parameters should use a string value.
|
||||
Rule 'Azure.Template.LocationType' -Ref 'AZR-000221' -Type '.json' -If { (HasLocationParameter) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } {
|
||||
Rule 'Azure.Template.LocationType' -Ref 'AZR-000221' -Type '.json' -If { (HasLocationParameter) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://github.com/Azure/arm-ttk/blob/master/arm-ttk/testcases/deploymentTemplate/Location-Should-Not-Be-Hardcoded.test.ps1
|
||||
|
||||
$parameters = @(GetTemplateParameters -Name 'location');
|
||||
|
@ -120,7 +120,7 @@ Rule 'Azure.Template.LocationType' -Ref 'AZR-000221' -Type '.json' -If { (HasLoc
|
|||
}
|
||||
|
||||
# Synopsis: Template resource location should be an expression or `global`.
|
||||
Rule 'Azure.Template.ResourceLocation' -Ref 'AZR-000222' -Type '.json' -If { (HasTemplateResources) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } {
|
||||
Rule 'Azure.Template.ResourceLocation' -Ref 'AZR-000222' -Type '.json' -If { (HasTemplateResources) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://github.com/Azure/arm-ttk/blob/master/arm-ttk/testcases/deploymentTemplate/Resources-Should-Have-Location.test.ps1
|
||||
|
||||
$resources = @(GetTemplateResources);
|
||||
|
@ -137,7 +137,7 @@ Rule 'Azure.Template.ResourceLocation' -Ref 'AZR-000222' -Type '.json' -If { (Ha
|
|||
}
|
||||
|
||||
# Synopsis: Template should reference a location parameter to specify resource location.
|
||||
Rule 'Azure.Template.UseLocationParameter' -Ref 'AZR-000223' -Level Warning -Type '.json' -If { (IsTemplateFile -Suffix '/deploymentTemplate.json') -and !(IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } {
|
||||
Rule 'Azure.Template.UseLocationParameter' -Ref 'AZR-000223' -Level Warning -Type '.json' -If { (IsTemplateFile -Suffix '/deploymentTemplate.json') -and !(IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContent($TargetObject)[0];
|
||||
if ($Assert.HasField($jsonObject, 'parameters.location').Result) {
|
||||
$jsonObject.parameters.PSObject.Properties.Remove('location')
|
||||
|
@ -148,7 +148,7 @@ Rule 'Azure.Template.UseLocationParameter' -Ref 'AZR-000223' -Level Warning -Typ
|
|||
}
|
||||
|
||||
# Synopsis: Template parameters `minValue` and `maxValue` constraints must be valid.
|
||||
Rule 'Azure.Template.ParameterMinMaxValue' -Ref 'AZR-000224' -Type '.json' -If { (HasTemplateParameters) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } {
|
||||
Rule 'Azure.Template.ParameterMinMaxValue' -Ref 'AZR-000224' -Type '.json' -If { (HasTemplateParameters) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://github.com/Azure/arm-ttk/blob/master/arm-ttk/testcases/deploymentTemplate/Min-And-Max-Value-Are-Numbers.test.ps1
|
||||
|
||||
# Get parameters with either minValue or maxValue
|
||||
|
@ -172,7 +172,7 @@ Rule 'Azure.Template.ParameterMinMaxValue' -Ref 'AZR-000224' -Type '.json' -If {
|
|||
}
|
||||
|
||||
# Synopsis: Use default deployment detail level for nested deployments.
|
||||
Rule 'Azure.Template.DebugDeployment' -Ref 'AZR-000225' -Type '.json' -If { (HasTemplateResources) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } {
|
||||
Rule 'Azure.Template.DebugDeployment' -Ref 'AZR-000225' -Type '.json' -If { (HasTemplateResources) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://github.com/Azure/arm-ttk/blob/master/arm-ttk/testcases/deploymentTemplate/Deployment-Resources-Must-Not-Be-Debug.test.ps1
|
||||
|
||||
# Get deployments
|
||||
|
@ -188,7 +188,7 @@ Rule 'Azure.Template.DebugDeployment' -Ref 'AZR-000225' -Type '.json' -If { (Has
|
|||
}
|
||||
|
||||
# Synopsis: Set the parameter default value to a value of the same type.
|
||||
Rule 'Azure.Template.ParameterDataTypes' -Ref 'AZR-000226' -Type '.json' -If { (HasTemplateParameters) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } {
|
||||
Rule 'Azure.Template.ParameterDataTypes' -Ref 'AZR-000226' -Type '.json' -If { (HasTemplateParameters) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContent($TargetObject)[0];
|
||||
$parameters = @($jsonObject.parameters.PSObject.Properties);
|
||||
if ($parameters.Length -eq 0) {
|
||||
|
@ -232,12 +232,12 @@ Rule 'Azure.Template.ParameterDataTypes' -Ref 'AZR-000226' -Type '.json' -If { (
|
|||
}
|
||||
|
||||
# Synopsis: Set the parameter value to a value that matches the specified strong type.
|
||||
Rule 'Azure.Template.ParameterStrongType' -Ref 'AZR-000227' -Type 'Microsoft.Resources/deployments' -Tag @{ release = 'GA'; ruleSet = '2021_12'; } {
|
||||
Rule 'Azure.Template.ParameterStrongType' -Ref 'AZR-000227' -Type 'Microsoft.Resources/deployments' -Tag @{ release = 'GA'; ruleSet = '2021_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$Assert.Create($PSRule.Issue.Get('PSRule.Rules.Azure.Template.ParameterStrongType'));
|
||||
}
|
||||
|
||||
# Synopsis: Template expressions should not exceed the maximum length.
|
||||
Rule 'Azure.Template.ExpressionLength' -Ref 'AZR-000228' -Type 'Microsoft.Resources/deployments' -Tag @{ release = 'GA'; ruleSet = '2021_12'; } {
|
||||
Rule 'Azure.Template.ExpressionLength' -Ref 'AZR-000228' -Type 'Microsoft.Resources/deployments' -Tag @{ release = 'GA'; ruleSet = '2021_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$Assert.Create($PSRule.Issue.Get('PSRule.Rules.Azure.Template.ExpressionLength'));
|
||||
}
|
||||
|
||||
|
@ -246,20 +246,20 @@ Rule 'Azure.Template.ExpressionLength' -Ref 'AZR-000228' -Type 'Microsoft.Resour
|
|||
#region Parameters
|
||||
|
||||
# Synopsis: Use ARM parameter file structure.
|
||||
Rule 'Azure.Template.ParameterFile' -Ref 'AZR-000229' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.Template.ParameterFile' -Ref 'AZR-000229' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject);
|
||||
$Assert.HasFields($jsonObject, @('$schema', 'contentVersion', 'parameters'));
|
||||
$jsonObject.PSObject.Properties | Within 'Name' '$schema', 'contentVersion', 'metadata', 'parameters';
|
||||
}
|
||||
|
||||
# Synopsis: Use a Azure template parameter schema with the https scheme.
|
||||
Rule 'Azure.Template.ParameterScheme' -Ref 'AZR-000230' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; } {
|
||||
Rule 'Azure.Template.ParameterScheme' -Ref 'AZR-000230' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject);
|
||||
$Assert.StartsWith($jsonObject, '$schema', 'https://');
|
||||
}
|
||||
|
||||
# Synopsis: Configure a metadata link for each parameter file.
|
||||
Rule 'Azure.Template.MetadataLink' -Ref 'AZR-000231' -Type '.json' -If { $Configuration.AZURE_PARAMETER_FILE_METADATA_LINK -eq $True -and (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09' } {
|
||||
Rule 'Azure.Template.MetadataLink' -Ref 'AZR-000231' -Type '.json' -If { $Configuration.AZURE_PARAMETER_FILE_METADATA_LINK -eq $True -and (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject);
|
||||
$field = $Assert.HasFieldValue($jsonObject, 'metadata.template');
|
||||
if (!$field.Result) {
|
||||
|
@ -271,7 +271,7 @@ Rule 'Azure.Template.MetadataLink' -Ref 'AZR-000231' -Type '.json' -If { $Config
|
|||
}
|
||||
|
||||
# Synopsis: Specify a value for each parameter in template parameter files.
|
||||
Rule 'Azure.Template.ParameterValue' -Ref 'AZR-000232' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; } {
|
||||
Rule 'Azure.Template.ParameterValue' -Ref 'AZR-000232' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject);
|
||||
$parameters = @($jsonObject.parameters.PSObject.Properties | Where-Object {
|
||||
$_.MemberType -eq 'NoteProperty'
|
||||
|
@ -290,7 +290,7 @@ Rule 'Azure.Template.ParameterValue' -Ref 'AZR-000232' -Type '.json' -If { (IsPa
|
|||
}
|
||||
|
||||
# Synopsis: Use a valid secret reference within parameter files.
|
||||
Rule 'Azure.Template.ValidSecretRef' -Ref 'AZR-000233' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; } {
|
||||
Rule 'Azure.Template.ValidSecretRef' -Ref 'AZR-000233' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject);
|
||||
$parameters = @($jsonObject.parameters.PSObject.Properties | Where-Object {
|
||||
$_.MemberType -eq 'NoteProperty' -and $Assert.HasField($_.Value, 'reference').Result
|
||||
|
@ -305,7 +305,7 @@ Rule 'Azure.Template.ValidSecretRef' -Ref 'AZR-000233' -Type '.json' -If { (IsPa
|
|||
}
|
||||
|
||||
# Synopsis: Use comments for each resource in ARM template to communicate purpose.
|
||||
Rule 'Azure.Template.UseComments' -Ref 'AZR-000234' -Level Information -Type '.json' -If { (IsTemplateFile) -and !(IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_12'; } {
|
||||
Rule 'Azure.Template.UseComments' -Ref 'AZR-000234' -Level Information -Type '.json' -If { (IsTemplateFile) -and !(IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$resources = @(GetTemplateResources | Where-Object { $Assert.NullOrEmpty($_, 'comments').Result });
|
||||
|
||||
$Assert.Count($resources, '.', 0).Reason(
|
||||
|
@ -316,7 +316,7 @@ Rule 'Azure.Template.UseComments' -Ref 'AZR-000234' -Level Information -Type '.j
|
|||
}
|
||||
|
||||
# Synopsis: Use descriptions for each resource in generated template(bicep, psarm, AzOps) to communicate purpose.
|
||||
Rule 'Azure.Template.UseDescriptions' -Ref 'AZR-000235' -Level Information -Type '.json' -If { (IsTemplateFile) -and (IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_12'; } {
|
||||
Rule 'Azure.Template.UseDescriptions' -Ref 'AZR-000235' -Level Information -Type '.json' -If { (IsTemplateFile) -and (IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$resources = @(GetTemplateResources | Where-Object { $Assert.NullOrEmpty($_, 'metadata.description').Result });
|
||||
|
||||
$Assert.Count($resources, '.', 0).Reason(
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
#
|
||||
|
||||
# Synopsis: Traffic Manager should use at lest two enabled endpoints
|
||||
Rule 'Azure.TrafficManager.Endpoints' -Ref 'AZR-000236' -Type 'Microsoft.Network/trafficManagerProfiles' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.TrafficManager.Endpoints' -Ref 'AZR-000236' -Type 'Microsoft.Network/trafficManagerProfiles' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Reliability'; } {
|
||||
$endpoints = @($TargetObject.Properties.endpoints | Where-Object { $_.Properties.endpointStatus -eq 'Enabled'});
|
||||
$Assert.Create($endpoints.Length -ge 2, ($LocalizedData.EnabledEndpoints -f $endpoints.Length))
|
||||
}
|
||||
|
||||
# Synopsis: Monitor Traffic Manager endpoints with HTTPS
|
||||
Rule 'Azure.TrafficManager.Protocol' -Ref 'AZR-000237' -Type 'Microsoft.Network/trafficManagerProfiles' -If { (IsHttpMonitor) } -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.TrafficManager.Protocol' -Ref 'AZR-000237' -Type 'Microsoft.Network/trafficManagerProfiles' -If { (IsHttpMonitor) } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$Assert.HasFieldValue($TargetObject, 'Properties.monitorConfig.protocol', 'HTTPS');
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Rule 'Azure.VM.UseManagedDisks' -Ref 'AZR-000238' -Type 'Microsoft.Compute/virtu
|
|||
}
|
||||
|
||||
# Synopsis: Check disk caching is configured correctly for the workload
|
||||
Rule 'Azure.VM.DiskCaching' -Ref 'AZR-000242' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.DiskCaching' -Ref 'AZR-000242' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Performance Efficiency'; } {
|
||||
# Check OS disk
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.storageProfile.osDisk.caching', 'ReadWrite');
|
||||
|
||||
|
@ -44,12 +44,12 @@ Rule 'Azure.VM.DiskCaching' -Ref 'AZR-000242' -Type 'Microsoft.Compute/virtualMa
|
|||
}
|
||||
|
||||
# Synopsis: Use Hybrid Use Benefit
|
||||
Rule 'Azure.VM.UseHybridUseBenefit' -Ref 'AZR-000243' -If { SupportsHybridUse } -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.UseHybridUseBenefit' -Ref 'AZR-000243' -If { SupportsHybridUse } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Cost Optimization'; } {
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.licenseType', 'Windows_Server');
|
||||
}
|
||||
|
||||
# Synopsis: Use accelerated networking for supported operating systems and VM types.
|
||||
Rule 'Azure.VM.AcceleratedNetworking' -Ref 'AZR-000244' -If { SupportsAcceleratedNetworking } -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.AcceleratedNetworking' -Ref 'AZR-000244' -If { SupportsAcceleratedNetworking } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Performance Efficiency'; } {
|
||||
$resources = @(GetSubResources -ResourceType 'Microsoft.Network/networkInterfaces');
|
||||
if ($resources.Length -eq 0) {
|
||||
return $Assert.Pass();
|
||||
|
@ -60,12 +60,12 @@ Rule 'Azure.VM.AcceleratedNetworking' -Ref 'AZR-000244' -If { SupportsAccelerate
|
|||
}
|
||||
|
||||
# Synopsis: Linux VMs should use public key pair
|
||||
Rule 'Azure.VM.PublicKey' -Ref 'AZR-000245' -If { VMHasLinuxOS } -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.PublicKey' -Ref 'AZR-000245' -If { VMHasLinuxOS } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$Assert.HasFieldValue($TargetObject, 'Properties.osProfile.linuxConfiguration.disablePasswordAuthentication', $True)
|
||||
}
|
||||
|
||||
# Synopsis: Ensure that the VM agent is provisioned automatically
|
||||
Rule 'Azure.VM.Agent' -Ref 'AZR-000246' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.Agent' -Ref 'AZR-000246' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$Assert.HasDefaultValue($TargetObject, 'Properties.osProfile.linuxConfiguration.provisionVMAgent', $True)
|
||||
$Assert.HasDefaultValue($TargetObject, 'Properties.osProfile.windowsConfiguration.provisionVMAgent', $True)
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ Rule 'Azure.VM.Updates' -Ref 'AZR-000247' -Type 'Microsoft.Compute/virtualMachin
|
|||
}
|
||||
|
||||
# Synopsis: Use VM naming requirements
|
||||
Rule 'Azure.VM.Name' -Ref 'AZR-000248' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.Name' -Ref 'AZR-000248' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftcompute
|
||||
|
||||
# Between 1 and 64 characters long
|
||||
|
@ -90,7 +90,7 @@ Rule 'Azure.VM.Name' -Ref 'AZR-000248' -Type 'Microsoft.Compute/virtualMachines'
|
|||
}
|
||||
|
||||
# Synopsis: Use VM naming requirements
|
||||
Rule 'Azure.VM.ComputerName' -Ref 'AZR-000249' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.ComputerName' -Ref 'AZR-000249' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftcompute
|
||||
|
||||
$maxLength = 64
|
||||
|
@ -126,7 +126,7 @@ Rule 'Azure.VM.DiskAttached' -Ref 'AZR-000250' -Type 'Microsoft.Compute/disks' -
|
|||
# TODO: Check IOPS
|
||||
|
||||
# Synopsis: Managed disk is smaller than SKU size
|
||||
Rule 'Azure.VM.DiskSizeAlignment' -Ref 'AZR-000251' -Type 'Microsoft.Compute/disks' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.DiskSizeAlignment' -Ref 'AZR-000251' -Type 'Microsoft.Compute/disks' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Cost Optimization'; } {
|
||||
$diskSize = @(32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)
|
||||
$actualSize = $TargetObject.Properties.diskSizeGB
|
||||
|
||||
|
@ -149,7 +149,7 @@ Rule 'Azure.VM.ADE' -Ref 'AZR-000252' -Type 'Microsoft.Compute/disks' -If { IsEx
|
|||
}
|
||||
|
||||
# Synopsis: Use Managed Disk naming requirements
|
||||
Rule 'Azure.VM.DiskName' -Ref 'AZR-000253' -Type 'Microsoft.Compute/disks' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.DiskName' -Ref 'AZR-000253' -Type 'Microsoft.Compute/disks' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftcompute
|
||||
|
||||
# Between 1 and 80 characters long
|
||||
|
@ -167,12 +167,12 @@ Rule 'Azure.VM.DiskName' -Ref 'AZR-000253' -Type 'Microsoft.Compute/disks' -Tag
|
|||
#region Availability set
|
||||
|
||||
# Synopsis: Availability sets should be deployed with at least two members
|
||||
Rule 'Azure.VM.ASMinMembers' -Ref 'AZR-000255' -Type 'Microsoft.Compute/availabilitySets' -If { IsExport } -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.ASMinMembers' -Ref 'AZR-000255' -Type 'Microsoft.Compute/availabilitySets' -If { IsExport } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Reliability'; } {
|
||||
$Assert.GreaterOrEqual($TargetObject, 'properties.virtualMachines', 2)
|
||||
}
|
||||
|
||||
# Synopsis: Use Availability Set naming requirements
|
||||
Rule 'Azure.VM.ASName' -Ref 'AZR-000256' -Type 'Microsoft.Compute/availabilitySets' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.ASName' -Ref 'AZR-000256' -Type 'Microsoft.Compute/availabilitySets' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftcompute
|
||||
|
||||
# Between 1 and 80 characters long
|
||||
|
@ -190,7 +190,7 @@ Rule 'Azure.VM.ASName' -Ref 'AZR-000256' -Type 'Microsoft.Compute/availabilitySe
|
|||
#region Proximity Placement Groups
|
||||
|
||||
# Synopsis: Use Proximity Placement Groups naming requirements
|
||||
Rule 'Azure.VM.PPGName' -Ref 'AZR-000260' -Type 'Microsoft.Compute/proximityPlacementGroups' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VM.PPGName' -Ref 'AZR-000260' -Type 'Microsoft.Compute/proximityPlacementGroups' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftcompute
|
||||
|
||||
# Between 1 and 80 characters long
|
||||
|
@ -205,7 +205,7 @@ Rule 'Azure.VM.PPGName' -Ref 'AZR-000260' -Type 'Microsoft.Compute/proximityPlac
|
|||
#endregion Proximity Placement Groups
|
||||
|
||||
# Synopsis: Protect Custom Script Extensions commands
|
||||
Rule 'Azure.VM.ScriptExtensions' -Ref 'AZR-000332' -Type 'Microsoft.Compute/virtualMachines', 'Microsoft.Compute/virtualMachines/extensions' -Tag @{ release = 'GA'; ruleSet = '2022_12' } {
|
||||
Rule 'Azure.VM.ScriptExtensions' -Ref 'AZR-000332' -Type 'Microsoft.Compute/virtualMachines', 'Microsoft.Compute/virtualMachines/extensions' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$vmConfig = @($TargetObject);
|
||||
|
||||
if ($PSRule.TargetType -eq 'Microsoft.Compute/virtualMachines') {
|
||||
|
@ -232,7 +232,7 @@ Rule 'Azure.VM.ScriptExtensions' -Ref 'AZR-000332' -Type 'Microsoft.Compute/virt
|
|||
#region Azure Monitor Agent
|
||||
|
||||
# Synopsis: Use Azure Monitor Agent as replacement for Log Analytics Agent.
|
||||
Rule 'Azure.VM.MigrateAMA' -Ref 'AZR-000317' -Type 'Microsoft.Compute/virtualMachines' -If { HasOMSOrAMAExtension } -Tag @{ release = 'GA'; ruleSet = '2022_12' } {
|
||||
Rule 'Azure.VM.MigrateAMA' -Ref 'AZR-000317' -Type 'Microsoft.Compute/virtualMachines' -If { HasOMSOrAMAExtension } -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$extensions = @(GetSubResources -ResourceType 'Microsoft.Compute/virtualMachines/extensions' |
|
||||
Where-Object { (($_.Properties.publisher -eq 'Microsoft.EnterpriseCloud.Monitoring') -and ($_.Properties.type -eq 'MicrosoftMonitoringAgent')) -or
|
||||
(($_.Properties.publisher -eq 'Microsoft.EnterpriseCloud.Monitoring') -and ($_.Properties.type -eq 'OmsAgentForLinux')) })
|
||||
|
@ -245,7 +245,7 @@ Rule 'Azure.VM.MigrateAMA' -Ref 'AZR-000317' -Type 'Microsoft.Compute/virtualMac
|
|||
#region IaaS SQL Server disks
|
||||
|
||||
# Synopsis: Use Premium SSD disks or greater for data and log files for production SQL Server workloads.
|
||||
Rule 'Azure.VM.SQLServerDisk' -Ref 'AZR-000324' -Type 'Microsoft.Compute/virtualMachines' -If { HasPublisherMicrosoftSQLServer } -Tag @{ release = 'GA'; ruleSet = '2022_12'; } {
|
||||
Rule 'Azure.VM.SQLServerDisk' -Ref 'AZR-000324' -Type 'Microsoft.Compute/virtualMachines' -If { HasPublisherMicrosoftSQLServer } -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Performance Efficiency'; } {
|
||||
$disks = @(GetOSAndDataDisks)
|
||||
$Assert.Less($disks, '.', 1).Reason($LocalizedData.SQLServerVMDisks).
|
||||
PathPrefix('properties.storageProfile')
|
||||
|
@ -256,7 +256,7 @@ Rule 'Azure.VM.SQLServerDisk' -Ref 'AZR-000324' -Type 'Microsoft.Compute/virtual
|
|||
#region Azure Monitor Agent
|
||||
|
||||
# Synopsis: Use Azure Monitor Agent for collecting monitoring data.
|
||||
Rule 'Azure.VM.AMA' -Ref 'AZR-000345' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2022_12'; } {
|
||||
Rule 'Azure.VM.AMA' -Ref 'AZR-000345' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$amaTypes = @('AzureMonitorWindowsAgent', 'AzureMonitorLinuxAgent')
|
||||
$extensions = @(GetSubResources -ResourceType 'Microsoft.Compute/virtualMachines/extensions' |
|
||||
Where-Object { $_.properties.publisher -eq 'Microsoft.Azure.Monitor' -or $_.properties.type -in $amaTypes })
|
||||
|
@ -270,7 +270,7 @@ Rule 'Azure.VM.AMA' -Ref 'AZR-000345' -Type 'Microsoft.Compute/virtualMachines'
|
|||
#region Maintenance Configuration
|
||||
|
||||
# Synopsis: Use a maintenance configuration for virtual machines.
|
||||
Rule 'Azure.VM.MaintenanceConfig' -Ref 'AZR-000375' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'Preview'; ruleSet = '2023_06'; } {
|
||||
Rule 'Azure.VM.MaintenanceConfig' -Ref 'AZR-000375' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'Preview'; ruleSet = '2023_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$maintenanceConfig = @(GetSubResources -ResourceType 'Microsoft.Maintenance/configurationAssignments' |
|
||||
Where-Object { $_.properties.maintenanceConfigurationId })
|
||||
$Assert.GreaterOrEqual($maintenanceConfig, '.', 1).Reason($LocalizedData.VMMaintenanceConfig, $PSRule.TargetName)
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#region Virtual machine scale set
|
||||
|
||||
# Synopsis: Use VM naming requirements
|
||||
Rule 'Azure.VMSS.Name' -Ref 'AZR-000261' -Type 'Microsoft.Compute/virtualMachineScaleSets' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VMSS.Name' -Ref 'AZR-000261' -Type 'Microsoft.Compute/virtualMachineScaleSets' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftcompute
|
||||
|
||||
# Between 1 and 64 characters long
|
||||
|
@ -22,7 +22,7 @@ Rule 'Azure.VMSS.Name' -Ref 'AZR-000261' -Type 'Microsoft.Compute/virtualMachine
|
|||
}
|
||||
|
||||
# Synopsis: Use VM naming requirements
|
||||
Rule 'Azure.VMSS.ComputerName' -Ref 'AZR-000262' -Type 'Microsoft.Compute/virtualMachineScaleSets' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VMSS.ComputerName' -Ref 'AZR-000262' -Type 'Microsoft.Compute/virtualMachineScaleSets' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftcompute
|
||||
|
||||
$maxLength = 64
|
||||
|
@ -51,7 +51,7 @@ Rule 'Azure.VMSS.PublicKey' -Ref 'AZR-000288' -Type 'Microsoft.Compute/virtualMa
|
|||
}
|
||||
|
||||
# Synopsis: Protect Custom Script Extensions commands
|
||||
Rule 'Azure.VMSS.ScriptExtensions' -Ref 'AZR-000333' -Type 'Microsoft.Compute/virtualMachineScaleSets', 'Microsoft.Computer/virtualMachineScaleSets/CustomScriptExtension', 'Microsoft.Compute/virtualMachineScaleSets/extensions' -Tag @{ release = 'GA'; ruleSet = '2022_12' } {
|
||||
Rule 'Azure.VMSS.ScriptExtensions' -Ref 'AZR-000333' -Type 'Microsoft.Compute/virtualMachineScaleSets', 'Microsoft.Computer/virtualMachineScaleSets/CustomScriptExtension', 'Microsoft.Compute/virtualMachineScaleSets/extensions' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
|
||||
$vmssConfig = @($TargetObject);
|
||||
|
||||
## Extension Prof
|
||||
|
@ -67,7 +67,7 @@ Rule 'Azure.VMSS.ScriptExtensions' -Ref 'AZR-000333' -Type 'Microsoft.Compute/vi
|
|||
}
|
||||
|
||||
# Synopsis: Use Azure Monitor Agent as replacement for Log Analytics Agent.
|
||||
Rule 'Azure.VMSS.MigrateAMA' -Ref 'AZR-000318' -Type 'Microsoft.Compute/virtualMachineScaleSets' -If { HasOMSOrAMAExtension } -Tag @{ release = 'GA'; ruleSet = '2022_12' } {
|
||||
Rule 'Azure.VMSS.MigrateAMA' -Ref 'AZR-000318' -Type 'Microsoft.Compute/virtualMachineScaleSets' -If { HasOMSOrAMAExtension } -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$property = $TargetObject.Properties.virtualMachineProfile.extensionProfile.extensions.properties |
|
||||
Where-Object { (($_.publisher -eq 'Microsoft.EnterpriseCloud.Monitoring') -and ($_.type -eq 'MicrosoftMonitoringAgent')) -or
|
||||
(($_.publisher -eq 'Microsoft.EnterpriseCloud.Monitoring') -and ($_.type -eq 'OmsAgentForLinux')) }
|
||||
|
@ -80,7 +80,7 @@ Rule 'Azure.VMSS.MigrateAMA' -Ref 'AZR-000318' -Type 'Microsoft.Compute/virtualM
|
|||
}
|
||||
|
||||
# Synopsis: Use Azure Monitor Agent for collecting monitoring data.
|
||||
Rule 'Azure.VMSS.AMA' -Ref 'AZR-000346' -Type 'Microsoft.Compute/virtualMachineScaleSets' -Tag @{ release = 'GA'; ruleSet = '2022_12'; } {
|
||||
Rule 'Azure.VMSS.AMA' -Ref 'AZR-000346' -Type 'Microsoft.Compute/virtualMachineScaleSets' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
$amaTypes = @('AzureMonitorWindowsAgent', 'AzureMonitorLinuxAgent')
|
||||
$property = $TargetObject.Properties.virtualMachineProfile.extensionProfile.extensions.properties |
|
||||
Where-Object { $_.publisher -eq 'Microsoft.Azure.Monitor' -or $_.type -in $amaTypes }
|
||||
|
|
|
@ -8,19 +8,19 @@
|
|||
#region Rules
|
||||
|
||||
# Synopsis: Migrate from legacy ExpressRoute gateway SKUs
|
||||
Rule 'Azure.VNG.ERLegacySKU' -Ref 'AZR-000271' -Type 'Microsoft.Network/virtualNetworkGateways' -With 'Azure.VNG.ERGateway' -Tag @{ release = 'GA'; ruleSet = '2020_06' } {
|
||||
Rule 'Azure.VNG.ERLegacySKU' -Ref 'AZR-000271' -Type 'Microsoft.Network/virtualNetworkGateways' -With 'Azure.VNG.ERGateway' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
|
||||
Within 'Properties.sku.name' -Not 'Basic';
|
||||
}
|
||||
|
||||
# Synopsis: Use availability zone SKU for virtual network gateways deployed with VPN gateway type
|
||||
Rule 'Azure.VNG.VPNAvailabilityZoneSKU' -Ref 'AZR-000272' -Type 'Microsoft.Network/virtualNetworkGateways' -With 'Azure.VNG.VPNGateway' -Tag @{ release = 'GA'; ruleSet = '2021_12'; } {
|
||||
Rule 'Azure.VNG.VPNAvailabilityZoneSKU' -Ref 'AZR-000272' -Type 'Microsoft.Network/virtualNetworkGateways' -With 'Azure.VNG.VPNGateway' -Tag @{ release = 'GA'; ruleSet = '2021_12'; 'Azure.WAF/pillar' = 'Reliability'; } {
|
||||
$vpnAvailabilityZoneSKUs = @('VpnGw1AZ', 'VpnGw2AZ', 'VpnGw3AZ', 'VpnGw4AZ', 'VpnGw5AZ');
|
||||
$Assert.In($TargetObject, 'Properties.sku.name', $vpnAvailabilityZoneSKUs).
|
||||
Reason($LocalizedData.VPNAvailabilityZoneSKU, $TargetObject.Name, ($vpnAvailabilityZoneSKUs -join ', '));
|
||||
}
|
||||
|
||||
# Synopsis: Use availability zone SKU for virtual network gateways deployed with ExpressRoute gateway type
|
||||
Rule 'Azure.VNG.ERAvailabilityZoneSKU' -Ref 'AZR-000273' -Type 'Microsoft.Network/virtualNetworkGateways' -With 'Azure.VNG.ERGateway' -Tag @{ release = 'GA'; ruleSet = '2021_12'; } {
|
||||
Rule 'Azure.VNG.ERAvailabilityZoneSKU' -Ref 'AZR-000273' -Type 'Microsoft.Network/virtualNetworkGateways' -With 'Azure.VNG.ERGateway' -Tag @{ release = 'GA'; ruleSet = '2021_12'; 'Azure.WAF/pillar' = 'Reliability'; } {
|
||||
$erAvailabilityZoneSKUs = @('ErGw1AZ', 'ErGw2AZ', 'ErGw3AZ');
|
||||
$Assert.In($TargetObject, 'Properties.sku.name', $erAvailabilityZoneSKUs).
|
||||
Reason($LocalizedData.ERAvailabilityZoneSKU, $TargetObject.Name, ($erAvailabilityZoneSKUs -join ', '));
|
||||
|
|
Загрузка…
Ссылка в новой задаче