Skip to content

Commit

Permalink
feature: add synapse workspace & synapse spark pool cmd's (#204)
Browse files Browse the repository at this point in the history
* feat: develop synapse workspace, spark pools & sql pools rules
  • Loading branch information
vanwinkelseppe authored Apr 23, 2024
1 parent 6f1e35b commit 177378b
Show file tree
Hide file tree
Showing 10 changed files with 639 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ To learn more about the recommendations used by **Azure Quick Review (azqr)**, y
* Azure SignalR Service
* Azure SQL Database
* Azure Storage Account
* Azure Synapse Analytics Workspace
* Azure Synapse Spark Pool
* Azure Synapse Dedicated SQL Pool
* Azure Traffic Manager
* Azure Virtual Machine
* Azure Virtual Network
Expand Down
28 changes: 28 additions & 0 deletions cmd/azqr/synw.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

package azqr

import (
"github.com/Azure/azqr/internal/scanners"
"github.com/Azure/azqr/internal/scanners/synw"
"github.com/spf13/cobra"
)

func init() {
scanCmd.AddCommand(synwCmd)
}

var synwCmd = &cobra.Command{
Use: "synw",
Short: "Scan Azure Synapse Workspace",
Long: "Scan Azure Synapse Workspace",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
serviceScanners := []scanners.IAzureScanner{
&synw.SynapseWorkspaceScanner{},
}

scan(cmd, serviceScanners)
},
}
3 changes: 3 additions & 0 deletions docs/content/en/docs/Overview/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ To learn more about the recommendations used by **Azure Quick Review (azqr)**, y
* Azure SignalR Service
* Azure SQL Database
* Azure Storage Account
* Azure Synapse Analytics Workspace
* Azure Synapse Spark Pool
* Azure Synapse Dedicated SQL Pool
* Azure Traffic Manager
* Azure Virtual Machine
* Azure Virtual Network
Expand Down
13 changes: 13 additions & 0 deletions docs/content/en/docs/Recommendations/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,16 @@ Azure Quick Review checks the following recommendations for Azure resources. The
306 | High Availability | High | Web Pub Sub SKU | [Learn](https://azure.microsoft.com/en-us/pricing/details/web-pubsub/)
307 | Governance | Low | Web Pub Sub Name should comply with naming conventions | [Learn](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations)
308 | Governance | Low | Web Pub Sub should have tags | [Learn](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json)
309 | Monitoring and Alerting | Low | Azure Synapse Workspace should have diagnostic settings enabled | [Learn](https://learn.microsoft.com/en-us/azure/synapse-analytics/monitor-synapse-analytics)
310 | Security | High | Azure Synapse Workspace should have private endpoints enabled | [Learn](https://learn.microsoft.com/en-us/azure/synapse-analytics/security/synapse-workspace-managed-private-endpoints)
311 | High Availability | High | Azure Synapse Workspace SLA | [Learn](https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services)
312 | Governance | Low | Azure Synapse Workspace Name should comply with naming conventions | [Learn](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations)
313 | Governance | Low | Azure Synapse Workspace should have tags | [Learn](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json)
312 | Security | High | Azure Synapse Workspace should establish network segmentation boundaries | [Learn](https://learn.microsoft.com/en-us/security/benchmark/azure/baselines/azure-synapse-analytics-security-baseline?toc=%2Fazure%2Fsynapse-analytics%2Ftoc.json)
313 | Security | High | Azure Synapse Workspace should disable public network access | [Learn](https://learn.microsoft.com/en-us/security/benchmark/azure/baselines/azure-synapse-analytics-security-baseline?toc=%2Fazure%2Fsynapse-analytics%2Ftoc.json)
314 | High Availability | High | Azure Synapse Spark Pool SLA | [Learn](https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services)
315 | Governance | Low | Azure Synapse Spark Pool Name should comply with naming conventions | [Learn](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations)
316 | Governance | Low | Azure Synapse Spark Pool should have tags | [Learn](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json)
317 | High Availability | High | Azure Synapse Dedicated SQL Pool SLA | [Learn](https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services)
318 | Governance | Low | Azure Synapse Dedicated SQL Pool Name should comply with naming conventions | [Learn](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations)
319 | Governance | Low | Azure Synapse Dedicated SQL Pool should have tags | [Learn](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json)
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/sql/armsql v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/synapse/armsynapse v0.8.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/trafficmanager/armtrafficmanager v1.3.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/webpubsub/armwebpubsub v1.2.0
github.com/rs/zerolog v1.31.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0/go.mod h1:T5RfihdXtBDxt1Ch2wobif3TvzTdumDy29kahv6AV9A=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0 h1:UrGzkHueDwAWDdjQxC+QaXHd4tVCkISYE9j7fSSXF8k=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0/go.mod h1:qskvSQeW+cxEE2bcKYyKimB1/KiQ9xpJ99bcHY0BX6c=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/synapse/armsynapse v0.8.0 h1:IKCilT2DdxjeCXhiCIZb5hywpA1KDGKwpdA1WL20wT0=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/synapse/armsynapse v0.8.0/go.mod h1:IzuvA34YNVnlifc1+KhCouAKEf1VYzV439FOpyfTHzA=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/trafficmanager/armtrafficmanager v1.3.0 h1:e3kTG23M5ps+DjvPolK4dcgohDY8sHsXU7zrdHj1WzY=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/trafficmanager/armtrafficmanager v1.3.0/go.mod h1:Os5dq8Cvvz97rJauZhZJAfKHN+OEvF/0nVmHzF4aVys=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/webpubsub/armwebpubsub v1.2.0 h1:U+zDy6lU9scW8b58JpcQAlI+lsitiVSjz/RzBqbS5gM=
Expand Down
2 changes: 2 additions & 0 deletions internal/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import (
"github.com/Azure/azqr/internal/scanners/sigr"
"github.com/Azure/azqr/internal/scanners/sql"
"github.com/Azure/azqr/internal/scanners/st"
"github.com/Azure/azqr/internal/scanners/synw"
"github.com/Azure/azqr/internal/scanners/traf"
"github.com/Azure/azqr/internal/scanners/vm"
"github.com/Azure/azqr/internal/scanners/vnet"
Expand Down Expand Up @@ -471,6 +472,7 @@ func GetScanners() []scanners.IAzureScanner {
&sb.ServiceBusScanner{},
&sigr.SignalRScanner{},
&sql.SQLScanner{},
&synw.SynapseWorkspaceScanner{},
&traf.TrafficManagerScanner{},
&st.StorageScanner{},
&vm.VirtualMachineScanner{},
Expand Down
182 changes: 182 additions & 0 deletions internal/scanners/synw/rules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

package synw

import (
"strings"

"github.com/Azure/azqr/internal/scanners"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/synapse/armsynapse"
)

// GetRules - Returns the rules for the SynapseWorkspaceScanner
func (a *SynapseWorkspaceScanner) GetRules() map[string]scanners.AzureRule {
result := a.getWorkspaceRules()
for k, v := range a.getSparkPoolRules() {
result[k] = v
}
for k, v := range a.getSqlPoolRules() {
result[k] = v
}
return result
}
func (a *SynapseWorkspaceScanner) getWorkspaceRules() map[string]scanners.AzureRule {
return map[string]scanners.AzureRule{
"synw-001": {
Id: "synw-001",
Category: scanners.RulesCategoryMonitoringAndAlerting,
Recommendation: "Azure Synapse Workspace should have diagnostic settings enabled",
Impact: scanners.ImpactLow,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
service := target.(*armsynapse.Workspace)
_, ok := scanContext.DiagnosticsSettings[strings.ToLower(*service.ID)]
return !ok, ""
},
Url: "https://learn.microsoft.com/en-us/azure/data-factory/monitor-configure-diagnostics",
},
"synw-002": {
Id: "synw-002",
Category: scanners.RulesCategorySecurity,
Recommendation: "Azure Synapse Workspace should have private endpoints enabled",
Impact: scanners.ImpactHigh,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
i := target.(*armsynapse.Workspace)
pe := len(i.Properties.PrivateEndpointConnections) > 0
return !pe, ""
},
Url: "https://learn.microsoft.com/en-us/azure/synapse-analytics/security/synapse-workspace-managed-private-endpoints",
},
"synw-003": {
Id: "synw-003",
Category: scanners.RulesCategoryHighAvailability,
Recommendation: "Azure Synapse Workspace SLA",
Impact: scanners.ImpactHigh,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
return false, "99.9%"
},
Url: "https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services",
},
"synw-004": {
Id: "synw-004",
Category: scanners.RulesCategoryGovernance,
Recommendation: "Azure Synapse Workspace Name should comply with naming conventions",
Impact: scanners.ImpactLow,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
c := target.(*armsynapse.Workspace)
caf := strings.HasPrefix(*c.Name, "synw")
return !caf, ""
},
Url: "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations",
},
"synw-005": {
Id: "synw-005",
Category: scanners.RulesCategoryGovernance,
Recommendation: "Azure Synapse Workspace should have tags",
Impact: scanners.ImpactLow,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
c := target.(*armsynapse.Workspace)
return len(c.Tags) == 0, ""
},
Url: "https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json",
},
"synw-006": {
Id: "synw-006",
Category: scanners.RulesCategorySecurity,
Recommendation: "Azure Synapse Workspace should establish network segmentation boundaries",
Impact: scanners.ImpactHigh,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
c := target.(*armsynapse.Workspace)
return *c.Properties.ManagedVirtualNetwork != "default", ""
},
Url: "https://learn.microsoft.com/en-us/security/benchmark/azure/baselines/azure-synapse-analytics-security-baseline?toc=%2Fazure%2Fsynapse-analytics%2Ftoc.json",
},
"synw-007": {
Id: "synw-007",
Category: scanners.RulesCategorySecurity,
Recommendation: "Azure Synapse Workspace should disable public network access",
Impact: scanners.ImpactHigh,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
c := target.(*armsynapse.Workspace)
return string(*c.Properties.PublicNetworkAccess) == "Enabled", ""
},
Url: "https://learn.microsoft.com/en-us/security/benchmark/azure/baselines/azure-synapse-analytics-security-baseline?toc=%2Fazure%2Fsynapse-analytics%2Ftoc.json",
},
}
}

