diff --git a/src/main/java/net/geant/nmaas/portal/api/bulk/BulkController.java b/src/main/java/net/geant/nmaas/portal/api/bulk/BulkController.java
index c4211889458bbd48e832ea4273d35fc30fab98a4..ea7f46dd5a5ff48e624aeb969fc10e06977a94fb 100644
--- a/src/main/java/net/geant/nmaas/portal/api/bulk/BulkController.java
+++ b/src/main/java/net/geant/nmaas/portal/api/bulk/BulkController.java
@@ -14,9 +14,11 @@ import net.geant.nmaas.portal.service.BulkDomainService;
 import net.geant.nmaas.portal.service.UserService;
 import org.modelmapper.ModelMapper;
 import org.springframework.core.io.InputStreamResource;
+import org.springframework.dao.PermissionDeniedDataAccessException;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -30,6 +32,7 @@ import java.security.Principal;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 @RestController
@@ -91,17 +94,14 @@ public class BulkController {
     @GetMapping
     @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN')")
     public ResponseEntity<List<BulkDeploymentViewS>> getAllDeploymentRecords() {
-        return ResponseEntity.ok(mapToView(bulkDeploymentRepository.findAll()));
+        return ResponseEntity.ok(mapToViewList(bulkDeploymentRepository.findAll()));
     }
 
     @GetMapping("/{id}")
     @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN') || hasRole('ROLE_VL_MANAGER')")
     public ResponseEntity<BulkDeploymentView> getDeploymentRecord(@PathVariable Long id) {
         BulkDeployment bulk = bulkDeploymentRepository.findById(id).orElseThrow();
-        BulkDeploymentView bulkView = modelMapper.map(bulk, BulkDeploymentView.class);
-        bulkView.setCreator(getUserView(bulk.getCreatorId()));
-        mapDetails(bulk, bulkView);
-        return ResponseEntity.ok(bulkView);
+        return ResponseEntity.ok(mapToView(bulk, BulkDeploymentView.class));
     }
 
     @GetMapping(value = "/app/csv/{id}", produces = "text/csv")
@@ -124,7 +124,7 @@ public class BulkController {
     @GetMapping("/domains")
     @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN')")
     public ResponseEntity<List<BulkDeploymentViewS>> getDomainDeploymentRecords() {
-        return ResponseEntity.ok(mapToView(bulkDeploymentRepository.findByType(BulkType.DOMAIN)));
+        return ResponseEntity.ok(mapToViewList(bulkDeploymentRepository.findByType(BulkType.DOMAIN)));
     }
 
     @GetMapping("/domains/vl")
@@ -132,14 +132,14 @@ public class BulkController {
     public ResponseEntity<List<BulkDeploymentViewS>> getDomainDeploymentRecordsRestrictedToOwner(Principal principal) {
         User user = this.userService.findByUsername(principal.getName()).orElseThrow(() -> new MissingElementException("Missing user " + principal.getName()));
 
-        return ResponseEntity.ok(mapToView(bulkDeploymentRepository.findByType(BulkType.DOMAIN)).stream()
-                    .filter(bulk -> bulk.getCreator().getId().equals(user.getId())).collect(Collectors.toList()));
+        return ResponseEntity.ok(mapToViewList(bulkDeploymentRepository.findByType(BulkType.DOMAIN)).stream()
+                .filter(bulk -> bulk.getCreator().getId().equals(user.getId())).collect(Collectors.toList()));
     }
 
     @GetMapping("/apps")
     @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN')")
     public ResponseEntity<List<BulkDeploymentViewS>> getAppDeploymentRecords() {
-        return ResponseEntity.ok(mapToView(bulkDeploymentRepository.findByType(BulkType.APPLICATION)));
+        return ResponseEntity.ok(mapToViewList(bulkDeploymentRepository.findByType(BulkType.APPLICATION)));
     }
 
     @GetMapping("/apps/vl")
@@ -147,21 +147,47 @@ public class BulkController {
     public ResponseEntity<List<BulkDeploymentViewS>> getAppDeploymentRecordsRestrictedToOwner(Principal principal) {
         User user = this.userService.findByUsername(principal.getName()).orElseThrow(() -> new MissingElementException("Missing user " + principal.getName()));
 
-        return ResponseEntity.ok(mapToView(bulkDeploymentRepository.findByType(BulkType.APPLICATION)).stream()
+        return ResponseEntity.ok(mapToViewList(bulkDeploymentRepository.findByType(BulkType.APPLICATION)).stream()
                 .filter(bulk -> bulk.getCreator().getId().equals(user.getId())).collect(Collectors.toList()));
     }
 
-    private List<BulkDeploymentViewS> mapToView(List<BulkDeployment> deployments) {
+    @DeleteMapping("/{id}")
+    @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN') || hasRole('ROLE_VL_MANAGER')")
+    public ResponseEntity<Void> removeBulkDeployment(
+            @PathVariable Long id,
+            @RequestParam(name = "removeAll") boolean removeApps,
+            Principal principal
+    ) {
+        User user = this.userService.findByUsername(principal.getName()).orElseThrow(() -> new MissingElementException("Missing user " + principal.getName()));
+
+        Optional<BulkDeployment> bulk = this.bulkDeploymentRepository.findById(id);
+        if (bulk.isEmpty()) {
+            return ResponseEntity.notFound().build();
+        }
+
+        if(bulk.get().getCreatorId().equals(user.getId()) ) {
+            throw new PermissionDeniedDataAccessException("User doesnt have access to this bulk deployment", new Throwable());
+        }
+        if (removeApps) {
+            bulkApplicationService.deleteAppInstancesFromBulk(mapToView(bulk.get(), BulkDeploymentView.class));
+        }
+        bulkDeploymentRepository.delete(bulk.get());
+        return ResponseEntity.ok().build();
+    }
+
+    private List<BulkDeploymentViewS> mapToViewList(List<BulkDeployment> deployments) {
         return deployments.stream()
-                .map(bulk -> {
-                    BulkDeploymentViewS bulkView = modelMapper.map(bulk, BulkDeploymentViewS.class);
-                    bulkView.setCreator(getUserView(bulk.getCreatorId()));
-                    mapDetails(bulk, bulkView);
-                    return bulkView;
-                })
+                .map(bulk -> mapToView(bulk, BulkDeploymentViewS.class))
                 .collect(Collectors.toList());
     }
 
+    private <T extends BulkDeploymentViewS> T mapToView(BulkDeployment bulk, Class<T> viewType) {
+        T bulkView = modelMapper.map(bulk, viewType);
+        bulkView.setCreator(getUserView(bulk.getCreatorId()));
+        mapDetails(bulk, bulkView);
+        return bulkView;
+    }
+
     private void mapDetails(BulkDeployment deployment, BulkDeploymentViewS view) {
         if (deployment.getType().equals(BulkType.APPLICATION)) {
             Map<String, String> details = new HashMap<>();
diff --git a/src/main/java/net/geant/nmaas/portal/service/BulkApplicationService.java b/src/main/java/net/geant/nmaas/portal/service/BulkApplicationService.java
index bebf1c9f83b47a8ce983904e071a0e7697a01bf3..656dcd11d86a55736201a081bac2c8e88c6d5c13 100644
--- a/src/main/java/net/geant/nmaas/portal/service/BulkApplicationService.java
+++ b/src/main/java/net/geant/nmaas/portal/service/BulkApplicationService.java
@@ -22,6 +22,8 @@ public interface BulkApplicationService {
 
     List<BulkAppDetails> getAppsBulkDetails(BulkDeploymentView view);
 
-    InputStreamResource getInputStreamAppBulkDetails(List<BulkAppDetails> list );
+    InputStreamResource getInputStreamAppBulkDetails(List<BulkAppDetails> list);
+
+    void deleteAppInstancesFromBulk(BulkDeploymentView bulk);
 
 }
diff --git a/src/main/java/net/geant/nmaas/portal/service/impl/BulkApplicationServiceImpl.java b/src/main/java/net/geant/nmaas/portal/service/impl/BulkApplicationServiceImpl.java
index aea95a4edb36d392e16ba3d136942ea7d9b6edef..8efe9388d045dca0ad459e0abb45f42a549db0f0 100644
--- a/src/main/java/net/geant/nmaas/portal/service/impl/BulkApplicationServiceImpl.java
+++ b/src/main/java/net/geant/nmaas/portal/service/impl/BulkApplicationServiceImpl.java
@@ -14,6 +14,7 @@ import net.geant.nmaas.orchestration.events.app.AppAutoDeploymentReviewEvent;
 import net.geant.nmaas.orchestration.events.app.AppAutoDeploymentStatusUpdateEvent;
 import net.geant.nmaas.orchestration.events.app.AppAutoDeploymentTriggeredEvent;
 import net.geant.nmaas.portal.api.bulk.BulkAppDetails;
+import net.geant.nmaas.portal.api.bulk.BulkDeploymentEntryView;
 import net.geant.nmaas.portal.api.bulk.BulkDeploymentView;
 import net.geant.nmaas.portal.api.bulk.BulkDeploymentViewS;
 import net.geant.nmaas.portal.api.bulk.BulkType;
@@ -21,6 +22,7 @@ import net.geant.nmaas.portal.api.bulk.CsvApplication;
 import net.geant.nmaas.portal.api.domain.AppInstanceState;
 import net.geant.nmaas.portal.api.domain.UserViewMinimal;
 import net.geant.nmaas.portal.api.exception.MissingElementException;
+import net.geant.nmaas.portal.exceptions.ObjectNotFoundException;
 import net.geant.nmaas.portal.persistent.entity.AppInstance;
 import net.geant.nmaas.portal.persistent.entity.Application;
 import net.geant.nmaas.portal.persistent.entity.BulkDeployment;
@@ -55,6 +57,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -300,6 +303,24 @@ public class BulkApplicationServiceImpl implements BulkApplicationService {
         );
     }
 
+    @Override
+    public void deleteAppInstancesFromBulk(BulkDeploymentView bulk) {
+        List<BulkDeploymentEntryView> apps = bulk.getEntries();
+        for (BulkDeploymentEntryView app : apps) {
+            Long appInstanceId = Long.valueOf(findAppDetail(app, BULK_ENTRY_DETAIL_KEY_APP_INSTANCE_ID));
+            AppInstance appInstance = instanceService.find(appInstanceId)
+                    .orElseThrow(() -> new ObjectNotFoundException("App instance not found"));
+
+            appLifecycleManager.removeApplication(appInstance.getInternalId());
+            instanceService.delete(appInstanceId);
+        }
+    }
+
+    private String findAppDetail(BulkDeploymentEntryView app, String key) {
+        return Optional.ofNullable(app.getDetails().get(key))
+                .orElseThrow(() -> new ObjectNotFoundException(key + " not found"));
+    }
+
     private static BulkDeployment createBulkDeployment(UserViewMinimal creator) {
         BulkDeployment bulkDeployment = new BulkDeployment();
         bulkDeployment.setType(BulkType.APPLICATION);
@@ -355,8 +376,8 @@ public class BulkApplicationServiceImpl implements BulkApplicationService {
 
             //deploy
             Map<String, String> params = appDeploymentMonitor.appDeploymentParameters(instance.getInternalId());
-            params.forEach( (key, value) -> {
-                configurationParameters.put(key,  Objects.isNull(value) || Objects.equals(value, "") ? EMPTY_VALUE : value.replace("\"", ""));
+            params.forEach((key, value) -> {
+                configurationParameters.put(key, Objects.isNull(value) || Objects.equals(value, "") ? EMPTY_VALUE : value.replace("\"", ""));
                 log.debug("Params = {} - {}", key, value);
             });
 
diff --git a/src/test/shell/data/i18n/de.json b/src/test/shell/data/i18n/de.json
index e3e42ed3373fd2480e3dc738c52d211d70ecabf9..b52b0a6004b08b2b98a258cac21fe5180623a4e1 100644
--- a/src/test/shell/data/i18n/de.json
+++ b/src/test/shell/data/i18n/de.json
@@ -1223,8 +1223,9 @@
     },
     "REMOVE" : {
       "HEADER" : "Remove bulk deployment",
-      "APP" : "Do you want to remove all instances created by this bulk ? ",
-      "REMOVE" : "Remove"
+      "APP" : "Do you want to remove all instances created by this bulk deployment?",
+      "REMOVE" : "Remove",
+      "ERROR": "Error removing bulk deployment:"
     }
   },
   "SHARED" : {
diff --git a/src/test/shell/data/i18n/en.json b/src/test/shell/data/i18n/en.json
index 402870080081830944d824acd57dcd7f960ee538..dbfdaf12bd1c046a4c86d54aed4ac8bf846f5e4d 100644
--- a/src/test/shell/data/i18n/en.json
+++ b/src/test/shell/data/i18n/en.json
@@ -1226,8 +1226,9 @@
     },
     "REMOVE" : {
       "HEADER" : "Remove bulk deployment",
-      "APP" : "Do you want to remove all instances created by this bulk ? ",
-      "REMOVE" : "Remove"
+      "APP" : "Do you want to remove all instances created by this bulk deployment?",
+      "REMOVE" : "Remove",
+      "ERROR": "Error removing bulk deployment:"
     }
   },
   "SHARED" : {
diff --git a/src/test/shell/data/i18n/fr.json b/src/test/shell/data/i18n/fr.json
index 48d78d0edb1d27885e14223d6ce88de858f37fd1..6cc4d288c04ae373748290b6163f06dec9e79b8d 100644
--- a/src/test/shell/data/i18n/fr.json
+++ b/src/test/shell/data/i18n/fr.json
@@ -1224,8 +1224,9 @@
     },
     "REMOVE" : {
       "HEADER" : "Remove bulk deployment",
-      "APP" : "Do you want to remove all instances created by this bulk ? ",
-      "REMOVE" : "Remove"
+      "APP" : "Do you want to remove all instances created by this bulk deployment?",
+      "REMOVE" : "Remove",
+      "ERROR": "Error removing bulk deployment:"
     }
   },
   "SHARED" : {
diff --git a/src/test/shell/data/i18n/pl.json b/src/test/shell/data/i18n/pl.json
index d27810427bfadc4d874d8c7f5a6703ab3084c6f5..f6d296d186ce8f8e1f12eb3b4cf4c43281176f6c 100644
--- a/src/test/shell/data/i18n/pl.json
+++ b/src/test/shell/data/i18n/pl.json
@@ -1225,8 +1225,9 @@
     },
     "REMOVE" : {
       "HEADER" : "Remove bulk deployment",
-      "APP" : "Do you want to remove all instances created by this bulk ? ",
-      "REMOVE" : "Remove"
+      "APP" : "Do you want to remove all instances created by this bulk deployment?",
+      "REMOVE" : "Remove",
+      "ERROR": "Error removing bulk deployment:"
     }
   },
   "SHARED" : {