Родитель
79e6726f2a
Коммит
c2fd4368b8
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"tool": "Credential Scanner",
|
||||
"suppressions": [
|
||||
{
|
||||
"placeholder": "$CREDENTIAL_PLACEHOLDER$",
|
||||
"_justification": "This is dummy credential used as a placeholder for unit testing."
|
||||
}
|
||||
]
|
||||
}
|
|
@ -19,7 +19,8 @@
|
|||
},
|
||||
"files.associations": {
|
||||
"**/.azure-pipelines/*.yaml": "azure-pipelines",
|
||||
"**/.azure-pipelines/jobs/*.yaml": "azure-pipelines"
|
||||
"**/.azure-pipelines/jobs/*.yaml": "azure-pipelines",
|
||||
"**/tests/**/Resources*.Template*.json": "arm-template"
|
||||
},
|
||||
"cSpell.words": [
|
||||
"Kubernetes",
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
## Unreleased
|
||||
|
||||
- Fixed unused VM resource false positives in templates. [#312](https://github.com/Microsoft/PSRule.Rules.Azure/issues/312)
|
||||
- Fixed handling SKU for accelerated networking. [#314](https://github.com/Microsoft/PSRule.Rules.Azure/issues/314)
|
||||
- Fixed detection of hybrid use benefit in templates. [#313](https://github.com/Microsoft/PSRule.Rules.Azure/issues/313)
|
||||
|
||||
## v0.10.0-B2003004 (pre-release)
|
||||
|
||||
- Fixed detection of diagnostic logging for Front Door. [#307](https://github.com/Microsoft/PSRule.Rules.Azure/issues/307)
|
||||
|
|
|
@ -97,23 +97,27 @@ function global:GetOrderedNSGRules {
|
|||
}
|
||||
|
||||
function global:SupportsAcceleratedNetworking {
|
||||
[CmdletBinding()]
|
||||
param ()
|
||||
process {
|
||||
if ($Rule.TargetType -ne 'Microsoft.Compute/virtualMachines' -or !(IsExport)) {
|
||||
return $False;
|
||||
}
|
||||
|
||||
if ($Null -eq ($TargetObject.Resources | Where-Object { $_.ResourceType -eq 'Microsoft.Network/networkInterfaces'})) {
|
||||
return $False;
|
||||
}
|
||||
|
||||
$vmSize = $TargetObject.Properties.hardwareProfile.vmSize;
|
||||
|
||||
if ($vmSize -notlike 'Standard_*_*') {
|
||||
return $False;
|
||||
if ($vmSize -match '^Standard_(F|B[1-2][0-9]ms)') {
|
||||
return $True;
|
||||
}
|
||||
else {
|
||||
return $False;
|
||||
}
|
||||
}
|
||||
|
||||
$vmSizeParts = $vmSize.Split('_');
|
||||
|
||||
if ($Null -eq $vmSizeParts) {
|
||||
return $False;
|
||||
}
|
||||
|
@ -123,17 +127,16 @@ function global:SupportsAcceleratedNetworking {
|
|||
|
||||
# Generation v2
|
||||
if ($generation -eq 'v2') {
|
||||
if ($size -notmatch 'Standard_(A|NC|DS1_|D1_)') {
|
||||
if ($size -notmatch '^(A|NC|DS1$|D1$|F[1-2]s)') {
|
||||
return $True;
|
||||
}
|
||||
}
|
||||
# Generation v3
|
||||
elseif ($generation -eq 'v3') {
|
||||
if ($size -notmatch 'Standard_(E2s?_|E[2-8]-2|D2s?|NC)') {
|
||||
if ($size -notmatch '^(E2s?|E[2-8]-2|D2s?|NC)') {
|
||||
return $True;
|
||||
}
|
||||
}
|
||||
|
||||
return $False;
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +151,6 @@ function global:IsAppGwPublic {
|
|||
}
|
||||
|
||||
$result = $False;
|
||||
|
||||
foreach ($ip in $TargetObject.Properties.frontendIPConfigurations) {
|
||||
if (Exists 'properties.publicIPAddress.id' -InputObject $ip) {
|
||||
$result = $True;
|
||||
|
@ -185,7 +187,8 @@ function global:IsWindowsOS {
|
|||
if ($Rule.TargetType -ne 'Microsoft.Compute/virtualMachines') {
|
||||
return $False;
|
||||
}
|
||||
return $TargetObject.Properties.storageProfile.osDisk.osType -eq 'Windows';
|
||||
return ($TargetObject.Properties.storageProfile.osDisk.osType -eq 'Windows') -or
|
||||
($TargetObject.Properties.storageProfile.imageReference.publisher -in 'MicrosoftSQLServer', 'MicrosoftWindowsServer');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ Rule 'Azure.VM.Standalone' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ rel
|
|||
}
|
||||
|
||||
# Synopsis: VMs should not use expired promo SKU
|
||||
Rule 'Azure.VM.PromoSku' -If { (IsVMPromoSku) } -Tag @{ release = 'GA' } {
|
||||
Rule 'Azure.VM.PromoSku' -If { IsVMPromoSku } -Tag @{ release = 'GA' } {
|
||||
Match 'Properties.hardwareProfile.vmSize' -Not -Expression 'Standard_DS{0,1}1{0,1}[1-9]{1}_v2_Promo'
|
||||
}
|
||||
|
||||
|
@ -47,17 +47,16 @@ Rule 'Azure.VM.BasicSku' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ relea
|
|||
# Synopsis: Check disk caching is configured correctly for the workload
|
||||
Rule 'Azure.VM.DiskCaching' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release = 'GA' } {
|
||||
# Check OS disk
|
||||
Within 'properties.storageProfile.osDisk.caching' 'ReadWrite'
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.storageProfile.osDisk.caching', 'ReadWrite');
|
||||
|
||||
# Check data disks
|
||||
$dataDisks = @($TargetObject.properties.storageProfile.dataDisks)
|
||||
|
||||
foreach ($disk in $dataDisks) {
|
||||
if ($disk.managedDisk.storageAccountType -eq 'Premium_LRS') {
|
||||
$disk.caching -eq 'ReadOnly'
|
||||
$Assert.HasFieldValue($disk, 'caching', 'ReadOnly');
|
||||
}
|
||||
else {
|
||||
$disk.caching -eq 'None'
|
||||
$Assert.HasFieldValue($disk, 'caching', 'None');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +67,7 @@ Rule 'Azure.VM.UniqueDns' -Type 'Microsoft.Network/networkInterfaces' -Tag @{ re
|
|||
}
|
||||
|
||||
# Synopsis: Managed disks should be attached to virtual machines
|
||||
Rule 'Azure.VM.DiskAttached' -Type 'Microsoft.Compute/disks' -If { ($TargetObject.ResourceName -notlike '*-ASRReplica') } -Tag @{ release = 'GA' } {
|
||||
Rule 'Azure.VM.DiskAttached' -Type 'Microsoft.Compute/disks' -If { ($TargetObject.ResourceName -notlike '*-ASRReplica') -and (IsExport) } -Tag @{ release = 'GA' } {
|
||||
# Disks should be attached unless they are used by ASR, which are not attached until fail over
|
||||
# Disks for VMs that are off are marked as Reserved
|
||||
Within 'properties.diskState' 'Attached', 'Reserved' -Reason $LocalizedData.ResourceNotAssociated
|
||||
|
@ -94,13 +93,14 @@ Rule 'Azure.VM.DiskSizeAlignment' -Type 'Microsoft.Compute/disks' -Tag @{ releas
|
|||
# TODO: Check number of disks
|
||||
|
||||
# Synopsis: Use Hybrid Use Benefit
|
||||
Rule 'Azure.VM.UseHybridUseBenefit' -If { (IsWindowsOS) } -Tag @{ release = 'GA' } {
|
||||
Within 'properties.licenseType' 'Windows_Server'
|
||||
Rule 'Azure.VM.UseHybridUseBenefit' -If { IsWindowsOS } -Tag @{ release = 'GA' } {
|
||||
$Assert.HasFieldValue($TargetObject, 'properties.licenseType', 'Windows_Server');
|
||||
}
|
||||
|
||||
# Synopsis: Enabled accelerated networking for supported operating systems
|
||||
Rule 'Azure.VM.AcceleratedNetworking' -If { (SupportsAcceleratedNetworking) } -Tag @{ release = 'GA' } {
|
||||
$networkInterfaces = GetSubResources -ResourceType 'Microsoft.Network/networkInterfaces'
|
||||
Rule 'Azure.VM.AcceleratedNetworking' -If { SupportsAcceleratedNetworking } -Tag @{ release = 'GA' } {
|
||||
$networkInterfaces = GetSubResources -ResourceType 'Microsoft.Network/networkInterfaces';
|
||||
$Null -ne $networkInterfaces;
|
||||
foreach ($interface in $networkInterfaces) {
|
||||
($interface.Properties.enableAcceleratedNetworking -eq $True)
|
||||
}
|
||||
|
@ -108,12 +108,12 @@ Rule 'Azure.VM.AcceleratedNetworking' -If { (SupportsAcceleratedNetworking) } -T
|
|||
|
||||
# Synopsis: Availability sets should be aligned
|
||||
Rule 'Azure.VM.ASAlignment' -Type 'Microsoft.Compute/availabilitySets' -Tag @{ release = 'GA' } {
|
||||
Within 'sku.name' 'aligned'
|
||||
$Assert.HasFieldValue($TargetObject, 'sku.name', 'aligned');
|
||||
}
|
||||
|
||||
# Synopsis: Availability sets should be deployed with at least two members
|
||||
Rule 'Azure.VM.ASMinMembers' -Type 'Microsoft.Compute/availabilitySets' -Tag @{ release = 'GA' } {
|
||||
($TargetObject.properties.virtualmachines.id | Measure-Object).Count -ge 2
|
||||
$Assert.GreaterOrEqual($TargetObject, 'properties.virtualmachines', 2)
|
||||
}
|
||||
|
||||
# Synopsis: Use Azure Disk Encryption
|
||||
|
@ -134,15 +134,15 @@ Rule 'Azure.VM.Agent' -Type 'Microsoft.Compute/virtualMachines' -Tag @{ release
|
|||
}
|
||||
|
||||
# Synopsis: Ensure automatic updates are enabled at deployment
|
||||
Rule 'Azure.VM.Updates' -Type 'Microsoft.Compute/virtualMachines' -If { (IsWindowsOS) } -Tag @{ release = 'GA' } {
|
||||
Rule 'Azure.VM.Updates' -Type 'Microsoft.Compute/virtualMachines' -If { IsWindowsOS } -Tag @{ release = 'GA' } {
|
||||
$Assert.HasDefaultValue($TargetObject, 'Properties.osProfile.windowsConfiguration.enableAutomaticUpdates', $True)
|
||||
}
|
||||
|
||||
#region Network Interface
|
||||
|
||||
# Synopsis: Network interfaces should be attached
|
||||
Rule 'Azure.VM.NICAttached' -Type 'Microsoft.Network/networkInterfaces' -Tag @{ release = 'GA' } {
|
||||
Exists 'Properties.virtualMachine.id'
|
||||
Rule 'Azure.VM.NICAttached' -Type 'Microsoft.Network/networkInterfaces' -If { IsExport } -Tag @{ release = 'GA' } {
|
||||
$Assert.HasFieldValue($TargetObject, 'Properties.virtualMachine.id');
|
||||
}
|
||||
|
||||
#endregion Network Interface
|
||||
|
|
|
@ -269,6 +269,71 @@ Describe 'Azure.VirtualMachine' {
|
|||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'vm-A';
|
||||
|
||||
# Check which SKUs are excluded
|
||||
$anDisabledSku = @(
|
||||
'Standard_F2s_v2'
|
||||
'Standard_B2ms'
|
||||
'Standard_B4ms'
|
||||
'Standard_B8ms'
|
||||
'Standard_D2_v3'
|
||||
'Standard_D1_v2'
|
||||
'Standard_NC6s_v3'
|
||||
'Standard_NC6'
|
||||
'Standard_A1_v2'
|
||||
'Standard_A8_v2'
|
||||
'Standard_DS13'
|
||||
'Standard_NV12'
|
||||
)
|
||||
$anEnabledSku = @(
|
||||
'Standard_D2_v2'
|
||||
'Standard_E4s_v3'
|
||||
'Standard_E32s_v3'
|
||||
'Standard_D8s_v3'
|
||||
'Standard_D4_v3'
|
||||
'Standard_D64s_v3'
|
||||
'Standard_D5_v2'
|
||||
'Standard_D16_v3'
|
||||
'Standard_DS11_v2'
|
||||
'Standard_B12ms'
|
||||
'Standard_B16ms'
|
||||
'Standard_B20ms'
|
||||
'Standard_F4s_v2'
|
||||
'Standard_F8s_v2'
|
||||
'Standard_F16s_v2'
|
||||
)
|
||||
$vmObject = [PSCustomObject]@{
|
||||
Name = "vm-A"
|
||||
ResourceId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Compute/virtualMachines/vm-A"
|
||||
ResourceName = "vm-A"
|
||||
ResourceType = "Microsoft.Compute/virtualMachines"
|
||||
Properties = [PSCustomObject]@{
|
||||
hardwareProfile = [PSCustomObject]@{
|
||||
vmSize = "na"
|
||||
}
|
||||
}
|
||||
SubscriptionId = '00000000-0000-0000-0000-000000000000'
|
||||
Resources = @(
|
||||
[PSCustomObject]@{
|
||||
ResourceType = 'Microsoft.Network/networkInterfaces'
|
||||
}
|
||||
)
|
||||
}
|
||||
foreach ($sku in $anDisabledSku) {
|
||||
$vmObject.Name = $sku;
|
||||
$vmObject.Properties.hardwareProfile.vmSize = $sku;
|
||||
$result = $vmObject | Invoke-PSRule -Name 'Azure.VM.AcceleratedNetworking' @invokeParams -Outcome All;
|
||||
$result | Should -Not -BeNullOrEmpty;
|
||||
$result.Outcome | Should -Be 'None';
|
||||
}
|
||||
|
||||
foreach ($sku in $anEnabledSku) {
|
||||
$vmObject.Name = $sku;
|
||||
$vmObject.Properties.hardwareProfile.vmSize = $sku;
|
||||
$result = $vmObject | Invoke-PSRule -Name 'Azure.VM.AcceleratedNetworking' @invokeParams -Outcome All;
|
||||
$result | Should -Not -BeNullOrEmpty;
|
||||
$result.Outcome | Should -Be 'Fail';
|
||||
}
|
||||
}
|
||||
|
||||
It 'Azure.VM.ASAlignment' {
|
||||
|
@ -383,4 +448,317 @@ Describe 'Azure.VirtualMachine' {
|
|||
$ruleResult.TargetName | Should -BeIn 'nic-A', 'nic-B', 'aks-agentpool-00000000-nic-1', 'aks-agentpool-00000000-nic-2', 'aks-agentpool-00000000-nic-3';
|
||||
}
|
||||
}
|
||||
|
||||
Context 'With template' {
|
||||
$templatePath = Join-Path -Path $here -ChildPath 'Resources.VirtualMachine.Template.json';
|
||||
$outputFile = Join-Path -Path $rootPath -ChildPath out/tests/Resources.VirtualMNachine.json;
|
||||
Export-AzTemplateRuleData -TemplateFile $templatePath -OutputPath $outputFile;
|
||||
$result = Invoke-PSRule -Module PSRule.Rules.Azure -InputPath $outputFile -Outcome All -WarningAction Ignore -ErrorAction Stop;
|
||||
|
||||
It 'Azure.VM.UseManagedDisks' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.VM.UseManagedDisks' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'vm-A';
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
}
|
||||
|
||||
It 'Azure.VM.Standalone' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.VM.Standalone' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'vm-A';
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
}
|
||||
|
||||
It 'Azure.VM.PromoSku' {
|
||||
$expiredSku = @(
|
||||
'Standard_DS2_v2_Promo'
|
||||
'Standard_DS3_v2_Promo'
|
||||
'Standard_DS4_v2_Promo'
|
||||
'Standard_DS5_v2_Promo'
|
||||
'Standard_DS11_v2_Promo'
|
||||
'Standard_DS12_v2_Promo'
|
||||
'Standard_DS13_v2_Promo'
|
||||
'Standard_DS14_v2_Promo'
|
||||
'Standard_D2_v2_Promo'
|
||||
'Standard_D3_v2_Promo'
|
||||
'Standard_D4_v2_Promo'
|
||||
'Standard_D5_v2_Promo'
|
||||
'Standard_D11_v2_Promo'
|
||||
'Standard_D12_v2_Promo'
|
||||
'Standard_D13_v2_Promo'
|
||||
'Standard_D14_v2_Promo'
|
||||
)
|
||||
$notExpiredSku = @(
|
||||
'Standard_H8_Promo'
|
||||
'Standard_H16_Promo'
|
||||
)
|
||||
$notPromo = @(
|
||||
'Standard_D4s_v3'
|
||||
)
|
||||
$vmObject = [PSCustomObject]@{
|
||||
Name = "vm-A"
|
||||
ResourceId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Compute/virtualMachines/vm-A"
|
||||
ResourceName = "vm-A"
|
||||
ResourceType = "Microsoft.Compute/virtualMachines"
|
||||
Properties = [PSCustomObject]@{
|
||||
hardwareProfile = [PSCustomObject]@{
|
||||
vmSize = "nn"
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($sku in $expiredSku) {
|
||||
$vmObject.Properties.hardwareProfile.vmSize = $sku;
|
||||
$result = $vmObject | Invoke-PSRule -Name 'Azure.VM.PromoSku' -Module PSRule.Rules.Azure -WarningAction Ignore;
|
||||
$result | Should -Not -BeNullOrEmpty;
|
||||
$result.IsSuccess() | Should -Be $False;
|
||||
}
|
||||
foreach ($sku in $notExpiredSku) {
|
||||
$vmObject.Properties.hardwareProfile.vmSize = $sku;
|
||||
$result = $vmObject | Invoke-PSRule -Name 'Azure.VM.PromoSku' -Module PSRule.Rules.Azure -WarningAction Ignore;
|
||||
$result | Should -Not -BeNullOrEmpty;
|
||||
$result.IsSuccess() | Should -Be $True;
|
||||
}
|
||||
foreach ($sku in $notPromo) {
|
||||
$vmObject.Properties.hardwareProfile.vmSize = $sku;
|
||||
$result = $vmObject | Invoke-PSRule -Name 'Azure.VM.PromoSku' -Module PSRule.Rules.Azure -WarningAction Ignore -Outcome All;
|
||||
$result | Should -Not -BeNullOrEmpty;
|
||||
$result.Outcome | Should -Be 'None';
|
||||
}
|
||||
}
|
||||
|
||||
It 'Azure.VM.BasicSku' {
|
||||
$basicSku = @(
|
||||
'Basic_A0'
|
||||
'Basic_A1'
|
||||
'Basic_A2'
|
||||
'Basic_A3'
|
||||
'Basic_A4'
|
||||
)
|
||||
$otherSku = @(
|
||||
'Standard_D4s_v3'
|
||||
)
|
||||
$vmObject = [PSCustomObject]@{
|
||||
Name = "vm-A"
|
||||
ResourceId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Compute/virtualMachines/vm-A"
|
||||
ResourceName = "vm-A"
|
||||
ResourceType = "Microsoft.Compute/virtualMachines"
|
||||
Properties = [PSCustomObject]@{
|
||||
hardwareProfile = [PSCustomObject]@{
|
||||
vmSize = "nn"
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($sku in $basicSku) {
|
||||
$vmObject.Properties.hardwareProfile.vmSize = $sku;
|
||||
$result = $vmObject | Invoke-PSRule -Name 'Azure.VM.BasicSku' -Module PSRule.Rules.Azure -WarningAction Ignore;
|
||||
$result | Should -Not -BeNullOrEmpty;
|
||||
$result.IsSuccess() | Should -Be $False;
|
||||
}
|
||||
foreach ($sku in $otherSku) {
|
||||
$vmObject.Properties.hardwareProfile.vmSize = $sku;
|
||||
$result = $vmObject | Invoke-PSRule -Name 'Azure.VM.BasicSku' -Module PSRule.Rules.Azure -WarningAction Ignore;
|
||||
$result | Should -Not -BeNullOrEmpty;
|
||||
$result.IsSuccess() | Should -Be $True;
|
||||
}
|
||||
}
|
||||
|
||||
It 'Azure.VM.DiskCaching' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.VM.DiskCaching' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'vm-A';
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
}
|
||||
|
||||
It 'Azure.VM.UniqueDns' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.VM.UniqueDns' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -BeIn 'vm-A-nic1';
|
||||
}
|
||||
|
||||
It 'Azure.VM.DiskAttached' {
|
||||
$filteredResult = $result | Where-Object {
|
||||
$_.RuleName -eq 'Azure.VM.DiskAttached' -and
|
||||
$_.TargetType -eq 'Microsoft.Compute/disks'
|
||||
};
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# None
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'None' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 2;
|
||||
$ruleResult.TargetName | Should -BeIn 'vm-A-disk1', 'vm-A-disk2';
|
||||
}
|
||||
|
||||
It 'Azure.VM.DiskSizeAlignment' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.VM.DiskSizeAlignment' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 2;
|
||||
$ruleResult.TargetName | Should -BeIn 'vm-A-disk1', 'vm-A-disk2';
|
||||
}
|
||||
|
||||
It 'Azure.VM.UseHybridUseBenefit' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.VM.UseHybridUseBenefit' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'vm-A';
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
}
|
||||
|
||||
It 'Azure.VM.AcceleratedNetworking' {
|
||||
$filteredResult = $result | Where-Object {
|
||||
$_.RuleName -eq 'Azure.VM.AcceleratedNetworking' -and
|
||||
$_.TargetType -eq 'Microsoft.Compute/virtualMachines'
|
||||
};
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# None
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'None' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'vm-A';
|
||||
}
|
||||
|
||||
It 'Azure.VM.ADE' {
|
||||
$filteredResult = $result | Where-Object {
|
||||
$_.RuleName -eq 'Azure.VM.ADE' -and
|
||||
$_.TargetType -eq 'Microsoft.Compute/disks'
|
||||
};
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 2;
|
||||
$ruleResult.TargetName | Should -BeIn 'vm-A-disk1', 'vm-A-disk2';
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
}
|
||||
|
||||
It 'Azure.VM.PublicKey' {
|
||||
$filteredResult = $result | Where-Object {
|
||||
$_.RuleName -eq 'Azure.VM.PublicKey' -and
|
||||
$_.TargetType -eq 'Microsoft.Compute/virtualMachines'
|
||||
};
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# None
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'None' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -BeIn 'vm-A';
|
||||
}
|
||||
|
||||
It 'Azure.VM.Agent' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.VM.Agent' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -BeIn 'vm-A';
|
||||
}
|
||||
|
||||
It 'Azure.VM.Updates' {
|
||||
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.VM.Updates' };
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -Be 'vm-A';
|
||||
}
|
||||
|
||||
It 'Azure.VM.NICAttached' {
|
||||
$filteredResult = $result | Where-Object {
|
||||
$_.RuleName -eq 'Azure.VM.NICAttached' -and
|
||||
$_.TargetType -eq 'Microsoft.Network/networkInterfaces'
|
||||
};
|
||||
|
||||
# Fail
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# Pass
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
|
||||
$ruleResult | Should -BeNullOrEmpty;
|
||||
|
||||
# None
|
||||
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'None' });
|
||||
$ruleResult | Should -Not -BeNullOrEmpty;
|
||||
$ruleResult.Length | Should -Be 1;
|
||||
$ruleResult.TargetName | Should -BeIn 'vm-A-nic1';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -713,7 +713,7 @@ Describe 'Azure.FrontDoor' -Tag 'Network', 'FrontDoor' {
|
|||
}
|
||||
}
|
||||
|
||||
Context 'With Template' {
|
||||
Context 'With template' {
|
||||
$templatePath = Join-Path -Path $here -ChildPath 'Resources.Template3.json';
|
||||
$outputFile = Join-Path -Path $rootPath -ChildPath out/tests/Resources.FrontDoor.json;
|
||||
Export-AzTemplateRuleData -TemplateFile $templatePath -OutputPath $outputFile;
|
||||
|
|
|
@ -0,0 +1,309 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"virtualMachineName": {
|
||||
"type": "string",
|
||||
"defaultValue": "vm-A",
|
||||
"metadata": {
|
||||
"description": "The name of the virtual machine."
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"defaultValue": "[resourceGroup().location]",
|
||||
"metadata": {
|
||||
"description": "The location to deploy the SQL server to."
|
||||
}
|
||||
},
|
||||
"subnetName": {
|
||||
"type": "string",
|
||||
"defaultValue": "subnet-A",
|
||||
"metadata": {
|
||||
"description": "The name of the subnet to deploy to."
|
||||
}
|
||||
},
|
||||
"vnetId": {
|
||||
"type": "string",
|
||||
"defaultValue": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.Network/virtualNetworks/vnet-A",
|
||||
"metadata": {
|
||||
"description": "The id of the virtual network to deploy to."
|
||||
}
|
||||
},
|
||||
"enableAcceleratedNetworking": {
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"metadata": {
|
||||
"description": "Determines if accelerated networking is configured."
|
||||
}
|
||||
},
|
||||
"osDiskType": {
|
||||
"type": "string",
|
||||
"defaultValue": "Premium_LRS",
|
||||
"metadata": {
|
||||
"description": "The type of storage to use for the OS disk."
|
||||
}
|
||||
},
|
||||
"dataDisks": {
|
||||
"type": "array",
|
||||
"defaultValue": [
|
||||
{
|
||||
"lun": 0,
|
||||
"createOption": "attach",
|
||||
"caching": "None",
|
||||
"writeAcceleratorEnabled": false,
|
||||
"id": null,
|
||||
"name": "vm-A-disk1",
|
||||
"storageAccountType": null,
|
||||
"diskSizeGB": null,
|
||||
"diskEncryptionSet": {
|
||||
"id": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"lun": 1,
|
||||
"createOption": "attach",
|
||||
"caching": "None",
|
||||
"writeAcceleratorEnabled": false,
|
||||
"id": null,
|
||||
"name": "vm-A-disk2",
|
||||
"storageAccountType": null,
|
||||
"diskSizeGB": null,
|
||||
"diskEncryptionSet": {
|
||||
"id": null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dataDiskResources": {
|
||||
"type": "array",
|
||||
"defaultValue": [
|
||||
{
|
||||
"name": "vm-A-disk1",
|
||||
"sku": "Standard_LRS",
|
||||
"properties": {
|
||||
"diskSizeGB": 128,
|
||||
"creationData": {
|
||||
"createOption": "empty"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vm-A-disk2",
|
||||
"sku": "Standard_LRS",
|
||||
"properties": {
|
||||
"diskSizeGB": 32,
|
||||
"creationData": {
|
||||
"createOption": "empty"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"virtualMachineSize": {
|
||||
"type": "string",
|
||||
"defaultValue": "Standard_E4s_v3"
|
||||
},
|
||||
"adminUsername": {
|
||||
"type": "string",
|
||||
"defaultValue": "vm-admin"
|
||||
},
|
||||
"adminPassword": {
|
||||
"type": "secureString",
|
||||
"defaultValue": "$CREDENTIAL_PLACEHOLDER$"
|
||||
},
|
||||
"sqlStorageWorkloadType": {
|
||||
"type": "string",
|
||||
"defaultValue": "OLTP"
|
||||
},
|
||||
"sqlStorageDisksConfigurationType": {
|
||||
"type": "string",
|
||||
"defaultValue": "NEW"
|
||||
},
|
||||
"dataPath": {
|
||||
"type": "string",
|
||||
"defaultValue": "F:\\data"
|
||||
},
|
||||
"dataDisksLUNs": {
|
||||
"type": "array",
|
||||
"defaultValue": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"logPath": {
|
||||
"type": "string",
|
||||
"defaultValue": "G:\\log"
|
||||
},
|
||||
"logDisksLUNs": {
|
||||
"type": "array",
|
||||
"defaultValue": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"tempDbPath": {
|
||||
"type": "string",
|
||||
"defaultValue": "D:\\tempDb"
|
||||
},
|
||||
"rServicesEnabled": {
|
||||
"type": "string",
|
||||
"defaultValue": "false"
|
||||
},
|
||||
"tags": {
|
||||
"type": "object",
|
||||
"defaultValue": {}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"subnetRef": "[concat(parameters('vnetId'), '/subnets/', parameters('subnetName'))]",
|
||||
"networkInterfaceName": "[concat(parameters('virtualMachineName'), '-nic1')]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"name": "[variables('networkInterfaceName')]",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"apiVersion": "2019-07-01",
|
||||
"location": "[parameters('location')]",
|
||||
"dependsOn": [],
|
||||
"properties": {
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
},
|
||||
"privateIPAllocationMethod": "Dynamic"
|
||||
}
|
||||
}
|
||||
],
|
||||
"enableAcceleratedNetworking": "[parameters('enableAcceleratedNetworking')]"
|
||||
},
|
||||
"tags": "[parameters('tags')]"
|
||||
},
|
||||
{
|
||||
"name": "[parameters('dataDiskResources')[copyIndex()].name]",
|
||||
"type": "Microsoft.Compute/disks",
|
||||
"apiVersion": "2019-07-01",
|
||||
"location": "[parameters('location')]",
|
||||
"properties": "[parameters('dataDiskResources')[copyIndex()].properties]",
|
||||
"sku": {
|
||||
"name": "[parameters('dataDiskResources')[copyIndex()].sku]"
|
||||
},
|
||||
"copy": {
|
||||
"name": "managedDiskResources",
|
||||
"count": "[length(parameters('dataDiskResources'))]"
|
||||
},
|
||||
"tags": "[parameters('tags')]"
|
||||
},
|
||||
{
|
||||
"name": "[parameters('virtualMachineName')]",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"apiVersion": "2019-07-01",
|
||||
"location": "[parameters('location')]",
|
||||
"dependsOn": [
|
||||
"managedDiskResources",
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('networkInterfaceName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[parameters('virtualMachineSize')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"osDisk": {
|
||||
"createOption": "fromImage",
|
||||
"managedDisk": {
|
||||
"storageAccountType": "[parameters('osDiskType')]"
|
||||
}
|
||||
},
|
||||
"imageReference": {
|
||||
"publisher": "microsoftsqlserver",
|
||||
"offer": "sql2019-ws2019",
|
||||
"sku": "standard",
|
||||
"version": "latest"
|
||||
},
|
||||
"copy": [
|
||||
{
|
||||
"name": "dataDisks",
|
||||
"count": "[length(parameters('dataDisks'))]",
|
||||
"input": {
|
||||
"lun": "[parameters('dataDisks')[copyIndex('dataDisks')].lun]",
|
||||
"createOption": "[parameters('dataDisks')[copyIndex('dataDisks')].createOption]",
|
||||
"caching": "[parameters('dataDisks')[copyIndex('dataDisks')].caching]",
|
||||
"writeAcceleratorEnabled": "[parameters('dataDisks')[copyIndex('dataDisks')].writeAcceleratorEnabled]",
|
||||
"diskSizeGB": "[parameters('dataDisks')[copyIndex('dataDisks')].diskSizeGB]",
|
||||
"managedDisk": {
|
||||
"id": "[coalesce(parameters('dataDisks')[copyIndex('dataDisks')].id, if(equals(parameters('dataDisks')[copyIndex('dataDisks')].name, json('null')), json('null'), resourceId('Microsoft.Compute/disks', parameters('dataDisks')[copyIndex('dataDisks')].name)))]",
|
||||
"storageAccountType": "[parameters('dataDisks')[copyIndex('dataDisks')].storageAccountType]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[parameters('virtualMachineName')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"adminPassword": "[parameters('adminPassword')]",
|
||||
"windowsConfiguration": {
|
||||
"enableAutomaticUpdates": true,
|
||||
"provisionVmAgent": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": "[parameters('tags')]"
|
||||
},
|
||||
{
|
||||
"name": "[parameters('virtualMachineName')]",
|
||||
"type": "Microsoft.SqlVirtualMachine/SqlVirtualMachines",
|
||||
"apiVersion": "2017-03-01-preview",
|
||||
"location": "[parameters('location')]",
|
||||
"properties": {
|
||||
"virtualMachineResourceId": "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]",
|
||||
"sqlManagement": "Full",
|
||||
"SqlServerLicenseType": "PAYG",
|
||||
"AutoPatchingSettings": {
|
||||
"Enable": false
|
||||
},
|
||||
"KeyVaultCredentialSettings": {
|
||||
"Enable": false
|
||||
},
|
||||
"StorageConfigurationSettings": {
|
||||
"DiskConfigurationType": "[parameters('sqlStorageDisksConfigurationType')]",
|
||||
"StorageWorkloadType": "[parameters('sqlStorageWorkloadType')]",
|
||||
"SQLDataSettings": {
|
||||
"LUNs": "[parameters('dataDisksLUNs')]",
|
||||
"DefaultFilePath": "[parameters('dataPath')]"
|
||||
},
|
||||
"SQLLogSettings": {
|
||||
"LUNs": "[parameters('logDisksLUNs')]",
|
||||
"DefaultFilePath": "[parameters('logPath')]"
|
||||
},
|
||||
"SQLTempDbSettings": {
|
||||
"DefaultFilePath": "[parameters('tempDbPath')]"
|
||||
}
|
||||
},
|
||||
"ServerConfigurationsManagementSettings": {
|
||||
"SQLConnectivityUpdateSettings": {
|
||||
"ConnectivityType": "Private",
|
||||
"Port": 1433,
|
||||
"SQLAuthUpdateUserName": "",
|
||||
"SQLAuthUpdatePassword": ""
|
||||
},
|
||||
"AdditionalFeaturesServerConfigurations": {
|
||||
"IsRServicesEnabled": "[parameters('rServicesEnabled')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]"
|
||||
],
|
||||
"tags": "[parameters('tags')]"
|
||||
}
|
||||
]
|
||||
}
|
Загрузка…
Ссылка в новой задаче