func (a *SynapseWorkspaceScanner) getSparkPoolRules() map[string]scanners.AzureRule {
return map[string]scanners.AzureRule{
"synsp-001": {
Id: "synsp-001",
Category: scanners.RulesCategoryGovernance,
Recommendation: "Azure Synapse Spark Pool Name should comply with naming conventions",
Impact: scanners.ImpactLow,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
c := target.(*armsynapse.BigDataPoolResourceInfo)
caf := strings.HasPrefix(*c.Name, "synsp")
return !caf, ""
},
Url: "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations",
},
"synsp-002": {
Id: "synsp-002",
Category: scanners.RulesCategoryHighAvailability,
Recommendation: "Azure Synapse Spark Pool SLA",
Impact: scanners.ImpactHigh,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
return false, "99.9%"
},
Url: "https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services",
},
"synsp-003": {
Id: "synsp-003",
Category: scanners.RulesCategoryGovernance,
Recommendation: "Azure Synapse Spark Pool should have tags",
Impact: scanners.ImpactLow,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
c := target.(*armsynapse.BigDataPoolResourceInfo)
return len(c.Tags) == 0, ""
},
Url: "https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json",
},
}
}

func (a *SynapseWorkspaceScanner) getSqlPoolRules() map[string]scanners.AzureRule {
return map[string]scanners.AzureRule{
"syndp-001": {
Id: "syndp-001",
Category: scanners.RulesCategoryGovernance,
Recommendation: "Azure Synapse Dedicated SQL Pool Name should comply with naming conventions",
Impact: scanners.ImpactLow,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
c := target.(*armsynapse.SQLPool)
caf := strings.HasPrefix(*c.Name, "syndp")
return !caf, ""
},
Url: "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations",
},
"syndp-002": {
Id: "syndp-002",
Category: scanners.RulesCategoryHighAvailability,
Recommendation: "Azure Synapse Dedicated SQL Pool SLA",
Impact: scanners.ImpactHigh,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
return false, "99.9%"
},
Url: "https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services",
},
"syndp-003": {
Id: "syndp-003",
Category: scanners.RulesCategoryGovernance,
Recommendation: "Azure Synapse Dedicated SQL Pool should have tags",
Impact: scanners.ImpactLow,
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) {
c := target.(*armsynapse.SQLPool)
return len(c.Tags) == 0, ""
},
Url: "https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json",
},
}
}
Loading

0 comments on commit 177378b

Please sign in to comment.