Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -3,95 +3,80 @@ package Cx
import data.generic.common as common_lib
import data.generic.azureresourcemanager as arm_lib

types := ["Microsoft.Sql/servers/databases/auditingSettings", "auditingSettings", "Microsoft.Sql/servers/auditingSettings"]
dbTypes := ["Microsoft.Sql/servers/databases", "databases", "Microsoft.Sql/servers"]
types := ["Microsoft.Sql/servers/databases/auditingSettings", "auditingSettings", "Microsoft.Sql/servers/auditingSettings"]

CxPolicy[result] {
doc := input.document[i]

[path, value] = walk(doc)

value.type == dbTypes[_]
childrenArr := get_children(doc, value, path)

child := childrenArr[k].value[_]
child := childrenArr[k].value[i2]
child.type == types[_]

child_path := childrenArr[k].path

[val, _] := arm_lib.getDefaultValueFromParametersIfPresent(doc, child.properties.state)
lower(val) == "enabled"
not common_lib.valid_key(child.properties, "retentionDays")

results := invalid_retention_days(doc, child, child_path, i2)
results != ""

result := {
"documentId": input.document[i].id,
"resourceType": child.type,
"resourceName": child.name,
"searchKey": results.searchKey,
"issueType": results.issueType,
"keyExpectedValue": results.keyExpectedValue,
"keyActualValue": results.keyActualValue,
"searchLine": results.searchLine
}
}

invalid_retention_days(doc, child, child_path, i2) = results {
not common_lib.valid_key(child.properties, "retentionDays")
results := {
"searchKey": sprintf("%s.name={{%s}}.properties", [common_lib.concat_path(child_path), child.name]),
"issueType": "MissingAttribute",
"keyExpectedValue": "'auditingSettings.properties.retentionDays' should be defined and above 90 days",
"keyActualValue": "'auditingSettings.properties.retentionDays' is missing",
"searchLine": common_lib.build_search_line(child_path, ["properties"]),
"searchLine": get_searchLine(child_path, i2, ["properties"])
}
}

