diff --git a/controllers/drupalsite_controller_test.go b/controllers/drupalsite_controller_test.go
index 8028d3818a52ca15ee49347f060cf7ee4c660937..1844dee23704f90f8198ebff7e419183cc34d7d1 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,33 @@ 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 clone labels are set on the drupalSite
+				By("Expecting the clone labels to be set on the cloned site")
+				Eventually(func() bool {
+					k8sClient.Get(ctx, types.NamespacedName{Name: keyClone.Name, Namespace: keyClone.Namespace}, &cr)
+					return (cr.Labels["clonedFrom"] == key.Name && cr.Labels["clonedOn"] != "")
+				}, timeout, interval).Should(BeTrue())
+
+				// Check if the cloneFrom field is reset on the drupalSite
+				By("Expecting the cloneFrom field is reset on the cloned site")
+				Eventually(func() bool {
+					k8sClient.Get(ctx, types.NamespacedName{Name: keyClone.Name, Namespace: keyClone.Namespace}, &cr)
+					return (cr.Spec.Configuration.CloneFrom == "")
+				}, timeout, interval).Should(BeTrue())
+
+				// 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 +1118,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 +1841,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 +1993,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..4ad09501a5f6ce20e4eb861dae4b880adb2a50b3 100644
--- a/controllers/drupalsite_controller_utils.go
+++ b/controllers/drupalsite_controller_utils.go
@@ -20,6 +20,7 @@ import (
 	"crypto/md5"
 	"encoding/hex"
 	"fmt"
+	"time"
 
 	"github.com/go-logr/logr"
 	buildv1 "github.com/openshift/api/build/v1"
@@ -170,29 +171,44 @@ func (r *DrupalSiteReconciler) ensureSpecFinalizer(ctx context.Context, drp *web
 
 	// Validate that CloneFrom is an existing DrupalSite
 	if drp.Spec.Configuration.CloneFrom != "" {
-		sourceSite := webservicesv1a1.DrupalSite{}
-		err := r.Get(ctx, types.NamespacedName{Name: string(drp.Spec.Configuration.CloneFrom), Namespace: drp.Namespace}, &sourceSite)
-		switch {
-		case k8sapierrors.IsNotFound(err):
-			return false, newApplicationError(fmt.Errorf("CloneFrom DrupalSite doesn't exist"), ErrInvalidSpec)
-		case err != nil:
-			return false, newApplicationError(err, ErrClientK8s)
-		}
-		// The destination disk size must be at least as large as the source
-		if drp.Spec.Configuration.DiskSize < sourceSite.Spec.Configuration.DiskSize {
-			drp.Spec.Configuration.DiskSize = sourceSite.Spec.Configuration.DiskSize
-			update = true
-		}
-		// The extraConfigurationRepo should be set in the clone site if defined in the source
-		// TODO: Remove logic for ExtraConfigurationRepo once we deprecate the field
-		if sourceSite.Spec.Configuration.ExtraConfigurationRepo != "" && drp.Spec.Configuration.ExtraConfigurationRepo == "" {
-			drp.Spec.Configuration.ExtraConfigurationRepo = sourceSite.Spec.Configuration.ExtraConfigurationRepo
-			update = true
-		}
-		// The extraConfigurationRepository should be set in the clone site if defined in the source
-		if sourceSite.Spec.Configuration.ExtraConfigurationRepository.Branch != "" && sourceSite.Spec.Configuration.ExtraConfigurationRepository.RepositoryUrl != "" && drp.Spec.Configuration.ExtraConfigurationRepository.Branch == "" && drp.Spec.Configuration.ExtraConfigurationRepository.RepositoryUrl != "" {
-			drp.Spec.Configuration.ExtraConfigurationRepository.Branch = sourceSite.Spec.Configuration.ExtraConfigurationRepository.Branch
-			drp.Spec.Configuration.ExtraConfigurationRepository.RepositoryUrl = sourceSite.Spec.Configuration.ExtraConfigurationRepository.RepositoryUrl
+		if !drp.ConditionTrue("Initialized") {
+			sourceSite := webservicesv1a1.DrupalSite{}
+			err := r.Get(ctx, types.NamespacedName{Name: string(drp.Spec.Configuration.CloneFrom), Namespace: drp.Namespace}, &sourceSite)
+			switch {
+			case k8sapierrors.IsNotFound(err):
+				return false, newApplicationError(fmt.Errorf("CloneFrom DrupalSite doesn't exist"), ErrInvalidSpec)
+			case err != nil:
+				return false, newApplicationError(err, ErrClientK8s)
+			}
+
+			// The destination disk size must be at least as large as the source
+			if drp.Spec.Configuration.DiskSize != sourceSite.Spec.Configuration.DiskSize {
+				drp.Spec.Configuration.DiskSize = sourceSite.Spec.Configuration.DiskSize
+				update = true
+			}
+			// The extraConfigurationRepo should be set in the clone site if defined in the source
+			// TODO: Remove logic for ExtraConfigurationRepo once we deprecate the field
+			if sourceSite.Spec.Configuration.ExtraConfigurationRepo != "" && drp.Spec.Configuration.ExtraConfigurationRepo == "" {
+				drp.Spec.Configuration.ExtraConfigurationRepo = sourceSite.Spec.Configuration.ExtraConfigurationRepo
+				update = true
+			}
+			// The extraConfigurationRepository should be set in the clone site if defined in the source
+			if sourceSite.Spec.Configuration.ExtraConfigurationRepository.Branch != "" && sourceSite.Spec.Configuration.ExtraConfigurationRepository.RepositoryUrl != "" && drp.Spec.Configuration.ExtraConfigurationRepository.Branch == "" && drp.Spec.Configuration.ExtraConfigurationRepository.RepositoryUrl != "" {
+				drp.Spec.Configuration.ExtraConfigurationRepository.Branch = sourceSite.Spec.Configuration.ExtraConfigurationRepository.Branch
+				drp.Spec.Configuration.ExtraConfigurationRepository.RepositoryUrl = sourceSite.Spec.Configuration.ExtraConfigurationRepository.RepositoryUrl
+				update = true
+			}
+		} else {
+			if drp.Labels == nil {
+				drp.Labels = map[string]string{}
+			}
+			// Source site name from which the clone was requested
+			drp.Labels["clonedFrom"] = string(drp.Spec.Configuration.CloneFrom)
+			// Set the time when the clone was requested
+			loc, _ := time.LoadLocation("")
+			drp.Labels["clonedOn"] = time.Now().In(loc).Format("Jan_2_2006_3-04pm_UTC")
+			// Reset the `cloneFrom` field
+			drp.Spec.Configuration.CloneFrom = ""
 			update = true
 		}
 	}