diff --git a/netbox_awx_plugin/signals.py b/netbox_awx_plugin/signals.py
index 90a3ddc591898164df0fee1920b70ff0d54e8f77..71e597fec08e0d033bb460fc513e9cc304a3c95f 100644
--- a/netbox_awx_plugin/signals.py
+++ b/netbox_awx_plugin/signals.py
@@ -3,6 +3,7 @@ from django.dispatch import receiver
 from django_rq import get_queue
 from dcim.models import Interface, Device, DeviceRole, DeviceType, Site
 from ipam.models import Prefix
+from virtualization.models import VirtualMachine
 from netbox.config import get_config
 from netbox.constants import RQ_QUEUE_DEFAULT
 from .models import AWXInventory
@@ -54,6 +55,7 @@ def save_group_instance(sender, instance, **kwargs):
 
 
 @receiver(post_save, sender=Device)
+@receiver(post_save, sender=VirtualMachine)
 def save_device(sender, instance, created, **kwargs):
     device = sender.objects.get(id=instance.id)
     if not device.primary_ip4 is None and device.primary_ip4.dns_name:
diff --git a/netbox_awx_plugin/synchronization.py b/netbox_awx_plugin/synchronization.py
index 685bbf03620906dd7e557badf165f90ad57d6108..e5114fdef8b5fbb8ab0b59bf0164f5a7082d9364 100644
--- a/netbox_awx_plugin/synchronization.py
+++ b/netbox_awx_plugin/synchronization.py
@@ -1,6 +1,8 @@
 from dcim.models import Device, DeviceRole, DeviceType, Site
 from ipam.models import Prefix
 from dcim.choices import DeviceStatusChoices
+from virtualization.choices import VirtualMachineStatusChoices
+from virtualization.models import VirtualMachine
 from rest_framework import serializers
 import json
 import logging
@@ -89,6 +91,39 @@ class DeviceSerializer(serializers.BaseSerializer):
         }
 
 
+class VMInterfaceSerializer(serializers.BaseSerializer):
+    def to_representation(self, instance):
+        ip_addresses = []
+        for ip in instance.ip_addresses.all():
+            serializer = IPAddressSerializer(ip)
+            ip_addresses.append(serializer.data)
+        return {
+            "name": instance.name,
+            "mac": instance.mac_address,
+            "ip_addresses": ip_addresses
+        }
+
+
+class VMSerializer(serializers.BaseSerializer):
+    def to_representation(self, instance):
+        variables = {
+            "netbox_virtualmachine_name": instance.name,
+            "netbox_virtualmachine_vcpus": float(instance.vcpus),
+            "netbox_virtualmachine_memory": instance.memory,
+            "netbox_virtualmachine_disk": instance.disk,
+        }
+        variables["netbox_interfaces"] = []
+        for interface in instance.interfaces.all():
+            serializer = VMInterfaceSerializer(interface)
+            variables["netbox_interfaces"].append(serializer.data)
+        return {
+            "name": instance.primary_ip4.dns_name,
+            "description": instance.description,
+            "enabled": instance.status == VirtualMachineStatusChoices.STATUS_ACTIVE,
+            "variables": json.dumps(variables),
+        }
+
+
 class AWXHostSerializer(serializers.BaseSerializer):
     def to_internal_value(self, data):
         return {
@@ -113,6 +148,7 @@ serializers = {
     DeviceType: DeviceTypeSerializer,
     Prefix: PrefixSerializer,
     Device: DeviceSerializer,
+    VirtualMachine: VMSerializer,
 }
 
 
@@ -127,9 +163,12 @@ def sync_host(inventory, sender, instance):
         if not host_serializer.is_valid() or host_serializer.validated_data != serializer.data:
             inventory.update_host(host["id"], serializer.data)
 
-    sync_host_group_association(inventory, host, DeviceRole, instance.device_role)
-    sync_host_group_association(inventory, host, DeviceType, instance.device_type)
-    sync_host_group_association(inventory, host, Site, instance.site)
+    if instance.site:
+        sync_host_group_association(inventory, host, Site, instance.site)
+    if instance.role:
+        sync_host_group_association(inventory, host, DeviceRole, instance.role)
+    if sender == Device:
+        sync_host_group_association(inventory, host, DeviceType, instance.device_type)
 
     # print(Prefix.objects.filter(prefix__net_contains_or_equals=device.primary_ip4.address))
 
@@ -188,4 +227,7 @@ def sync_all(job):
     for device in Device.objects.all():
         if not device.primary_ip4 is None and device.primary_ip4.dns_name:
             sync_host(inventory, Device, device)
+    for vm in VirtualMachine.objects.all():
+        if not vm.primary_ip4 is None and vm.primary_ip4.dns_name:
+            sync_host(inventory, VirtualMachine, vm)
     job.terminate()