CxPolicy[result] {
doc := input.document[i]

[path, value] = walk(doc)

value.type == dbTypes[_]
childrenArr := get_children(doc, value, path)

child := childrenArr[k].value[_]
child.type == types[_]

child_path := childrenArr[k].path

[val, _] := arm_lib.getDefaultValueFromParametersIfPresent(doc, child.properties.state)
lower(val) == "enabled"
} else = results {
[val_rd, val_rd_type] := arm_lib.getDefaultValueFromParametersIfPresent(doc, child.properties.retentionDays)

val_rd < 90

result := {
"documentId": input.document[i].id,
"resourceType": child.type,
"resourceName": child.name,
results := {
"searchKey": sprintf("%s.name={{%s}}.properties.retentionDays", [common_lib.concat_path(child_path), child.name]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("'auditingSettings.properties.retentionDays' %s should be defined and above 90 days", [val_rd_type]),
"keyActualValue": sprintf("'auditingSettings.properties.retentionDays' %s is %d", [val_rd_type, child.properties.retentionDays]),
"searchLine": common_lib.build_search_line(child_path, ["properties", "retentionDays"]),
"searchLine": get_searchLine(child_path, i2, ["properties", "retentionDays"])
}
} else = ""

get_searchLine(path,index,path_to_field) = sk {
is_number(path[count(path) - 1])
sk := common_lib.build_search_line(path, path_to_field)
} else = sk {
sk := common_lib.build_search_line(path, array.concat([index],path_to_field))
}

get_children(doc, parent, path) = childArr {
common_lib.valid_key(parent, "resources")
childArr := [{"value": parent.resources, "path": array.concat(path, ["resources"])}]
} else = childArr {
not common_lib.valid_key(parent, "resources")
not common_lib.valid_key(parent, "dependsOn")
values := [x |
[path_child, value_child] := walk(doc)
value_child.name != parent.name
not common_lib.valid_key(value_child, "dependsOn")
startswith(value_child.name, parent.name)
x := {"value": [value_child], "path": path_child}
]
count(values) > 0
unique := {y | y := values[_]}
childArr := [y | y := unique[_]]
} else = childArr {
not common_lib.valid_key(parent, "resources")
values := [x |
[path_child, value_child] := walk(doc)
value_child.name != parent.name
common_lib.valid_key(value_child, "dependsOn")
d := value_child.dependsOn[_]
search_values := {"type": parent.type, "name": parent.name}
contains(d, search_values.type)
contains(d, search_values.name)
contains(d, parent.type)
contains(d, parent.name)
x := {"value": [value_child], "path": path_child}
]
count(values) > 0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
name: 'sqlServer1'
location: resourceGroup().location
tags: {
displayName: 'sqlServer1'
}
properties: {
administratorLogin: 'adminUsername'
administratorLoginPassword: 'adminPassword'
}
}

resource auditingSetting 'Microsoft.Sql/servers/auditingSettings@2022-05-01-preview' = {
name: 'default'
parent: sqlServer1
properties: {
state: 'Disabled'
isAzureMonitorTargetEnabled: true
retentionDays: 10
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.37.4.10188",
"templateHash": "8941966037535999376"
}
},
"resources": [
{
"type": "Microsoft.Sql/servers",
"apiVersion": "2021-02-01-preview",
"name": "sqlServer1",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "sqlServer1"
},
"properties": {
"administratorLogin": "adminUsername",
"administratorLoginPassword": "adminPassword"
}
},
{
"type": "Microsoft.Sql/servers/auditingSettings",
"apiVersion": "2022-05-01-preview",
"name": "[format('{0}/{1}', 'sqlServer1', 'default')]",
"properties": {
"state": "Disabled",
"isAzureMonitorTargetEnabled": true,
"retentionDays": 10
},
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', 'sqlServer1')]"
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
name: 'sqlServer1'
location: resourceGroup().location
tags: {
displayName: 'sqlServer1'
}
properties: {
administratorLogin: 'adminUsername'
administratorLoginPassword: 'adminPassword'
}
}

resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
parent: sqlServer1
name: 'sqlDatabase1'
location: resourceGroup().location
tags: {
displayName: 'sqlDatabase1'
}
properties: {
collation: 'SQL_Latin1_General_CP1_CI_AS'
edition: 'Basic'
maxSizeBytes: '1073741824'
requestedServiceObjectiveName: 'Basic'
}
}

resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
parent: sqlServer1_sqlDatabase1
name: 'default'
properties: {
auditActionsAndGroups: [
'DATABASE_LOGOUT_GROUP'
]
isAzureMonitorTargetEnabled: true
isStorageSecondaryKeyInUse: true
queueDelayMs: 1000
state: 'Enabled'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"functions": [],
"variables": {},
"resources": [
{
"name": "sqlServer1",
"type": "Microsoft.Sql/servers",
"apiVersion": "2021-02-01-preview",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "sqlServer1"
},
"properties": {
"administratorLogin": "adminUsername",
"administratorLoginPassword": "adminPassword"
},
"resources": [
{
"name": "sqlServer1/sqlDatabase1",
"type": "Microsoft.Sql/servers/databases",
"apiVersion": "2021-02-01-preview",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "sqlDatabase1"
},
"properties": {
"collation": "SQL_Latin1_General_CP1_CI_AS",
"edition": "Basic",
"maxSizeBytes": "1073741824",
"requestedServiceObjectiveName": "Basic"
},
"resources": [
{
"type": "Microsoft.Sql/servers/databases/auditingSettings",
"apiVersion": "2021-02-01-preview",
"name": "sqlServer1/sqlDatabase1/default",
"properties": {
"auditActionsAndGroups": [ "DATABASE_LOGOUT_GROUP" ],
"isAzureMonitorTargetEnabled": true,
"isStorageSecondaryKeyInUse": true,
"queueDelayMs": 1000,
"state": "Enabled"
}
}
]
}
]
}
],
"outputs": {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
"line": 29,
"filename": "positive6.json"
},
{
"queryName": "SQL Server Database With Unrecommended Retention Days",
"severity": "LOW",
"line": 40,
"filename": "positive7.json"
},
{
"queryName": "SQL Server Database With Unrecommended Retention Days",
"severity": "LOW",
Expand Down Expand Up @@ -70,5 +76,11 @@
"severity": "LOW",
"line": 16,
"filename": "positive6.bicep"
},
{
"queryName": "SQL Server Database With Unrecommended Retention Days",
"severity": "LOW",
"line": 31,
"filename": "positive7.bicep"
}
]
Loading