diff --git a/docs/source/module/workflows/geant_ip/index.rst b/docs/source/module/workflows/geant_ip/index.rst
index bf8b1a3b6c23bb94d586e329d6eab73a829b8b58..c2dd7576ef9f1c3882b97c782aa00a3e5ff894c9 100644
--- a/docs/source/module/workflows/geant_ip/index.rst
+++ b/docs/source/module/workflows/geant_ip/index.rst
@@ -13,6 +13,7 @@ Submodules
    :titlesonly:
 
    create_geant_ip
-   modify_geant_ip
    create_imported_geant_ip
    import_geant_ip
+   migrate_geant_ip
+   modify_geant_ip
diff --git a/docs/source/module/workflows/geant_ip/migrate_geant_ip.rst b/docs/source/module/workflows/geant_ip/migrate_geant_ip.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fccea90684ed789a58198c2295a261a1a4eab166
--- /dev/null
+++ b/docs/source/module/workflows/geant_ip/migrate_geant_ip.rst
@@ -0,0 +1,6 @@
+``gso.workflows.geant_ip.migrate_geant_ip``
+===========================================
+
+.. automodule:: gso.workflows.geant_ip.migrate_geant_ip
+   :members:
+   :show-inheritance:
diff --git a/test/workflows/geant_ip/test_migrate_geant_ip.py b/test/workflows/geant_ip/test_migrate_geant_ip.py
new file mode 100644
index 0000000000000000000000000000000000000000..304fc75bb3abde349b6c2e4b7d793c87cce7ae40
--- /dev/null
+++ b/test/workflows/geant_ip/test_migrate_geant_ip.py
@@ -0,0 +1,46 @@
+import pytest
+
+from gso.products.product_types.geant_ip import GeantIP
+from test.workflows import assert_complete, extract_state, run_workflow
+
+
+@pytest.mark.workflow()
+def test_migrate_geant_ip_success(
+    faker, edge_port_subscription_factory, partner_factory, geant_ip_subscription_factory
+):
+    partner = partner_factory()
+    subscription_id = geant_ip_subscription_factory(partner=partner)
+    new_edge_port_1 = edge_port_subscription_factory(partner=partner)
+    new_edge_port_2 = edge_port_subscription_factory(partner=partner)
+    subscription = GeantIP.from_subscription(subscription_id)
+
+    form_input_data = [
+        {"subscription_id": subscription_id},
+        {
+            "tt_number": faker.tt_number(),
+            "edge_port_selection": [
+                {
+                    "old_edge_port": subscription.geant_ip.geant_ip_ap_list[0].geant_ip_sbp.edge_port.description,
+                    "new_edge_port": new_edge_port_1,
+                },
+                {
+                    "old_edge_port": subscription.geant_ip.geant_ip_ap_list[1].geant_ip_sbp.edge_port.description,
+                    "new_edge_port": new_edge_port_2,
+                },
+            ],
+        },
+    ]
+
+    result, _, _ = run_workflow("migrate_geant_ip", form_input_data)
+
+    assert_complete(result)
+    state = extract_state(result)
+    subscription = GeantIP.from_subscription(state["subscription_id"])
+    assert subscription.insync
+    assert len(subscription.geant_ip.geant_ip_ap_list) == 2
+    assert (
+        str(subscription.geant_ip.geant_ip_ap_list[0].geant_ip_sbp.edge_port.owner_subscription_id) == new_edge_port_1
+    )
+    assert (
+        str(subscription.geant_ip.geant_ip_ap_list[1].geant_ip_sbp.edge_port.owner_subscription_id) == new_edge_port_2
+    )