Repository: clouditor/clouditor
Pull request #1144 (2023-06-27 09:22:53)

Extend discovery based on Medina issues
This PR updates/adds the following discovered resources properties:
- Update function runtime/version 
- Fix OsLoggingEnabled
- Add ActivityLoggingEnabled

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/clouditor/clouditor/pull/1144?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) Report
> Merging [#1144](https://app.codecov.io/gh/clouditor/clouditor/pull/1144?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (5c56b58) into [main](https://app.codecov.io/gh/clouditor/clouditor/commit/ee1af3e9a1644037595549572fde597598765c82?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (ee1af3e) will **decrease** coverage by `0.31%`.
> The diff coverage is `54.92%`.

```diff
@@            Coverage Diff             @@
##             main    #1144      +/-   ##
==========================================
- Coverage   84.32%   84.02%   -0.31%     
==========================================
  Files          93       93              
  Lines        8678     8730      +52     
==========================================
+ Hits         7318     7335      +17     
- Misses       1031     1063      +32     
- Partials      329      332       +3     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `84.02% <54.92%> (-0.31%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://app.codecov.io/gh/clouditor/clouditor/pull/1144?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) | Coverage Δ | |
|---|---|---|
| [service/discovery/azure/azure.go](https://app.codecov.io/gh/clouditor/clouditor/pull/1144?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXp1cmUvYXp1cmUuZ28=) | `86.50% <ø> (ø)` | |
| [service/discovery/azure/compute.go](https://app.codecov.io/gh/clouditor/clouditor/pull/1144?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXp1cmUvY29tcHV0ZS5nbw==) | `85.83% <54.92%> (-5.71%)` | :arrow_down: |

... and [1 file with indirect coverage changes](https://app.codecov.io/gh/clouditor/clouditor/pull/1144/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)



Patch:
diff --git a/api/orchestrator/orchestrator.pb.go b/api/orchestrator/orchestrator.pb.go
index 8d6a321b..6f287a6e 100644
--- a/api/orchestrator/orchestrator.pb.go
+++ b/api/orchestrator/orchestrator.pb.go
@@ -4449,7 +4449,7 @@ func (x *TargetOfEvaluationChangeEvent) GetControlInScope() *ControlInScope {
 	return nil
 }
 
-// As long as the repeating maps is not supported, we have to do this workaround.
+// As long as repeated maps are not supported, we have to do this workaround.
 type CloudService_Tag struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
diff --git a/go.mod b/go.mod
index 59f30461..4bf9b360 100644
--- a/go.mod
+++ b/go.mod
@@ -30,7 +30,7 @@ require (
 
 // runtime dependencies (Azure)
 require (
-	github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0
+	github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0-beta.2
 	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0
 	github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/appservice/armappservice/v2 v2.1.0
 	github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3 v3.0.0
@@ -174,6 +174,7 @@ require (
 )
 
 require (
+	github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.10.0
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
 	github.com/go-ini/ini v1.67.0 // indirect
diff --git a/go.sum b/go.sum
index 217b00dc..1cb135bc 100644
--- a/go.sum
+++ b/go.sum
@@ -41,6 +41,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 h1:8kDqDngH+DmVBiCtIjCFTGa7MBnsIOkF9IccInFEbjk=
 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0-beta.2 h1:C3zKsGguxcLd8a2uEytB8+TFtBGd75bXRxEs0QBwsv0=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0-beta.2/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg=
 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U=
 github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
@@ -53,6 +55,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3 v3.0
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dataprotection/armdataprotection v1.0.0 h1:VFqjVi532z3gdltbAkYrPl9Ez0czn3ZPM+bjmvLq6fk=
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dataprotection/armdataprotection v1.0.0/go.mod h1:CmZQSRwBPP7KNjDA+PHaoR2m8wgOsbTd9ncqZgSzgHA=
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.10.0 h1:dAPBLcjVx4qtf915ebQ10szmxqwqtlOxiQJEfjMllXs=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.10.0/go.mod h1:4hjzROcZTj3XS2sGdNOp5037ncCI+y+6kmXSRKIDvvg=
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0 h1:QM6sE5k2ZT/vI5BEe0r7mqjsUSnhVBFbOsVkEuaEfiA=
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0/go.mod h1:243D9iHbcQXoFUtgHJwL7gl2zx1aDuDMjvBZVGr2uW0=
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0 h1:ECsQtyERDVz3NP3kvDOTLvbQhqWp/x9EsGKtb4ogUr8=
diff --git a/openapi/orchestrator/openapi.yaml b/openapi/orchestrator/openapi.yaml
index b5146718..cf979686 100644
--- a/openapi/orchestrator/openapi.yaml
+++ b/openapi/orchestrator/openapi.yaml
@@ -1608,7 +1608,7 @@ components:
                     type: object
                     additionalProperties:
                         type: string
-            description: As long as the repeating maps is not supported, we have to do this workaround.
+            description: As long as repeated maps are not supported, we have to do this workaround.
         Control:
             type: object
             properties:
diff --git a/service/discovery/azure/azure.go b/service/discovery/azure/azure.go
index 2ba69bdc..ff80258a 100644
--- a/service/discovery/azure/azure.go
+++ b/service/discovery/azure/azure.go
@@ -66,6 +66,8 @@ const (
 
 	Duration30Days = time.Duration(30 * time.Hour * 24)
 	Duration7Days  = time.Duration(7 * time.Hour * 24)
+
+	RetentionPeriod90Days = 90
 )
 
 var (
@@ -140,7 +142,7 @@ type clients struct {
 	applicationGatewayClient *armnetwork.ApplicationGatewaysClient
 
 	// AppService
-	functionsClient *armappservice.WebAppsClient
+	sitesClient *armappservice.WebAppsClient
 
 	// Compute
 	virtualMachinesClient *armcompute.VirtualMachinesClient
diff --git a/service/discovery/azure/compute.go b/service/discovery/azure/compute.go
index e81322ad..42482407 100644
--- a/service/discovery/azure/compute.go
+++ b/service/discovery/azure/compute.go
@@ -123,41 +123,82 @@ func (d *azureComputeDiscovery) List() (list []voc.IsCloudResource, err error) {
 	}
 	list = append(list, virtualMachines...)
 
-	// Discover functions
-	function, err := d.discoverFunctions()
+	// Discover functions and web apps
+	resources, err := d.discoverFunctionsWebApps()
 	if err != nil {
 		return nil, fmt.Errorf("could not discover functions: %w", err)
 	}
-	list = append(list, function...)
+	// if resources != nil {
+	list = append(list, resources...)
+	// }
 
 	return
 }
 
-// Discover function
-func (d *azureComputeDiscovery) discoverFunctions() ([]voc.IsCloudResource, error) {
+// Discover functions and web apps
+func (d *azureComputeDiscovery) discoverFunctionsWebApps() ([]voc.IsCloudResource, error) {
 	var list []voc.IsCloudResource
 
 	// initialize functions client
-	if err := d.initFunctionsClient(); err != nil {
+	if err := d.initWebAppsClient(); err != nil {
 		return nil, err
 	}
 
 	// List functions
 	err := listPager(d.azureDiscovery,
-		d.clients.functionsClient.NewListPager,
-		d.clients.functionsClient.NewListByResourceGroupPager,
+		d.clients.sitesClient.NewListPager,
+		d.clients.sitesClient.NewListByResourceGroupPager,
 		func(res armappservice.WebAppsClientListResponse) []*armappservice.Site {
 			return res.Value
 		},
 		func(res armappservice.WebAppsClientListByResourceGroupResponse) []*armappservice.Site {
 			return res.Value
 		},
-		func(function *armappservice.Site) error {
-			r := d.handleFunction(function)
-
-			log.Infof("Adding function %+v", r)
+		func(site *armappservice.Site) error {
+			var r voc.IsCompute
+
+			// Check kind of site (see https://github.com/Azure/app-service-linux-docs/blob/master/Things_You_Should_Know/kind_property.md)
+			switch *site.Kind {
+			case "app": // Windows Web App
+				// TODO(all): TBD
+				log.Debug("Windows Web App currently not implemented.")
+			case "app,linux": // Linux Web app
+				// TODO(all): TBD
+				log.Debug("Linux Web App currently not implemented.")
+			case "app,linux,container": // Linux Container Web App
+				// TODO(all): TBD
+				log.Debug("Linux Container Web App Web App currently not implemented.")
+			case "hyperV": // Windows Container Web App
+				// TODO(all): TBD
+				log.Debug("Windows Container Web App currently not implemented.")
+			case "app,container,windows": // Windows Container Web App
+				// TODO(all): TBD
+				log.Debug("Windows Web App currently not implemented.")
+			case "app,linux,kubernetes": // Linux Web App on ARC
+				// TODO(all): TBD
+				log.Debug("Linux Web App on ARC currently not implemented.")
+			case "app,linux,container,kubernetes": // Linux Container Web App on ARC
+				// TODO(all): TBD
+				log.Debug("Linux Container Web App on ARC currently not implemented.")
+			case "functionapp": // Function Code App
+				r = d.handleFunction(site)
+			case "functionapp,linux": // Linux Consumption Function app
+				log.Debug("Windows Web App currently not implemented.")
+				r = d.handleFunction(site)
+			case "functionapp,linux,container,kubernetes": // Function Container App on ARC
+				// TODO(all): TBD
+				log.Debug("Function Container App on ARC currently not implemented.")
+			case "functionapp,linux,kubernetes": // Function Code App on ARC
+				// TODO(all): TBD
+				log.Debug("Function Code App on ARC currently not implemented.")
+			default:
+				log.Debugf("%s currently not supported.", *site.Kind)
+			}
 
-			list = append(list, r)
+			if r != nil {
+				log.Infof("Adding function %+v", r)
+				list = append(list, r)
+			}
 
 			return nil
 		})
@@ -169,12 +210,51 @@ func (d *azureComputeDiscovery) discoverFunctions() ([]voc.IsCloudResource, erro
 }
 
 func (d *azureComputeDiscovery) handleFunction(function *armappservice.Site) voc.IsCompute {
+	var (
+		runtimeLanguage string
+		runtimeVersion  string
+		config          armappservice.WebAppsClientGetConfigurationResponse
+		err             error
+	)
+
 	// If a mandatory field is empty, the whole function is empty
-	if function == nil || function.ID == nil {
+	if function == nil {
 		return nil
 	}
 
-	runtimeLanguage, runtimeVersion := runtimeInfo(*function.Properties.SiteConfig.LinuxFxVersion)
+	if *function.Kind == "functionapp,linux" { // Linux function
+		runtimeLanguage, runtimeVersion = runtimeInfo(*function.Properties.SiteConfig.LinuxFxVersion)
+	} else if *function.Kind == "functionapp" { // Windows function, we need to get also the config information
+		// Get site config
+		config, err = d.clients.sitesClient.GetConfiguration(context.Background(), *function.Properties.ResourceGroup, *function.Name, &armappservice.WebAppsClientGetConfigurationOptions{})
+		if err != nil {
+			log.Errorf("error getting site config: %v", err)
+		}
+
+		// Check all runtime versions to get the used runtime language and runtime version
+		if config.Properties.JavaVersion != nil {
+			runtimeLanguage = "Java"
+			runtimeVersion = *config.Properties.JavaVersion
+		} else if config.Properties.NodeVersion != nil {
+			runtimeLanguage = "Node.js"
+			runtimeVersion = *config.Properties.NodeVersion
+		} else if config.Properties.PowerShellVersion != nil {
+			runtimeLanguage = "PowerShell"
+			runtimeVersion = *config.Properties.PowerShellVersion
+		} else if config.Properties.PhpVersion != nil {
+			runtimeLanguage = "PHP"
+			runtimeVersion = *config.Properties.PhpVersion
+		} else if config.Properties.PythonVersion != nil {
+			runtimeLanguage = "Python"
+			runtimeVersion = *config.Properties.PythonVersion
+		} else if config.Properties.JavaContainer != nil {
+			runtimeLanguage = "JavaContainer"
+			runtimeVersion = *config.Properties.JavaContainer
+		} else if config.Properties.NetFrameworkVersion != nil {
+			runtimeLanguage = ".NET"
+			runtimeVersion = *config.Properties.NetFrameworkVersion
+		}
+	}
 
 	return &voc.Function{
 		Compute: &voc.Compute{
@@ -189,6 +269,7 @@ func (d *azureComputeDiscovery) handleFunction(function *armappservice.Site) voc
 				labels(function.Tags),
 				voc.FunctionType,
 				function,
+				config,
 			),
 			NetworkInterfaces: []voc.ResourceID{},
 		},
@@ -250,7 +331,7 @@ func (d *azureComputeDiscovery) discoverVirtualMachines() ([]voc.IsCloudResource
 func (d *azureComputeDiscovery) handleVirtualMachines(vm *armcompute.VirtualMachine) (voc.IsCompute, error) {
 	var (
 		bootLogging              = []voc.ResourceID{}
-		osLogging                = []voc.ResourceID{}
+		osLoggingEnabled         bool
 		autoUpdates              *voc.AutomaticUpdates
 		monitoringLogDataEnabled bool
 		securityAlertsEnabled    bool
@@ -272,6 +353,18 @@ func (d *azureComputeDiscovery) handleVirtualMachines(vm *armcompute.VirtualMach
 		securityAlertsEnabled = d.defenderProperties[DefenderVirtualMachineType].securityAlertsEnabled
 	}
 
+	// Check extensions
+	for _, extension := range vm.Resources {
+		// Azure Monitor Agent (AMA) collects monitoring data from the guest operating system of Azure and hybrid virtual machines and delivers it to Azure Monitor for use (https://learn.microsoft.com/en-us/azure/azure-monitor/agents/agents-overview). The extension names are
+		// * OMSAgentForLinux for Linux VMs and (legacy agent)
+		// * MicrosoftMonitoringAgent for Windows VMs (legacy agent)
+		// * AzureMonitoringWindowsAgent (new agent)
+		// * AzureMonitoringLinuxAgent (new agent)
+		if strings.Contains(*extension.ID, "OmsAgentForLinux") || strings.Contains(*extension.ID, "MicrosoftMonitoringAgent") || strings.Contains(*extension.ID, "AzureMonitoringWindowsAgent") || strings.Contains(*extension.ID, "AzureMonitoringLinuxAgent") {
+			osLoggingEnabled = true
+		}
+	}
+
 	r := &voc.VirtualMachine{
 		Compute: &voc.Compute{
 			Resource: discovery.NewResource(d,
@@ -303,9 +396,9 @@ func (d *azureComputeDiscovery) handleVirtualMachines(vm *armcompute.VirtualMach
 		},
 		OsLogging: &voc.OSLogging{
 			Logging: &voc.Logging{
-				Enabled:         false,
+				Enabled:         osLoggingEnabled,
 				RetentionPeriod: 0,
-				LoggingService:  osLogging,
+				LoggingService:  []voc.ResourceID{}, // TODO(all): TBD
 				Auditing: &voc.Auditing{
 					SecurityFeature: &voc.SecurityFeature{},
 				},
@@ -313,6 +406,13 @@ func (d *azureComputeDiscovery) handleVirtualMachines(vm *armcompute.VirtualMach
 				SecurityAlertsEnabled:    monitoringLogDataEnabled,
 			},
 		},
+		ActivityLogging: &voc.ActivityLogging{
+			Logging: &voc.Logging{
+				Enabled:         true, // is always enabled
+				RetentionPeriod: RetentionPeriod90Days,
+				LoggingService:  []voc.ResourceID{}, // TODO(all): TBD
+			},
+		},
 		AutomaticUpdates: autoUpdates,
 	}
 
@@ -534,9 +634,9 @@ func (d *azureComputeDiscovery) keyURL(diskEncryptionSetID string) (string, *arm
 	return util.Deref(keyURL), &kv.DiskEncryptionSet, nil
 }
 
-// initFunctionsClient creates the client if not already exists
-func (d *azureComputeDiscovery) initFunctionsClient() (err error) {
-	d.clients.functionsClient, err = initClient(d.clients.functionsClient, d.azureDiscovery, armappservice.NewWebAppsClient)
+// initWebAppsClient creates the client if not already exists
+func (d *azureComputeDiscovery) initWebAppsClient() (err error) {
+	d.clients.sitesClient, err = initClient(d.clients.sitesClient, d.azureDiscovery, armappservice.NewWebAppsClient)
 	return
 }
 
diff --git a/voc/virtual_machine.go b/voc/virtual_machine.go
index 4e6e68d3..d38d4c52 100644
--- a/voc/virtual_machine.go
+++ b/voc/virtual_machine.go
@@ -36,4 +36,5 @@ type VirtualMachine struct {
 	BootLogging       *BootLogging       `json:"bootLogging"`
 	MalwareProtection *MalwareProtection `json:"malwareProtection"`
 	OsLogging         *OSLogging         `json:"osLogging"`
+	ActivityLogging   *ActivityLogging   `json:"activityLogging"`
 }


Test patch:
diff --git a/service/discovery/azure/compute_test.go b/service/discovery/azure/compute_test.go
index bbfe378d..bd26979a 100644
--- a/service/discovery/azure/compute_test.go
+++ b/service/discovery/azure/compute_test.go
@@ -112,6 +112,11 @@ func (m mockComputeSender) Do(req *http.Request) (res *http.Response, err error)
 							},
 						},
 					},
+					"resources": &[]map[string]interface{}{
+						{
+							"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm1/extensions/MicrosoftMonitoringAgent",
+						},
+					},
 				},
 				{
 					"id":       "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm2",
@@ -161,6 +166,11 @@ func (m mockComputeSender) Do(req *http.Request) (res *http.Response, err error)
 							},
 						},
 					},
+					"resources": &[]map[string]interface{}{
+						{
+							"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm2/extensions/OmsAgentForLinux",
+						},
+					},
 				},
 				{
 					"id":       "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm3",
@@ -251,6 +261,7 @@ func (m mockComputeSender) Do(req *http.Request) (res *http.Response, err error)
 					"id":       "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function1",
 					"name":     "function1",
 					"location": "West Europe",
+					"kind":     "functionapp,linux",
 					"tags": map[string]interface{}{
 						"testKey1": "testTag1",
 						"testKey2": "testTag2",
@@ -261,6 +272,26 @@ func (m mockComputeSender) Do(req *http.Request) (res *http.Response, err error)
 						},
 					},
 				},
+				{
+					"id":       "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function2",
+					"name":     "function2",
+					"location": "West Europe",
+					"kind":     "functionapp",
+					"tags": map[string]interface{}{
+						"testKey1": "testTag1",
+						"testKey2": "testTag2",
+					},
+					"properties": map[string]interface{}{
+						"siteConfig":    map[string]interface{}{},
+						"resourceGroup": "res1",
+					},
+				},
+			},
+		}, 200)
+	} else if req.URL.Path == "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function2/config/web" {
+		return createResponse(req, map[string]interface{}{
+			"properties": map[string]interface{}{
+				"javaVersion": "1.8",
 			},
 		}, 200)
 	} else if req.URL.Path == "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/diskEncryptionSets/encryptionkeyvault1" {
@@ -450,7 +481,7 @@ func TestCompute(t *testing.T) {
 
 	assert.NoError(t, err)
 	assert.NotNil(t, list)
-	assert.Equal(t, 8, len(list))
+	assert.Equal(t, 9, len(list))
 	assert.NotEmpty(t, d.Name())
 }
 
@@ -499,7 +530,7 @@ func TestFunction(t *testing.T) {
 
 	assert.NoError(t, err)
 	assert.NotNil(t, list)
-	assert.Equal(t, 8, len(list))
+	assert.Equal(t, 9, len(list))
 
 	function, ok := list[7].(*voc.Function)
 
@@ -510,7 +541,7 @@ func TestFunction(t *testing.T) {
 func TestComputeDiscoverFunctionsWhenInputIsInvalid(t *testing.T) {
 	d := azureComputeDiscovery{azureDiscovery: &azureDiscovery{}}
 
-	discoverFunctionsResponse, err := d.discoverFunctions()
+	discoverFunctionsResponse, err := d.discoverFunctionsWebApps()
 
 	assert.ErrorContains(t, err, ErrGettingNextPage.Error())
 	assert.Nil(t, discoverFunctionsResponse)
@@ -727,7 +758,7 @@ func Test_azureComputeDiscovery_List(t *testing.T) {
 							GeoLocation: voc.GeoLocation{
 								Region: "eastus",
 							},
-							Raw: "{\"*armcompute.VirtualMachine\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm1\",\"location\":\"eastus\",\"name\":\"vm1\",\"properties\":{\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true,\"storageUri\":\"https://logstoragevm1.blob.core.windows.net/\"}},\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"123\"},{\"id\":\"234\"}]},\"osProfile\":{\"linuxConfiguration\":{\"patchSettings\":{\"patchMode\":\"AutomaticByPlatform\"}}},\"storageProfile\":{\"dataDisks\":[{\"managedDisk\":{\"id\":\"data_disk_1\"}},{\"managedDisk\":{\"id\":\"data_disk_2\"}}],\"osDisk\":{\"managedDisk\":{\"id\":\"os_test_disk\"}}},\"timeCreated\":\"2017-05-24T13:28:53.4540398Z\"}}]}",
+							Raw: "{\"*armcompute.VirtualMachine\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm1\",\"location\":\"eastus\",\"name\":\"vm1\",\"properties\":{\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true,\"storageUri\":\"https://logstoragevm1.blob.core.windows.net/\"}},\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"123\"},{\"id\":\"234\"}]},\"osProfile\":{\"linuxConfiguration\":{\"patchSettings\":{\"patchMode\":\"AutomaticByPlatform\"}}},\"storageProfile\":{\"dataDisks\":[{\"managedDisk\":{\"id\":\"data_disk_1\"}},{\"managedDisk\":{\"id\":\"data_disk_2\"}}],\"osDisk\":{\"managedDisk\":{\"id\":\"os_test_disk\"}}},\"timeCreated\":\"2017-05-24T13:28:53.4540398Z\"},\"resources\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm1/extensions/MicrosoftMonitoringAgent\"}]}]}",
 						},
 						NetworkInterfaces: []voc.ResourceID{"123", "234"},
 					},
@@ -744,7 +775,7 @@ func Test_azureComputeDiscovery_List(t *testing.T) {
 					},
 					OsLogging: &voc.OSLogging{
 						Logging: &voc.Logging{
-							Enabled:         false,
+							Enabled:         true,
 							LoggingService:  []voc.ResourceID{},
 							RetentionPeriod: 0,
 							Auditing: &voc.Auditing{
@@ -757,6 +788,13 @@ func Test_azureComputeDiscovery_List(t *testing.T) {
 						Interval: Duration30Days,
 					},
 					MalwareProtection: &voc.MalwareProtection{},
+					ActivityLogging: &voc.ActivityLogging{
+						Logging: &voc.Logging{
+							Enabled:         true,
+							RetentionPeriod: RetentionPeriod90Days,
+							LoggingService:  []voc.ResourceID{},
+						},
+					},
 				},
 				&voc.VirtualMachine{
 					Compute: &voc.Compute{
@@ -770,7 +808,7 @@ func Test_azureComputeDiscovery_List(t *testing.T) {
 							GeoLocation: voc.GeoLocation{
 								Region: "eastus",
 							},
-							Raw: "{\"*armcompute.VirtualMachine\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm2\",\"location\":\"eastus\",\"name\":\"vm2\",\"properties\":{\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true}},\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"987\"},{\"id\":\"654\"}]},\"osProfile\":{\"windowsConfiguration\":{\"patchSettings\":{\"patchMode\":\"AutomaticByOS\"}}},\"storageProfile\":{\"dataDisks\":[{\"managedDisk\":{\"id\":\"data_disk_2\"}},{\"managedDisk\":{\"id\":\"data_disk_3\"}}],\"osDisk\":{\"managedDisk\":{\"id\":\"os_test_disk\"}}}}}]}",
+							Raw: "{\"*armcompute.VirtualMachine\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm2\",\"location\":\"eastus\",\"name\":\"vm2\",\"properties\":{\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true}},\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"987\"},{\"id\":\"654\"}]},\"osProfile\":{\"windowsConfiguration\":{\"patchSettings\":{\"patchMode\":\"AutomaticByOS\"}}},\"storageProfile\":{\"dataDisks\":[{\"managedDisk\":{\"id\":\"data_disk_2\"}},{\"managedDisk\":{\"id\":\"data_disk_3\"}}],\"osDisk\":{\"managedDisk\":{\"id\":\"os_test_disk\"}}}},\"resources\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm2/extensions/OmsAgentForLinux\"}]}]}",
 						},
 						NetworkInterfaces: []voc.ResourceID{"987", "654"},
 					},
@@ -787,7 +825,7 @@ func Test_azureComputeDiscovery_List(t *testing.T) {
 					},
 					OsLogging: &voc.OSLogging{
 						Logging: &voc.Logging{
-							Enabled:         false,
+							Enabled:         true,
 							LoggingService:  []voc.ResourceID{},
 							RetentionPeriod: 0,
 							Auditing: &voc.Auditing{
@@ -800,6 +838,13 @@ func Test_azureComputeDiscovery_List(t *testing.T) {
 						Interval: Duration30Days,
 					},
 					MalwareProtection: &voc.MalwareProtection{},
+					ActivityLogging: &voc.ActivityLogging{
+						Logging: &voc.Logging{
+							Enabled:         true,
+							RetentionPeriod: RetentionPeriod90Days,
+							LoggingService:  []voc.ResourceID{},
+						},
+					},
 				},
 				&voc.VirtualMachine{
 					Compute: &voc.Compute{
@@ -843,6 +888,13 @@ func Test_azureComputeDiscovery_List(t *testing.T) {
 						Interval: time.Duration(0),
 					},
 					MalwareProtection: &voc.MalwareProtection{},
+					ActivityLogging: &voc.ActivityLogging{
+						Logging: &voc.Logging{
+							Enabled:         true,
+							RetentionPeriod: RetentionPeriod90Days,
+							LoggingService:  []voc.ResourceID{},
+						},
+					},
 				},
 				&voc.Function{
 					Compute: &voc.Compute{
@@ -859,7 +911,7 @@ func Test_azureComputeDiscovery_List(t *testing.T) {
 							GeoLocation: voc.GeoLocation{
 								Region: "West Europe",
 							},
-							Raw: "{\"*armappservice.Site\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function1\",\"location\":\"West Europe\",\"name\":\"function1\",\"properties\":{\"siteConfig\":{\"linuxFxVersion\":\"PYTHON|3.8\"}},\"tags\":{\"testKey1\":\"testTag1\",\"testKey2\":\"testTag2\"}}]}",
+							Raw: "{\"*armappservice.Site\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function1\",\"kind\":\"functionapp,linux\",\"location\":\"West Europe\",\"name\":\"function1\",\"properties\":{\"siteConfig\":{\"linuxFxVersion\":\"PYTHON|3.8\"}},\"tags\":{\"testKey1\":\"testTag1\",\"testKey2\":\"testTag2\"}}],\"armappservice.WebAppsClientGetConfigurationResponse\":[{}]}",
 						},
 						NetworkInterfaces: []voc.ResourceID{},
 					},
@@ -867,6 +919,29 @@ func Test_azureComputeDiscovery_List(t *testing.T) {
 					RuntimeVersion:  "3.8",
 					RuntimeLanguage: "PYTHON",
 				},
+				&voc.Function{
+					Compute: &voc.Compute{
+						Resource: &voc.Resource{
+							ID:           "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function2",
+							ServiceID:    testdata.MockCloudServiceID1,
+							Name:         "function2",
+							CreationTime: util.SafeTimestamp(&time.Time{}),
+							Type:         voc.FunctionType,
+							Labels: map[string]string{
+								"testKey1": "testTag1",
+								"testKey2": "testTag2",
+							},
+							GeoLocation: voc.GeoLocation{
+								Region: "West Europe",
+							},
+							Raw: "{\"*armappservice.Site\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function2\",\"kind\":\"functionapp\",\"location\":\"West Europe\",\"name\":\"function2\",\"properties\":{\"resourceGroup\":\"res1\",\"siteConfig\":{}},\"tags\":{\"testKey1\":\"testTag1\",\"testKey2\":\"testTag2\"}}],\"armappservice.WebAppsClientGetConfigurationResponse\":[{\"properties\":{\"javaVersion\":\"1.8\"}}]}",
+						},
+						NetworkInterfaces: []voc.ResourceID{},
+					},
+
+					RuntimeVersion:  "1.8",
+					RuntimeLanguage: "Java",
+				},
 			},
 			wantErr: assert.NoError,
 		},
@@ -941,7 +1016,7 @@ func Test_azureComputeDiscovery_discoverFunctions(t *testing.T) {
 			},
 		},
 		{
-			name: "No error",
+			name: "Happy path",
 			fields: fields{
 				azureDiscovery: NewMockAzureDiscovery(newMockComputeSender()),
 			},
@@ -962,13 +1037,35 @@ func Test_azureComputeDiscovery_discoverFunctions(t *testing.T) {
 							GeoLocation: voc.GeoLocation{
 								Region: "West Europe",
 							},
-							Raw: "{\"*armappservice.Site\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function1\",\"location\":\"West Europe\",\"name\":\"function1\",\"properties\":{\"siteConfig\":{\"linuxFxVersion\":\"PYTHON|3.8\"}},\"tags\":{\"testKey1\":\"testTag1\",\"testKey2\":\"testTag2\"}}]}",
+							Raw: "{\"*armappservice.Site\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function1\",\"kind\":\"functionapp,linux\",\"location\":\"West Europe\",\"name\":\"function1\",\"properties\":{\"siteConfig\":{\"linuxFxVersion\":\"PYTHON|3.8\"}},\"tags\":{\"testKey1\":\"testTag1\",\"testKey2\":\"testTag2\"}}],\"armappservice.WebAppsClientGetConfigurationResponse\":[{}]}",
 						},
 						NetworkInterfaces: []voc.ResourceID{},
 					},
 					RuntimeVersion:  "3.8",
 					RuntimeLanguage: "PYTHON",
 				},
+				&voc.Function{
+					Compute: &voc.Compute{
+						Resource: &voc.Resource{
+							ID:           "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function2",
+							ServiceID:    testdata.MockCloudServiceID1,
+							Name:         "function2",
+							CreationTime: util.SafeTimestamp(&time.Time{}),
+							Type:         []string{"Function", "Compute", "Resource"},
+							Labels: map[string]string{
+								"testKey1": "testTag1",
+								"testKey2": "testTag2",
+							},
+							GeoLocation: voc.GeoLocation{
+								Region: "West Europe",
+							},
+							Raw: "{\"*armappservice.Site\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function2\",\"kind\":\"functionapp\",\"location\":\"West Europe\",\"name\":\"function2\",\"properties\":{\"resourceGroup\":\"res1\",\"siteConfig\":{}},\"tags\":{\"testKey1\":\"testTag1\",\"testKey2\":\"testTag2\"}}],\"armappservice.WebAppsClientGetConfigurationResponse\":[{\"properties\":{\"javaVersion\":\"1.8\"}}]}",
+						},
+						NetworkInterfaces: []voc.ResourceID{},
+					},
+					RuntimeVersion:  "1.8",
+					RuntimeLanguage: "Java",
+				},
 			},
 			wantErr: assert.NoError,
 		},
@@ -978,7 +1075,7 @@ func Test_azureComputeDiscovery_discoverFunctions(t *testing.T) {
 			d := &azureComputeDiscovery{
 				azureDiscovery: tt.fields.azureDiscovery,
 			}
-			got, err := d.discoverFunctions()
+			got, err := d.discoverFunctionsWebApps()
 			if !tt.wantErr(t, err) {
 				return
 			}
@@ -988,14 +1085,13 @@ func Test_azureComputeDiscovery_discoverFunctions(t *testing.T) {
 }
 
 func Test_azureComputeDiscovery_handleFunction(t *testing.T) {
-	functionID := "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function1"
-	functionName := "function1"
 	diskRegion := "West Europe"
 	testTag1 := "testTag1"
 	testTag2 := "testTag2"
 
 	type fields struct {
 		azureDiscovery *azureDiscovery
+		clientWebApps  bool
 	}
 	type args struct {
 		function *armappservice.Site
@@ -1014,28 +1110,20 @@ func Test_azureComputeDiscovery_handleFunction(t *testing.T) {
 			want: nil,
 		},
 		{
-			name: "Empty functionID",
-			args: args{
-				function: &armappservice.Site{
-					ID: nil,
-				},
-			},
-			want: nil,
-		},
-		{
-			name: "No error",
+			name: "Happy path: Linux function",
 			fields: fields{
 				azureDiscovery: NewMockAzureDiscovery(newMockComputeSender()),
 			},
 			args: args{
 				function: &armappservice.Site{
-					ID:       &functionID,
-					Name:     &functionName,
+					ID:       util.Ref("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function1"),
+					Name:     util.Ref("function1"),
 					Location: &diskRegion,
 					Tags: map[string]*string{
 						"testKey1": &testTag1,
 						"testKey2": &testTag2,
 					},
+					Kind: util.Ref("functionapp,linux"),
 					Properties: &armappservice.SiteProperties{
 						SiteConfig: &armappservice.SiteConfig{
 							LinuxFxVersion: util.Ref("PYTHON|3.8"),
@@ -1058,7 +1146,7 @@ func Test_azureComputeDiscovery_handleFunction(t *testing.T) {
 						GeoLocation: voc.GeoLocation{
 							Region: "West Europe",
 						},
-						Raw: "{\"*armappservice.Site\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function1\",\"location\":\"West Europe\",\"name\":\"function1\",\"properties\":{\"siteConfig\":{\"linuxFxVersion\":\"PYTHON|3.8\"}},\"tags\":{\"testKey1\":\"testTag1\",\"testKey2\":\"testTag2\"}}]}",
+						Raw: "{\"*armappservice.Site\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function1\",\"kind\":\"functionapp,linux\",\"location\":\"West Europe\",\"name\":\"function1\",\"properties\":{\"siteConfig\":{\"linuxFxVersion\":\"PYTHON|3.8\"}},\"tags\":{\"testKey1\":\"testTag1\",\"testKey2\":\"testTag2\"}}],\"armappservice.WebAppsClientGetConfigurationResponse\":[{}]}",
 					},
 					NetworkInterfaces: []voc.ResourceID{},
 				},
@@ -1066,12 +1154,63 @@ func Test_azureComputeDiscovery_handleFunction(t *testing.T) {
 				RuntimeLanguage: "PYTHON",
 			},
 		},
+		{
+			name: "Happy path: Windows function",
+			fields: fields{
+				azureDiscovery: NewMockAzureDiscovery(newMockComputeSender()),
+				clientWebApps:  true,
+			},
+			args: args{
+				function: &armappservice.Site{
+					ID:       util.Ref("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function2"),
+					Name:     util.Ref("function2"),
+					Location: &diskRegion,
+					Tags: map[string]*string{
+						"testKey1": &testTag1,
+						"testKey2": &testTag2,
+					},
+					Kind: util.Ref("functionapp"),
+					Properties: &armappservice.SiteProperties{
+						SiteConfig:    &armappservice.SiteConfig{},
+						ResourceGroup: util.Ref("res1"),
+					},
+				},
+			},
+			want: &voc.Function{
+				Compute: &voc.Compute{
+					Resource: &voc.Resource{
+						ID:           "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function2",
+						ServiceID:    testdata.MockCloudServiceID1,
+						Name:         "function2",
+						CreationTime: util.SafeTimestamp(&time.Time{}),
+						Type:         []string{"Function", "Compute", "Resource"},
+						Labels: map[string]string{
+							"testKey1": testTag1,
+							"testKey2": testTag2,
+						},
+						GeoLocation: voc.GeoLocation{
+							Region: "West Europe",
+						},
+						Raw: "{\"*armappservice.Site\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Web/sites/function2\",\"kind\":\"functionapp\",\"location\":\"West Europe\",\"name\":\"function2\",\"properties\":{\"resourceGroup\":\"res1\",\"siteConfig\":{}},\"tags\":{\"testKey1\":\"testTag1\",\"testKey2\":\"testTag2\"}}],\"armappservice.WebAppsClientGetConfigurationResponse\":[{\"properties\":{\"javaVersion\":\"1.8\"}}]}",
+					},
+					NetworkInterfaces: []voc.ResourceID{},
+				},
+				RuntimeVersion:  "1.8",
+				RuntimeLanguage: "Java",
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			az := &azureComputeDiscovery{
 				azureDiscovery: tt.fields.azureDiscovery,
 			}
+			// Set clients if needed
+			if tt.fields.clientWebApps {
+				// initialize backup vaults client
+				_ = az.initWebAppsClient()
+			}
+
 			assert.Equalf(t, tt.want, az.handleFunction(tt.args.function), "handleFunction(%v)", tt.args.function)
 		})
 	}
@@ -1117,7 +1256,7 @@ func Test_azureComputeDiscovery_discoverVirtualMachines(t *testing.T) {
 							GeoLocation: voc.GeoLocation{
 								Region: "eastus",
 							},
-							Raw: "{\"*armcompute.VirtualMachine\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm1\",\"location\":\"eastus\",\"name\":\"vm1\",\"properties\":{\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true,\"storageUri\":\"https://logstoragevm1.blob.core.windows.net/\"}},\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"123\"},{\"id\":\"234\"}]},\"osProfile\":{\"linuxConfiguration\":{\"patchSettings\":{\"patchMode\":\"AutomaticByPlatform\"}}},\"storageProfile\":{\"dataDisks\":[{\"managedDisk\":{\"id\":\"data_disk_1\"}},{\"managedDisk\":{\"id\":\"data_disk_2\"}}],\"osDisk\":{\"managedDisk\":{\"id\":\"os_test_disk\"}}},\"timeCreated\":\"2017-05-24T13:28:53.4540398Z\"}}]}",
+							Raw: "{\"*armcompute.VirtualMachine\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm1\",\"location\":\"eastus\",\"name\":\"vm1\",\"properties\":{\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true,\"storageUri\":\"https://logstoragevm1.blob.core.windows.net/\"}},\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"123\"},{\"id\":\"234\"}]},\"osProfile\":{\"linuxConfiguration\":{\"patchSettings\":{\"patchMode\":\"AutomaticByPlatform\"}}},\"storageProfile\":{\"dataDisks\":[{\"managedDisk\":{\"id\":\"data_disk_1\"}},{\"managedDisk\":{\"id\":\"data_disk_2\"}}],\"osDisk\":{\"managedDisk\":{\"id\":\"os_test_disk\"}}},\"timeCreated\":\"2017-05-24T13:28:53.4540398Z\"},\"resources\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm1/extensions/MicrosoftMonitoringAgent\"}]}]}",
 						},
 						NetworkInterfaces: []voc.ResourceID{"123", "234"},
 					},
@@ -1134,7 +1273,7 @@ func Test_azureComputeDiscovery_discoverVirtualMachines(t *testing.T) {
 					},
 					OsLogging: &voc.OSLogging{
 						Logging: &voc.Logging{
-							Enabled:         false,
+							Enabled:         true,
 							LoggingService:  []voc.ResourceID{},
 							RetentionPeriod: 0,
 							Auditing: &voc.Auditing{
@@ -1147,6 +1286,13 @@ func Test_azureComputeDiscovery_discoverVirtualMachines(t *testing.T) {
 						Interval: Duration30Days,
 					},
 					MalwareProtection: &voc.MalwareProtection{},
+					ActivityLogging: &voc.ActivityLogging{
+						Logging: &voc.Logging{
+							Enabled:         true,
+							RetentionPeriod: RetentionPeriod90Days,
+							LoggingService:  []voc.ResourceID{},
+						},
+					},
 				},
 				&voc.VirtualMachine{
 					Compute: &voc.Compute{
@@ -1160,7 +1306,7 @@ func Test_azureComputeDiscovery_discoverVirtualMachines(t *testing.T) {
 							GeoLocation: voc.GeoLocation{
 								Region: "eastus",
 							},
-							Raw: "{\"*armcompute.VirtualMachine\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm2\",\"location\":\"eastus\",\"name\":\"vm2\",\"properties\":{\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true}},\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"987\"},{\"id\":\"654\"}]},\"osProfile\":{\"windowsConfiguration\":{\"patchSettings\":{\"patchMode\":\"AutomaticByOS\"}}},\"storageProfile\":{\"dataDisks\":[{\"managedDisk\":{\"id\":\"data_disk_2\"}},{\"managedDisk\":{\"id\":\"data_disk_3\"}}],\"osDisk\":{\"managedDisk\":{\"id\":\"os_test_disk\"}}}}}]}",
+							Raw: "{\"*armcompute.VirtualMachine\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm2\",\"location\":\"eastus\",\"name\":\"vm2\",\"properties\":{\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true}},\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"987\"},{\"id\":\"654\"}]},\"osProfile\":{\"windowsConfiguration\":{\"patchSettings\":{\"patchMode\":\"AutomaticByOS\"}}},\"storageProfile\":{\"dataDisks\":[{\"managedDisk\":{\"id\":\"data_disk_2\"}},{\"managedDisk\":{\"id\":\"data_disk_3\"}}],\"osDisk\":{\"managedDisk\":{\"id\":\"os_test_disk\"}}}},\"resources\":[{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm2/extensions/OmsAgentForLinux\"}]}]}",
 						},
 						NetworkInterfaces: []voc.ResourceID{"987", "654"},
 					},
@@ -1177,7 +1323,7 @@ func Test_azureComputeDiscovery_discoverVirtualMachines(t *testing.T) {
 					},
 					OsLogging: &voc.OSLogging{
 						Logging: &voc.Logging{
-							Enabled:         false,
+							Enabled:         true,
 							LoggingService:  []voc.ResourceID{},
 							RetentionPeriod: 0,
 							Auditing: &voc.Auditing{
@@ -1190,6 +1336,13 @@ func Test_azureComputeDiscovery_discoverVirtualMachines(t *testing.T) {
 						Interval: Duration30Days,
 					},
 					MalwareProtection: &voc.MalwareProtection{},
+					ActivityLogging: &voc.ActivityLogging{
+						Logging: &voc.Logging{
+							Enabled:         true,
+							RetentionPeriod: RetentionPeriod90Days,
+							LoggingService:  []voc.ResourceID{},
+						},
+					},
 				},
 				&voc.VirtualMachine{
 					Compute: &voc.Compute{
@@ -1233,6 +1386,13 @@ func Test_azureComputeDiscovery_discoverVirtualMachines(t *testing.T) {
 						Interval: time.Duration(0),
 					},
 					MalwareProtection: &voc.MalwareProtection{},
+					ActivityLogging: &voc.ActivityLogging{
+						Logging: &voc.Logging{
+							Enabled:         true,
+							RetentionPeriod: RetentionPeriod90Days,
+							LoggingService:  []voc.ResourceID{},
+						},
+					},
 				},
 			},
 			wantErr: assert.NoError,
@@ -1390,6 +1550,13 @@ func Test_azureComputeDiscovery_handleVirtualMachines(t *testing.T) {
 					Interval: time.Duration(0),
 				},
 				MalwareProtection: &voc.MalwareProtection{},
+				ActivityLogging: &voc.ActivityLogging{
+					Logging: &voc.Logging{
+						Enabled:         true,
+						RetentionPeriod: RetentionPeriod90Days,
+						LoggingService:  []voc.ResourceID{},
+					},
+				},
 			},
 			wantErr: assert.NoError,
 		},