diff --git a/gso/migrations/versions/2023-05-08_61f8e90581c5_add_terminate_device_workflow.py b/gso/migrations/versions/2023-05-08_61f8e90581c5_add_terminate_device_workflow.py
new file mode 100644
index 0000000000000000000000000000000000000000..8b3f8398c9609c0de0ce56f2cb352aa2a335e1cc
--- /dev/null
+++ b/gso/migrations/versions/2023-05-08_61f8e90581c5_add_terminate_device_workflow.py
@@ -0,0 +1,39 @@
+"""add Terminate device workflow.
+
+Revision ID: 61f8e90581c5
+Revises: 21e7bb0e5cad
+Create Date: 2023-05-08 10:48:21.655880
+
+"""
+import sqlalchemy as sa
+from alembic import op
+
+# revision identifiers, used by Alembic.
+revision = '61f8e90581c5'
+down_revision = '21e7bb0e5cad'
+branch_labels = None
+depends_on = None
+
+
+from orchestrator.migrations.helpers import create_workflow, delete_workflow
+
+new_workflows = [
+    {
+        "name": "terminate_device",
+        "target": "TERMINATE",
+        "description": "Terminate device",
+        "product_type": "Device"
+    }
+]
+
+
+def upgrade() -> None:
+    conn = op.get_bind()
+    for workflow in new_workflows:
+        create_workflow(conn, workflow)
+
+
+def downgrade() -> None:
+    conn = op.get_bind()
+    for workflow in new_workflows:
+        delete_workflow(conn, workflow["name"])
diff --git a/gso/migrations/versions/2023-05-08_647e066bc99e_add_terminate_iptrunk_workflow.py b/gso/migrations/versions/2023-05-08_647e066bc99e_add_terminate_iptrunk_workflow.py
new file mode 100644
index 0000000000000000000000000000000000000000..49cb67b43eed421e58df6a54a900bffe58e04a3a
--- /dev/null
+++ b/gso/migrations/versions/2023-05-08_647e066bc99e_add_terminate_iptrunk_workflow.py
@@ -0,0 +1,39 @@
+"""add Terminate Iptrunk workflow.
+
+Revision ID: 647e066bc99e
+Revises: 61f8e90581c5
+Create Date: 2023-05-08 18:59:01.309425
+
+"""
+import sqlalchemy as sa
+from alembic import op
+
+# revision identifiers, used by Alembic.
+revision = '647e066bc99e'
+down_revision = '61f8e90581c5'
+branch_labels = None
+depends_on = None
+
+
+from orchestrator.migrations.helpers import create_workflow, delete_workflow
+
+new_workflows = [
+    {
+        "name": "terminate_iptrunk",
+        "target": "TERMINATE",
+        "description": "Terminate IPtrunk",
+        "product_type": "Iptrunk"
+    }
+]
+
+
+def upgrade() -> None:
+    conn = op.get_bind()
+    for workflow in new_workflows:
+        create_workflow(conn, workflow)
+
+
+def downgrade() -> None:
+    conn = op.get_bind()
+    for workflow in new_workflows:
+        delete_workflow(conn, workflow["name"])
diff --git a/gso/products/product_blocks/iptrunk.py b/gso/products/product_blocks/iptrunk.py
index f2c882bf9a68680c786f9c25ec00b2b838471d7d..40c0016dab7d0767e174de4a332098b185796008 100644
--- a/gso/products/product_blocks/iptrunk.py
+++ b/gso/products/product_blocks/iptrunk.py
@@ -27,14 +27,14 @@ class IptrunkBlockInactive(ProductBlockModel,
     iptrunk_sideA_node: DeviceBlockInactive
     iptrunk_sideA_ae_iface: Optional[str] = None
     iptrunk_sideA_ae_geant_a_sid: Optional[str] = None
-    iptrunk_sideA_ae_members: Optional[list] = None
-    iptrunk_sideA_ae_members_description: Optional[list] = None
+    iptrunk_sideA_ae_members: list[str] = Field(default_factory=list)
+    iptrunk_sideA_ae_members_description: list[str] = Field(default_factory=list)
     #
     iptrunk_sideB_node: DeviceBlockInactive
     iptrunk_sideB_ae_iface: Optional[str] = None
     iptrunk_sideB_ae_geant_a_sid: Optional[str] = None
-    iptrunk_sideB_ae_members: Optional[list] = None
-    iptrunk_sideB_ae_members_description: Optional[list] = None
+    iptrunk_sideB_ae_members: list[str] = Field(default_factory=list)
+    iptrunk_sideB_ae_members_description: list[str] = Field(default_factory=list)
 
 
 class IptrunkBlockProvisioning(IptrunkBlockInactive,
diff --git a/gso/workflows/__init__.py b/gso/workflows/__init__.py
index 1e11efa4d52a9a7270b4a48b0e757040c1e2e23b..268bada22e4b28b76ffc3e1371b1e23d2a8c2c47 100644
--- a/gso/workflows/__init__.py
+++ b/gso/workflows/__init__.py
@@ -5,4 +5,6 @@ LazyWorkflowInstance("gso.workflows.device.terminate_device",
                      "terminate_device")
 LazyWorkflowInstance("gso.workflows.device.get_facts", "get_facts")
 LazyWorkflowInstance("gso.workflows.iptrunk.create_iptrunk", "create_iptrunk")
+LazyWorkflowInstance("gso.workflows.iptrunk.terminate_iptrunk",
+                     "terminate_iptrunk")
 LazyWorkflowInstance("gso.workflows.site.create_site", "create_site")
diff --git a/gso/workflows/device/create_device.py b/gso/workflows/device/create_device.py
index f501fe15317f0eb5a5d65ed75c45c562f6bbc552..3f9cddceeb80b40ef79a3e73e65e05b4dd4c8047 100644
--- a/gso/workflows/device/create_device.py
+++ b/gso/workflows/device/create_device.py
@@ -75,8 +75,8 @@ def get_info_from_ipam(subscription: device.DeviceInactive) -> State:
     # subscription.device.lo_ipv4_address = lo.v4
     # subscription.device.lo_ipv6_address = lo.v6
     # TODO: get info about how these should be generated
-    subscription.device.device_lo_ipv4_address = "10.10.10.10"
-    subscription.device.device_lo_ipv6_address = "fc00:798:10::10"
+    subscription.device.device_lo_ipv4_address = ipaddress.ip_address('10.10.10.10')
+    subscription.device.device_lo_ipv6_address = ipaddress.ip_address('fc00:798:10::10')
     subscription.device.device_lo_iso_address \
         = "49.51e5.0001.0620.4009.6047.00"
     subscription.device.device_si_ipv4_network = "192.168.0.0/31"
diff --git a/gso/workflows/device/terminate_device.py b/gso/workflows/device/terminate_device.py
index 686128a19e0464a0d579b1370c21af3a746ba17b..d5de3c3d17f22d220da5001241f306e283d94d10 100644
--- a/gso/workflows/device/terminate_device.py
+++ b/gso/workflows/device/terminate_device.py
@@ -41,7 +41,7 @@ def deprovision_user(subscription: Device) -> None:
                        initial_input_form_generator),
     target=Target.TERMINATE,
 )
