Repository: cloud-custodian/cloud-custodian

Issue:
azure - sqldatabase - add more filters
**Is your feature request related to a problem? Please describe.**
custodian unable to filter azure sqldatabases with properties like transparentDataEncryption, dataMaskingPolicies, vulnerabilityAssessments, auditingSettings etc.

**Describe the solution you'd like**
enhance azure.sqldatabase resource to filter with foresaid options.

**Describe alternatives you've considered**
Alternative solution to use Azure CLI to directly filter resources without using custodian



Discussion:
Similar to #6551 - these settings have been implemented by the SQL team as dedicated ARM resources rather than properties so we'll need to add support for these child resources.

For example:
https://docs.microsoft.com/en-us/azure/templates/microsoft.sql/2014-04-01/servers/databases/transparentdataencryption?tabs=json

Transparent Data included in #6640 

Vulnerability assessments implemented at `sql-server` scope in #6651 

Resolving patch:
diff --git a/tools/c7n_azure/c7n_azure/resources/sqldatabase.py b/tools/c7n_azure/c7n_azure/resources/sqldatabase.py
--- a/tools/c7n_azure/c7n_azure/resources/sqldatabase.py
+++ b/tools/c7n_azure/c7n_azure/resources/sqldatabase.py
@@ -148,6 +148,88 @@ def _process_resource_set(self, resources, event=None):
         return result
 
 
+@SqlDatabase.filter_registry.register('data-masking-policy')
+class DataMaskingPolicyFilter(Filter):
+    """
+    Filter by the current data masking policy
+    configuration for this database.
+
+    This filter will exclude the `master` database
+    because data masking can not be configured on it.
+
+    :example:
+
+    Find SQL databases with data masking disabled
+
+    .. code-block:: yaml
+
+        policies:
+          - name: sql-database-masking
+            resource: azure.sql-database
+            filters:
+              - type: data-masking-policy
+                enabled: false
+
+    """
+
+    schema = type_schema(
+        'data-masking-policy',
+        required=['type', 'enabled'],
+        **{
+            'enabled': {"type": "boolean"},
+        }
+    )
+
+    log = logging.getLogger('custodian.azure.sqldatabase.data-masking-policy-filter')
+
+    def __init__(self, data, manager=None):
+        super(DataMaskingPolicyFilter, self).__init__(data, manager)
+        self.enabled = self.data['enabled']
+
+    def process(self, resources, event=None):
+        resources, exceptions = ThreadHelper.execute_in_parallel(
+            resources=resources,
+            event=event,
+            execution_method=self._process_resource_set,
+            executor_factory=self.executor_factory,
+            log=log
+        )
+        if exceptions:
+            raise exceptions[0]
+        return resources
+
+    def _process_resource_set(self, resources, event=None):
+        client = self.manager.get_client()
+        result = []
+        for resource in resources:
+            database_name = resource['name']
+            if StringUtils.equal(database_name, "master"):
+                continue
+
+            if 'c7n:data-masking-policy' not in resource:
+                server_id = resource[ChildTypeInfo.parent_key]
+                server_name = ResourceIdParser.get_resource_name(server_id)
+
+                dmr = client.data_masking_policies.get(
+                    resource['resourceGroup'],
+                    server_name,
+                    database_name)
+
+                if dmr:
+                    resource['c7n:data-masking-policy'] = dmr.serialize(True).get('properties', {})
+                else:
+                    resource['c7n:data-masking-policy'] = {}
+
+            required_status = 'Enabled' if self.enabled else 'Disabled'
+
+            if StringUtils.equal(
+                    resource['c7n:data-masking-policy'].get('dataMaskingState'),
+                    required_status):
+                result.append(resource)
+
+        return result
+
+
 class BackupRetentionPolicyHelper:
 
     SHORT_TERM_SQL_OPERATIONS = 'backup_short_term_retention_policies'


