Родитель
1021649dde
Коммит
2a190d4a77
|
@ -2,6 +2,12 @@
|
|||
|
||||
## Unreleased
|
||||
|
||||
- **Breaking change**: Updated and renamed baselines make them easier to use. [#27](https://github.com/BernieWhite/PSRule.Rules.Kubernetes/issues/27)
|
||||
- `KubeBaseline` is now `Kubernetes`, the default baseline.
|
||||
- `AKSBaseline` is now `AKS`.
|
||||
- The `Kubernetes` baseline include common Kubernetes rules.
|
||||
- The `AKS` baseline include all of `Kubernetes` plus additional AKS specific rules.
|
||||
|
||||
## v0.1.0-B1912003 (pre-release)
|
||||
|
||||
- Fixed `Kubernetes.AKS.PublicLB` handling of internal LB annotation. [#17](https://github.com/BernieWhite/PSRule.Rules.Kubernetes/issues/17)
|
||||
|
|
20
README.md
20
README.md
|
@ -63,7 +63,6 @@ Kubernetes.Pod.Resources Fail Resource requirements are set for
|
|||
Kubernetes.Pod.Secrets Pass Use Kubernetes secrets to store information such as passwords or connec…
|
||||
Kubernetes.Pod.Health Fail Containers should use liveness and readiness probes.
|
||||
Kubernetes.Pod.Replicas Fail Consider increasing replicas to two or more to provide high availabilit…
|
||||
Kubernetes.AKS.PublicLB Pass Consider creating services with an internal load balancer instead of a …
|
||||
Kubernetes.Metadata Fail Consider applying recommended labels defined by Kubernetes.…
|
||||
|
||||
TargetName: azure-vote-front
|
||||
|
@ -78,7 +77,6 @@ Kubernetes.Pod.Resources Fail Resource requirements are set for
|
|||
Kubernetes.Pod.Secrets Pass Use Kubernetes secrets to store information such as passwords or connec…
|
||||
Kubernetes.Pod.Health Fail Containers should use liveness and readiness probes.
|
||||
Kubernetes.Pod.Replicas Fail Consider increasing replicas to two or more to provide high availabilit…
|
||||
Kubernetes.AKS.PublicLB Fail Consider creating services with an internal load balancer instead of a …
|
||||
Kubernetes.Metadata Fail Consider applying recommended labels defined by Kubernetes.…
|
||||
```
|
||||
|
||||
|
@ -99,6 +97,23 @@ In the example above:
|
|||
- `-Format Yaml` - indicates that the input is YAML.
|
||||
- `-ObjectPath items` - indicates that the input nests objects to evaluate under the `items` property.
|
||||
|
||||
### Using baselines
|
||||
|
||||
PSRule for Kubernetes comes with the following baselines:
|
||||
|
||||
- `Kubernetes` - Includes common Kubernetes rules. This is the default.
|
||||
- `AKS` - Includes all the rules from `Kubernetes` plus additional Azure Kubernetes Service (AKS) specific rules.
|
||||
|
||||
To use the `AKS` baseline instead of the default use `Invoke-PSRule -Baseline AKS`.
|
||||
|
||||
For example:
|
||||
|
||||
```powershell
|
||||
Invoke-PSRule -f $sourceUrl -Module 'PSRule.Rules.Kubernetes' -Baseline AKS;
|
||||
```
|
||||
|
||||
If `-Baseline AKS` is not specified, the default baseline `Kubernetes` will be used.
|
||||
|
||||
### Additional options
|
||||
|
||||
To filter results to only failed rules, use `Invoke-PSRule -Outcome Fail`.
|
||||
|
@ -125,7 +140,6 @@ The output of this example is:
|
|||
```text
|
||||
RuleName Pass Fail Outcome
|
||||
-------- ---- ---- -------
|
||||
Kubernetes.AKS.PublicLB 1 1 Fail
|
||||
Kubernetes.API.Removal 0 2 Fail
|
||||
Kubernetes.Metadata 0 4 Fail
|
||||
Kubernetes.Pod.PrivilegeEscalation 0 2 Fail
|
||||
|
|
|
@ -100,7 +100,7 @@ task VersionModule ModuleDependencies, {
|
|||
$manifest = Test-ModuleManifest -Path $manifestPath;
|
||||
$requiredModules = $manifest.RequiredModules | ForEach-Object -Process {
|
||||
if ($_.Name -eq 'PSRule' -and $Configuration -eq 'Release') {
|
||||
@{ ModuleName = 'PSRule'; ModuleVersion = '0.11.0' }
|
||||
@{ ModuleName = 'PSRule'; ModuleVersion = '0.12.0' }
|
||||
}
|
||||
else {
|
||||
@{ ModuleName = $_.Name; ModuleVersion = $_.Version }
|
||||
|
@ -108,7 +108,7 @@ task VersionModule ModuleDependencies, {
|
|||
};
|
||||
Update-ModuleManifest -Path $manifestPath -RequiredModules $requiredModules;
|
||||
$manifestContent = Get-Content -Path $manifestPath -Raw;
|
||||
$manifestContent = $manifestContent -replace 'PSRule = ''System.Collections.Hashtable''', 'PSRule = @{ Baseline = ''KubeBaseline'' }';
|
||||
$manifestContent = $manifestContent -replace 'PSRule = ''System.Collections.Hashtable''', 'PSRule = @{ Baseline = ''Kubernetes'' }';
|
||||
$manifestContent | Set-Content -Path $manifestPath;
|
||||
}
|
||||
|
||||
|
@ -150,8 +150,8 @@ task PSScriptAnalyzer NuGet, {
|
|||
|
||||
# Synopsis: Install PSRule
|
||||
task PSRule NuGet, {
|
||||
if ($Null -eq (Get-InstalledModule -Name PSRule -MinimumVersion 0.11.0 -ErrorAction Ignore)) {
|
||||
Install-Module -Name PSRule -MinimumVersion 0.11.0 -Scope CurrentUser -Force;
|
||||
if ($Null -eq (Get-InstalledModule -Name PSRule -MinimumVersion 0.12.0 -ErrorAction Ignore)) {
|
||||
Install-Module -Name PSRule -MinimumVersion 0.12.0 -Scope CurrentUser -Force;
|
||||
}
|
||||
Import-Module -Name PSRule -Verbose:$False;
|
||||
}
|
||||
|
@ -238,9 +238,9 @@ task BuildHelp BuildModule, PlatyPS, {
|
|||
}
|
||||
|
||||
# Copy generated help into module out path
|
||||
# $Null = Copy-Item -Path out/docs/PSRule.Rules.Kubernetes/ -Destination out/modules/PSRule.Rules.Kubernetes/en-US/ -Recurse;
|
||||
# $Null = Copy-Item -Path out/docs/PSRule.Rules.Kubernetes/ -Destination out/modules/PSRule.Rules.Kubernetes/en-AU/ -Recurse;
|
||||
# $Null = Copy-Item -Path out/docs/PSRule.Rules.Kubernetes/ -Destination out/modules/PSRule.Rules.Kubernetes/en-GB/ -Recurse;
|
||||
# $Null = Copy-Item -Path out/docs/PSRule.Rules.Kubernetes/* -Destination out/modules/PSRule.Rules.Kubernetes/en-US/ -Recurse;
|
||||
# $Null = Copy-Item -Path out/docs/PSRule.Rules.Kubernetes/* -Destination out/modules/PSRule.Rules.Kubernetes/en-AU/ -Recurse;
|
||||
# $Null = Copy-Item -Path out/docs/PSRule.Rules.Kubernetes/* -Destination out/modules/PSRule.Rules.Kubernetes/en-GB/ -Recurse;
|
||||
$Null = Copy-Item -Path docs/rules/en-US/*.md -Destination out/modules/PSRule.Rules.Kubernetes/en-US/;
|
||||
$Null = Copy-Item -Path docs/rules/en-US/*.md -Destination out/modules/PSRule.Rules.Kubernetes/en-AU/;
|
||||
$Null = Copy-Item -Path docs/rules/en-US/*.md -Destination out/modules/PSRule.Rules.Kubernetes/en-GB/;
|
||||
|
|
|
@ -75,7 +75,7 @@ FunctionsToExport = @()
|
|||
CmdletsToExport = @()
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = '*'
|
||||
VariablesToExport = @()
|
||||
|
||||
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
|
||||
AliasesToExport = @()
|
||||
|
@ -108,7 +108,7 @@ PrivateData = @{
|
|||
ReleaseNotes = 'https://github.com/BernieWhite/PSRule.Rules.Kubernetes/blob/master/CHANGELOG.md'
|
||||
} # End of PSData hashtable
|
||||
PSRule = @{
|
||||
Baseline = 'KubeBaseline'
|
||||
Baseline = 'Kubernetes'
|
||||
}
|
||||
} # End of PrivateData hashtable
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# Synopsis: A baseline for Kubernetes.
|
||||
kind: Baseline
|
||||
metadata:
|
||||
name: KubeBaseline
|
||||
name: Kubernetes
|
||||
spec:
|
||||
binding:
|
||||
targetName:
|
||||
|
@ -12,12 +12,15 @@ spec:
|
|||
- kind
|
||||
field:
|
||||
namespace: [ 'metadata.namespace' ]
|
||||
rule:
|
||||
tag:
|
||||
group: core
|
||||
|
||||
---
|
||||
# Synopsis: A baseline for Azure Kubernetes Service (AKS).
|
||||
kind: Baseline
|
||||
metadata:
|
||||
name: AKSBaseline
|
||||
name: AKS
|
||||
spec:
|
||||
binding:
|
||||
targetName:
|
||||
|
@ -26,3 +29,6 @@ spec:
|
|||
- kind
|
||||
field:
|
||||
namespace: [ 'metadata.namespace' ]
|
||||
rule:
|
||||
tag:
|
||||
group: [ 'core', 'AKS' ]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
# Synopsis: Services should not include a public load balancer
|
||||
Rule 'Kubernetes.AKS.PublicLB' -Type Service -Tag @{ category = 'Pod security' } -If { $PSRule.TargetName -ne 'addon-http-application-routing-nginx-ingress' } {
|
||||
Rule 'Kubernetes.AKS.PublicLB' -Type Service -If { $PSRule.TargetName -ne 'addon-http-application-routing-nginx-ingress' } -Tag @{ group = 'AKS' } {
|
||||
if ($Assert.HasFieldValue($TargetObject, 'spec.type', 'LoadBalancer').Result) {
|
||||
Within 'metadata.annotations.''service.beta.kubernetes.io/azure-load-balancer-internal''' 'true'
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
# Synopsis: Avoid using legacy API endpoints
|
||||
Rule 'Kubernetes.API.Removal' -Type DaemonSet, Deployment, StatefulSet, ReplicaSet, NetworkPolicy, PodSecurityPolicy -Tag @{ category = 'API' } {
|
||||
Rule 'Kubernetes.API.Removal' -Type DaemonSet, Deployment, StatefulSet, ReplicaSet, NetworkPolicy, PodSecurityPolicy -Tag @{ group = 'core' } {
|
||||
if ($PSRule.TargetType -in 'DaemonSet', 'Deployment', 'StatefulSet', 'ReplicaSet') {
|
||||
$TargetObject.apiVersion -eq 'apps/v1'
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
# Synopsis: Use recommended labels
|
||||
Rule 'Kubernetes.Metadata' -Type 'Deployment', 'Service', 'ReplicaSet', 'Pod' -Tag @{ category = 'Resource management'; } {
|
||||
Rule 'Kubernetes.Metadata' -Type 'Deployment', 'Service', 'ReplicaSet', 'Pod' -Tag @{ group = 'core' } {
|
||||
Exists 'metadata.labels.''app.kubernetes.io/name''' -Reason ($LocalizedData.RecommendLabel -f 'app.kubernetes.io/name')
|
||||
Exists 'metadata.labels.''app.kubernetes.io/instance''' -Reason ($LocalizedData.RecommendLabel -f 'app.kubernetes.io/instance')
|
||||
Exists 'metadata.labels.''app.kubernetes.io/version''' -Reason ($LocalizedData.RecommendLabel -f 'app.kubernetes.io/version')
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
# Synopsis: Containers should deny privilege escalation
|
||||
Rule 'Kubernetes.Pod.PrivilegeEscalation' -Type Deployment, Pod, ReplicaSet -If { (HasContainerSpec) } -Tag @{ category = 'Pod security'; } {
|
||||
Rule 'Kubernetes.Pod.PrivilegeEscalation' -Type Deployment, Pod, ReplicaSet -If { (HasContainerSpec) } -Tag @{ group = 'core' } {
|
||||
foreach ($container in (GetContainerSpec)) {
|
||||
$container | Exists 'securityContext.allowPrivilegeEscalation'
|
||||
$container.securityContext.allowPrivilegeEscalation -eq $False
|
||||
|
@ -11,7 +11,7 @@ Rule 'Kubernetes.Pod.PrivilegeEscalation' -Type Deployment, Pod, ReplicaSet -If
|
|||
}
|
||||
|
||||
# Synopsis: Containers should use specific tags instead of latest
|
||||
Rule 'Kubernetes.Pod.Latest' -Type Deployment, Pod, ReplicaSet -If { (HasContainerSpec) } -Tag @{ category = 'Pod security'; } {
|
||||
Rule 'Kubernetes.Pod.Latest' -Type Deployment, Pod, ReplicaSet -If { (HasContainerSpec) } -Tag @{ group = 'core' } {
|
||||
foreach ($container in (GetContainerSpec)) {
|
||||
$container.image -like '*:*' -and
|
||||
$container.image -notlike '*:latest'
|
||||
|
@ -19,7 +19,7 @@ Rule 'Kubernetes.Pod.Latest' -Type Deployment, Pod, ReplicaSet -If { (HasContain
|
|||
}
|
||||
|
||||
# Synopsis: Resource requirements are set for each container
|
||||
Rule 'Kubernetes.Pod.Resources' -Type Deployment, Pod, ReplicaSet -If { (HasContainerSpec) } -Tag @{ category = 'Resource management'; } {
|
||||
Rule 'Kubernetes.Pod.Resources' -Type Deployment, Pod, ReplicaSet -If { (HasContainerSpec) } -Tag @{ group = 'core' } {
|
||||
foreach ($container in (GetContainerSpec)) {
|
||||
$container | Exists 'resources.requests.cpu' -Reason $LocalizedData.PodCPURequest
|
||||
$container | Exists 'resources.requests.memory' -Reason $LocalizedData.PodMemRequest
|
||||
|
@ -29,7 +29,7 @@ Rule 'Kubernetes.Pod.Resources' -Type Deployment, Pod, ReplicaSet -If { (HasCont
|
|||
}
|
||||
|
||||
# Synopsis: Sensitive environment variables should be secured
|
||||
Rule 'Kubernetes.Pod.Secrets' -Type Deployment, Pod, ReplicaSet -If { (HasContainerSpec) } -Tag @{ category = 'Pod security'; } {
|
||||
Rule 'Kubernetes.Pod.Secrets' -Type Deployment, Pod, ReplicaSet -If { (HasContainerSpec) } -Tag @{ group = 'core' } {
|
||||
foreach ($container in (GetContainerSpec)) {
|
||||
if ($Assert.HasField($container, 'env').Result) {
|
||||
foreach ($variable in $container.env) {
|
||||
|
@ -48,7 +48,7 @@ Rule 'Kubernetes.Pod.Secrets' -Type Deployment, Pod, ReplicaSet -If { (HasContai
|
|||
}
|
||||
|
||||
# Synopsis: Containers should use liveness and readiness probes
|
||||
Rule 'Kubernetes.Pod.Health' -Type Deployment, Pod, ReplicaSet -If { (HasContainerSpec) } -Tag @{ category = 'Reliability'; } {
|
||||
Rule 'Kubernetes.Pod.Health' -Type Deployment, Pod, ReplicaSet -If { (HasContainerSpec) } -Tag @{ group = 'core' } {
|
||||
foreach ($container in (GetContainerSpec)) {
|
||||
$container | Exists 'livenessProbe' -Reason ($LocalizedData.LivenessProbe -f $container.name)
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ Rule 'Kubernetes.Pod.Health' -Type Deployment, Pod, ReplicaSet -If { (HasContain
|
|||
}
|
||||
|
||||
# Synopsis: Use two or more replicas
|
||||
Rule 'Kubernetes.Pod.Replicas' -Type Deployment, ReplicaSet, StatefulSet -Tag @{ category = 'Reliability'; } {
|
||||
Rule 'Kubernetes.Pod.Replicas' -Type Deployment, ReplicaSet, StatefulSet -Tag @{ group = 'core' } {
|
||||
Exists 'spec.replicas'
|
||||
$TargetObject.spec.replicas -ge 2
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ $here = (Resolve-Path $PSScriptRoot).Path;
|
|||
Describe 'Kubernetes.AKS' {
|
||||
$testParams = @{
|
||||
Module = 'PSRule.Rules.Kubernetes'
|
||||
# Option = Join-Path -Path $here -ChildPath ps-rule.yaml
|
||||
InputPath = Join-Path -Path $here -ChildPath Resources.AKS.yaml
|
||||
Baseline = 'AKS'
|
||||
}
|
||||
|
||||
$result = Invoke-PSRule @testParams -WarningAction Ignore;
|
||||
|
|
|
@ -36,7 +36,7 @@ Describe 'Rule quality' {
|
|||
It $rule.RuleName {
|
||||
$rule.Synopsis | Should -Not -BeNullOrEmpty;
|
||||
$rule.Description | Should -Not -BeNullOrEmpty;
|
||||
$rule.Tag.category | Should -Not -BeNullOrEmpty;
|
||||
$rule.Info.Annotations.category | Should -Not -BeNullOrEmpty;
|
||||
$rule.Info.Annotations.severity | Should -Not -BeNullOrEmpty;
|
||||
$rule.Info.GetOnlineHelpUri() | Should -Not -BeNullOrEmpty;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче