def process(self, resources, event=None): s = self.manager.get_session() # Translate definitions display names into ids policyClient = s.client("azure.mgmt.resource.policy.PolicyClient") definitions = [d for d in policyClient.policy_definitions.list()] definition_ids = [ d.id.lower() for d in definitions if self.definitions is None or d.display_name in self.definitions or d.name in self.definitions ] # Find non-compliant resources client = PolicyInsightsClient(s.get_credentials()) query = client.policy_states.list_query_results_for_subscription( policy_states_resource='latest', subscription_id=s.subscription_id).value non_compliant = [ f.resource_id.lower() for f in query if f.policy_definition_id.lower() in definition_ids ] if self.compliant: return [ r for r in resources if r['id'].lower() not in non_compliant ] else: return [r for r in resources if r['id'].lower() in non_compliant]
def list_query_results_for_policy_definition(self, subscription_id, policy_definition_name, query_options=None, raw=None, credentials=None): policy_insights_client = PolicyInsightsClient(credentials) summarize_for_policy_definition = policy_insights_client.policy_states.summarize_for_policy_definition( subscription_id=subscription_id, policy_definition_name=policy_definition_name, query_options=query_options, raw=raw) return summarize_for_policy_definition
def get_non_compliant_resources_by_id(subscription_id, policies_by_id, default_owner): """ Fetches the policy states, filters the non compliant ones which are tag related. Returns a dictionary of Resource ID to the non compliant resource details """ policy_insights_client = PolicyInsightsClient(credentials) ps = policy_insights_client.policy_states.list_query_results_for_subscription( 'latest', subscription_id) creation_time = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') non_compliant_resources_map = {} for each in ps.value: each_dict = each.as_dict() if each_dict['is_compliant'] == False: policy = policies_by_id[each_dict['policy_definition_name']] splits = each_dict['resource_id'].split('/') resource_id = splits[len(splits) - 1] unique_key = resource_id + '-' + policy['display_name'] unique_key = unique_key.lower().replace(' ', '_') resource_id = each_dict['resource_id'] ncr = { 'PartitionKey': subscription_id, 'RowKey': unique_key, 'DisplayName': policy['display_name'], 'ResourceId': each_dict['resource_id'], 'ComplianceResourceId': each_dict['policy_assignment_id'], 'NotificationTime': creation_time, 'TechnicalOwner': default_owner, 'CreatedAtTime': each_dict['timestamp'] } if unique_key in non_compliant_resources_map: current_item = non_compliant_resources_map[unique_key] current_entry_time = datetime.strptime( current_item['CreatedAtTime'], '%Y-%m-%dT%H:%M:%S.%fZ') new_entry_time = datetime.strptime(ncr['CreatedAtTime'], '%Y-%m-%dT%H:%M:%S.%fZ') if current_entry_time < new_entry_time: non_compliant_resources_map[unique_key] = ncr else: non_compliant_resources_map[unique_key] = ncr return non_compliant_resources_map
def policy_insights_client_query(self, subscription_id_param, policy_states="latest"): """ Grabs the policy states for a give subscription :param policy_states: :param creds: :param subscription_id_param: :return: """ policy_insights_client = PolicyInsightsClient( credentials=self.credentials) states = policy_insights_client.policy_states query_results = states.list_query_results_for_subscription( subscription_id=subscription_id_param, policy_states_resource=policy_states) return query_results.value
def policy_insights_management_grp_query(self, management_group_name, policy_states="latest", query_options=None): """ Retrieve policy insights for a particular management group. Returns policy insights with policy states :param policy_states: :param creds: :param management_group_name: :return: """ policy_insights_client = PolicyInsightsClient( credentials=self.credentials) states = policy_insights_client.policy_states query_results = states.list_query_results_for_management_group( policy_states_resource=policy_states, management_group_name=management_group_name, query_options=query_options, custom_headers=None, raw=False, ) return query_results.value
def get_non_compliant_resources_by_id(subscription_id, policies_by_id, default_owner): """ Fetches the policy states, filters the non compliant ones which are tag related. Returns a dictionary of Resource ID to the non compliant resource details """ policy_insights_client = PolicyInsightsClient(credentials) ps = policy_insights_client.policy_states.list_query_results_for_subscription( 'latest', subscription_id) creation_time = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') non_compliant_resources_map = {} for each in ps.value: each_dict = each.as_dict() policy = policies_by_id[each_dict['policy_definition_name']] if each_dict['is_compliant'] == False and policy[ 'display_name'] == EXPECTED_TAG_POLICY_DISPLAY_NAME: splits = each_dict['resource_id'].split('/') resource_id = splits[len(splits) - 1] unique_key = resource_id ncr = { 'PartitionKey': subscription_id, 'RowKey': unique_key, 'DisplayName': EXPECTED_TAG_POLICY_DISPLAY_NAME, 'ResourceId': each_dict['resource_id'], 'ComplianceResourceId': each_dict['policy_assignment_id'], 'NotificationTime': creation_time, 'Owner': default_owner, 'CreatedAtTime': each_dict['timestamp'] } # Always override in case of duplicates non_compliant_resources_map[unique_key] = ncr return non_compliant_resources_map
def main(): SUBSCRIPTION_ID = os.environ.get("SUBSCRIPTION_ID", None) GROUP_NAME = "testgroupx" REMEDIATION = "remediationxxyyzz" POLICY_NAME = "policyxyz" POLICY_ASSIGNMENT_NAME = "assignmentx" # Create client # # For other authentication approaches, please see: https://pypi.org/project/azure-identity/ resource_client = ResourceManagementClient( credential=DefaultAzureCredential(), subscription_id=SUBSCRIPTION_ID) policyinsights_client = PolicyInsightsClient( credential=DefaultAzureCredential(), subscription_id=SUBSCRIPTION_ID) # - init depended client - policy_client = PolicyClient(credential=DefaultAzureCredential(), subscription_id=SUBSCRIPTION_ID) # - end - # Create resource group resource_client.resource_groups.create_or_update(GROUP_NAME, {"location": "eastus"}) # - init depended resources - # Create policy definition definition = policy_client.policy_definitions.create_or_update( POLICY_NAME, { 'policy_type': 'Custom', 'description': 'Don\'t create a VM anywhere', 'policy_rule': { 'if': { 'allOf': [{ 'source': 'action', 'equals': 'Microsoft.Compute/virtualMachines/read' }, { 'field': 'location', 'in': ['eastus', 'eastus2', 'centralus'] }] }, 'then': { 'effect': 'deny' } } }) print("Create policy definition: {}".format(definition)) # Policy Assignment - By Name scope = '/subscriptions/{}/resourceGroups/{}'.format( SUBSCRIPTION_ID, GROUP_NAME) # Create policy assignment assignment = policy_client.policy_assignments.create( scope, POLICY_ASSIGNMENT_NAME, { 'policy_definition_id': definition.id, }) print("Create policy assignment: {}".format(assignment)) # - end - # Create remediation remediation = policyinsights_client.remediations.create_or_update_at_resource_group( GROUP_NAME, REMEDIATION, {"policy_assignment_id": assignment.id}) print("Create remediation:\n{}".format(remediation)) # Get remediation remediation = policyinsights_client.remediations.get_at_resource_group( GROUP_NAME, REMEDIATION) print("Get remediation:\n{}".format(remediation)) # Delete remediation remediation = policyinsights_client.remediations.delete_at_resource_group( GROUP_NAME, REMEDIATION) print("Delete remediation.\n") # Delete Group resource_client.resource_groups.begin_delete(GROUP_NAME).result()