Test patch:
diff --git a/tools/c7n_azure/tests_azure/cassettes/SqlDatabaseTest.test_data_masking_filter.json b/tools/c7n_azure/tests_azure/cassettes/SqlDatabaseTest.test_data_masking_filter.json
new file mode 100644
--- /dev/null
+++ b/tools/c7n_azure/tests_azure/cassettes/SqlDatabaseTest.test_data_masking_filter.json
@@ -0,0 +1,252 @@
+{
+    "version": 1,
+    "interactions": [
+        {
+            "request": {
+                "method": "GET",
+                "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/providers/Microsoft.Sql/servers?api-version=2019-06-01-preview",
+                "body": null,
+                "headers": {}
+            },
+            "response": {
+                "status": {
+                    "code": 200,
+                    "message": "OK"
+                },
+                "headers": {
+                    "date": [
+                        "Fri, 30 Apr 2021 16:48:58 GMT"
+                    ],
+                    "content-type": [
+                        "application/json; charset=utf-8"
+                    ],
+                    "cache-control": [
+                        "no-cache"
+                    ],
+                    "content-length": [
+                        "1200"
+                    ]
+                },
+                "body": {
+                    "data": {
+                        "value": [
+                            {
+                                "identity": {
+                                    "principalId": "5558ad35-b8e7-45a7-9c6e-a493baa9e5cb",
+                                    "type": "SystemAssigned",
+                                    "tenantId": "00000000-0000-0000-0000-000000000003"
+                                },
+                                "kind": "v12.0",
+                                "properties": {
+                                    "administratorLogin": "custodian",
+                                    "version": "12.0",
+                                    "state": "Ready",
+                                    "fullyQualifiedDomainName": "cctestsqlservertqtfgpqzllch4.database.windows.net",
+                                    "privateEndpointConnections": [
+                                        {
+                                            "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Sql/servers/cctestsqlservertqtfgpqzllch4/privateEndpointConnections/test123-33f26040-5de1-486a-9b76-a56f28a46a12",
+                                            "properties": {
+                                                "privateEndpoint": {
+                                                    "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Network/privateEndpoints/test123"
+                                                },
+                                                "privateLinkServiceConnectionState": {
+                                                    "status": "Approved",
+                                                    "description": "Auto-approved",
+                                                    "actionsRequired": "None"
+                                                },
+                                                "provisioningState": "Ready"
+                                            }
+                                        }
+                                    ],
+                                    "minimalTlsVersion": "1.2",
+                                    "publicNetworkAccess": "Disabled"
+                                },
+                                "location": "eastus2",
+                                "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Sql/servers/cctestsqlservertqtfgpqzllch4",
+                                "name": "cctestsqlservertqtfgpqzllch4",
+                                "type": "Microsoft.Sql/servers"
+                            }
+                        ]
+                    }
+                }
+            }
+        },
+        {
+            "request": {
+                "method": "GET",
+                "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Sql/servers/cctestsqlservertqtfgpqzllch4/databases?api-version=2017-10-01-preview",
+                "body": null,
+                "headers": {}
+            },
+            "response": {
+                "status": {
+                    "code": 200,
+                    "message": "OK"
+                },
+                "headers": {
+                    "date": [
+                        "Fri, 30 Apr 2021 16:48:59 GMT"
+                    ],
+                    "content-type": [
+                        "application/json; charset=utf-8"
+                    ],
+                    "cache-control": [
+                        "no-cache"
+                    ],
+                    "content-length": [
+                        "2734"
+                    ]
+                },
+                "body": {
+                    "data": {
+                        "value": [
+                            {
+                                "sku": {
+                                    "name": "Standard",
+                                    "tier": "Standard",
+                                    "capacity": 10
+                                },
+                                "kind": "v12.0,user",
+                                "properties": {
+                                    "collation": "SQL_Latin1_General_CP1_CI_AS",
+                                    "maxSizeBytes": 268435456000,
+                                    "status": "Online",
+                                    "databaseId": "7af22fe1-cb5a-49f9-bdf0-638e0e9cbc9f",
+                                    "creationDate": "2021-04-21T15:14:57.6Z",
+                                    "currentServiceObjectiveName": "S0",
+                                    "requestedServiceObjectiveName": "S0",
+                                    "defaultSecondaryLocation": "centralus",
+                                    "catalogCollation": "SQL_Latin1_General_CP1_CI_AS",
+                                    "zoneRedundant": false,
+                                    "earliestRestoreDate": "2021-04-21T15:25:17Z",
+                                    "readScale": "Disabled",
+                                    "readReplicaCount": 0,
+                                    "currentSku": {
+                                        "name": "Standard",
+                                        "tier": "Standard",
+                                        "capacity": 10
+                                    }
+                                },
+                                "location": "eastus2",
+                                "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Sql/servers/cctestsqlservertqtfgpqzllch4/databases/cclongtermretentiondb",
+                                "name": "cclongtermretentiondb",
+                                "type": "Microsoft.Sql/servers/databases"
+                            },
+                            {
+                                "sku": {
+                                    "name": "Standard",
+                                    "tier": "Standard",
+                                    "capacity": 10
+                                },
+                                "kind": "v12.0,user",
+                                "properties": {
+                                    "collation": "SQL_Latin1_General_CP1_CI_AS",
+                                    "maxSizeBytes": 2147483648,
+                                    "status": "Online",
+                                    "databaseId": "99338c6f-5608-4257-9861-0cdfa07417f0",
+                                    "creationDate": "2021-04-21T15:14:57.457Z",
+                                    "currentServiceObjectiveName": "S0",
+                                    "requestedServiceObjectiveName": "S0",
+                                    "defaultSecondaryLocation": "centralus",
+                                    "catalogCollation": "SQL_Latin1_General_CP1_CI_AS",
+                                    "zoneRedundant": false,
+                                    "earliestRestoreDate": "2021-04-21T15:25:07Z",
+                                    "readScale": "Disabled",
+                                    "readReplicaCount": 0,
+                                    "currentSku": {
+                                        "name": "Standard",
+                                        "tier": "Standard",
+                                        "capacity": 10
+                                    }
+                                },
+                                "location": "eastus2",
+                                "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Sql/servers/cctestsqlservertqtfgpqzllch4/databases/cctestdb",
+                                "name": "cctestdb",
+                                "type": "Microsoft.Sql/servers/databases"
+                            },
+                            {
+                                "sku": {
+                                    "name": "System",
+                                    "tier": "System",
+                                    "capacity": 0
+                                },
+                                "kind": "v12.0,system",
+                                "managedBy": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Sql/servers/cctestsqlservertqtfgpqzllch4",
+                                "properties": {
+                                    "collation": "SQL_Latin1_General_CP1_CI_AS",
+                                    "maxSizeBytes": 32212254720,
+                                    "status": "Online",
+                                    "databaseId": "f66fbb30-0835-4b16-b20c-537cfba87945",
+                                    "creationDate": "2021-04-21T15:13:00.593Z",
+                                    "currentServiceObjectiveName": "System0",
+                                    "requestedServiceObjectiveName": "System0",
+                                    "defaultSecondaryLocation": "centralus",
+                                    "catalogCollation": "SQL_Latin1_General_CP1_CI_AS",
+                                    "zoneRedundant": false,
+                                    "readScale": "Disabled",
+                                    "readReplicaCount": 0,
+                                    "currentSku": {
+                                        "name": "System",
+                                        "tier": "System",
+                                        "capacity": 0
+                                    }
+                                },
+                                "location": "eastus2",
+                                "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Sql/servers/cctestsqlservertqtfgpqzllch4/databases/master",
+                                "name": "master",
+                                "type": "Microsoft.Sql/servers/databases"
+                            }
+                        ]
+                    }
+                }
+            }
+        },
+        {
+            "request": {
+                "method": "GET",
+                "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Sql/servers/cctestsqlservertqtfgpqzllch4/databases/cctestdb/dataMaskingPolicies/Default?api-version=2014-04-01",
+                "body": null,
+                "headers": {}
+            },
+            "response": {
+                "status": {
+                    "code": 200,
+                    "message": "OK"
+                },
+                "headers": {
+                    "date": [
+                        "Fri, 30 Apr 2021 16:48:59 GMT"
+                    ],
+                    "content-type": [
+                        "application/json; odata=minimalmetadata; streaming=true; charset=utf-8"
+                    ],
+                    "dataserviceversion": [
+                        "3.0;"
+                    ],
+                    "cache-control": [
+                        "no-store, no-cache"
+                    ],
+                    "content-length": [
+                        "599"
+                    ]
+                },
+                "body": {
+                    "data": {
+                        "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Sql/servers/cctestsqlservertqtfgpqzllch4/databases/cctestdb/dataMaskingPolicies/Default",
+                        "name": "Default",
+                        "type": "Microsoft.Sql/servers/databases/dataMaskingPolicies",
+                        "location": "East US 2",
+                        "kind": null,
+                        "managedBy": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_sqlserver/providers/Microsoft.Sql/servers/cctestsqlservertqtfgpqzllch4/databases/cctestdb",
+                        "properties": {
+                            "dataMaskingState": "Disabled",
+                            "applicationPrincipals": "",
+                            "exemptPrincipals": "",
+                            "maskingLevel": ""
+                        }
+                    }
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_sqldatabase.py b/tools/c7n_azure/tests_azure/tests_resources/test_sqldatabase.py
--- a/tools/c7n_azure/tests_azure/tests_resources/test_sqldatabase.py
+++ b/tools/c7n_azure/tests_azure/tests_resources/test_sqldatabase.py
@@ -120,6 +120,24 @@ def test_data_encryption_filter(self):
         resources = p.run()
         self.assertEqual(1, len(resources))
 
+    def test_data_masking_filter(self):
+        p = self.load_policy({
+            'name': 'test-azure-sql-database',
+            'resource': 'azure.sql-database',
+            'filters': [
+                {
+                    'type': 'value',
+                    'key': 'name',
+                    'value': 'cctestdb'
+                },
+                {
+                    'type': 'data-masking-policy',
+                    'enabled': False
+                }],
+        })
+        resources = p.run()
+        self.assertEqual(1, len(resources))
+
 
 class ShortTermBackupRetentionPolicyFilterTest(BaseTest):