diff --git a/workflows/__init__.py b/workflows/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..9dc5e5f196823138f4415f7c7eeb2b02a51d4017
--- /dev/null
+++ b/workflows/__init__.py
@@ -0,0 +1,6 @@
+from orchestrator.workflows import LazyWorkflowInstance
+
+LazyWorkflowInstance("workflows.trunk.create_trunk", "create_trunk")
+LazyWorkflowInstance("workflows.trunk.create_trunk_config", "create_trunk_config")
+LazyWorkflowInstance("workflows.trunk.create_trunk_config_common", "create_trunk_config_common")
+LazyWorkflowInstance("workflows.trunk.create_trunk_config_side", "create_trunk_config_side")
diff --git a/workflows/trunk/create_trunk.py b/workflows/trunk/create_trunk.py
new file mode 100644
index 0000000000000000000000000000000000000000..16c5444bcc46b7c572bcc2fd05d6b62d2f141b21
--- /dev/null
+++ b/workflows/trunk/create_trunk.py
@@ -0,0 +1,73 @@
+from typing import Optional
+from uuid import uuid4
+
+from orchestrator.forms import FormPage
+from orchestrator.targets import Target
+from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr
+from orchestrator.workflow import done, init, step, workflow
+from orchestrator.workflows.steps import resync, set_status, store_process_subscription
+from orchestrator.workflows.utils import wrap_create_initial_input_form
+
+from products.product_types.trunk import TrunkInactive, TrunkProvisioning
+
+
+def initial_input_form_generator(product_name: str) -> FormGenerator:
+    class CreateTrunkForm(FormPage):
+        class Config:
+            title = product_name
+
+        trunk_name: str
+        geant_s_sid: Optional[str]
+
+    user_input = yield CreateTrunkForm
+
+    return user_input.dict()
+
+
+def _provision_in_group_management_system(trunk_name: str) -> int:
+
+    return abs(hash(trunk_name))
+
+
+@step("Create subscription")
+def create_subscription(product: UUIDstr) -> State:
+    subscription = TrunkInactive.from_product_id(product, uuid4())
+
+    return {"subscription": subscription, "subscription_id": subscription.subscription_id}
+
+
+@step("Initialize subscription")
+def initialize_subscription(subscription: TrunkInactive, trunk_name: str, geant_s_sid: str) -> State:
+    subscription.trunk.trunk_name = trunk_name
+    subscription.trunk.geant_s_sid = geant_s_sid
+    subscription.description = f"Trunk {trunk_name}"
+    subscription = TrunkProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING)
+
+    return {"subscription": subscription}
+
+
+@step("Provision trunk")
+def provision_trunk(subscription: TrunkProvisioning, trunk_name: str) -> State:
+    trunk_id = _provision_in_group_management_system(trunk_name)
+    subscription.trunk.trunk_id = trunk_id
+
+    return {"subscription": subscription}
+
+
+@workflow(
+    "Create trunk",
+    initial_input_form=wrap_create_initial_input_form(initial_input_form_generator),
+    target=Target.CREATE,
+)
+def create_trunk():
+
+    return (
+        init
+        >> create_subscription
+        >> store_process_subscription(Target.CREATE)
+        >> initialize_subscription
+        >> provision_trunk
+        >> set_status(SubscriptionLifecycle.ACTIVE)
+        >> resync
+        >> done
+    )
diff --git a/workflows/trunk/create_trunk_config.py b/workflows/trunk/create_trunk_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..44464dd06db494503ca6d65179887115604ff66f
--- /dev/null
+++ b/workflows/trunk/create_trunk_config.py
@@ -0,0 +1,95 @@
+from typing import List, Optional
+from uuid import uuid4
+from random import randint
+
+from orchestrator.db.models import ProductTable, SubscriptionTable
+from orchestrator.forms import FormPage
+from orchestrator.forms.validators import Choice, choice_list
+from orchestrator.targets import Target
+from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr
+from orchestrator.workflow import done, init, step, workflow
+from orchestrator.workflows.steps import resync, set_status, store_process_subscription
+from orchestrator.workflows.utils import wrap_create_initial_input_form
+
+from products.product_types.trunk_config import TrunkConfigInactive, TrunkConfigProvisioning
+from products.product_types.trunk import Trunk
+
+
+def trunk_selector() -> list:
+    trunk_subscriptions = {}
+    for trunk_id, trunk_description in (
+        SubscriptionTable.query.join(ProductTable)
+        .filter(
+            ProductTable.product_type == "Trunk",
+            SubscriptionTable.status == "active",
+        )
+        .with_entities(SubscriptionTable.subscription_id, SubscriptionTable.description)
+        .all()
+    ):
+        trunk_subscriptions[str(trunk_id)] = trunk_description
+
+    return choice_list(
+        Choice("TrunkEnum", zip(trunk_subscriptions.keys(), trunk_subscriptions.items())),
+        min_items=1,
+        max_items=1,
+    )
+
+
+def initial_input_form_generator(product_name: str) -> FormGenerator:
+    class CreateTrunkConfigForm(FormPage):
+        class Config:
+            title = product_name
+
+        trunk_ids: trunk_selector()
+
+    user_input = yield CreateTrunkConfigForm
+
+    return user_input.dict()
+
+
+def _provision_in_group_management_system() -> int:
+
+    return random.randint(0, 2147483648)
+
+
+@step("Create subscription")
+def create_subscription(product: UUIDstr) -> State:
+    subscription = TrunkConfigInactive.from_product_id(product, uuid4())
+
+    return {"subscription": subscription, "subscription_id": subscription.subscription_id}
+
+
+@step("Initialize subscription")
+def initialize_subscription(subscription: TrunkConfigInactive, trunk_ids: List[str]) -> State:
+    subscription.trunk_config.trunk = Trunk.from_subscription(trunk_ids[0]).trunk
+    subscription.description = f"TrunkConfig from Trunk {subscription.trunk_config.trunk.trunk_name}"
+    subscription = TrunkConfigProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING)
+
+    return {"subscription": subscription}
+
+
+@step("Provision trunk config")
+def provision_trunk_config(subscription: TrunkConfigProvisioning) -> State:
+    trunk_config_id = _provision_in_group_management_system()
+    subscription.trunk_config.trunk_config_id = trunk_config_id
+
+    return {"subscription": subscription}
+
+
+@workflow(
+    "Create trunk config",
+    initial_input_form=wrap_create_initial_input_form(initial_input_form_generator),
+    target=Target.CREATE,
+)
+def create_trunk():
+
+    return (
+        init
+        >> create_subscription
+        >> store_process_subscription(Target.CREATE)
+        >> initialize_subscription
+        >> provision_trunk_config
+        >> set_status(SubscriptionLifecycle.ACTIVE)
+        >> resync
+        >> done
+    )
diff --git a/workflows/trunk/create_trunk_config_common.py b/workflows/trunk/create_trunk_config_common.py
new file mode 100644
index 0000000000000000000000000000000000000000..875a9f39e6f2ef04bbe4d925c8df79b068a97a6f
--- /dev/null
+++ b/workflows/trunk/create_trunk_config_common.py
@@ -0,0 +1,102 @@
+from typing import List, Optional
+from uuid import uuid4
+
+from orchestrator.db.models import ProductTable, SubscriptionTable
+from orchestrator.forms import FormPage
+from orchestrator.forms.validators import Choice, choice_list
+from orchestrator.targets import Target
+from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr
+from orchestrator.workflow import done, init, step, workflow
+from orchestrator.workflows.steps import resync, set_status, store_process_subscription
+from orchestrator.workflows.utils import wrap_create_initial_input_form
+
+from products.product_types.trunk_config_common import TrunkConfigCommonInactive, TrunkConfigCommonProvisioning
+from products.product_types.trunk_config import TrunkConfig
+
+
+def trunk_config_selector() -> list:
+    trunk_config_subscriptions = {}
+    for trunk_config_id, trunk_config_description in (
+        SubscriptionTable.query.join(ProductTable)
+        .filter(
+            ProductTable.product_type == "TrunkConfig",
+            SubscriptionTable.status == "active",
+        )
+        .with_entities(SubscriptionTable.subscription_id, SubscriptionTable.description)
+        .all()
+    ):
+        trunk_config_subscriptions[str(trunk_config_id)] = trunk_config_description
+
+    return choice_list(
+        Choice("TrunkConfigEnum", zip(trunk_config_subscriptions.keys(), trunk_config_subscriptions.items())),
+        min_items=1,
+        max_items=1,
+    )
+
+
+def initial_input_form_generator(product_name: str) -> FormGenerator:
+    class CreateTrunkConfigForm(FormPage):
+        class Config:
+            title = product_name
+
+        speed: str
+        is_leased_line: Optional[bool]
+        isis_metric: int
+        minimum_links: int
+        trunk_config_ids: trunk_config_selector()
+
+    user_input = yield CreateTrunkConfigCommonForm
+
+    return user_input.dict()
+
+
+def _provision_in_group_management_system() -> int:
+
+    return random.randint(0, 2147483648)
+
+
+@step("Create subscription")
+def create_subscription(product: UUIDstr) -> State:
+    subscription = TrunkConfigCommonInactive.from_product_id(product, uuid4())
+
+    return {"subscription": subscription, "subscription_id": subscription.subscription_id}
+
+
+@step("Initialize subscription")
+def initialize_subscription(subscription: TrunkConfigCommonInactive, speed: str, is_leased_line: bool, isis_metric: int, minimum_links: int, trunk_config_ids: List[str]) -> State:
+    subscription.trunk_config_common.speed = speed
+    subscription.trunk_config_common.is_leased_line = is_leased_line
+    subscription.trunk_config_common.isis_metric = isis_metric
+    subscription.trunk_config_common.minimum_links = minimum_links
+    subscription.trunk_config_common.trunk_config = TrunkConfig.from_subscription(trunk_config_ids[0]).trunk_config
+    subscription.description = f"TrunkConfigCommon from TrunkConfig {subscription.trunk_config_common.trunk_config.trunk_config_id}"
+    subscription = TrunkConfigCommonProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING)
+
+    return {"subscription": subscription}
+
+
+@step("Provision trunk config common")
+def provision_trunk_config_common(subscription: TrunkConfigCommonProvisioning) -> State:
+    trunk_config_common_id = _provision_in_group_management_system()
+    subscription.trunk_config_common.trunk_config_common_id = trunk_config_common_id
+
+    return {"subscription": subscription}
+
+
+@workflow(
+    "Create trunk config common",
+    initial_input_form=wrap_create_initial_input_form(initial_input_form_generator),
+    target=Target.CREATE,
+)
+def create_trunk():
+
+    return (
+        init
+        >> create_subscription
+        >> store_process_subscription(Target.CREATE)
+        >> initialize_subscription
+        >> provision_trunk_config_common
+        >> set_status(SubscriptionLifecycle.ACTIVE)
+        >> resync
+        >> done
+    )
diff --git a/workflows/trunk/create_trunk_config_side.py b/workflows/trunk/create_trunk_config_side.py
new file mode 100644
index 0000000000000000000000000000000000000000..5b67836f162e95b090169a6e5038cd1e892606b1
--- /dev/null
+++ b/workflows/trunk/create_trunk_config_side.py
@@ -0,0 +1,106 @@
+from typing import List, Optional
+from uuid import uuid4
+
+from orchestrator.db.models import ProductTable, SubscriptionTable
+from orchestrator.forms import FormPage
+from orchestrator.forms.validators import Choice, choice_list
+from orchestrator.targets import Target
+from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr
+from orchestrator.workflow import done, init, step, workflow
+from orchestrator.workflows.steps import resync, set_status, store_process_subscription
+from orchestrator.workflows.utils import wrap_create_initial_input_form
+
+from products.product_types.trunk_config_side import TrunkConfigSideInactive, TrunkConfigSideProvisioning
+from products.product_types.trunk_config import TrunkConfig
+
+
+def trunk_config_selector() -> list:
+    trunk_config_subscriptions = {}
+    for trunk_config_id, trunk_config_description in (
+        SubscriptionTable.query.join(ProductTable)
+        .filter(
+            ProductTable.product_type == "TrunkConfig",
+            SubscriptionTable.status == "active",
+        )
+        .with_entities(SubscriptionTable.subscription_id, SubscriptionTable.description)
+        .all()
+    ):
+        trunk_config_subscriptions[str(trunk_config_id)] = trunk_config_description
+
+    return choice_list(
+        Choice("TrunkConfigEnum", zip(trunk_config_subscriptions.keys(), trunk_config_subscriptions.items())),
+        min_items=1,
+        max_items=1,
+    )
+
+
+def initial_input_form_generator(product_name: str) -> FormGenerator:
+    class CreateTrunkConfigForm(FormPage):
+        class Config:
+            title = product_name
+
+        fqdn: str
+        ae_name: Optional[str]
+        geant_a_sid: Optional[str]
+        ipv4_address: Optional[str]
+        ipv6_address: Optional[str]
+        members: Optional[list]
+        trunk_config_ids: trunk_config_selector()
+
+    user_input = yield CreateTrunkConfigSideForm
+
+    return user_input.dict()
+
+
+def _provision_in_group_management_system(fqdn: str) -> int:
+
+    return abs(hash(fqdn))
+
+
+@step("Create subscription")
+def create_subscription(product: UUIDstr) -> State:
+    subscription = TrunkConfigSideInactive.from_product_id(product, uuid4())
+
+    return {"subscription": subscription, "subscription_id": subscription.subscription_id}
+
+
+@step("Initialize subscription")
+def initialize_subscription(subscription: TrunkConfigSideInactive, fqdn: str, ae_name: str, geant_a_sid: str, ipv4_address: str, ipv6_address: str, members: list, trunk_config_ids: List[str]) -> State:
+    subscription.trunk_config_side.fqdn = fqdn
+    subscription.trunk_config_side.ae_name = ae_name
+    subscription.trunk_config_side.geant_a_sid = geant_a_sid
+    subscription.trunk_config_side.ipv4_address = ipv4_address
+    subscription.trunk_config_side.ipv6_address = ipv6_address
+    subscription.trunk_config_side.members = members
+    subscription.trunk_config_side.trunk_config = TrunkConfig.from_subscription(trunk_config_ids[0]).trunk_config
+    subscription.description = f"TrunkConfigSide from TrunkConfig {subscription.trunk_config_side.trunk_config.trunk_config_id}"
+    subscription = TrunkConfigSideProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING)
+
+    return {"subscription": subscription}
+
+
+@step("Provision trunk config side")
+def provision_trunk_config_side(subscription: TrunkConfigSideProvisioning, fqdn: str) -> State:
+    trunk_config_side_id = _provision_in_group_management_system(fqdn)
+    subscription.trunk_config_side.trunk_config_side_id = trunk_config_side_id
+
+    return {"subscription": subscription}
+
+
+@workflow(
+    "Create trunk config side",
+    initial_input_form=wrap_create_initial_input_form(initial_input_form_generator),
+    target=Target.CREATE,
+)
+def create_trunk():
+
+    return (
+        init
+        >> create_subscription
+        >> store_process_subscription(Target.CREATE)
+        >> initialize_subscription
+        >> provision_trunk_config_side
+        >> set_status(SubscriptionLifecycle.ACTIVE)
+        >> resync
+        >> done
+    )