Skip to content

Commit

Permalink
WAF Alignments of rules - wave 1 #2493
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite committed Apr 27, 2024
1 parent 60b1d9b commit d7bd505
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .ps-rule/Rule.Rule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Rule 'Rule.Help' -Type 'PSRule.Rules.Rule' {
# Synopsis: Rules must flag if the Azure feature is GA or preview.
Rule 'Rule.Release' -Type 'PSRule.Rules.Rule' {
Recommend 'Add a release tag to the rule.'
$Assert.In($TargetObject, 'Tag.release', @('GA', 'preview'), $True)
$Assert.In($TargetObject, 'Tag.release', @('GA', 'preview', 'deprecated'), $True)
}

# Synopsis: Rules must be added to a rule set.
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ Each rule **must** meet the following requirements:
- Have a `release` tag either `GA` or `preview`. e.g. `-Tag @{ release = 'GA' }`
- Rules are marked as `GA` if they relate to generally available Azure features.
- Rules are marked as `preview` if they relate to _preview_ Azure features.
- Rules are marked as `deprecated` if they are no longer relevant and will be removed in the next major release.
- Have a `ruleSet` tag. e.g. `-Tag @{ release = 'GA'; ruleSet = '2020_09' }`
- The rule set tag identifies the quarter that the rule was first released.
- This is used to include rules in quarterly baselines.
Expand Down
14 changes: 14 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ link_users: true
See [upgrade notes][1] for helpful information when upgrading from previous versions.

[1]: upgrade-notes.md
[2]: deprecations.md

**Important notes**:

Expand All @@ -32,6 +33,19 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

## Unreleased

What's changed since pre-release v1.36.0-B0046:

- General improvements:
- **Important change**: Deprecated rules with no clear WAF alignment by @BernieWhite.
[#2493](https://github.com/Azure/PSRule.Rules.Azure/issues/2493)
- The following rules are deprecated:
- `Azure.Template.UseParameters`
- `Azure.Template.UseVariables`
- `Azure.Template.DefineParameters`
- `Azure.Template.ValidSecretRef`
- These rules have been deprecated and will be removed in v2.
- See [deprecations][2] for more information.

## v1.36.0-B0046 (pre-release)

What's changed since pre-release v1.36.0-B0020:
Expand Down
24 changes: 23 additions & 1 deletion docs/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ New name | Old name

### Realignment of rule names for network interfaces

Orginally when many of the rules targeting network interfaces were created, network interfaces only applied to virtual machines.
Originally when many of the rules targeting network interfaces were created, network interfaces only applied to virtual machines.
Today, network interfaces can be attached to different types of resources including:

- Virtual machines.
Expand All @@ -62,3 +62,25 @@ Possible locations where the old rule names may be used include:
- Within the `rule.exclude` or `rule.include` option defined within `ps-rule.yaml` or by using `New-PSRuleOption`.
- Within the `rule.exclude` or `rule.include` option defined within a custom baseline.
- Other custom scripts that run PSRule cmdlets directly.

### Realignment of rules

The Well-Architected Framework and PSRule are regularly updated.
As a result, some rules may not have a clear linkage with the latest guidance or practices.

To ensure that PSRule for Azure continues to provide clear guidance, examples, and references some rules will be removed.
The following rules are deprecated and will be removed in v2:

Reference ID | Name | Deprecated from | Reason
------------ | ---- | --------------- | ------
AZR-000217 | Azure.Template.UseParameters | v1.36.0 | Linting already handled by Bicep linter. No clear linkage to WAF.
AZR-000219 | Azure.Template.UseVariables | v1.36.0 | Linting already handled by Bicep linter. No clear linkage to WAF.
AZR-000218 | Azure.Template.DefineParameters | v1.36.0 | No applicable to Bicep. No clear linkage to WAF.
AZR-000233 | Azure.Template.ValidSecretRef | v1.36.0 | Linting already handled by Bicep linter. No clear linkage to WAF.

Deprecated rules will not be run by default, but can be enabled by:

- Explicitly configuring the rule name or ID in the `Rule.Include` option, when a baseline not used.
- Adding the rule name or ID to the `Rule.Include` option in a custom baseline.

From v2, the deprecated rules will be removed and will no longer be available in new releases.
4 changes: 4 additions & 0 deletions docs/en/rules/Azure.Template.DefineParameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ For example:
This rule is not applicable and ignored for templates generated with Bicep, PSArm and AzOps.
Generated templates from these tools may not require any parameters to be set.

This rule is deprecated from v1.36.0.
By default, PSRule will not evaluate this rule unless explicitly enabled.
See https://aka.ms/ps-rule-azure/deprecations.

## LINKS

- [Parameters](https://learn.microsoft.com/azure/azure-resource-manager/templates/template-syntax#parameters)
Expand Down
135 changes: 115 additions & 20 deletions docs/en/rules/Azure.Template.ResourceLocation.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
reviewed: 2024-04-27
severity: Awareness
pillar: Operational Excellence
category: Release engineering
category: OE:05 Infrastructure as code
resource: All resources
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.Template.ResourceLocation/
---
Expand All @@ -10,38 +11,132 @@ online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.Templa

## SYNOPSIS

Template resource location should be an expression or `global`.
Resource locations should be an expression or `global`.

## DESCRIPTION

The template parameter `location` is a standard parameter recommended for deployment templates.
The `location` parameter is a intended for specifying the deployment location of the primary resource.
The `location` property is a required property for most Azure resources.
For non-regional resources such as Front Door and DNS Zones specify a literal location `global` instead.

When defining a resource that requires a location, use the `location` parameter. For example:
The resource `location` determines where the resource configuration is stored and managed from.
Commonly this will also indicate which region your data is stored in.

When defining resources in Bicep or ARM templates, avoid hardcoding the location value, even when you know the location.
The location value should be a parameter what can be easily set or overridden when deploying the template.
This makes the template more flexible and reusable across different environments as requirements change.

Reusable templates and modules may include different resources that are deployed to different locations.
Define a `location` parameter value for resources that are likely to be in the same location.
This approach minimizes the number of times users are asked to provide location information.
For resources that aren't available in all locations, use a separate parameter.

Use Azure Policy to enforce the location of resources in your environment at runtime.

## RECOMMENDATION

Consider updating the resource `location` property to use a parameter to make templates and modules more flexible and reusable.

## EXAMPLES

### Configure with Azure template

To deploy resources that pass this rule:

- Set the `location` property to a parameter or `global`.

For example:

```json
{
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('VNETName')]",
"apiVersion": "2020-06-01",
"location": "[parameters('location')]",
"properties": {}
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-01-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_GRS"
},
"kind": "StorageV2",
"properties": {
"allowBlobPublicAccess": false,
"supportsHttpsTrafficOnly": true,
"minimumTlsVersion": "TLS1_2",
"accessTier": "Hot",
"allowSharedKeyAccess": false,
"networkAcls": {
"defaultAction": "Deny"
}
}
}
```

Additionally, the template may include other resources.
Use the `location` parameter value for resources that are likely to be in the same location.
This approach minimizes the number of times users are asked to provide location information.
For resources that aren't available in all locations, use a separate parameter.
To define a location parameter:

For non-regional resources such as Front Door and DNS Zones specify a literal location `global`.
- Under the `parameters` template property define a `string` sub-property.

## RECOMMENDATION
For example:

```json
{
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "The location resources will be deployed."
}
}
}
}
```

### Configure with Bicep

To deploy resources that pass this rule:

- Set the `location` property to a parameter or `global`.

For example:

```bicep
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: name
location: location
sku: {
name: 'Standard_GRS'
}
kind: 'StorageV2'
properties: {
allowBlobPublicAccess: false
supportsHttpsTrafficOnly: true
minimumTlsVersion: 'TLS1_2'
accessTier: 'Hot'
allowSharedKeyAccess: false
networkAcls: {
defaultAction: 'Deny'
}
}
}
```

To define a location parameter:

- Use the `param` keyword.

For example:

```bicep
@description('The location resources will be deployed.')
param location string = resourceGroup().location
```

## NOTES

Consider updating the resource `location` property to use `[parameters('location)]`.
By default, the Bicep linter rule `no-hardcoded-location` will raise a warning if a resource location is hardcoded.

## LINKS

- [ARM template best practices](https://learn.microsoft.com/azure/azure-resource-manager/templates/template-best-practices#location-recommendations-for-parameters)
- [Release deployment](https://learn.microsoft.com/azure/architecture/framework/devops/release-engineering-cd#automation)
- [Parameters](https://learn.microsoft.com/azure/azure-resource-manager/templates/template-syntax#parameters)
- [OE:05 Infrastructure as code](https://learn.microsoft.com/azure/well-architected/operational-excellence/infrastructure-as-code-design)
- [Bicep parameters](https://learn.microsoft.com/azure/azure-resource-manager/bicep/parameters)
- [Linter rule - no hardcoded locations](https://learn.microsoft.com/azure/azure-resource-manager/bicep/linter-rule-no-hardcoded-location)
- [ARM template best practices](https://learn.microsoft.com/azure/azure-resource-manager/templates/best-practices#location-recommendations-for-parameters)
- [ARM parameters](https://learn.microsoft.com/azure/azure-resource-manager/templates/syntax#parameters)
8 changes: 7 additions & 1 deletion docs/en/rules/Azure.Template.UseParameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ Parameters that are not used may make template use more complex for no benefit.

Consider removing unused parameters from Azure template files.

## NOTES

This rule is deprecated from v1.36.0.
By default, PSRule will not evaluate this rule unless explicitly enabled.
See https://aka.ms/ps-rule-azure/deprecations.

## LINKS

- [Release deployment](https://learn.microsoft.com/azure/well-architected/operational-excellence/)
- [Parameters](https://learn.microsoft.com/azure/azure-resource-manager/templates/template-syntax#parameters)
- [ARM template best practices](https://learn.microsoft.com/azure/azure-resource-manager/templates/template-best-practices#general-recommendations-for-parameters)
- [Release deployment](https://learn.microsoft.com/azure/architecture/framework/devops/release-engineering-cd#automation)
8 changes: 7 additions & 1 deletion docs/en/rules/Azure.Template.UseVariables.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ Variables that are not used may add template complexity for no benefit.

Consider removing unused variables from Azure template files.

## NOTES

This rule is deprecated from v1.36.0.
By default, PSRule will not evaluate this rule unless explicitly enabled.
See https://aka.ms/ps-rule-azure/deprecations.

## LINKS

- [Release deployment](https://learn.microsoft.com/azure/well-architected/operational-excellence/)
- [Variables](https://learn.microsoft.com/azure/azure-resource-manager/templates/template-syntax#variables)
- [ARM template best practices](https://learn.microsoft.com/azure/azure-resource-manager/templates/template-best-practices#variables)
- [Release deployment](https://learn.microsoft.com/azure/architecture/framework/devops/release-engineering-cd#automation)
6 changes: 6 additions & 0 deletions docs/en/rules/Azure.Template.ValidSecretRef.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ For example:
}
```

## NOTES

This rule is deprecated from v1.36.0.
By default, PSRule will not evaluate this rule unless explicitly enabled.
See https://aka.ms/ps-rule-azure/deprecations.

## LINKS

- [OE:05 Infrastructure as code](https://learn.microsoft.com/azure/well-architected/operational-excellence/infrastructure-as-code-design)
Expand Down
8 changes: 4 additions & 4 deletions src/PSRule.Rules.Azure/rules/Azure.Template.Rule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Rule 'Azure.Template.Resources' -Ref 'AZR-000216' -Type '.json' -If { (IsTemplat
}

# 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'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
Rule 'Azure.Template.UseParameters' -Ref 'AZR-000217' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'deprecated'; ruleSet = '2020_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
$jsonContent = Get-Content -Path $TargetObject.FullName -Raw;
$parameters = @(GetTemplateParameters);
if ($parameters.Length -eq 0) {
Expand All @@ -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'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
Rule 'Azure.Template.DefineParameters' -Ref 'AZR-000218' -Type '.json' -If { (IsTemplateFile) -and !(IsGenerated) } -Tag @{ release = 'deprecated'; 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'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
Rule 'Azure.Template.UseVariables' -Ref 'AZR-000219' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'deprecated'; 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 {
Expand Down Expand Up @@ -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'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
Rule 'Azure.Template.ValidSecretRef' -Ref 'AZR-000233' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'deprecated'; 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
Expand Down
Loading

0 comments on commit d7bd505

Please sign in to comment.