From c5c57f630dfe01cac25399a8dfc081bdb8aeac46 Mon Sep 17 00:00:00 2001 From: James Woolfenden Date: Wed, 18 Oct 2023 15:10:31 +0100 Subject: [PATCH] feat(arm): implement CKV_AZURE_103 for ARM (#5527) * feat(arm): implement CKV_AZURE_103 for ARM * adjust logic --------- Co-authored-by: gruebel --- .../resource/DataFactoryUsesGitRepository.py | 30 ++ .../fail.json | 308 ++++++++++++++ .../fail2.json | 385 ++++++++++++++++++ .../pass.json | 316 ++++++++++++++ .../unknown.json | 308 ++++++++++++++ .../test_DataFactoryUsesGitRepository.py | 41 ++ 6 files changed, 1388 insertions(+) create mode 100644 checkov/arm/checks/resource/DataFactoryUsesGitRepository.py create mode 100644 tests/arm/checks/resource/example_DataFactoryUsesGitRepository/fail.json create mode 100644 tests/arm/checks/resource/example_DataFactoryUsesGitRepository/fail2.json create mode 100644 tests/arm/checks/resource/example_DataFactoryUsesGitRepository/pass.json create mode 100644 tests/arm/checks/resource/example_DataFactoryUsesGitRepository/unknown.json create mode 100644 tests/arm/checks/resource/test_DataFactoryUsesGitRepository.py diff --git a/checkov/arm/checks/resource/DataFactoryUsesGitRepository.py b/checkov/arm/checks/resource/DataFactoryUsesGitRepository.py new file mode 100644 index 00000000000..a30fd7be905 --- /dev/null +++ b/checkov/arm/checks/resource/DataFactoryUsesGitRepository.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +from typing import Any + +from checkov.common.models.enums import CheckCategories, CheckResult +from checkov.arm.base_resource_check import BaseResourceCheck + + +class DataFactoryUsesGitRepository(BaseResourceCheck): + def __init__(self) -> None: + name = "Ensure that Azure Data Factory uses Git repository for source control" + id = "CKV_AZURE_103" + supported_resources = ("Microsoft.DataFactory/factories",) + categories = (CheckCategories.GENERAL_SECURITY,) + super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources) + + def scan_resource_conf(self, conf: dict[str, Any]) -> CheckResult: + properties = conf.get("properties") + if properties and isinstance(properties, dict): + self.evaluated_keys = ["properties/repoConfiguration/type"] + repo = properties.get("repoConfiguration") + if not repo: + return CheckResult.FAILED + if repo and isinstance(repo, dict) and repo.get("type") is not None: + return CheckResult.PASSED + return CheckResult.UNKNOWN + return CheckResult.FAILED + + +check = DataFactoryUsesGitRepository() diff --git a/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/fail.json b/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/fail.json new file mode 100644 index 00000000000..30b03bd6dc2 --- /dev/null +++ b/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/fail.json @@ -0,0 +1,308 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "subscription": { + "defaultValue": "", + "type": "string" + }, + "resourceGroup": { + "defaultValue": "", + "type": "string" + }, + "name": { + "defaultValue": "myv2datafactory", + "type": "string" + }, + "version": { + "defaultValue": "V2", + "type": "string" + }, + "location": { + "defaultValue": "eastus", + "type": "string" + }, + "tagsByResource": { + "type": "Object" + }, + "vNetEnabled": { + "defaultValue": false, + "type": "bool" + }, + "publicNetworkAccess": { + "defaultValue": true, + "type": "bool" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "Private endpoints. Empty if no private network access selected." + } + }, + "gitConfigureLater": { + "defaultValue": true, + "type": "bool" + }, + "gitRepoType": { + "defaultValue": "FactoryVSTSConfiguration", + "type": "string" + }, + "gitAccountName": { + "defaultValue": "", + "type": "string" + }, + "gitProjectName": { + "defaultValue": "", + "type": "string" + }, + "gitRepositoryName": { + "defaultValue": "", + "type": "string" + }, + "gitCollaborationBranch": { + "defaultValue": "master", + "type": "string" + }, + "gitRootFolder": { + "defaultValue": "/", + "type": "string" + }, + "userAssignedIdentities": { + "defaultValue": { + "type": "SystemAssigned" + }, + "type": "object" + }, + "userAssignedIdentitiesStr": { + "defaultValue": "", + "type": "string" + }, + "vaultBaseUrl": { + "defaultValue": "", + "type": "string" + }, + "keyName": { + "defaultValue": "", + "type": "string" + }, + "keyVersion": { + "defaultValue": "", + "type": "string" + }, + "enableCMK": { + "defaultValue": false, + "type": "bool" + }, + "cmkIdentity": { + "defaultValue": "", + "type": "string" + } + }, + "variables": { + "hasPE": "[greater(length(parameters('privateEndpoints')), 0)]", + "resourceGroupId": "[if(variables('hasPE'),parameters('privateEndpoints')[0].privateEndpointConfiguration.resourceGroup.value.name, '')]", + "subNetId": "[if(variables('hasPE'),parameters('privateEndpoints')[0].privateEndpointConfiguration.privateEndpoint.properties.subnet.id, '')]", + "subNetSub": "[if(variables('hasPE'),split(variables('subNetId'),'/')[2],'')]", + "subNetRg": "[if(variables('hasPE'),split(variables('subNetId'),'/')[4],'')]", + "subNetName": "[if(variables('hasPE'),split(variables('subNetId'),'/')[8],'')]", + "integrateDns": "[if(variables('hasPE'),parameters('privateEndpoints')[0].privateDnsZoneConfiguration.integrateWithPrivateDnsZone, 'true')]" + }, + "resources": [ + { + "condition": "[equals(parameters('version'), 'V2')]", + "type": "Microsoft.DataFactory/factories", + "apiVersion": "2018-06-01", + "name": "fail", + "location": "[parameters('location')]", + "identity": "[if(parameters('enableCMK'),json(parameters('userAssignedIdentitiesStr')), parameters('userAssignedIdentities'))]", + "properties": { + "repoConfiguration": "", + "publicNetworkAccess": "[if(bool(parameters('publicNetworkAccess')), 'Enabled', 'Disabled')]", + "encryption": "[if(parameters('enableCMK'), json(concat('{\"identity\":{\"userAssignedIdentity\":\"', parameters('cmkIdentity'), '\"},','\"VaultBaseUrl\": \"', parameters('vaultBaseUrl'), '\",','\"KeyName\": \"', parameters('keyName'), '\",','\"KeyVersion\": \"', parameters('keyVersion'), '\"}')), json('null'))]" + }, + "tags": "[ if(contains(parameters('tagsByResource'), 'Microsoft.DataFactory/factories'), parameters('tagsByResource')['Microsoft.DataFactory/factories'], json('{}')) ]", + "resources": [ + { + "condition": "[and(equals(parameters('version'), 'V2'), parameters('vNetEnabled'))]", + "name": "[concat(parameters('name'), '/default')]", + "type": "Microsoft.DataFactory/factories/managedVirtualNetworks", + "apiVersion": "2018-06-01", + "properties": {}, + "dependsOn": [ + "[concat('Microsoft.DataFactory/factories/', parameters('name'))]" + ] + }, + { + "condition": "[and(equals(parameters('version'), 'V2'), parameters('vNetEnabled'))]", + "name": "[concat(parameters('name'), '/AutoResolveIntegrationRuntime')]", + "type": "Microsoft.DataFactory/factories/integrationRuntimes", + "apiVersion": "2018-06-01", + "properties": { + "type": "Managed", + "managedVirtualNetwork": { + "referenceName": "default", + "type": "ManagedVirtualNetworkReference" + }, + "typeProperties": { + "computeProperties": { + "location": "AutoResolve", + "dataFlowProperties": { + "computeType": "General", + "coreCount": 8, + "timeToLive": 0 + } + } + } + }, + "dependsOn": [ + "[concat('Microsoft.DataFactory/factories/', parameters('name'))]", + "[concat('Microsoft.DataFactory/factories/', parameters('name'), '/managedVirtualNetworks/default')]" + ] + } + ] + }, + { + "condition": "[and(not(parameters('publicNetworkAccess')), equals(parameters('privateEndpoints')[0].privateEndpointConfiguration.resourceGroup.mode, 1))]", + "apiVersion": "2018-05-01", + "name": "[concat('deployResourceGroup-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name)]", + "type": "Microsoft.Resources/deployments", + "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]", + "location": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.location]", + "dependsOn": [ + "[parameters('name')]" + ], + "copy": { + "name": "privateendpointscopy", + "count": "[length(parameters('privateEndpoints'))]" + }, + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2021-04-01", + "name": "[variables('resourceGroupId')]", + "location": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.location]", + "properties": {} + } + ] + } + } + }, + { + "condition": "[not(parameters('publicNetworkAccess'))]", + "apiVersion": "2017-05-10", + "name": "[concat('deployPrivateEndpoint-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name)]", + "type": "Microsoft.Resources/deployments", + "resourceGroup": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name]", + "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]", + "dependsOn": [ + "[parameters('name')]", + "[concat('deployResourceGroup-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name)]" + ], + "copy": { + "name": "privateendpointscopy", + "count": "[length(parameters('privateEndpoints'))]" + }, + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "location": "[parameters('location')]", + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name]", + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2020-03-01", + "properties": { + "subnet": { + "id": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.properties.subnet.id]" + }, + "privateLinkServiceConnections": [ + { + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name]", + "properties": { + "privateLinkServiceId": "[concat('/subscriptions/',parameters('subscription'),'/resourcegroups/',parameters('resourceGroup'), '/providers/Microsoft.DataFactory/factories/', parameters('name'))]", + "groupIds": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.properties.privateLinkServiceConnections[0].properties.groupIds]" + } + } + ] + }, + "tags": {} + } + ] + } + } + }, + { + "apiVersion": "2017-05-10", + "name": "[concat('deployPrivateDnsZone-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name)]", + "type": "Microsoft.Resources/deployments", + "resourceGroup": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name]", + "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]", + "dependsOn": [ + "[concat('Microsoft.Resources/deployments/', concat('deployPrivateEndpoint-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name))]" + ], + "condition": "[and(not(parameters('publicNetworkAccess')), variables('integrateDns'))]", + "copy": { + "name": "privateendpointdnscopy", + "count": "[length(parameters('privateEndpoints'))]" + }, + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2018-09-01", + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]", + "location": "global", + "tags": {}, + "properties": {} + }, + { + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2018-09-01", + "name": "[concat(string(parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName), '/', uniquestring(variables('subNetId')))]", + "location": "global", + "dependsOn": [ + "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]" + ], + "properties": { + "virtualNetwork": { + "id": "[concat('/subscriptions/',variables('subNetSub'),'/resourceGroups/',variables('subNetRg'),'/providers/Microsoft.Network/virtualNetworks/',variables('subNetName'))]" + }, + "registrationEnabled": false + } + }, + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2020-03-01", + "name": "[concat(parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name, '/', 'default')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]" + ], + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]", + "properties": { + "privateDnsZoneId": "[concat('/subscriptions/',variables('subNetSub'),'/resourcegroups/',variables('subNetRg'), '/providers/Microsoft.Network/privateDnsZones/', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName )]" + } + } + ] + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/fail2.json b/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/fail2.json new file mode 100644 index 00000000000..540891682c9 --- /dev/null +++ b/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/fail2.json @@ -0,0 +1,385 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.10.61.36676", + "templateHash": "3351458417114662416" + } + }, + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources. Leave the default value." + } + }, + "azureADUserName": { + "type": "string", + "metadata": { + "description": "Your Azure AD user identity (this identity will be granted admin rights to the Azure SQL instance)." + } + }, + "azureADObjectID": { + "type": "string", + "metadata": { + "description": "Object ID for your Azure AD user identity (see the README.md file in the Azure Quickstart guide for instructions on how to get your Azure AD user object ID)." + } + }, + "azureDataLakeStoreAccountName": { + "type": "string", + "defaultValue": "[format('adls{0}', uniqueString(resourceGroup().id))]", + "maxLength": 24, + "minLength": 3, + "metadata": { + "description": "Name of the Azure Data Lake Storage Gen2 storage account. Storage account name requirements:\r\n- Storage account names must be between 3 and 24 characters in length and may contain numbers and lowercase letters only.\r\n- Your storage account name must be unique within Azure. No two storage accounts can have the same name.\r\n" + } + }, + "azureDataFactoryName": { + "type": "string", + "defaultValue": "[format('adf-{0}', uniqueString(resourceGroup().id))]", + "metadata": { + "description": "Name of the Azure Data Factory instance." + } + }, + "azureDatabricksName": { + "type": "string", + "defaultValue": "[format('databricks-{0}', uniqueString(resourceGroup().id))]", + "maxLength": 30, + "minLength": 3, + "metadata": { + "description": "Name of the Azure Databricks workspace. Databricks workspace name requirements:\r\n- Databricks workspace names must be between 3 and 30 characters in length and may contain numbers, letters, underscores, and hyphens only.\r\n" + } + }, + "databricksNPIP": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Do you want to enable No Public IP (NPIP) for your Azure Databricks workspace (true or false)?" + } + }, + "deployEventHub": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Do you want to deploy a new Azure Event Hub for streaming use cases (true or false)? Leave default name if you choose false." + } + }, + "eventHubName": { + "type": "string", + "defaultValue": "[format('eh-{0}', uniqueString(resourceGroup().id))]", + "maxLength": 50, + "minLength": 6, + "metadata": { + "description": "Name of the Azure Event Hub. Event Hub name requirements:\r\n- Event Hub names must be between 6 and 50 characters in length and may contain numbers, letters, and hyphens only.\r\n- The name must start with a letter, and it must end with a letter or number\r\n" + } + }, + "deployAzureKeyVault": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Do you want to deploy a new Azure Key Vault instance (true or false)? Leave default name if you choose false." + } + }, + "azureKeyVaultName": { + "type": "string", + "defaultValue": "[format('kv-{0}', uniqueString(resourceGroup().id))]", + "maxLength": 24, + "minLength": 3, + "metadata": { + "description": "Name of the Azure Key Vault. Key Vault name requirements:\r\n- Key vault names must be between 3 and 24 characters in length and may contain numbers, letters, and dashes only.\r\n" + } + }, + "deploySqlDb": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Do you want to deploy a new Azure SQL Database (true or false)? Leave default name if you choose false." + } + }, + "azureSqlServerName": { + "type": "string", + "defaultValue": "[format('{0}sqlsrv', uniqueString(resourceGroup().id))]", + "metadata": { + "description": "Name of Azure SQL logical server" + } + }, + "azureSqlDatabaseName": { + "type": "string", + "defaultValue": "analytics-db", + "maxLength": 128, + "metadata": { + "description": "Database name" + } + }, + "sqlAdministratorLogin": { + "type": "string", + "metadata": { + "description": "SQL administrator username" + } + }, + "sqlAdministratorLoginPassword": { + "type": "secureString", + "metadata": { + "description": "SQL administrator password" + } + } + }, + "variables": { + "akvRoleName": "Key Vault Secrets User", + "akvRoleIdMapping": { + "Key Vault Secrets User": "4633458b-17de-408a-b874-0445c86b69e6" + } + }, + "resources": [ + { + "condition": "[parameters('deployEventHub')]", + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2021-11-01", + "name": "[format('{0}ns', parameters('eventHubName'))]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard", + "tier": "Standard", + "capacity": 1 + }, + "properties": { + "isAutoInflateEnabled": false, + "maximumThroughputUnits": 0 + } + }, + { + "condition": "[parameters('deployEventHub')]", + "type": "Microsoft.EventHub/namespaces/eventhubs", + "apiVersion": "2021-11-01", + "name": "[format('{0}/{1}', format('{0}ns', parameters('eventHubName')), parameters('eventHubName'))]", + "properties": { + "messageRetentionInDays": 7, + "partitionCount": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.EventHub/namespaces', format('{0}ns', parameters('eventHubName')))]" + ] + }, + { + "condition": "[parameters('deploySqlDb')]", + "type": "Microsoft.Sql/servers", + "apiVersion": "2021-11-01", + "name": "[parameters('azureSqlServerName')]", + "location": "[parameters('location')]", + "properties": { + "minimalTlsVersion": "1.2", + "administratorLogin": "[parameters('sqlAdministratorLogin')]", + "administratorLoginPassword": "[parameters('sqlAdministratorLoginPassword')]", + "administrators": { + "administratorType": "ActiveDirectory", + "azureADOnlyAuthentication": false, + "login": "[parameters('azureADUserName')]", + "sid": "[parameters('azureADObjectID')]", + "tenantId": "[subscription().tenantId]" + } + } + }, + { + "condition": "[parameters('deploySqlDb')]", + "type": "Microsoft.Sql/servers/databases", + "apiVersion": "2021-11-01", + "name": "[format('{0}/{1}', parameters('azureSqlServerName'), parameters('azureSqlDatabaseName'))]", + "location": "[parameters('location')]", + "sku": { + "capacity": 8, + "family": "Gen5", + "name": "GP_Gen5", + "tier": "GeneralPurpose" + }, + "dependsOn": [ + "[resourceId('Microsoft.Sql/servers', parameters('azureSqlServerName'))]" + ] + }, + { + "condition": "[parameters('deploySqlDb')]", + "type": "Microsoft.Sql/servers/firewallRules", + "apiVersion": "2020-11-01-preview", + "name": "[format('{0}/{1}', parameters('azureSqlServerName'), 'Allow Azure Services')]", + "properties": { + "startIpAddress": "0.0.0.0", + "endIpAddress": "0.0.0.0" + }, + "dependsOn": [ + "[resourceId('Microsoft.Sql/servers', parameters('azureSqlServerName'))]" + ] + }, + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2021-09-01", + "name": "[parameters('azureDataLakeStoreAccountName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard_LRS" + }, + "kind": "StorageV2", + "properties": { + "minimumTlsVersion": "TLS1_2", + "isHnsEnabled": true + } + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('azureDataLakeStoreAccountName'))]", + "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('azureDataLakeStoreAccountName')), parameters('azureADObjectID'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe'))]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]", + "principalId": "[parameters('azureADObjectID')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', parameters('azureDataLakeStoreAccountName'))]" + ], + "metadata": { + "description": "Assigns the user to Storage Blob Data Contributor Role" + } + }, + { + "type": "Microsoft.DataFactory/factories", + "apiVersion": "2018-06-01", + "name": "fail2", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + } + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('azureDataLakeStoreAccountName'))]", + "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('azureDataLakeStoreAccountName')), resourceId('Microsoft.DataFactory/factories', parameters('azureDataFactoryName')), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe'))]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]", + "principalId": "[reference(resourceId('Microsoft.DataFactory/factories', parameters('azureDataFactoryName')), '2018-06-01', 'full').identity.principalId]", + "principalType": "ServicePrincipal" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', parameters('azureDataLakeStoreAccountName'))]", + "[resourceId('Microsoft.DataFactory/factories', parameters('azureDataFactoryName'))]" + ], + "metadata": { + "description": "Assigns the ADF Managed Identity to Storage Blob Data Contributor Role" + } + }, + { + "type": "Microsoft.DataFactory/factories/linkedservices", + "apiVersion": "2018-06-01", + "name": "[format('{0}/{1}', parameters('azureDataFactoryName'), format('{0}-linkedService', parameters('azureDataLakeStoreAccountName')))]", + "properties": { + "type": "AzureBlobFS", + "typeProperties": { + "accountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('azureDataLakeStoreAccountName')), '2021-09-01').keys[0].value]", + "url": "[reference(resourceId('Microsoft.Storage/storageAccounts', parameters('azureDataLakeStoreAccountName'))).primaryEndpoints.dfs]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', parameters('azureDataLakeStoreAccountName'))]", + "[resourceId('Microsoft.DataFactory/factories', parameters('azureDataFactoryName'))]" + ] + }, + { + "condition": "[parameters('deploySqlDb')]", + "type": "Microsoft.DataFactory/factories/linkedservices", + "apiVersion": "2018-06-01", + "name": "[format('{0}/{1}', parameters('azureDataFactoryName'), format('{0}-linkedService', parameters('azureSqlServerName')))]", + "properties": { + "type": "AzureSqlDatabase", + "typeProperties": { + "connectionString": "[format('Data Source={0}{1};Initial Catalog={2};User ID = {3};Password={4};', parameters('azureSqlServerName'), environment().suffixes.sqlServerHostname, parameters('azureSqlDatabaseName'), parameters('sqlAdministratorLogin'), parameters('sqlAdministratorLoginPassword'))]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.DataFactory/factories', parameters('azureDataFactoryName'))]" + ] + }, + { + "type": "Microsoft.Databricks/workspaces", + "apiVersion": "2018-04-01", + "name": "[parameters('azureDatabricksName')]", + "location": "[parameters('location')]", + "sku": { + "name": "premium" + }, + "properties": { + "managedResourceGroupId": "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('databricks-rg-{0}-{1}', parameters('azureDatabricksName'), uniqueString(parameters('azureDatabricksName'), resourceGroup().id)))]", + "parameters": { + "enableNoPublicIp": { + "value": "[parameters('databricksNPIP')]" + } + } + } + }, + { + "condition": "[parameters('deployAzureKeyVault')]", + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('azureKeyVaultName')]", + "location": "[parameters('location')]", + "properties": { + "enableRbacAuthorization": true, + "tenantId": "[subscription().tenantId]", + "sku": { + "name": "standard", + "family": "A" + }, + "networkAcls": { + "defaultAction": "Allow", + "bypass": "AzureServices" + } + } + }, + { + "condition": "[parameters('deployAzureKeyVault')]", + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('azureKeyVaultName'))]", + "name": "[guid(variables('akvRoleIdMapping')[variables('akvRoleName')], parameters('azureADObjectID'), resourceId('Microsoft.KeyVault/vaults', parameters('azureKeyVaultName')))]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('akvRoleIdMapping')[variables('akvRoleName')])]", + "principalId": "[parameters('azureADObjectID')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', parameters('azureKeyVaultName'))]" + ] + }, + { + "condition": "[parameters('deployAzureKeyVault')]", + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('azureKeyVaultName'))]", + "name": "[guid(variables('akvRoleIdMapping')[variables('akvRoleName')], resourceId('Microsoft.DataFactory/factories', parameters('azureDataFactoryName')), resourceId('Microsoft.KeyVault/vaults', parameters('azureKeyVaultName')))]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('akvRoleIdMapping')[variables('akvRoleName')])]", + "principalId": "[reference(resourceId('Microsoft.DataFactory/factories', parameters('azureDataFactoryName')), '2018-06-01', 'full').identity.principalId]", + "principalType": "ServicePrincipal" + }, + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', parameters('azureKeyVaultName'))]", + "[resourceId('Microsoft.DataFactory/factories', parameters('azureDataFactoryName'))]" + ] + }, + { + "condition": "[parameters('deployAzureKeyVault')]", + "type": "Microsoft.DataFactory/factories/linkedservices", + "apiVersion": "2018-06-01", + "name": "[format('{0}/{1}', parameters('azureDataFactoryName'), format('{0}-linkedService', parameters('azureKeyVaultName')))]", + "properties": { + "type": "AzureKeyVault", + "typeProperties": { + "baseUrl": "[reference(resourceId('Microsoft.KeyVault/vaults', parameters('azureKeyVaultName')), '2022-07-01').vaultUri]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', parameters('azureKeyVaultName'))]", + "[resourceId('Microsoft.DataFactory/factories', parameters('azureDataFactoryName'))]" + ] + } + ] +} \ No newline at end of file diff --git a/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/pass.json b/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/pass.json new file mode 100644 index 00000000000..b7bef6473fb --- /dev/null +++ b/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/pass.json @@ -0,0 +1,316 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "subscription": { + "defaultValue": "", + "type": "string" + }, + "resourceGroup": { + "defaultValue": "", + "type": "string" + }, + "name": { + "defaultValue": "myv2datafactory", + "type": "string" + }, + "version": { + "defaultValue": "V2", + "type": "string" + }, + "location": { + "defaultValue": "eastus", + "type": "string" + }, + "tagsByResource": { + "type": "Object" + }, + "vNetEnabled": { + "defaultValue": false, + "type": "bool" + }, + "publicNetworkAccess": { + "defaultValue": true, + "type": "bool" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "Private endpoints. Empty if no private network access selected." + } + }, + "gitConfigureLater": { + "defaultValue": true, + "type": "bool" + }, + "gitRepoType": { + "defaultValue": "FactoryVSTSConfiguration", + "type": "string" + }, + "gitAccountName": { + "defaultValue": "", + "type": "string" + }, + "gitProjectName": { + "defaultValue": "", + "type": "string" + }, + "gitRepositoryName": { + "defaultValue": "", + "type": "string" + }, + "gitCollaborationBranch": { + "defaultValue": "master", + "type": "string" + }, + "gitRootFolder": { + "defaultValue": "/", + "type": "string" + }, + "userAssignedIdentities": { + "defaultValue": { + "type": "SystemAssigned" + }, + "type": "object" + }, + "userAssignedIdentitiesStr": { + "defaultValue": "", + "type": "string" + }, + "vaultBaseUrl": { + "defaultValue": "", + "type": "string" + }, + "keyName": { + "defaultValue": "", + "type": "string" + }, + "keyVersion": { + "defaultValue": "", + "type": "string" + }, + "enableCMK": { + "defaultValue": false, + "type": "bool" + }, + "cmkIdentity": { + "defaultValue": "", + "type": "string" + } + }, + "variables": { + "hasPE": "[greater(length(parameters('privateEndpoints')), 0)]", + "resourceGroupId": "[if(variables('hasPE'),parameters('privateEndpoints')[0].privateEndpointConfiguration.resourceGroup.value.name, '')]", + "subNetId": "[if(variables('hasPE'),parameters('privateEndpoints')[0].privateEndpointConfiguration.privateEndpoint.properties.subnet.id, '')]", + "subNetSub": "[if(variables('hasPE'),split(variables('subNetId'),'/')[2],'')]", + "subNetRg": "[if(variables('hasPE'),split(variables('subNetId'),'/')[4],'')]", + "subNetName": "[if(variables('hasPE'),split(variables('subNetId'),'/')[8],'')]", + "integrateDns": "[if(variables('hasPE'),parameters('privateEndpoints')[0].privateDnsZoneConfiguration.integrateWithPrivateDnsZone, 'true')]" + }, + "resources": [ + { + "condition": "[equals(parameters('version'), 'V2')]", + "type": "Microsoft.DataFactory/factories", + "apiVersion": "2018-06-01", + "name": "pass", + "location": "[parameters('location')]", + "identity": "[if(parameters('enableCMK'),json(parameters('userAssignedIdentitiesStr')), parameters('userAssignedIdentities'))]", + "properties": { + "repoConfiguration": { + "accountName": "string", + "collaborationBranch": "string", + "disablePublish": "bool", + "lastCommitId": "string", + "repositoryName": "string", + "rootFolder": "string", + "type": "[parameters('gitRepoType')]" + }, + "publicNetworkAccess": "[if(bool(parameters('publicNetworkAccess')), 'Enabled', 'Disabled')]", + "encryption": "[if(parameters('enableCMK'), json(concat('{\"identity\":{\"userAssignedIdentity\":\"', parameters('cmkIdentity'), '\"},','\"VaultBaseUrl\": \"', parameters('vaultBaseUrl'), '\",','\"KeyName\": \"', parameters('keyName'), '\",','\"KeyVersion\": \"', parameters('keyVersion'), '\"}')), json('null'))]" + }, + "tags": "[ if(contains(parameters('tagsByResource'), 'Microsoft.DataFactory/factories'), parameters('tagsByResource')['Microsoft.DataFactory/factories'], json('{}')) ]", + "resources": [ + { + "condition": "[and(equals(parameters('version'), 'V2'), parameters('vNetEnabled'))]", + "name": "[concat(parameters('name'), '/default')]", + "type": "Microsoft.DataFactory/factories/managedVirtualNetworks", + "apiVersion": "2018-06-01", + "properties": {}, + "dependsOn": [ + "[concat('Microsoft.DataFactory/factories/', parameters('name'))]" + ] + }, + { + "condition": "[and(equals(parameters('version'), 'V2'), parameters('vNetEnabled'))]", + "name": "[concat(parameters('name'), '/AutoResolveIntegrationRuntime')]", + "type": "Microsoft.DataFactory/factories/integrationRuntimes", + "apiVersion": "2018-06-01", + "properties": { + "type": "Managed", + "managedVirtualNetwork": { + "referenceName": "default", + "type": "ManagedVirtualNetworkReference" + }, + "typeProperties": { + "computeProperties": { + "location": "AutoResolve", + "dataFlowProperties": { + "computeType": "General", + "coreCount": 8, + "timeToLive": 0 + } + } + } + }, + "dependsOn": [ + "[concat('Microsoft.DataFactory/factories/', parameters('name'))]", + "[concat('Microsoft.DataFactory/factories/', parameters('name'), '/managedVirtualNetworks/default')]" + ] + } + ] + }, + { + "condition": "[and(not(parameters('publicNetworkAccess')), equals(parameters('privateEndpoints')[0].privateEndpointConfiguration.resourceGroup.mode, 1))]", + "apiVersion": "2018-05-01", + "name": "[concat('deployResourceGroup-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name)]", + "type": "Microsoft.Resources/deployments", + "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]", + "location": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.location]", + "dependsOn": [ + "[parameters('name')]" + ], + "copy": { + "name": "privateendpointscopy", + "count": "[length(parameters('privateEndpoints'))]" + }, + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2021-04-01", + "name": "[variables('resourceGroupId')]", + "location": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.location]", + "properties": {} + } + ] + } + } + }, + { + "condition": "[not(parameters('publicNetworkAccess'))]", + "apiVersion": "2017-05-10", + "name": "[concat('deployPrivateEndpoint-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name)]", + "type": "Microsoft.Resources/deployments", + "resourceGroup": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name]", + "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]", + "dependsOn": [ + "[parameters('name')]", + "[concat('deployResourceGroup-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name)]" + ], + "copy": { + "name": "privateendpointscopy", + "count": "[length(parameters('privateEndpoints'))]" + }, + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "location": "[parameters('location')]", + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name]", + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2020-03-01", + "properties": { + "subnet": { + "id": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.properties.subnet.id]" + }, + "privateLinkServiceConnections": [ + { + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name]", + "properties": { + "privateLinkServiceId": "[concat('/subscriptions/',parameters('subscription'),'/resourcegroups/',parameters('resourceGroup'), '/providers/Microsoft.DataFactory/factories/', parameters('name'))]", + "groupIds": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.properties.privateLinkServiceConnections[0].properties.groupIds]" + } + } + ] + }, + "tags": {} + } + ] + } + } + }, + { + "apiVersion": "2017-05-10", + "name": "[concat('deployPrivateDnsZone-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name)]", + "type": "Microsoft.Resources/deployments", + "resourceGroup": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name]", + "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]", + "dependsOn": [ + "[concat('Microsoft.Resources/deployments/', concat('deployPrivateEndpoint-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name))]" + ], + "condition": "[and(not(parameters('publicNetworkAccess')), variables('integrateDns'))]", + "copy": { + "name": "privateendpointdnscopy", + "count": "[length(parameters('privateEndpoints'))]" + }, + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2018-09-01", + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]", + "location": "global", + "tags": {}, + "properties": {} + }, + { + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2018-09-01", + "name": "[concat(string(parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName), '/', uniquestring(variables('subNetId')))]", + "location": "global", + "dependsOn": [ + "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]" + ], + "properties": { + "virtualNetwork": { + "id": "[concat('/subscriptions/',variables('subNetSub'),'/resourceGroups/',variables('subNetRg'),'/providers/Microsoft.Network/virtualNetworks/',variables('subNetName'))]" + }, + "registrationEnabled": false + } + }, + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2020-03-01", + "name": "[concat(parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name, '/', 'default')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]" + ], + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]", + "properties": { + "privateDnsZoneId": "[concat('/subscriptions/',variables('subNetSub'),'/resourcegroups/',variables('subNetRg'), '/providers/Microsoft.Network/privateDnsZones/', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName )]" + } + } + ] + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/unknown.json b/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/unknown.json new file mode 100644 index 00000000000..6cd0eaeccb2 --- /dev/null +++ b/tests/arm/checks/resource/example_DataFactoryUsesGitRepository/unknown.json @@ -0,0 +1,308 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "subscription": { + "defaultValue": "", + "type": "string" + }, + "resourceGroup": { + "defaultValue": "", + "type": "string" + }, + "name": { + "defaultValue": "myv2datafactory", + "type": "string" + }, + "version": { + "defaultValue": "V2", + "type": "string" + }, + "location": { + "defaultValue": "eastus", + "type": "string" + }, + "tagsByResource": { + "type": "Object" + }, + "vNetEnabled": { + "defaultValue": false, + "type": "bool" + }, + "publicNetworkAccess": { + "defaultValue": true, + "type": "bool" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "Private endpoints. Empty if no private network access selected." + } + }, + "gitConfigureLater": { + "defaultValue": true, + "type": "bool" + }, + "gitRepoType": { + "defaultValue": "FactoryVSTSConfiguration", + "type": "string" + }, + "gitAccountName": { + "defaultValue": "", + "type": "string" + }, + "gitProjectName": { + "defaultValue": "", + "type": "string" + }, + "gitRepositoryName": { + "defaultValue": "", + "type": "string" + }, + "gitCollaborationBranch": { + "defaultValue": "master", + "type": "string" + }, + "gitRootFolder": { + "defaultValue": "/", + "type": "string" + }, + "userAssignedIdentities": { + "defaultValue": { + "type": "SystemAssigned" + }, + "type": "object" + }, + "userAssignedIdentitiesStr": { + "defaultValue": "", + "type": "string" + }, + "vaultBaseUrl": { + "defaultValue": "", + "type": "string" + }, + "keyName": { + "defaultValue": "", + "type": "string" + }, + "keyVersion": { + "defaultValue": "", + "type": "string" + }, + "enableCMK": { + "defaultValue": false, + "type": "bool" + }, + "cmkIdentity": { + "defaultValue": "", + "type": "string" + } + }, + "variables": { + "hasPE": "[greater(length(parameters('privateEndpoints')), 0)]", + "resourceGroupId": "[if(variables('hasPE'),parameters('privateEndpoints')[0].privateEndpointConfiguration.resourceGroup.value.name, '')]", + "subNetId": "[if(variables('hasPE'),parameters('privateEndpoints')[0].privateEndpointConfiguration.privateEndpoint.properties.subnet.id, '')]", + "subNetSub": "[if(variables('hasPE'),split(variables('subNetId'),'/')[2],'')]", + "subNetRg": "[if(variables('hasPE'),split(variables('subNetId'),'/')[4],'')]", + "subNetName": "[if(variables('hasPE'),split(variables('subNetId'),'/')[8],'')]", + "integrateDns": "[if(variables('hasPE'),parameters('privateEndpoints')[0].privateDnsZoneConfiguration.integrateWithPrivateDnsZone, 'true')]" + }, + "resources": [ + { + "condition": "[equals(parameters('version'), 'V2')]", + "type": "Microsoft.DataFactory/factories", + "apiVersion": "2018-06-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": "[if(parameters('enableCMK'),json(parameters('userAssignedIdentitiesStr')), parameters('userAssignedIdentities'))]", + "properties": { + "repoConfiguration": "[if(bool(parameters('gitConfigureLater')), json('null'), json(concat('{\"type\": \"', parameters('gitRepoType'), '\",','\"accountName\": \"', parameters('gitAccountName'), '\",','\"repositoryName\": \"', parameters('gitRepositoryName'), '\",', if(equals(parameters('gitRepoType'), 'FactoryVSTSConfiguration'), concat('\"projectName\": \"', parameters('gitProjectName'), '\",'), ''),'\"collaborationBranch\": \"', parameters('gitCollaborationBranch'), '\",','\"rootFolder\": \"', parameters('gitRootFolder'), '\"}')))]", + "publicNetworkAccess": "[if(bool(parameters('publicNetworkAccess')), 'Enabled', 'Disabled')]", + "encryption": "[if(parameters('enableCMK'), json(concat('{\"identity\":{\"userAssignedIdentity\":\"', parameters('cmkIdentity'), '\"},','\"VaultBaseUrl\": \"', parameters('vaultBaseUrl'), '\",','\"KeyName\": \"', parameters('keyName'), '\",','\"KeyVersion\": \"', parameters('keyVersion'), '\"}')), json('null'))]" + }, + "tags": "[ if(contains(parameters('tagsByResource'), 'Microsoft.DataFactory/factories'), parameters('tagsByResource')['Microsoft.DataFactory/factories'], json('{}')) ]", + "resources": [ + { + "condition": "[and(equals(parameters('version'), 'V2'), parameters('vNetEnabled'))]", + "name": "[concat(parameters('name'), '/default')]", + "type": "Microsoft.DataFactory/factories/managedVirtualNetworks", + "apiVersion": "2018-06-01", + "properties": {}, + "dependsOn": [ + "[concat('Microsoft.DataFactory/factories/', parameters('name'))]" + ] + }, + { + "condition": "[and(equals(parameters('version'), 'V2'), parameters('vNetEnabled'))]", + "name": "[concat(parameters('name'), '/AutoResolveIntegrationRuntime')]", + "type": "Microsoft.DataFactory/factories/integrationRuntimes", + "apiVersion": "2018-06-01", + "properties": { + "type": "Managed", + "managedVirtualNetwork": { + "referenceName": "default", + "type": "ManagedVirtualNetworkReference" + }, + "typeProperties": { + "computeProperties": { + "location": "AutoResolve", + "dataFlowProperties": { + "computeType": "General", + "coreCount": 8, + "timeToLive": 0 + } + } + } + }, + "dependsOn": [ + "[concat('Microsoft.DataFactory/factories/', parameters('name'))]", + "[concat('Microsoft.DataFactory/factories/', parameters('name'), '/managedVirtualNetworks/default')]" + ] + } + ] + }, + { + "condition": "[and(not(parameters('publicNetworkAccess')), equals(parameters('privateEndpoints')[0].privateEndpointConfiguration.resourceGroup.mode, 1))]", + "apiVersion": "2018-05-01", + "name": "[concat('deployResourceGroup-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name)]", + "type": "Microsoft.Resources/deployments", + "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]", + "location": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.location]", + "dependsOn": [ + "[parameters('name')]" + ], + "copy": { + "name": "privateendpointscopy", + "count": "[length(parameters('privateEndpoints'))]" + }, + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2021-04-01", + "name": "[variables('resourceGroupId')]", + "location": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.location]", + "properties": {} + } + ] + } + } + }, + { + "condition": "[not(parameters('publicNetworkAccess'))]", + "apiVersion": "2017-05-10", + "name": "[concat('deployPrivateEndpoint-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name)]", + "type": "Microsoft.Resources/deployments", + "resourceGroup": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name]", + "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]", + "dependsOn": [ + "[parameters('name')]", + "[concat('deployResourceGroup-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name)]" + ], + "copy": { + "name": "privateendpointscopy", + "count": "[length(parameters('privateEndpoints'))]" + }, + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "location": "[parameters('location')]", + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name]", + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2020-03-01", + "properties": { + "subnet": { + "id": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.properties.subnet.id]" + }, + "privateLinkServiceConnections": [ + { + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name]", + "properties": { + "privateLinkServiceId": "[concat('/subscriptions/',parameters('subscription'),'/resourcegroups/',parameters('resourceGroup'), '/providers/Microsoft.DataFactory/factories/', parameters('name'))]", + "groupIds": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.properties.privateLinkServiceConnections[0].properties.groupIds]" + } + } + ] + }, + "tags": {} + } + ] + } + } + }, + { + "apiVersion": "2017-05-10", + "name": "[concat('deployPrivateDnsZone-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name)]", + "type": "Microsoft.Resources/deployments", + "resourceGroup": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name]", + "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]", + "dependsOn": [ + "[concat('Microsoft.Resources/deployments/', concat('deployPrivateEndpoint-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name))]" + ], + "condition": "[and(not(parameters('publicNetworkAccess')), variables('integrateDns'))]", + "copy": { + "name": "privateendpointdnscopy", + "count": "[length(parameters('privateEndpoints'))]" + }, + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2018-09-01", + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]", + "location": "global", + "tags": {}, + "properties": {} + }, + { + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2018-09-01", + "name": "[concat(string(parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName), '/', uniquestring(variables('subNetId')))]", + "location": "global", + "dependsOn": [ + "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]" + ], + "properties": { + "virtualNetwork": { + "id": "[concat('/subscriptions/',variables('subNetSub'),'/resourceGroups/',variables('subNetRg'),'/providers/Microsoft.Network/virtualNetworks/',variables('subNetName'))]" + }, + "registrationEnabled": false + } + }, + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2020-03-01", + "name": "[concat(parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name, '/', 'default')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]" + ], + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName]", + "properties": { + "privateDnsZoneId": "[concat('/subscriptions/',variables('subNetSub'),'/resourcegroups/',variables('subNetRg'), '/providers/Microsoft.Network/privateDnsZones/', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subResource.expectedPrivateDnsZoneName )]" + } + } + ] + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/tests/arm/checks/resource/test_DataFactoryUsesGitRepository.py b/tests/arm/checks/resource/test_DataFactoryUsesGitRepository.py new file mode 100644 index 00000000000..22d61ad2ba3 --- /dev/null +++ b/tests/arm/checks/resource/test_DataFactoryUsesGitRepository.py @@ -0,0 +1,41 @@ +import os +import unittest +from pathlib import Path + +from checkov.arm.checks.resource.DataFactoryUsesGitRepository import check +from checkov.arm.runner import Runner +from checkov.runner_filter import RunnerFilter + + +class TestDataFactoryUsesGitRepository(unittest.TestCase): + + def test_summary(self): + # given + test_files_dir = Path(__file__).parent / "example_DataFactoryUsesGitRepository" + + # when + report = Runner().run(root_folder=str(test_files_dir), runner_filter=RunnerFilter(checks=[check.id])) + + # then + summary = report.get_summary() + + passing_resources = { + "Microsoft.DataFactory/factories.pass", + } + failing_resources = { + "Microsoft.DataFactory/factories.fail", + "Microsoft.DataFactory/factories.fail2", + } + + passed_check_resources = {c.resource for c in report.passed_checks} + failed_check_resources = {c.resource for c in report.failed_checks} + + self.assertEqual(summary["passed"], len(passing_resources)) + self.assertEqual(summary["failed"], len(failing_resources)) + self.assertEqual(summary["skipped"], 0) + self.assertEqual(summary["parsing_errors"], 0) + + self.assertEqual(passing_resources, passed_check_resources) + self.assertEqual(failing_resources, failed_check_resources) + +