-def terminate_user():
+def terminate_device():
     return (
         init
         >> store_process_subscription(Target.TERMINATE)
diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py
index e4205e111c699e8fbf3992a02eb4732b628e3cc8..2b485a9b18f8444d528684069514c68eac7a4965 100644
--- a/gso/workflows/iptrunk/create_iptrunk.py
+++ b/gso/workflows/iptrunk/create_iptrunk.py
@@ -1,4 +1,4 @@
-# import ipaddress
+import ipaddress
 from uuid import uuid4
 
 from orchestrator.forms import FormPage
@@ -19,6 +19,8 @@ from gso.products.product_types.device import Device
 # from gso.products.product_types import device
 from orchestrator.db.models import ProductTable, SubscriptionTable
 from orchestrator.forms.validators import Choice, choice_list
+from orchestrator.utils.json import json_dumps
+
 
 
 def device_selector(choice_value: str) -> list:
@@ -91,8 +93,8 @@ def create_subscription(product: UUIDstr) -> State:
 @step("Get information from IPAM ")
 def get_info_from_ipam(subscription: iptrunk.IptrunkInactive) -> State:
     # TODO: get info about how these should be generated
-    subscription.iptrunk.iptrunk_ipv4_network = "192.168.1.0/31"
-    subscription.iptrunk.iptrunk_ipv6_network = "fc00:798:1::150/126"
+    subscription.iptrunk.iptrunk_ipv4_network = ipaddress.ip_network('192.168.255.0/31')
+    subscription.iptrunk.iptrunk_ipv6_network = ipaddress.ip_network('fc00:798:255::150/126')
     return {"subscription": subscription}
 
 
@@ -153,35 +155,30 @@ def initialize_subscription(
 def provision_iptrunk_dry(
     subscription: iptrunk.IptrunkProvisioning,
 ) -> State:
-    # import ansible_runner
-    #
-    # r = ansible_runner.run(
-    #     private_data_dir="/opt/geant-gap-ansible",
-    #     playbook="base_config.yaml",
-    #     inventory=subscription.iptrunk.fqdn,
-    #     extravars={
-    #         "lo_ipv4_address": str(subscription.iptrunk.lo_ipv4_address),
-    #         "lo_ipv6_address": str(subscription.iptrunk.lo_ipv6_address),
-    #         "lo_iso_address": subscription.iptrunk.lo_iso_address,
-    #         "snmp_location": subscription.iptrunk.snmp_location,
-    #         "si_ipv4_network": str(subscription.iptrunk.si_ipv4_network),
-    #         "lt_ipv4_network": str(subscription.iptrunk.ias_lt_ipv4_network),
-    #         "lt_ipv6_network": str(subscription.iptrunk.ias_lt_ipv6_network),
-    #         "site_country_code": subscription.iptrunk.site_country_code,
-    #         "verb": "deploy",
-    #     },
-    # )
-    # out = r.stdout.read()
-    # out_splitted = out.splitlines()
+    import ansible_runner
+    
+    r = ansible_runner.run(
+        private_data_dir="/opt/geant-gap-ansible",
+        playbook="iptrunks.yaml",
+        inventory= str(subscription.iptrunk.iptrunk_sideA_node.device_fqdn +"\n"+
+                    subscription.iptrunk.iptrunk_sideB_node.device_fqdn+"\n"),
+        extravars={
+            "verb": "compile",
+            "wfo_trunk_json":json_dumps(subscription),
+            "config_object":"trunk_interface",
+        },
+    )
+    out = r.stdout.read()
+    out_splitted = out.splitlines()
     # # if r.rc != 0:
     # #    raise ValueError("Ansible has failed")
-    # return {"dry_run_output": out_splitted, "return_code": r.rc}
+    return {"dry_run_output": out_splitted, "return_code": r.rc}
     #  provisioning_proxy.provision_node(
     #      node_subscription_params=subscription,
     #      dry_run=True)
     #   TODO: figure out what to return when we are suspending & waiting
     #       for the provisioning-proxy to call back
-    return {"return_code": 0}
+    #return {"return_code": 0}
 
 
 @inputstep("Confirm step", assignee="CHANGES")
diff --git a/gso/workflows/iptrunk/terminate_iptrunk.py b/gso/workflows/iptrunk/terminate_iptrunk.py
new file mode 100644
index 0000000000000000000000000000000000000000..ddb65eacfd800868a76f2a5fe5b4f0a472035d42
--- /dev/null
+++ b/gso/workflows/iptrunk/terminate_iptrunk.py
@@ -0,0 +1,53 @@
+from orchestrator.forms import FormPage
+from orchestrator.forms.validators import Label
+from orchestrator.targets import Target
+from orchestrator.types import InputForm, SubscriptionLifecycle, UUIDstr
+from orchestrator.workflow import done, init, step, workflow
+from orchestrator.workflows.steps import (
+    resync,
+    set_status,
+    store_process_subscription,
+    unsync,
+)
+from orchestrator.workflows.utils import wrap_modify_initial_input_form
+
+from gso.products.product_types.iptrunk import Iptrunk
+
+
+def initial_input_form_generator(subscription_id: UUIDstr) -> InputForm:
+    subscription = Iptrunk.from_subscription(subscription_id)
+
+    class TerminateForm(FormPage):
+        are_you_sure: Label = (
+            f"Are you sure you want to remove {subscription.description}?"
+        )  # type:ignore
+
+    return TerminateForm
+
+
+def _deprovision_in_user_management_system(fqdn: str) -> str:
+    pass
+
+
+@step("Deprovision Iptrunk")
+def deprovision_iptrunk(subscription: Iptrunk) -> None:
+    #    _deprovision_in_user_management_system(subscription.user.user_id)
+    pass
+
+
+@workflow(
+    "Terminate IPtrunk",
+    initial_input_form=wrap_modify_initial_input_form(
+                       initial_input_form_generator),
+    target=Target.TERMINATE,
+)
+def terminate_iptrunk():
+    return (
+        init
+        >> store_process_subscription(Target.TERMINATE)
+        >> unsync
+        >> deprovision_iptrunk
+        >> set_status(SubscriptionLifecycle.TERMINATED)
+        >> resync
+        >> done
+    )