diff --git a/gso/services/provisioning_proxy.py b/gso/services/provisioning_proxy.py
index 2b7c98bdfc863fe691a3652b808d64a3eb01f7fa..d7f89fcff24038987a598433bc570c5edf02af2d 100644
--- a/gso/services/provisioning_proxy.py
+++ b/gso/services/provisioning_proxy.py
@@ -1,3 +1,4 @@
+import enum
 import json
 import logging
 
@@ -11,13 +12,26 @@ from orchestrator.types import UUIDstr, State
 from orchestrator.utils.json import json_dumps
 
 from gso import settings
-from gso.products.product_types.device import DeviceProvisioning
-from gso.products.product_types.iptrunk import IptrunkProvisioning
+from gso.products.product_types.iptrunk import IptrunkProvisioning, Iptrunk
 
 logger = logging.getLogger(__name__)
 
 
-def _send_request(endpoint: str, parameters: dict, process_id: UUIDstr):
+class CUDOperation(str, enum.Enum):
+    """
+    Enum for different C(R)UD operations that the provisioning proxy supports.
+    Read is not applicable, hence these become CUD and not CRUD operations.
+    """
+    #: Creation is done with a POST request
+    POST = 'POST'
+    #: Updating is done with a PUT request
+    PUT = 'PUT'
+    #: Removal is done with a DELETE request
+    DELETE = 'DELETE'
+
+
+def _send_request(endpoint: str, parameters: dict, process_id: UUIDstr,
+                  operation: CUDOperation):
     oss = settings.load_oss_params()
     pp_params = oss.PROVISIONING_PROXY
     assert pp_params
@@ -27,13 +41,19 @@ def _send_request(endpoint: str, parameters: dict, process_id: UUIDstr):
     logger.debug(f'[provisioning proxy] provisioning for process {process_id}')
 
     parameters.update({'callback': callback_url})
+    url = f'{pp_params.scheme}://{pp_params.api_base}/api/{endpoint}'
+
+    request = None
 
-    post_request = requests.post(
-        f'{pp_params.scheme}://{pp_params.api_base}/api/{endpoint}',
-        json=parameters)
+    if operation == CUDOperation.POST:
+        request = requests.post(url, json=parameters)
+    elif operation == CUDOperation.PUT:
+        request = requests.put(url, json=parameters)
+    elif operation == CUDOperation.DELETE:
+        request = requests.delete(url, json=parameters)
 
-    if post_request.status_code != 200:
-        raise AssertionError(post_request.text)
+    if request.status_code != 200:
+        raise AssertionError(request.text)
 
 
 def provision_device(
@@ -45,7 +65,7 @@ def provision_device(
         'subscription': json.loads(json_dumps(subscription))
     }
 
-    _send_request('device', parameters, process_id)
+    _send_request('device', parameters, process_id, CUDOperation.POST)
 
 
 def provision_ip_trunk(subscription: IptrunkProvisioning,
@@ -58,7 +78,21 @@ def provision_ip_trunk(subscription: IptrunkProvisioning,
         'object': ''  # FIXME
     }
 
-    _send_request('ip_trunk', parameters, process_id)
+    _send_request('ip_trunk', parameters, process_id, CUDOperation.POST)
+
+
+def modify_ip_trunk(old_subscription: Iptrunk,
+                    new_subscription: Iptrunk,
+                    process_id: UUIDstr,
+                    dry_run: bool = True):
+    parameters = {
+        'dry_run': dry_run,
+        'old_subscription': old_subscription,
+        'subscription': new_subscription
+        # FIXME missing parameters
+    }
+
+    _send_request('ip_trunk', parameters, process_id, CUDOperation.PUT)
 
 
 @inputstep('Await provisioning proxy results', assignee=Assignee('SYSTEM'))