diff --git a/.gitignore b/.gitignore
index 0a116f850780386a9fe1010b22164f4c7dbf8228..a9144d6699af12319a67e8bad5cec982f3ae6a8c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -168,5 +168,8 @@ delete_local_deployment.sh
 local_docker_deployment.sh
 local_k8s_deployment.sh
 
+# asdf configuration
+.tool-versions
+
 # Other logs
 **/logs/*.log.*
diff --git a/manifests/teservice.yaml b/manifests/teservice.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2fca50879fccf3008d3a77f0206624f9c888e00c
--- /dev/null
+++ b/manifests/teservice.yaml
@@ -0,0 +1,79 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: teservice
+spec:
+  selector:
+    matchLabels:
+      app: teservice
+  template:
+    metadata:
+      labels:
+        app: teservice
+    spec:
+      terminationGracePeriodSeconds: 5
+      shareProcessNamespace: true
+      containers:
+      - name: server
+        image: registry.gitlab.com/teraflow-h2020/controller/te:latest
+        imagePullPolicy: Always
+        ports:
+        - containerPort: 11010
+        env:
+        - name: ERLANG_LOGGER_LEVEL
+          value: "debug"
+        - name: ERLANG_COOKIE
+          value: "tfte-unsafe-cookie"
+        - name: ERLANG_NODE_NAME
+          valueFrom:
+            fieldRef:
+              fieldPath: metadata.name
+        - name: ERLANG_NODE_IP
+          valueFrom:
+            fieldRef:
+              fieldPath: status.podIP
+        readinessProbe:
+          initialDelaySeconds: 10
+          periodSeconds: 10
+          exec:
+            command: ["/tfte/bin/tfte", "status"]
+        livenessProbe:
+          initialDelaySeconds: 10
+          periodSeconds: 10
+          exec:
+            command: ["/tfte/bin/tfte", "status"]
+        resources:
+          requests:
+            cpu: 250m
+            memory: 512Mi
+          limits:
+            cpu: 700m
+            memory: 1024Mi
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: teservice
+spec:
+  type: ClusterIP
+  selector:
+    app: teservice
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 11010
+    targetPort: 11010
diff --git a/src/te/.dockerignore b/src/te/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..558d2f3ece10e09c6a5ecd710c21e3f727bdd25c
--- /dev/null
+++ b/src/te/.dockerignore
@@ -0,0 +1,4 @@
+Dockerfile
+_build
+README.md
+.tool-versions
diff --git a/src/te/.gitignore b/src/te/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..eeb7cfc4aefeeb2f4fa86e208119ebc360c3f7af
--- /dev/null
+++ b/src/te/.gitignore
@@ -0,0 +1,21 @@
+.tool-versions
+.rebar3
+_*
+.eunit
+*.o
+*.beam
+*.plt
+*.swp
+*.swo
+.erlang.cookie
+ebin
+log
+erl_crash.dump
+.rebar
+logs
+_build
+.idea
+*.iml
+rebar3.crashdump
+*~
+config/dev.config
diff --git a/src/te/Dockerfile b/src/te/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..d8745ac740aafb5e9e6cf238fce4afae0ea440db
--- /dev/null
+++ b/src/te/Dockerfile
@@ -0,0 +1,55 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Multi-stage Docker image build
+
+# Build stage 0
+FROM erlang:24.3-alpine
+
+RUN mkdir /buildroot
+WORKDIR /buildroot
+
+# Copy our Erlang application
+COPY . tfte
+
+# And build the release
+WORKDIR tfte
+RUN rebar3 as prod release
+
+# Build stage 1
+FROM alpine
+
+# Install some libs
+RUN apk add --no-cache libgcc libstdc++ && \
+    apk add --no-cache openssl && \
+    apk add --no-cache ncurses-libs
+
+# Install the released application
+COPY --from=0 /buildroot/tfte/_build/prod/rel/tfte /tfte
+
+# Expose relevant ports
+#EXPOSE ????
+
+ARG ERLANG_LOGGER_LEVEL_DEFAULT=debug
+ARG ERLANG_COOKIE_DEFAULT=tfte-unsafe-cookie
+ARG ERLANG_NODE_IP_DEFAULT=127.0.0.1
+ARG ERLANG_NODE_NAME_DEFAULT=tfte
+
+ENV ERLANG_LOGGER_LEVEL=$ERLANG_LOGGER_LEVEL_DEFAULT
+ENV ERLANG_COOKIE=$ERLANG_COOKIE_DEFAULT
+ENV ERLANG_NODE_IP=$ERLANG_NODE_IP_DEFAULT
+ENV ERLANG_NODE_NAME=$ERLANG_NODE_NAME_DEFAULT
+
+ENTRYPOINT ["/tfte/bin/tfte"]
+CMD ["foreground"]
diff --git a/src/te/README.md b/src/te/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..764021a4fe7a5c6324a718e443ddedc22e47ab82
--- /dev/null
+++ b/src/te/README.md
@@ -0,0 +1,50 @@
+TeraFlow Traffic Engineering Service
+====================================
+
+The Traffic Engineering service is tested on Ubuntu 20.04. Follow the instructions below to build, test, and run this service on your local environment.
+
+
+## Build
+
+    $ rebar3 compile
+
+
+## Execute Unit Tests
+
+    $ rebar3 eunit
+
+
+## Run Service Console
+
+First you need to crete a configuration file if not already done, and customize it if required:
+
+	$ cp config/dev.config.template config/dev.config
+
+Then you  can start the service in console mode:
+
+    $ rebar3 shell
+
+
+## Build Docker Image
+
+    $ docker build -t te:dev .
+
+
+## Run Docker Container
+
+    $ docker run -d --name te --init te:dev
+
+
+## Open a Console to a Docker Container
+
+    $ docker exec -it te /tfte/bin/tfte remote_console
+
+
+## Open a Console to a Kubernetes Pod
+
+    $ kubectl --namespace tfs exec -ti $(kubectl --namespace tfs get pods --selector=app=teservice -o name) -- /tfte/bin/tfte remote_console
+
+
+## Show Logs
+
+    $ docker logs te
\ No newline at end of file
diff --git a/src/te/apps/tfte/src/tfte.app.src b/src/te/apps/tfte/src/tfte.app.src
new file mode 100644
index 0000000000000000000000000000000000000000..f1ed6cc8042d0621e1cbebc97fd54300c2603a0e
--- /dev/null
+++ b/src/te/apps/tfte/src/tfte.app.src
@@ -0,0 +1,15 @@
+{application, tfte,
+ [{description, "Teraflow Traffic Engineering Service"},
+  {vsn, "0.1.0"},
+  {registered, []},
+  {mod, {tfte_app, []}},
+  {applications,
+   [kernel,
+    stdlib
+   ]},
+  {env,[]},
+  {modules, []},
+
+  {licenses, ["Apache 2.0"]},
+  {links, []}
+ ]}.
diff --git a/src/te/apps/tfte/src/tfte_app.erl b/src/te/apps/tfte/src/tfte_app.erl
new file mode 100644
index 0000000000000000000000000000000000000000..aafcb2bcdf8e262b1de7c13c237fec13ca65472b
--- /dev/null
+++ b/src/te/apps/tfte/src/tfte_app.erl
@@ -0,0 +1,18 @@
+%%%-------------------------------------------------------------------
+%% @doc tfte public API
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(tfte_app).
+
+-behaviour(application).
+
+-export([start/2, stop/1]).
+
+start(_StartType, _StartArgs) ->
+    tfte_sup:start_link().
+
+stop(_State) ->
+    ok.
+
+%% internal functions
diff --git a/src/te/apps/tfte/src/tfte_sup.erl b/src/te/apps/tfte/src/tfte_sup.erl
new file mode 100644
index 0000000000000000000000000000000000000000..a6f0a21f8742bfb26abd8e549a92276e93557313
--- /dev/null
+++ b/src/te/apps/tfte/src/tfte_sup.erl
@@ -0,0 +1,35 @@
+%%%-------------------------------------------------------------------
+%% @doc tfte top level supervisor.
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(tfte_sup).
+
+-behaviour(supervisor).
+
+-export([start_link/0]).
+
+-export([init/1]).
+
+-define(SERVER, ?MODULE).
+
+start_link() ->
+    supervisor:start_link({local, ?SERVER}, ?MODULE, []).
+
+%% sup_flags() = #{strategy => strategy(),         % optional
+%%                 intensity => non_neg_integer(), % optional
+%%                 period => pos_integer()}        % optional
+%% child_spec() = #{id => child_id(),       % mandatory
+%%                  start => mfargs(),      % mandatory
+%%                  restart => restart(),   % optional
+%%                  shutdown => shutdown(), % optional
+%%                  type => worker(),       % optional
+%%                  modules => modules()}   % optional
+init([]) ->
+    SupFlags = #{strategy => one_for_all,
+                 intensity => 0,
+                 period => 1},
+    ChildSpecs = [],
+    {ok, {SupFlags, ChildSpecs}}.
+
+%% internal functions
diff --git a/src/te/config/dev.config.template b/src/te/config/dev.config.template
new file mode 100644
index 0000000000000000000000000000000000000000..d6a4644adf43612d32c34fef0474adb94a226a25
--- /dev/null
+++ b/src/te/config/dev.config.template
@@ -0,0 +1,19 @@
+[
+    {tfte, [
+    ]},
+
+    {kernel, [
+        {logger_level, debug},
+        {logger, [
+            {handler, default, logger_std_h, #{
+                level => debug,
+                filter_default => log,
+                config => #{type => standard_io},
+                formatter => {logger_formatter, #{
+                    legacy_header => false,
+                    single_line => true
+                }}
+            }}
+        ]}
+    ]}
+].
\ No newline at end of file
diff --git a/src/te/config/sys.config.src b/src/te/config/sys.config.src
new file mode 100644
index 0000000000000000000000000000000000000000..70003158be2bce02c1e224230094758faea5b19f
--- /dev/null
+++ b/src/te/config/sys.config.src
@@ -0,0 +1,19 @@
+[
+    {tfte, [
+    ]},
+
+    {kernel, [
+        {logger_level, ${ERLANG_LOGGER_LEVEL}},
+        {logger, [
+            {handler, default, logger_std_h, #{
+                level => info,
+                filter_default => log,
+                config => #{type => standard_io},
+                formatter => {logger_formatter, #{
+                    legacy_header => false,
+                    single_line => true
+                }}
+            }}
+        ]}
+    ]}
+].
\ No newline at end of file
diff --git a/src/te/config/vm.args.src b/src/te/config/vm.args.src
new file mode 100644
index 0000000000000000000000000000000000000000..899705ce169a8302bdd201751342db58b5c85421
--- /dev/null
+++ b/src/te/config/vm.args.src
@@ -0,0 +1,4 @@
++C multi_time_warp
++sbwt none
+-name ${ERLANG_NODE_NAME}@${ERLANG_NODE_IP}
+-setcookie ${ERLANG_COOKIE}
diff --git a/src/te/rebar.config b/src/te/rebar.config
new file mode 100644
index 0000000000000000000000000000000000000000..b7b5e3e69461faab1d5bdf742478c8ca03e616de
--- /dev/null
+++ b/src/te/rebar.config
@@ -0,0 +1,28 @@
+{erl_opts, [debug_info]}.
+
+{deps, [
+]}.
+
+{shell, [
+    {config, "config/dev.config"},
+    {apps, [tfte]}
+]}.
+
+{relx, [
+    {release, {tfte, "1.0.0"}, [tfte]},
+    {vm_args_src, "config/vm.args.src"},
+    {sys_config_src, "config/sys.config.src"},
+    {dev_mode, true},
+    {include_erts, false},
+    {extended_start_script, true}
+]}.
+
+{profiles, [
+    {prod, [
+        {relx, [
+            {dev_mode, false},
+            {include_erts, true},
+            {include_src, false}
+        ]}
+    ]}
+]}.
diff --git a/src/te/rebar.lock b/src/te/rebar.lock
new file mode 100644
index 0000000000000000000000000000000000000000..57afcca04590ff2bbf2f83b8eac4f856df782c74
--- /dev/null
+++ b/src/te/rebar.lock
@@ -0,0 +1 @@
+[].
diff --git a/tutorial/1-6-setup-erlang-environmnet.md b/tutorial/1-6-setup-erlang-environmnet.md
new file mode 100644
index 0000000000000000000000000000000000000000..11e65a49a5e2012a40cb18ab64f678009bdba1f1
--- /dev/null
+++ b/tutorial/1-6-setup-erlang-environmnet.md
@@ -0,0 +1,48 @@
+# 1.5. Setup Erlang Environment
+
+First we need to install Erlang. There is multiple way, for development we will be using asdf.
+
+## 1.5.1. Setup Erlang using asdf
+
+First, install any missing dependencies:
+
+    sudo apt install curl git autoconf libncurses-dev build-essential m4 libssl-dev 
+
+Download asdf:
+
+    git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.10.2
+
+Make asdf activate on login by adding these lines at the end of the `~/.bashrc` file:
+
+    . $HOME/.asdf/asdf.sh
+    . $HOME/.asdf/completions/asdf.bash
+
+Logout and log back in to activate asdf.
+
+Install asdf plugin for Erlang:
+
+    asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git
+
+Install Erlang:
+
+    asdf install erlang 24.3.4.2
+
+Activate Erlang locally for TFS controller:
+
+    cd tfs-ctrl/
+    asdf local erlang 24.3.4.2
+
+Install rebar3:
+
+    cd ~
+    git clone https://github.com/erlang/rebar3.git
+    cd rebar3
+    asdf local erlang 24.3.4.2
+    ./bootstrap
+    ./rebar3 local install
+
+Update `~/.bashrc` to use rebar3 by adding this line at the end:
+
+    export PATH=$HOME/.cache/rebar3/bin:$PATH
+
+Logout and log back in.