diff --git a/controllers/drupalsite_controller_test.go b/controllers/drupalsite_controller_test.go
index 8028d3818a52ca15ee49347f060cf7ee4c660937..21f1dc7803d553a539cb17034f97f8fbb17eec6c 100644
--- a/controllers/drupalsite_controller_test.go
+++ b/controllers/drupalsite_controller_test.go
@@ -240,18 +240,204 @@ var _ = Describe("DrupalSite controller", func() {
 
 				// Check if the Schedule resource is created
 				By("Expecting Schedule to be created")
+				Eventually(func() error {
+					return k8sClient.Get(ctx, types.NamespacedName{Name: generateScheduleName(key.Namespace, key.Name), Namespace: veleroNamespace}, &schedule)
+				}, timeout, interval).Should(Succeed())
+
+				// Check Routes
+				By("Expecting Drupal Route(s) to be created")
+				for _, url := range cr.Spec.SiteURL {
+					route = routev1.Route{}
+					hash := md5.Sum([]byte(url))
+					Eventually(func() []metav1.OwnerReference {
+						k8sClient.Get(ctx, types.NamespacedName{Name: key.Name + "-" + hex.EncodeToString(hash[0:4]), Namespace: key.Namespace}, &route)
+						return route.ObjectMeta.OwnerReferences
+					}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+				}
+
+				// Check OidcReturnUris
+				By("Expecting OidcReturnURIs created")
+				for _, url := range cr.Spec.SiteURL {
+					oidcReturnUri = authz.OidcReturnURI{}
+					hash := md5.Sum([]byte(url))
+					Eventually(func() []metav1.OwnerReference {
+						k8sClient.Get(ctx, types.NamespacedName{Name: key.Name + "-" + hex.EncodeToString(hash[0:4]), Namespace: key.Namespace}, &oidcReturnUri)
+						return oidcReturnUri.ObjectMeta.OwnerReferences
+					}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+				}
+			})
+		})
+	})
+
+	Describe("Cloning a drupalSite object", func() {
+		Context("With cloneFrom", func() {
+			It("All dependent resources should be created", func() {
+				keyClone := types.NamespacedName{
+					Name:      Name + "-clone",
+					Namespace: Namespace,
+				}
+				drupalSiteObjectClone := &drupalwebservicesv1alpha1.DrupalSite{
+					TypeMeta: metav1.TypeMeta{
+						APIVersion: "drupal.webservices.cern.ch/v1alpha1",
+						Kind:       "DrupalSite",
+					},
+					ObjectMeta: metav1.ObjectMeta{
+						Name:      keyClone.Name,
+						Namespace: keyClone.Namespace,
+					},
+					Spec: drupalwebservicesv1alpha1.DrupalSiteSpec{
+						Version: drupalwebservicesv1alpha1.Version{
+							Name:        "v9.3-2",
+							ReleaseSpec: "stable",
+						},
+						Configuration: drupalwebservicesv1alpha1.Configuration{
+							DiskSize:         "6Gi",
+							QoSClass:         drupalwebservicesv1alpha1.QoSStandard,
+							DatabaseClass:    drupalwebservicesv1alpha1.DBODStandard,
+							CloneFrom:        drupalwebservicesv1alpha1.CloneFrom(key.Name),
+							ScheduledBackups: "enabled",
+						},
+						SiteURL: []drupalwebservicesv1alpha1.Url{dummySiteUrl},
+					},
+				}
+
+				By("By creating a new drupalSite")
+				Eventually(func() error {
+					return k8sClient.Create(ctx, drupalSiteObjectClone)
+				}, timeout, interval).Should(Succeed())
+
+				// Create drupalSite object
+				By("Expecting drupalSite object created")
+				cr := drupalwebservicesv1alpha1.DrupalSite{}
+				Eventually(func() error {
+					return k8sClient.Get(ctx, keyClone, &cr)
+				}, timeout, interval).Should(Succeed())
+
+				trueVar := true
+				expectedOwnerReference := metav1.OwnerReference{
+					APIVersion: "drupal.webservices.cern.ch/v1alpha1",
+					Kind:       "DrupalSite",
+					Name:       keyClone.Name,
+					UID:        cr.UID,
+					Controller: &trueVar,
+				}
+				configmap := corev1.ConfigMap{}
+				svc := corev1.Service{}
+				pvc := corev1.PersistentVolumeClaim{}
+				job := batchv1.Job{}
+				deploy := appsv1.Deployment{}
+				dbod := dbodv1a1.Database{}
+				route := routev1.Route{}
+				oidcReturnUri := authz.OidcReturnURI{}
+				schedule := velerov1.Schedule{}
+
+				// Check DBOD resource creation
+				By("Expecting Database resource created")
 				Eventually(func() []metav1.OwnerReference {
-					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace + "-" + key.Name, Namespace: veleroNamespace}, &schedule)
+					k8sClient.Get(ctx, types.NamespacedName{Name: keyClone.Name, Namespace: keyClone.Namespace}, &dbod)
+					return dbod.ObjectMeta.OwnerReferences
+				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+
+				// Update DBOD resource status field
+				By("Updating the DBOD instance in Database resource status")
+				Eventually(func() error {
+					k8sClient.Get(ctx, types.NamespacedName{Name: keyClone.Name, Namespace: keyClone.Namespace}, &dbod)
+					dbod.Status.DbodInstance = "test"
+					return k8sClient.Status().Update(ctx, &dbod)
+				}, timeout, interval).Should(Succeed())
+
+				By("Expecting the drupal deployment to have at least 2 containers")
+				Eventually(func() bool {
+					k8sClient.Get(ctx, types.NamespacedName{Name: keyClone.Name, Namespace: keyClone.Namespace}, &deploy)
+					return len(deploy.Spec.Template.Spec.Containers) >= 2
+				}, timeout, interval).Should(BeTrue())
+
+				// Check PHP-FPM configMap creation
+				By("Expecting PHP_FPM configmaps created")
+				Eventually(func() []metav1.OwnerReference {
+					k8sClient.Get(ctx, types.NamespacedName{Name: "php-fpm-" + keyClone.Name, Namespace: keyClone.Namespace}, &configmap)
+					return configmap.ObjectMeta.OwnerReferences
+				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+
+				// Check Nginx configMap creation
+				By("Expecting Nginx configmaps created")
+				Eventually(func() []metav1.OwnerReference {
+					k8sClient.Get(ctx, types.NamespacedName{Name: "nginx-" + keyClone.Name, Namespace: keyClone.Namespace}, &configmap)
+					return configmap.ObjectMeta.OwnerReferences
+				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+
+				// Check Site settings configMap creation
+				By("Expecting Site settings configmaps created")
+				Eventually(func() []metav1.OwnerReference {
+					k8sClient.Get(ctx, types.NamespacedName{Name: "site-settings-" + keyClone.Name, Namespace: keyClone.Namespace}, &configmap)
+					return configmap.ObjectMeta.OwnerReferences
+				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+
+				// Check PHP Cli configMap creation
+				By("Expecting PHP Cli configmaps created")
+				Eventually(func() []metav1.OwnerReference {
+					k8sClient.Get(ctx, types.NamespacedName{Name: "php-cli-config-" + keyClone.Name, Namespace: keyClone.Namespace}, &configmap)
+					return configmap.ObjectMeta.OwnerReferences
+				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+				// Check Drupal service
+				By("Expecting Drupal service created")
+				Eventually(func() []metav1.OwnerReference {
+					k8sClient.Get(ctx, types.NamespacedName{Name: keyClone.Name, Namespace: keyClone.Namespace}, &svc)
+					return svc.ObjectMeta.OwnerReferences
+				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+
+				// Check drupal persistentVolumeClaim
+				By("Expecting drupal persistentVolumeClaim created")
+				Eventually(func() []metav1.OwnerReference {
+					k8sClient.Get(ctx, types.NamespacedName{Name: "pv-claim-" + keyClone.Name, Namespace: keyClone.Namespace}, &pvc)
+					return pvc.ObjectMeta.OwnerReferences
+				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+
+				// Check Drupal deployments
+				By("Expecting Drupal deployments created")
+				Eventually(func() []metav1.OwnerReference {
+					k8sClient.Get(ctx, types.NamespacedName{Name: keyClone.Name, Namespace: keyClone.Namespace}, &deploy)
+					return deploy.ObjectMeta.OwnerReferences
+				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+
+				// // Check Drush job
+				By("Expecting Drush job created")
+				Eventually(func() []metav1.OwnerReference {
+					k8sClient.Get(ctx, types.NamespacedName{Name: "clone-" + keyClone.Name, Namespace: keyClone.Namespace}, &job)
 					return job.ObjectMeta.OwnerReferences
 				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
 
+				// Update drupalSite custom resource status fields to allow route conditions
+				By("Updating 'initialized' status field in drupalSite resource")
+				Eventually(func() error {
+					k8sClient.Get(ctx, types.NamespacedName{Name: keyClone.Name, Namespace: keyClone.Namespace}, &cr)
+					cr.Status.Conditions.SetCondition(status.Condition{Type: "Initialized", Status: "True"})
+					return k8sClient.Status().Update(ctx, &cr)
+				}, timeout, interval).Should(Succeed())
+
+				// Update deployment status fields to allow 'ready' status field to be set on the drupalSite resource
+				By("Updating 'ReadyReplicas' and 'AvailableReplicas' status fields in deployment resource")
+				Eventually(func() error {
+					k8sClient.Get(ctx, keyClone, &deploy)
+					deploy.Status.Replicas = 1
+					deploy.Status.AvailableReplicas = 1
+					deploy.Status.ReadyReplicas = 1
+					return k8sClient.Status().Update(ctx, &deploy)
+				}, timeout, interval).Should(Succeed())
+
+				// Check if the Schedule resource is created
+				By("Expecting Schedule to be created")
+				Eventually(func() error {
+					return k8sClient.Get(ctx, types.NamespacedName{Name: generateScheduleName(keyClone.Namespace, keyClone.Name), Namespace: veleroNamespace}, &schedule)
+				}, timeout, interval).Should(Succeed())
+
 				// Check Routes
 				By("Expecting Drupal Route(s) to be created")
 				for _, url := range cr.Spec.SiteURL {
 					route = routev1.Route{}
 					hash := md5.Sum([]byte(url))
 					Eventually(func() []metav1.OwnerReference {
-						k8sClient.Get(ctx, types.NamespacedName{Name: key.Name + "-" + hex.EncodeToString(hash[0:4]), Namespace: key.Namespace}, &route)
+						k8sClient.Get(ctx, types.NamespacedName{Name: keyClone.Name + "-" + hex.EncodeToString(hash[0:4]), Namespace: keyClone.Namespace}, &route)
 						return route.ObjectMeta.OwnerReferences
 					}, timeout, interval).Should(ContainElement(expectedOwnerReference))
 				}
@@ -262,10 +448,19 @@ var _ = Describe("DrupalSite controller", func() {
 					oidcReturnUri = authz.OidcReturnURI{}
 					hash := md5.Sum([]byte(url))
 					Eventually(func() []metav1.OwnerReference {
-						k8sClient.Get(ctx, types.NamespacedName{Name: key.Name + "-" + hex.EncodeToString(hash[0:4]), Namespace: key.Namespace}, &oidcReturnUri)
+						k8sClient.Get(ctx, types.NamespacedName{Name: keyClone.Name + "-" + hex.EncodeToString(hash[0:4]), Namespace: keyClone.Namespace}, &oidcReturnUri)
 						return oidcReturnUri.ObjectMeta.OwnerReferences
 					}, timeout, interval).Should(ContainElement(expectedOwnerReference))
 				}
+
+				// Check if the diskSize is set correctly
+				By("Expecting the clone site diskSize is set to the same as source site")
+				Eventually(func() bool {
+					cr_source := drupalwebservicesv1alpha1.DrupalSite{}
+					k8sClient.Get(ctx, types.NamespacedName{Name: key.Name, Namespace: key.Namespace}, &cr_source)
+					return (cr.Spec.Configuration.DiskSize == cr_source.Spec.Configuration.DiskSize)
+				}, timeout, interval).Should(BeTrue())
+
 			})
 		})
 	})
@@ -909,10 +1104,9 @@ var _ = Describe("DrupalSite controller", func() {
 
 				// Check if the Schedule resource is created
 				By("Expecting Schedule to be created")
-				Eventually(func() []metav1.OwnerReference {
-					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace + "-" + key.Name, Namespace: veleroNamespace}, &schedule)
-					return job.ObjectMeta.OwnerReferences
-				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+				Eventually(func() error {
+					return k8sClient.Get(ctx, types.NamespacedName{Name: generateScheduleName(key.Namespace, key.Name), Namespace: veleroNamespace}, &schedule)
+				}, timeout, interval).Should(Succeed())
 
 				// Check Routes
 				By("Expecting Drupal Route(s) to be created")
@@ -1633,10 +1827,9 @@ var _ = Describe("DrupalSite controller", func() {
 
 				// Check if the Schedule resource is created
 				By("Expecting Schedule to be created")
-				Eventually(func() []metav1.OwnerReference {
-					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace + "-" + key.Name, Namespace: veleroNamespace}, &schedule)
-					return job.ObjectMeta.OwnerReferences
-				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+				Eventually(func() error {
+					return k8sClient.Get(ctx, types.NamespacedName{Name: generateScheduleName(key.Namespace, key.Name), Namespace: veleroNamespace}, &schedule)
+				}, timeout, interval).Should(Succeed())
 
 				// Check Routes
 				By("Expecting Drupal Route(s) to be created")
@@ -1786,10 +1979,9 @@ var _ = Describe("DrupalSite controller", func() {
 
 				// Check if the Schedule resource is created
 				By("Expecting Schedule to be created")
-				Eventually(func() []metav1.OwnerReference {
-					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace + "-" + key.Name, Namespace: veleroNamespace}, &schedule)
-					return job.ObjectMeta.OwnerReferences
-				}, timeout, interval).Should(ContainElement(expectedOwnerReference))
+				Eventually(func() error {
+					return k8sClient.Get(ctx, types.NamespacedName{Name: generateScheduleName(key.Namespace, key.Name), Namespace: veleroNamespace}, &schedule)
+				}, timeout, interval).Should(Succeed())
 
 				// Check Routes
 				By("Expecting Drupal Route(s) to be created")
diff --git a/controllers/drupalsite_controller_utils.go b/controllers/drupalsite_controller_utils.go
index cda16e20232b9db0d0d633fbc1378e1d057d0d65..4c16babf001cec25d0ec0d3aee2c9f2845b3b960 100644
--- a/controllers/drupalsite_controller_utils.go
+++ b/controllers/drupalsite_controller_utils.go
@@ -31,6 +31,7 @@ import (
 	batchv1 "k8s.io/api/batch/v1"
 	corev1 "k8s.io/api/core/v1"
 	k8sapierrors "k8s.io/apimachinery/pkg/api/errors"
+	k8sapiresource "k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"knative.dev/pkg/apis"
@@ -178,8 +179,19 @@ func (r *DrupalSiteReconciler) ensureSpecFinalizer(ctx context.Context, drp *web
 		case err != nil:
 			return false, newApplicationError(err, ErrClientK8s)
 		}
+
+		// Parse the input strings (Mi or Gi) into 'quantity' type for easier comparison
+		destinationDiskSize, err := k8sapiresource.ParseQuantity(drp.Spec.Configuration.DiskSize)
+		if err != nil {
+			return false, newApplicationError(err, ErrFunctionDomain)
+		}
+		sourceDiskSize, err := k8sapiresource.ParseQuantity(sourceSite.Spec.Configuration.DiskSize)
+		if err != nil {
+			return false, newApplicationError(err, ErrFunctionDomain)
+		}
+
 		// The destination disk size must be at least as large as the source
-		if drp.Spec.Configuration.DiskSize < sourceSite.Spec.Configuration.DiskSize {
+		if destinationDiskSize.Cmp(sourceDiskSize) == -1 {
 			drp.Spec.Configuration.DiskSize = sourceSite.Spec.Configuration.DiskSize
 			update = true
 		}