diff --git a/helm/.helmignore b/helm/.helmignore
new file mode 100644
index 0000000000000000000000000000000000000000..0e8a0eb36f4ca2c939201c0d54b5d82a1ea34778
--- /dev/null
+++ b/helm/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/helm/Chart.yaml b/helm/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..969a2ef6044fa8b4fe749da1aef70295d3dc4a36
--- /dev/null
+++ b/helm/Chart.yaml
@@ -0,0 +1,23 @@
+apiVersion: v2
+name: oslsylva
+description: OSL Sylva Operator Helm chart for Kubernetes
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.0.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+appVersion: 0.0.1
diff --git a/helm/files/org.etsi.osl.controllers.sylva/config b/helm/files/org.etsi.osl.controllers.sylva/config
new file mode 100644
index 0000000000000000000000000000000000000000..11764038afa4e39de82cc537994a03903690cde2
--- /dev/null
+++ b/helm/files/org.etsi.osl.controllers.sylva/config
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Config
+clusters:
+- name: development-cluster
+  cluster:
+    certificate-authority: path/to/ca.crt # Path to certificate authority file
+    server: https://123.45.67.89:6443 # Cluster API server address
+contexts:
+- name: dev-user@development-cluster
+  context:
+    cluster: development-cluster
+    namespace: development # Default namespace
+    user: dev-user
+current-context: dev-user@development-cluster
+users:
+- name: dev-user
+  user:
+    client-certificate: path/to/cert.crt # Path to the client certificate
+    client-key: path/to/key.key # Path to the client key
diff --git a/helm/files/org.etsi.osl.controllers.sylva/management-cluster-kubeconfig b/helm/files/org.etsi.osl.controllers.sylva/management-cluster-kubeconfig
new file mode 100644
index 0000000000000000000000000000000000000000..11764038afa4e39de82cc537994a03903690cde2
--- /dev/null
+++ b/helm/files/org.etsi.osl.controllers.sylva/management-cluster-kubeconfig
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Config
+clusters:
+- name: development-cluster
+  cluster:
+    certificate-authority: path/to/ca.crt # Path to certificate authority file
+    server: https://123.45.67.89:6443 # Cluster API server address
+contexts:
+- name: dev-user@development-cluster
+  context:
+    cluster: development-cluster
+    namespace: development # Default namespace
+    user: dev-user
+current-context: dev-user@development-cluster
+users:
+- name: dev-user
+  user:
+    client-certificate: path/to/cert.crt # Path to the client certificate
+    client-key: path/to/key.key # Path to the client key
diff --git a/helm/templates/SylvaMDResourceOperator.yaml b/helm/templates/SylvaMDResourceOperator.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..46cab1aefb0c40d51f8e80db0107b099da71f321
--- /dev/null
+++ b/helm/templates/SylvaMDResourceOperator.yaml
@@ -0,0 +1,39 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  name: sylvamdresources.controllers.osl.etsi.org  # Name of the CRD
+spec:
+  group: controllers.osl.etsi.org          # Custom resource group
+  names:
+    kind: SylvaMDResource      # Name of the resource type
+    plural: sylvamdresources           # Plural form of the resource
+    singular: sylvamdresource          # Singular form of the resource
+  scope: Namespaced            # Namespaced resource
+  versions:
+    - name: v1alpha1                 # Version of the CRD
+      served: true
+      storage: true
+      schema:
+        openAPIV3Schema:
+          type: object
+          properties:
+            spec:
+              type: object
+              properties:
+                valuesyaml:
+                  type: string
+                clusterControlPlaneReplicas:
+                  type: string
+                clusterMd0Replicas:
+                  type: string
+            status:
+              type: object
+              properties:
+                state:
+                  type: string
+                stateText:
+                  type: string
+                infoText:
+                  type: string
+                secret:
+                  type: string
diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..89f9f71fba483f569751099ef78cdfb1da8a3f4c
--- /dev/null
+++ b/helm/templates/_helpers.tpl
@@ -0,0 +1,62 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "openslice.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "openslice.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "openslice.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "openslice.labels" -}}
+helm.sh/chart: {{ include "openslice.chart" . }}
+{{ include "openslice.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "openslice.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "openslice.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "openslice.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "openslice.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2c15994ec271010c34b5048a4e2103ebee9f6624
--- /dev/null
+++ b/helm/templates/deployment.yaml
@@ -0,0 +1,56 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:	
+  namespace: {{ .Release.Namespace }}
+  labels:
+    app: {{ include "openslice.fullname" . }}
+    org.etsi.osl.service: oslsylva
+    chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
+    {{- include "openslice.labels" . | nindent 4 }}
+  name: {{ include "openslice.fullname" . }}-oslsylva
+spec:
+  {{- if not .Values.autoscaling.enabled }}
+  replicas: {{ .Values.replicaCount }}
+  {{- end }}
+  selector:
+    matchLabels:
+      app: {{ include "openslice.fullname" . }}
+      org.etsi.osl.service: oslsylva
+      {{- include "openslice.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      labels:
+        app: {{ include "openslice.fullname" . }}
+        org.etsi.osl.service: oslsylva
+        {{- include "openslice.selectorLabels" . | nindent 8 }}
+    spec:
+      containers:
+        - image: "{{ .Values.image.oslsylva.repository }}:{{ .Values.image.oslsylva.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.image.oslsylva.pullPolicy | default "Always" }}
+          name: {{ include "openslice.fullname" . }}-oslsylva
+          env:
+            - name: SPRING_APPLICATION_JSON
+              value: >-
+                {
+                  "logging.level.org.springframework" : "{{ .Values.spring.logLevel | default "INFO" }}",
+                  "logging.level.org.etsi.osl.controllers.sylva" : "{{ .Values.logLevel | default "INFO" }}" 
+                }
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+          volumeMounts:
+            - name: oslsylva-kubeconfig
+              readOnly: true
+              mountPath: /root/.kube/config
+              subPath: config
+            - name: oslsylva-sylvamgtcluster-config
+              readOnly: true
+              mountPath: /opt/sylva-core/management-cluster-kubeconfig
+              subPath: management-cluster-kubeconfig
+      restartPolicy: Always
+      volumes:
+        - name: oslsylva-kubeconfig
+          secret:
+            secretName: {{ include "openslice.fullname" . }}-oslsylva-kubeconfig
+        - name: oslsylva-sylvamgtcluster-config
+          secret:
+            secretName: {{ include "openslice.fullname" . }}-oslsylva-sylvamgtcluster-config
diff --git a/helm/templates/secret-conf.yaml b/helm/templates/secret-conf.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ec596b3398f1c095278ba5334b8f2ecaa2c7c0cb
--- /dev/null
+++ b/helm/templates/secret-conf.yaml
@@ -0,0 +1,15 @@
+{{- $kubeconfig := .Values.kubeconfig | default (.Files.Get "files/org.etsi.osl.controllers.sylva/config") -}}
+apiVersion: v1
+kind: Secret
+metadata:
+  namespace: {{ .Release.Namespace }}
+  labels:
+    app: {{ include "openslice.fullname" . }}
+    org.etsi.osl.service: org.etsi.osl.controllers.sylva
+    chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
+    {{- include "openslice.labels" . | nindent 4 }}
+  name: {{ include "openslice.fullname" . }}-oslsylva-kubeconfig
+type: Opaque
+data:
+  config: |-
+    {{- required "A kubeconfig file is required." ($kubeconfig | b64enc) | nindent 4 }}
diff --git a/helm/templates/secret-sylvamgt-config.yaml b/helm/templates/secret-sylvamgt-config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..50bf6702f596ea87cbef7dbae4e4409354db1114
--- /dev/null
+++ b/helm/templates/secret-sylvamgt-config.yaml
@@ -0,0 +1,15 @@
+{{- $sylvamgtconfig := .Values.sylvamgtconfig | default (.Files.Get "files/org.etsi.osl.controllers.sylva/management-cluster-kubeconfig") -}}
+apiVersion: v1
+kind: Secret
+metadata:
+  namespace: {{ .Release.Namespace }}
+  labels:
+    app: {{ include "openslice.fullname" . }}
+    org.etsi.osl.service: org.etsi.osl.controllers.sylva
+    chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
+    {{- include "openslice.labels" . | nindent 4 }}
+  name: {{ include "openslice.fullname" . }}-oslsylva-sylvamgtcluster-config
+type: Opaque
+data:
+  management-cluster-kubeconfig: |-
+    {{- required "A kubeconfig file is required." ($sylvamgtconfig | b64enc) | nindent 4 }}
diff --git a/helm/values.yaml b/helm/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4759c93f846fea65064977cd750e326eeb7c3760
--- /dev/null
+++ b/helm/values.yaml
@@ -0,0 +1,30 @@
+# Default values for oslsylva.
+
+replicaCount: 1
+
+image:
+  oslsylva:
+    repository: labs.etsi.org:5050/osl/code/addons/org.etsi.osl.controllers.sylva
+    pullPolicy: Always
+    # Overrides the image tag whose default is the chart appVersion.
+    tag: "latest"
+
+logLevel: INFO
+spring:
+  loglevel: INFO
+
+autoscaling:
+  enabled: false
+  minReplicas: 1
+  maxReplicas: 100
+  targetCPUUtilizationPercentage: 80
+  targetMemoryUtilizationPercentage: 80
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ""