diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000000000000000000000000000000000..1fc8abd4492c8fed0e5b9ecb3724b1a54b8bab68
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,19 @@
+#   Copyright 2020 Canonical Ltd.
+#
+#   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.
+[submodule "installers/charm/pla/mod/operator"]
+	path = installers/charm/pla/mod/operator
+	url = https://github.com/canonical/operator
+[submodule "installers/charm/ng-ui/mod/operator"]
+	path = installers/charm/ng-ui/mod/operator
+	url = https://github.com/canonical/operator
diff --git a/docker/LCM/Dockerfile b/docker/LCM/Dockerfile
index 5733f2275f889027580db1ab7eadd47649b0deb2..0a2344e36bcfcbbd80379ec0391de7cc2e6f8c35 100644
--- a/docker/LCM/Dockerfile
+++ b/docker/LCM/Dockerfile
@@ -70,7 +70,7 @@ RUN curl -L https://launchpad.net/juju/2.7/2.7.6/+download/juju-2.7.6-k8s.tar.xz
     && mv juju /usr/local/bin/juju
 
 ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseSEVEN-daily
+ARG RELEASE=ReleaseEIGHT-daily
 ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
 ARG REPOSITORY=testing
 
diff --git a/docker/MON/Dockerfile b/docker/MON/Dockerfile
index 29cc893b40f7c69ca98ae440fa9c3768ce02422c..a91b957d6fb237d5f495c199629939b27f071328 100644
--- a/docker/MON/Dockerfile
+++ b/docker/MON/Dockerfile
@@ -45,7 +45,7 @@ RUN pip3 install  'macaroonbakery>=1.1,<2.0' 'pyRFC3339>=1.0,<2.0' \
       'paramiko' 'dogpile.cache==0.9.2'
 
 ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseFOUR-daily
+ARG RELEASE=ReleaseEIGHT-daily
 ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
 ARG REPOSITORY=testing
 
diff --git a/docker/NBI/Dockerfile b/docker/NBI/Dockerfile
index 5d756b32cce111d9828eacc467d96f4f36f5859a..f15188d09cd85d790f79a16ce68eb0955030d552 100644
--- a/docker/NBI/Dockerfile
+++ b/docker/NBI/Dockerfile
@@ -29,7 +29,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y git pyth
     && mkdir -p /app/storage/kafka && mkdir -p /app/log
 
 ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseFOUR-daily
+ARG RELEASE=ReleaseEIGHT-daily
 ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
 ARG REPOSITORY=testing
 
diff --git a/docker/NG-UI/Dockerfile b/docker/NG-UI/Dockerfile
index 0f8febb97d25b96f55a7252d890f0320ecfa232b..314beff102f8302676a296b3126ae4939d3aad7b 100644
--- a/docker/NG-UI/Dockerfile
+++ b/docker/NG-UI/Dockerfile
@@ -24,7 +24,7 @@ RUN apt-get update && apt-get install -y curl xz-utils gnupg2 \
     && apt-get install -y nginx
 
 ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseSEVEN-daily
+ARG RELEASE=ReleaseEIGHT-daily
 ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
 ARG REPOSITORY=testing
 ARG NGUI_VERSION
diff --git a/docker/PLA/Dockerfile b/docker/PLA/Dockerfile
index 6f7da1b6f3c1d18a28b9fafd73b49179b3a5b432..5d675e999f1b8699a5b4c2fbe020eb827ffe7580 100644
--- a/docker/PLA/Dockerfile
+++ b/docker/PLA/Dockerfile
@@ -24,7 +24,7 @@ RUN apt-get --yes update \
  && python3 -m pip install pymzn==0.18.3
 
 ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseFOUR-daily
+ARG RELEASE=ReleaseEIGHT-daily
 ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
 ARG REPOSITORY=testing
 
diff --git a/docker/POL/Dockerfile b/docker/POL/Dockerfile
index 2dd1382b23b6802727b61be66158542224167067..43a271ea9b8e932ad42b0272bc0c5b1183311d3c 100644
--- a/docker/POL/Dockerfile
+++ b/docker/POL/Dockerfile
@@ -30,7 +30,7 @@ RUN apt-get --yes update \
  && pip3 install pip==9.0.3
 
 ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseFOUR-daily
+ARG RELEASE=ReleaseEIGHT-daily
 ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
 ARG REPOSITORY=testing
 
diff --git a/docker/RO/Dockerfile b/docker/RO/Dockerfile
index 83f58db3377d9681666c2d6c6247cc601139aec7..299fbbef3fd6217548e4e51bbca4337db4f721dc 100644
--- a/docker/RO/Dockerfile
+++ b/docker/RO/Dockerfile
@@ -24,7 +24,7 @@ RUN apt-get update && apt-get -y install curl software-properties-common git tox
     && python3 -m pip install --upgrade pip && python3 -m pip install pyangbind networking-l2gw
 
 ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseSEVEN-daily
+ARG RELEASE=ReleaseEIGHT-daily
 ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
 ARG REPOSITORY=testing
 
diff --git a/docker/light-ui/Dockerfile b/docker/light-ui/Dockerfile
index 79262d1fea0d8789e5f911b32fac5dc51e96f8c2..204bfd890bb49a33f34c31c40361d3486db47235 100644
--- a/docker/light-ui/Dockerfile
+++ b/docker/light-ui/Dockerfile
@@ -20,7 +20,7 @@ RUN ln -s /usr/bin/nodejs /usr/bin/node
 RUN echo "daemon off;" >> /etc/nginx/nginx.conf
 
 ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseFOUR-daily
+ARG RELEASE=ReleaseEIGHT-daily
 ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
 ARG REPOSITORY=testing
 ARG LWUI_VERSION
diff --git a/docker/mk/Makefile.include b/docker/mk/Makefile.include
index b4e63f9391e22264823c8b67767d1597b4ec3527..e151748381ede62914eac9a61373bf9afa200c58 100644
--- a/docker/mk/Makefile.include
+++ b/docker/mk/Makefile.include
@@ -22,7 +22,7 @@ all: build
 TAG ?= 6
 
 REPOSITORY_BASE ?= http://osm-download.etsi.org/repository/osm/debian
-RELEASE         ?= ReleaseFOUR-daily
+RELEASE         ?= ReleaseEIGHT-daily
 REPOSITORY_KEY  ?= OSM%20ETSI%20Release%20Key.gpg
 REPOSITORY      ?= testing
 NO_CACHE        ?= --no-cache
diff --git a/docker/mk/get_version.sh b/docker/mk/get_version.sh
index 7508ac8d04d67f6fc737528ec79318f8ebd82051..af2036c100504ef65c1715b3d9252c73911c0bbc 100755
--- a/docker/mk/get_version.sh
+++ b/docker/mk/get_version.sh
@@ -1,6 +1,21 @@
 #!/bin/sh
+#
+#   Copyright 2020 ETSI
+#
+#   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.
+#
 
-RELEASE="ReleaseFOUR-daily"
+RELEASE="ReleaseEIGHT-daily"
 REPOSITORY_KEY="OSM%20ETSI%20Release%20Key.gpg"
 REPOSITORY="testing"
 REPOSITORY_BASE="http://osm-download.etsi.org/repository/osm/debian"
diff --git a/docker/osmclient/Dockerfile b/docker/osmclient/Dockerfile
index 49c705ba7a1efc5a8274e474572ba5fc5d9f997d..ab1a8ac61f8902cb73277424de39a1c5c1ee9d63 100644
--- a/docker/osmclient/Dockerfile
+++ b/docker/osmclient/Dockerfile
@@ -29,7 +29,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install wget pyt
 RUN python3 -m pip install -U pip && python3 -m pip install pyyaml python-magic pyangbind pytest==4.6.3 verboselogs
 
 ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseSEVEN-daily
+ARG RELEASE=ReleaseEIGHT-daily
 ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
 ARG REPOSITORY=testing
 
diff --git a/docker/tests/Dockerfile b/docker/tests/Dockerfile
index a7153186d82fb63d392f9cdaf5a8a87369faeced..4a8294c3d3f312830bdd17bf157b80c32e24f829 100644
--- a/docker/tests/Dockerfile
+++ b/docker/tests/Dockerfile
@@ -24,7 +24,7 @@ RUN python3 -m pip install haikunator requests robotframework robotframework-sel
     git+https://osm.etsi.org/gerrit/osm/IM.git git+https://osm.etsi.org/gerrit/osm/osmclient.git
 
 ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseSEVEN-daily
+ARG RELEASE=ReleaseEIGHT-daily
 ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
 ARG REPOSITORY=testing
 ARG TESTS_VERSION
@@ -60,4 +60,4 @@ ENV K8S_CREDENTIALS=/root/.kube/config
 ENV LC_ALL=C.UTF-8
 ENV LANG=C.UTF-8
 
-ENTRYPOINT [ "/robot-systest/run_test.sh"]
\ No newline at end of file
+ENTRYPOINT [ "/robot-systest/run_test.sh"]
diff --git a/installers/charm/README.md b/installers/charm/README.md
index 0fb31dbfdc7f124a1b6ecdffae279a9f4226c116..a8467b0177890598870243c1c0735622d8f1af45 100644
--- a/installers/charm/README.md
+++ b/installers/charm/README.md
@@ -43,7 +43,8 @@ The "layers" folder include one common layer for all the osm charms (osm-common)
 ├── nbi-k8s
 ├── pol-k8s
 ├── ro-k8s
-└── ui-k8s
+├── ui-k8s
+└── ng-ui --> new operator framework
 
 ```
 
diff --git a/installers/charm/bundles/osm-ha/README.md b/installers/charm/bundles/osm-ha/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..84dbde49d0fdd16bbfcfbdb697e0c4157cd4e5f7
--- /dev/null
+++ b/installers/charm/bundles/osm-ha/README.md
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2020 Canonical Ltd.
+
+ 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.
+-->
+# Charmed OSM
+
+
+Charmed OSM is an OSM distribution, developed and maintained by Canonical, which uses Juju charms to simplify its deployments and operations. Charmed OSM enables TSPs to easily deploy pure upstream OSM in highly available, production-grade and scalable clusters.
+
+- Industry‐aligned and fully compliant with upstream
+- Predictable release cadence and upgrade path
+- Simplified deployments and operations
+- Stable and secure
+- Highly Available and resilient against failures
+- Supported with [Ubuntu Advantage](https://ubuntu.com/advantage)
+- Availability of managed services
+
+
+## Quick start
+
+Go to the [OSM User Guide](https://osm.etsi.org/docs/user-guide/03-installing-osm.html#charmed-installation)
diff --git a/installers/charm/bundles/osm-ha/bundle.yaml b/installers/charm/bundles/osm-ha/bundle.yaml
index 212a5208df2237b8b08ff51d15ced18274128026..ea3d7a14b22fd8000eef6e4a525978813061429d 100644
--- a/installers/charm/bundles/osm-ha/bundle.yaml
+++ b/installers/charm/bundles/osm-ha/bundle.yaml
@@ -28,7 +28,7 @@ applications:
       zookeeper-units: 3
     annotations:
       gui-x: 0
-      gui-y: 1100
+      gui-y: 550
   mariadb-k8s:
     charm: "cs:~charmed-osm/mariadb-k8s"
     channel: "stable"
@@ -46,8 +46,8 @@ applications:
       query-cache-size: 0
       ha-mode: true
     annotations:
-      gui-x: -500
-      gui-y: -400
+      gui-x: -250
+      gui-y: -200
   kafka-k8s:
     charm: "cs:~charmed-osm/kafka-k8s"
     channel: "stable"
@@ -63,7 +63,7 @@ applications:
       zookeeper-service-name: zookeeper-k8s-endpoints
     annotations:
       gui-x: 0
-      gui-y: 600
+      gui-y: 300
   mongodb-k8s:
     charm: "cs:~charmed-osm/mongodb-k8s"
     channel: "stable"
@@ -80,7 +80,7 @@ applications:
       enable-sidecar: true
     annotations:
       gui-x: 0
-      gui-y: 100
+      gui-y: 50
   nbi-k8s:
     charm: "cs:~charmed-osm/nbi-k8s"
     channel: "%(channel)s"
@@ -93,7 +93,7 @@ applications:
       DATABASE_COMMONKEY: osm
     annotations:
       gui-x: 0
-      gui-y: -400
+      gui-y: -200
   ro-k8s:
     charm: "cs:~charmed-osm/ro-k8s"
     channel: "%(channel)s"
@@ -106,8 +106,8 @@ applications:
       ro_database: "mano_db"
       OPENMANO_TENANT: "osm"
     annotations:
-      gui-x: -500
-      gui-y: 600
+      gui-x: -250
+      gui-y: 300
   ui-k8s:
     charm: "cs:~charmed-osm/ui-k8s"
     channel: "%(channel)s"
@@ -115,9 +115,22 @@ applications:
     series: kubernetes
     options:
       mysql_database: lwui
+    annotations:
+      gui-x: 250
+      gui-y: -200
+  ng-ui:
+    charm: "%(prefix)s/ng-ui%(suffix)s"
+    channel: "%(channel)s"
+    scale: 3
+    series: kubernetes
+    options:
+      port: 80
+      https_port: 443
+      server_name: localhost
+      client_max_body_size: 15M
     annotations:
       gui-x: 500
-      gui-y: -400
+      gui-y: 100
   lcm-k8s:
     charm: "cs:~charmed-osm/lcm-k8s"
     channel: "%(channel)s"
@@ -132,12 +145,11 @@ applications:
       vca_password: secret
       vca_pubkey: pubkey
       vca_cacert: cacert
-      vca_apiproxy: apiproxy
       use_external_vca: true
       DATABASE_COMMONKEY: osm
     annotations:
-      gui-x: -500
-      gui-y: 100
+      gui-x: -250
+      gui-y: 50
   mon-k8s:
     charm: "cs:~charmed-osm/mon-k8s"
     channel: "%(channel)s"
@@ -158,8 +170,8 @@ applications:
       vca_cacert: cacert
       use_external_vca: true
     annotations:
-      gui-x: 500
-      gui-y: 100
+      gui-x: 250
+      gui-y: 50
   pol-k8s:
     charm: "cs:~charmed-osm/pol-k8s"
     channel: "%(channel)s"
@@ -170,8 +182,16 @@ applications:
     options:
       log_level: INFO
     annotations:
-      gui-x: -500
-      gui-y: 1100
+      gui-x: -250
+      gui-y: 550
+  pla:
+    charm: "%(prefix)s/pla%(suffix)s"
+    channel: "%(channel)s"
+    scale: 3
+    series: kubernetes
+    annotations:
+      gui-x: 500
+      gui-y: -200
   prometheus-k8s:
     charm: "cs:~charmed-osm/prometheus-k8s"
     channel: "stable"
@@ -184,16 +204,16 @@ applications:
       web-subpath: /
       default-target: "mon-k8s:8000"
     annotations:
-      gui-x: 500
-      gui-y: 600
+      gui-x: 250
+      gui-y: 300
   grafana-k8s:
     charm: "cs:~charmed-osm/grafana-k8s"
     channel: "stable"
     scale: 3
     series: kubernetes
     annotations:
-      gui-x: 500
-      gui-y: 1100
+      gui-x: 250
+      gui-y: 550
 
 relations:
   - - "kafka-k8s:zookeeper"
@@ -228,3 +248,9 @@ relations:
     - "nbi-k8s:nbi"
   - - "prometheus-k8s:prometheus"
     - "nbi-k8s:prometheus"
+  - - "pla:kafka"
+    - "kafka-k8s:kafka"
+  - - "pla:mongo"
+    - "mongodb-k8s:mongo"
+  - - 'ng-ui:nbi'
+    - 'nbi-k8s:nbi'
diff --git a/installers/charm/bundles/osm/README.md b/installers/charm/bundles/osm/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..84dbde49d0fdd16bbfcfbdb697e0c4157cd4e5f7
--- /dev/null
+++ b/installers/charm/bundles/osm/README.md
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2020 Canonical Ltd.
+
+ 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.
+-->
+# Charmed OSM
+
+
+Charmed OSM is an OSM distribution, developed and maintained by Canonical, which uses Juju charms to simplify its deployments and operations. Charmed OSM enables TSPs to easily deploy pure upstream OSM in highly available, production-grade and scalable clusters.
+
+- Industry‐aligned and fully compliant with upstream
+- Predictable release cadence and upgrade path
+- Simplified deployments and operations
+- Stable and secure
+- Highly Available and resilient against failures
+- Supported with [Ubuntu Advantage](https://ubuntu.com/advantage)
+- Availability of managed services
+
+
+## Quick start
+
+Go to the [OSM User Guide](https://osm.etsi.org/docs/user-guide/03-installing-osm.html#charmed-installation)
diff --git a/installers/charm/bundles/osm/bundle.yaml b/installers/charm/bundles/osm/bundle.yaml
index fc3dbcb4d632de4a56894586a561b743ffcd5d9f..c4567aca5a05687327aafaa927916fe947279c77 100644
--- a/installers/charm/bundles/osm/bundle.yaml
+++ b/installers/charm/bundles/osm/bundle.yaml
@@ -15,8 +15,8 @@ description: Single instance OSM bundle
 bundle: kubernetes
 applications:
   zookeeper-k8s:
-    charm: 'cs:~charmed-osm/zookeeper-k8s'
-    channel: 'stable'
+    charm: "cs:~charmed-osm/zookeeper-k8s"
+    channel: "stable"
     scale: 1
     series: kubernetes
     storage:
@@ -28,10 +28,10 @@ applications:
       zookeeper-units: 1
     annotations:
       gui-x: 0
-      gui-y: 1100
+      gui-y: 550
   mariadb-k8s:
-    charm: 'cs:~charmed-osm/mariadb-k8s'
-    channel: 'stable'
+    charm: "cs:~charmed-osm/mariadb-k8s"
+    channel: "stable"
     scale: 1
     series: kubernetes
     storage:
@@ -46,11 +46,11 @@ applications:
       query-cache-size: 0
       ha-mode: false
     annotations:
-      gui-x: -500
-      gui-y: -400
+      gui-x: -250
+      gui-y: -200
   kafka-k8s:
-    charm: 'cs:~charmed-osm/kafka-k8s'
-    channel: 'stable'
+    charm: "cs:~charmed-osm/kafka-k8s"
+    channel: "stable"
     scale: 1
     series: kubernetes
     storage:
@@ -63,10 +63,10 @@ applications:
       zookeeper-service-name: zookeeper-k8s-endpoints
     annotations:
       gui-x: 0
-      gui-y: 600
+      gui-y: 300
   mongodb-k8s:
-    charm: 'cs:~charmed-osm/mongodb-k8s'
-    channel: 'stable'
+    charm: "cs:~charmed-osm/mongodb-k8s"
+    channel: "stable"
     scale: 1
     series: kubernetes
     storage:
@@ -80,10 +80,10 @@ applications:
       enable-sidecar: false
     annotations:
       gui-x: 0
-      gui-y: 100
+      gui-y: 50
   nbi-k8s:
-    charm: '%(prefix)s/nbi-k8s%(suffix)s'
-    channel: '%(channel)s'
+    charm: "%(prefix)s/nbi-k8s%(suffix)s"
+    channel: "%(channel)s"
     scale: 1
     series: kubernetes
     storage:
@@ -93,34 +93,47 @@ applications:
       DATABASE_COMMONKEY: osm
     annotations:
       gui-x: 0
-      gui-y: -400
+      gui-y: -200
   ro-k8s:
-    charm: '%(prefix)s/ro-k8s%(suffix)s'
-    channel: '%(channel)s'
+    charm: "%(prefix)s/ro-k8s%(suffix)s"
+    channel: "%(channel)s"
     scale: 1
     series: kubernetes
     storage:
       log: 50M
     options:
-      vim_database: 'mano_vim_db'
-      ro_database: 'mano_db'
-      OPENMANO_TENANT: 'osm'
+      vim_database: "mano_vim_db"
+      ro_database: "mano_db"
+      OPENMANO_TENANT: "osm"
     annotations:
-      gui-x: -500
-      gui-y: 600
+      gui-x: -250
+      gui-y: 300
   ui-k8s:
-    charm: '%(prefix)s/ui-k8s%(suffix)s'
-    channel: '%(channel)s'
+    charm: "%(prefix)s/ui-k8s%(suffix)s"
+    channel: "%(channel)s"
     scale: 1
     series: kubernetes
     options:
       mysql_database: lwui
+    annotations:
+      gui-x: 250
+      gui-y: -200
+  ng-ui:
+    charm: "%(prefix)s/ng-ui%(suffix)s"
+    channel: "%(channel)s"
+    scale: 1
+    series: kubernetes
+    options:
+      port: 80
+      https_port: 443
+      server_name: localhost
+      client_max_body_size: 15M
     annotations:
       gui-x: 500
-      gui-y: -400
+      gui-y: 100
   lcm-k8s:
-    charm: '%(prefix)s/lcm-k8s%(suffix)s'
-    channel: '%(channel)s'
+    charm: "%(prefix)s/lcm-k8s%(suffix)s"
+    channel: "%(channel)s"
     scale: 1
     series: kubernetes
     storage:
@@ -132,15 +145,14 @@ applications:
       vca_password: secret
       vca_pubkey: pubkey
       vca_cacert: cacert
-      vca_apiproxy: apiproxy
       use_external_vca: false
       DATABASE_COMMONKEY: osm
     annotations:
-      gui-x: -500
-      gui-y: 100
+      gui-x: -250
+      gui-y: 50
   mon-k8s:
-    charm: '%(prefix)s/mon-k8s%(suffix)s'
-    channel: '%(channel)s'
+    charm: "%(prefix)s/mon-k8s%(suffix)s"
+    channel: "%(channel)s"
     scale: 1
     series: kubernetes
     storage:
@@ -158,11 +170,11 @@ applications:
       vca_cacert: cacert
       use_external_vca: false
     annotations:
-      gui-x: 500
-      gui-y: 100
+      gui-x: 250
+      gui-y: 50
   pol-k8s:
-    charm: '%(prefix)s/pol-k8s%(suffix)s'
-    channel: '%(channel)s'
+    charm: "%(prefix)s/pol-k8s%(suffix)s"
+    channel: "%(channel)s"
     scale: 1
     series: kubernetes
     storage:
@@ -170,11 +182,19 @@ applications:
     options:
       log_level: INFO
     annotations:
-      gui-x: -500
-      gui-y: 1100
+      gui-x: -250
+      gui-y: 550
+  pla:
+    charm: "%(prefix)s/pla%(suffix)s"
+    channel: "%(channel)s"
+    scale: 1
+    series: kubernetes
+    annotations:
+      gui-x: 500
+      gui-y: -200
   prometheus-k8s:
-    charm: 'cs:~charmed-osm/prometheus-k8s'
-    channel: 'stable'
+    charm: "cs:~charmed-osm/prometheus-k8s"
+    channel: "stable"
     scale: 1
     series: kubernetes
     storage:
@@ -184,47 +204,53 @@ applications:
       web-subpath: /
       default-target: "mon-k8s:8000"
     annotations:
-      gui-x: 500
-      gui-y: 600
+      gui-x: 250
+      gui-y: 300
   grafana-k8s:
-    charm: 'cs:~charmed-osm/grafana-k8s'
-    channel: 'stable'
+    charm: "cs:~charmed-osm/grafana-k8s"
+    channel: "stable"
     scale: 1
     series: kubernetes
     annotations:
-      gui-x: 500
-      gui-y: 1100
+      gui-x: 250
+      gui-y: 550
 
 relations:
-  - - 'kafka-k8s:zookeeper'
-    - 'zookeeper-k8s:zookeeper'
-  - - 'ro-k8s:mysql'
-    - 'mariadb-k8s:mysql'
-  - - 'nbi-k8s:mongo'
-    - 'mongodb-k8s:mongo'
-  - - 'nbi-k8s:kafka'
-    - 'kafka-k8s:kafka'
-  - - 'lcm-k8s:kafka'
-    - 'kafka-k8s:kafka'
-  - - 'lcm-k8s:mongo'
-    - 'mongodb-k8s:mongo'
-  - - 'mon-k8s:kafka'
-    - 'kafka-k8s:kafka'
-  - - 'mon-k8s:mongo'
-    - 'mongodb-k8s:mongo'
-  - - 'pol-k8s:kafka'
-    - 'kafka-k8s:kafka'
-  - - 'pol-k8s:mongo'
-    - 'mongodb-k8s:mongo'
-  - - 'lcm-k8s:ro'
-    - 'ro-k8s:ro'
-  - - 'prometheus-k8s:prometheus'
-    - 'mon-k8s:prometheus'
-  - - 'grafana-k8s:prometheus'
-    - 'prometheus-k8s:prometheus'
-  - - 'ui-k8s:mysql'
-    - 'mariadb-k8s:mysql'
-  - - 'ui-k8s:nbi'
+  - - "kafka-k8s:zookeeper"
+    - "zookeeper-k8s:zookeeper"
+  - - "ro-k8s:mysql"
+    - "mariadb-k8s:mysql"
+  - - "nbi-k8s:mongo"
+    - "mongodb-k8s:mongo"
+  - - "nbi-k8s:kafka"
+    - "kafka-k8s:kafka"
+  - - "lcm-k8s:kafka"
+    - "kafka-k8s:kafka"
+  - - "lcm-k8s:mongo"
+    - "mongodb-k8s:mongo"
+  - - "mon-k8s:kafka"
+    - "kafka-k8s:kafka"
+  - - "mon-k8s:mongo"
+    - "mongodb-k8s:mongo"
+  - - "pol-k8s:kafka"
+    - "kafka-k8s:kafka"
+  - - "pol-k8s:mongo"
+    - "mongodb-k8s:mongo"
+  - - "lcm-k8s:ro"
+    - "ro-k8s:ro"
+  - - "prometheus-k8s:prometheus"
+    - "mon-k8s:prometheus"
+  - - "grafana-k8s:prometheus"
+    - "prometheus-k8s:prometheus"
+  - - "ui-k8s:mysql"
+    - "mariadb-k8s:mysql"
+  - - "ui-k8s:nbi"
+    - "nbi-k8s:nbi"
+  - - "prometheus-k8s:prometheus"
+    - "nbi-k8s:prometheus"
+  - - "pla:kafka"
+    - "kafka-k8s:kafka"
+  - - "pla:mongo"
+    - "mongodb-k8s:mongo"
+  - - 'ng-ui:nbi'
     - 'nbi-k8s:nbi'
-  - - 'prometheus-k8s:prometheus'
-    - 'nbi-k8s:prometheus'
diff --git a/installers/charm/lcm-k8s/config.yaml b/installers/charm/lcm-k8s/config.yaml
index 41e3e84c8f794e2573239d8a34cc3c7df09d62b2..25f6a71e8febb9e3394a944bf2cd03937c851126 100644
--- a/installers/charm/lcm-k8s/config.yaml
+++ b/installers/charm/lcm-k8s/config.yaml
@@ -44,6 +44,10 @@ options:
     type: string
     description: "The VCA lxd cloud name"
     default: "localhost"
+  vca_k8s_cloud:
+    type: string
+    description: "The VCA K8s cloud name"
+    default: "k8scloud"
   advertised-hostname:
     description: LCM Hostname
     type: string
diff --git a/installers/charm/lcm-k8s/reactive/lcm.py b/installers/charm/lcm-k8s/reactive/lcm.py
index 85ec9c5b0cd311b09108eeaafa8298c785c8fff2..3ada8cb27395e40501a5aac9c4fbc932145e3d7d 100644
--- a/installers/charm/lcm-k8s/reactive/lcm.py
+++ b/installers/charm/lcm-k8s/reactive/lcm.py
@@ -21,7 +21,7 @@ from charmhelpers.core.hookenv import (
     config,
 )
 from charms import layer
-
+import yaml
 
 @hook("upgrade-charm")
 @when("leadership.is_leader")
@@ -131,4 +131,7 @@ def make_pod_spec(ro_host, ro_port, kafka_host, kafka_port, mongo_uri):
     }
     data.update(cfg)
 
-    return pod_spec_template % data
+    spec = yaml.safe_dump(pod_spec_template % data)
+    if "vca_apiproxy" in cfg and cfg["vca_apiproxy"] != "":
+        spec["containers"][0]["config"]["OSMLCM_VCA_APIPROXY"] = cfg["vca_apiproxy"]
+    return spec
\ No newline at end of file
diff --git a/installers/charm/lcm-k8s/reactive/spec_template.yaml b/installers/charm/lcm-k8s/reactive/spec_template.yaml
index 1a270965d5264b04069a61203985a6c4e56f3ed7..d8b51e77af310f53bc2371abb26ad401fc77a039 100644
--- a/installers/charm/lcm-k8s/reactive/spec_template.yaml
+++ b/installers/charm/lcm-k8s/reactive/spec_template.yaml
@@ -45,5 +45,5 @@ containers:
       OSMLCM_VCA_PUBKEY: %(vca_pubkey)s
       OSMLCM_VCA_SECRET: %(vca_password)s
       OSMLCM_VCA_CACERT: %(vca_cacert)s
-      OSMLCM_VCA_APIPROXY: %(vca_apiproxy)s
       OSMLCM_VCA_CLOUD: %(vca_cloud)s
+      OSMLCM_VCA_K8S_CLOUD: %(vca_k8s_cloud)s
diff --git a/installers/charm/nbi-k8s/reactive/spec_template.yaml b/installers/charm/nbi-k8s/reactive/spec_template.yaml
index 18adec48613f8e68865c12c0b9505400072f521d..5c030d9622e7c76944fbff63bcfe2e42fe103923 100644
--- a/installers/charm/nbi-k8s/reactive/spec_template.yaml
+++ b/installers/charm/nbi-k8s/reactive/spec_template.yaml
@@ -28,14 +28,14 @@ containers:
       OSMNBI_DATABASE_DRIVER: mongo
       OSMNBI_DATABASE_URI: %(mongo_uri)s
       OSMNBI_DATABASE_COMMONKEY: %(DATABASE_COMMONKEY)s
-      
+
       OSMNBI_STORAGE_DRIVER: mongo
       OSMNBI_STORAGE_PATH: /app/storage
       OSMNBI_STORAGE_COLLECTION: files
       OSMNBI_STORAGE_URI: %(mongo_uri)s
 
       OSMNBI_STATIC_DIR: /app/osm_nbi/html_public
-      
+
       OSMNBI_PROMETHEUS_HOST: %(prometheus_host)s
       OSMNBI_PROMETHEUS_PORT: %(prometheus_port)s
-      OSMNBI_LOG_LEVEL: %(log_level)s
\ No newline at end of file
+      OSMNBI_LOG_LEVEL: %(log_level)s
diff --git a/installers/charm/ng-ui/.yamllint.yaml b/installers/charm/ng-ui/.yamllint.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ab52c60096c0b8939ed0758059d862e0fefaecc8
--- /dev/null
+++ b/installers/charm/ng-ui/.yamllint.yaml
@@ -0,0 +1,23 @@
+# Copyright 2020 Canonical Ltd.
+#
+# 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.
+---
+extends: default
+
+yaml-files:
+  - "*.yaml"
+  - "*.yml"
+  - ".yamllint"
+ignore: |
+  .tox
+  mod
diff --git a/installers/charm/ng-ui/README.md b/installers/charm/ng-ui/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..e6a3d5835df4d2ae47930c86925d9607e269550b
--- /dev/null
+++ b/installers/charm/ng-ui/README.md
@@ -0,0 +1,57 @@
+<!-- #   Copyright 2020 Canonical Ltd.
+#
+#   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. -->
+
+# NG-UI Charm
+
+## How to deploy
+
+```bash
+juju deploy . # cs:~charmed-osm/ng-ui --channel edge
+juju relate ng-ui nbi-k8s
+```
+
+## How to expose the NG-UI through ingress
+
+```bash
+juju config ng-ui juju-external-hostname=ng.<k8s_worker_ip>.xip.io
+juju expose ng-ui
+```
+
+> Note: The <k8s_worker_ip> is the IP of the K8s worker node. With microk8s, you can see the IP with `microk8s.config`. It is usually the IP of your host machine.
+
+## How to scale
+
+```bash
+    juju scale-application ng-ui 3
+```
+
+## How to use certificates
+
+Generate your own certificate if you don't have one already:
+
+```bash
+sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ssl_certificate.key -out ssl_certificate.crt
+sudo chown $USER:$USER ssl_certificate.key
+juju config ng-ui ssl_certificate=`cat ssl_certificate.crt | base64 -w 0`
+juju config ng-ui ssl_certificate_key=`cat ssl_certificate.key | base64 -w 0`
+```
+
+## Config Examples
+
+```bash
+juju config ng-ui image=opensourcemano/ng-ui:<tag>
+juju config ng-ui port=80
+juju config server_name=<name>
+juju config client_max_body_size=25M
+```
diff --git a/installers/charm/ng-ui/config.yaml b/installers/charm/ng-ui/config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a80a280ec5c19e550eed8448712769e2a78b413c
--- /dev/null
+++ b/installers/charm/ng-ui/config.yaml
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Arctos Labs Scandinavia AB
+#
+# 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.
+
+options:
+  image:
+    description: Docker image name
+    type: string
+    default: opensourcemano/ng-ui:8
+  port:
+    description: Port number
+    type: int
+    default: 80
+  https_port:
+    description: Port number
+    type: int
+    default: 443
+  server_name:
+    description: Server name
+    type: string
+    default: localhost
+  client_max_body_size:
+    description: Client maximum body size
+    type: string
+    default: 15M
+  ssl_certificate:
+    description: Base64 encoded ssl certificate
+    type: string
+  ssl_certificate_key:
+    description: Base64 encoded ssl certificate key
+    type: string
diff --git a/installers/charm/ng-ui/files/default b/installers/charm/ng-ui/files/default
new file mode 100644
index 0000000000000000000000000000000000000000..e0147154138d7c20d1e723a92779da659b8f99bd
--- /dev/null
+++ b/installers/charm/ng-ui/files/default
@@ -0,0 +1,37 @@
+#   Copyright 2020 Canonical Ltd.
+#
+#   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.
+
+
+
+server {
+    listen $http_port;
+    listen $https_port default ssl;
+    server_name  $server_name;
+    root   /usr/share/nginx/html;
+    index  index.html index.htm;
+    client_max_body_size $client_max_body_size;
+    $ssl_crt
+    $ssl_crt_key
+    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
+    ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
+    location /osm {
+        proxy_pass https://$nbi_host:$nbi_port;
+        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
+        proxy_set_header Accept-Encoding "";
+    }
+
+    location / {
+        try_files $$uri $$uri/ /index.html;
+    }
+}
diff --git a/installers/charm/ng-ui/hooks/start b/installers/charm/ng-ui/hooks/start
new file mode 120000
index 0000000000000000000000000000000000000000..25b1f68fa39d58d33c08ca420c3d439d19be0c55
--- /dev/null
+++ b/installers/charm/ng-ui/hooks/start
@@ -0,0 +1 @@
+../src/charm.py
\ No newline at end of file
diff --git a/installers/charm/ng-ui/lib/ops b/installers/charm/ng-ui/lib/ops
new file mode 120000
index 0000000000000000000000000000000000000000..d93419320c2e0d3133a0bc8059e2f259bf5bb213
--- /dev/null
+++ b/installers/charm/ng-ui/lib/ops
@@ -0,0 +1 @@
+../mod/operator/ops
\ No newline at end of file
diff --git a/installers/charm/ng-ui/metadata.yaml b/installers/charm/ng-ui/metadata.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a0a592104599468b641cc2e6aaf424481e9d22b9
--- /dev/null
+++ b/installers/charm/ng-ui/metadata.yaml
@@ -0,0 +1,27 @@
+#   Copyright 2020 Canonical Ltd.
+#
+#   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.
+
+name: ng-ui
+summary: A Next Generation UI charm for Opensource MANO
+description: |
+  New UI for OSM
+series:
+  - kubernetes
+min-juju-version: 2.7.0
+deployment:
+  type: stateless
+  service: cluster
+requires:
+  nbi:
+    interface: osm-nbi
diff --git a/installers/charm/ng-ui/mod/operator b/installers/charm/ng-ui/mod/operator
new file mode 160000
index 0000000000000000000000000000000000000000..a84ce8776b368a8b2bccdb173716e342db9a6b36
--- /dev/null
+++ b/installers/charm/ng-ui/mod/operator
@@ -0,0 +1 @@
+Subproject commit a84ce8776b368a8b2bccdb173716e342db9a6b36
diff --git a/installers/charm/ng-ui/src/charm.py b/installers/charm/ng-ui/src/charm.py
new file mode 100755
index 0000000000000000000000000000000000000000..ce48927ad1e13b747df90ee7ccfe665daefededa
--- /dev/null
+++ b/installers/charm/ng-ui/src/charm.py
@@ -0,0 +1,200 @@
+#!/usr/bin/env python3
+#   Copyright 2020 Canonical Ltd.
+#
+#   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.
+
+import sys
+import logging
+import base64
+
+sys.path.append("lib")
+
+from ops.charm import CharmBase
+from ops.framework import StoredState, Object
+from ops.main import main
+from ops.model import (
+    ActiveStatus,
+    MaintenanceStatus,
+    BlockedStatus,
+    ModelError,
+    WaitingStatus,
+)
+
+from glob import glob
+from pathlib import Path
+from string import Template
+
+logger = logging.getLogger(__name__)
+
+
+class NGUICharm(CharmBase):
+    state = StoredState()
+
+    def __init__(self, framework, key):
+        super().__init__(framework, key)
+        self.state.set_default(spec=None)
+        self.state.set_default(nbi_host=None)
+        self.state.set_default(nbi_port=None)
+
+        # Observe Charm related events
+        self.framework.observe(self.on.config_changed, self.on_config_changed)
+        self.framework.observe(self.on.start, self.on_start)
+        self.framework.observe(self.on.upgrade_charm, self.on_upgrade_charm)
+        self.framework.observe(
+            self.on.nbi_relation_changed, self.on_nbi_relation_changed
+        )
+
+        # SSL Certificate path
+        self.ssl_folder = "/certs"
+        self.ssl_crt_name = "ssl_certificate.crt"
+        self.ssl_key_name = "ssl_certificate.key"
+
+    def _apply_spec(self):
+        # Only apply the spec if this unit is a leader.
+        unit = self.model.unit
+        if not unit.is_leader():
+            unit.status = ActiveStatus("ready")
+            return
+        if not self.state.nbi_host or not self.state.nbi_port:
+            unit.status = WaitingStatus("Waiting for NBI")
+            return
+        unit.status = MaintenanceStatus("Applying new pod spec")
+
+        new_spec = self.make_pod_spec()
+        if new_spec == self.state.spec:
+            unit.status = ActiveStatus("ready")
+            return
+        self.framework.model.pod.set_spec(new_spec)
+        self.state.spec = new_spec
+        unit.status = ActiveStatus("ready")
+
+    def make_pod_spec(self):
+        config = self.framework.model.config
+
+        config_spec = {
+            "http_port": config["port"],
+            "https_port": config["https_port"],
+            "server_name": config["server_name"],
+            "client_max_body_size": config["client_max_body_size"],
+            "nbi_host": self.state.nbi_host or config["nbi_host"],
+            "nbi_port": self.state.nbi_port or config["nbi_port"],
+            "ssl_crt": "",
+            "ssl_crt_key": "",
+        }
+
+        ssl_certificate = None
+        ssl_certificate_key = None
+        ssl_enabled = False
+
+        if "ssl_certificate" in config and "ssl_certificate_key" in config:
+            # Get bytes of cert and key
+            cert_b = base64.b64decode(config["ssl_certificate"])
+            key_b = base64.b64decode(config["ssl_certificate_key"])
+            # Decode key and cert
+            ssl_certificate = cert_b.decode("utf-8")
+            ssl_certificate_key = key_b.decode("utf-8")
+            # Get paths
+            cert_path = "{}/{}".format(self.ssl_folder, self.ssl_crt_name)
+            key_path = "{}/{}".format(self.ssl_folder, self.ssl_key_name)
+
+            config_spec["port"] = "{} ssl".format(config["https_port"])
+            config_spec["ssl_crt"] = "ssl_certificate {};".format(cert_path)
+            config_spec["ssl_crt_key"] = "ssl_certificate_key {};".format(key_path)
+            ssl_enabled = True
+        else:
+            config_spec["ssl_crt"] = ""
+            config_spec["ssl_crt_key"] = ""
+
+        files = [
+            {
+                "name": "configuration",
+                "mountPath": "/etc/nginx/sites-available/",
+                "files": {
+                    Path(filename)
+                    .name: Template(Path(filename).read_text())
+                    .substitute(config_spec)
+                    for filename in glob("files/*")
+                },
+            }
+        ]
+        port = config["https_port"] if ssl_enabled else config["port"]
+        ports = [
+            {"name": "port", "containerPort": port, "protocol": "TCP", },
+        ]
+
+        kubernetes = {
+            "readinessProbe": {
+                "tcpSocket": {"port": port},
+                "timeoutSeconds": 5,
+                "periodSeconds": 5,
+                "initialDelaySeconds": 10,
+            },
+            "livenessProbe": {
+                "tcpSocket": {"port": port},
+                "timeoutSeconds": 5,
+                "initialDelaySeconds": 45,
+            },
+        }
+
+        if ssl_certificate and ssl_certificate_key:
+            files.append(
+                {
+                    "name": "ssl",
+                    "mountPath": self.ssl_folder,
+                    "files": {
+                        self.ssl_crt_name: ssl_certificate,
+                        self.ssl_key_name: ssl_certificate_key,
+                    },
+                }
+            )
+        logger.debug(files)
+        spec = {
+            "version": 2,
+            "containers": [
+                {
+                    "name": self.framework.model.app.name,
+                    "image": "{}".format(config["image"]),
+                    "ports": ports,
+                    "kubernetes": kubernetes,
+                    "files": files,
+                }
+            ],
+        }
+
+        return spec
+
+    def on_config_changed(self, event):
+        """Handle changes in configuration"""
+        self._apply_spec()
+
+    def on_start(self, event):
+        """Called when the charm is being installed"""
+        self._apply_spec()
+
+    def on_upgrade_charm(self, event):
+        """Upgrade the charm."""
+        unit = self.model.unit
+        unit.status = MaintenanceStatus("Upgrading charm")
+        self.on_start(event)
+
+    def on_nbi_relation_changed(self, event):
+        unit = self.model.unit
+        if not unit.is_leader():
+            return
+        self.state.nbi_host = event.relation.data[event.unit].get("host")
+        self.state.nbi_port = event.relation.data[event.unit].get("port")
+        self._apply_spec()
+
+
+if __name__ == "__main__":
+    main(NGUICharm)
diff --git a/installers/charm/ng-ui/tox.ini b/installers/charm/ng-ui/tox.ini
new file mode 100644
index 0000000000000000000000000000000000000000..aafa301045b36e16986526ab8b021b54cef0524a
--- /dev/null
+++ b/installers/charm/ng-ui/tox.ini
@@ -0,0 +1,55 @@
+#   Copyright 2020 Canonical Ltd.
+#
+#   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.
+[tox]
+envlist = pep8
+skipsdist = True
+
+[testenv]
+setenv = VIRTUAL_ENV={envdir}
+         PYTHONHASHSEED=0
+whitelist_externals = juju
+passenv = HOME TERM CS_API_* OS_* AMULET_*
+deps = -r{toxinidir}/test-requirements.txt
+install_command =
+  pip install {opts} {packages}
+
+[testenv:black]
+basepython = python3
+deps =
+    black
+    yamllint
+commands =
+    black --check --diff src
+    yamllint .
+
+[testenv:pep8]
+basepython = python3
+deps=charm-tools
+commands = charm-proof
+
+[testenv:func-noop]
+basepython = python3
+commands =
+    true
+
+[testenv:func]
+basepython = python3
+commands = functest-run-suite
+
+[testenv:func-smoke]
+basepython = python3
+commands = functest-run-suite --keep-model --smoke
+
+[testenv:venv]
+commands = {posargs}
diff --git a/installers/charm/pla/.yamllint.yaml b/installers/charm/pla/.yamllint.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ab52c60096c0b8939ed0758059d862e0fefaecc8
--- /dev/null
+++ b/installers/charm/pla/.yamllint.yaml
@@ -0,0 +1,23 @@
+# Copyright 2020 Canonical Ltd.
+#
+# 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.
+---
+extends: default
+
+yaml-files:
+  - "*.yaml"
+  - "*.yml"
+  - ".yamllint"
+ignore: |
+  .tox
+  mod
diff --git a/installers/charm/pla/README.md b/installers/charm/pla/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..8d486d00a9b3dcb95206ce16743563b5980704ce
--- /dev/null
+++ b/installers/charm/pla/README.md
@@ -0,0 +1,14 @@
+<!-- #   Copyright 2020 Canonical Ltd.
+#
+#   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. -->
+# PLA Charm
\ No newline at end of file
diff --git a/installers/charm/pla/config.yaml b/installers/charm/pla/config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e0aeca410bfb90bad8dde96fb9105805ece49cfb
--- /dev/null
+++ b/installers/charm/pla/config.yaml
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Arctos Labs Scandinavia AB
+#
+# 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.
+
+options:
+  image:
+    description: Docker image name
+    type: string
+    default: opensourcemano/pla:8
+  port:
+    description: Port number
+    type: int
+    default: 8080 # Fake port
+  log_level:
+    description: Log level
+    type: string
+    default: INFO
+  database:
+    description: Database name
+    type: string
+    default: pla
+  database_common_key:
+    description: Common Key for Mongo database
+    type: string
+    default: osm
diff --git a/installers/charm/pla/hooks/install b/installers/charm/pla/hooks/install
new file mode 120000
index 0000000000000000000000000000000000000000..25b1f68fa39d58d33c08ca420c3d439d19be0c55
--- /dev/null
+++ b/installers/charm/pla/hooks/install
@@ -0,0 +1 @@
+../src/charm.py
\ No newline at end of file
diff --git a/installers/charm/pla/hooks/start b/installers/charm/pla/hooks/start
new file mode 120000
index 0000000000000000000000000000000000000000..25b1f68fa39d58d33c08ca420c3d439d19be0c55
--- /dev/null
+++ b/installers/charm/pla/hooks/start
@@ -0,0 +1 @@
+../src/charm.py
\ No newline at end of file
diff --git a/installers/charm/pla/hooks/upgrade-charm b/installers/charm/pla/hooks/upgrade-charm
new file mode 120000
index 0000000000000000000000000000000000000000..25b1f68fa39d58d33c08ca420c3d439d19be0c55
--- /dev/null
+++ b/installers/charm/pla/hooks/upgrade-charm
@@ -0,0 +1 @@
+../src/charm.py
\ No newline at end of file
diff --git a/installers/charm/pla/lib/ops b/installers/charm/pla/lib/ops
new file mode 120000
index 0000000000000000000000000000000000000000..d93419320c2e0d3133a0bc8059e2f259bf5bb213
--- /dev/null
+++ b/installers/charm/pla/lib/ops
@@ -0,0 +1 @@
+../mod/operator/ops
\ No newline at end of file
diff --git a/installers/charm/pla/metadata.yaml b/installers/charm/pla/metadata.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..90c9d400c64c49102b10acc42b4989d18628422e
--- /dev/null
+++ b/installers/charm/pla/metadata.yaml
@@ -0,0 +1,29 @@
+#   Copyright 2020 Canonical Ltd.
+#
+#   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.
+
+name: pla
+summary: A Placement charm for Opensource MANO
+description: |
+  Placement module for OSM
+series:
+  - kubernetes
+min-juju-version: 2.7.0
+deployment:
+  type: stateless
+  service: cluster
+requires:
+  kafka:
+    interface: kafka
+  mongo:
+    interface: mongodb
diff --git a/installers/charm/pla/mod/operator b/installers/charm/pla/mod/operator
new file mode 160000
index 0000000000000000000000000000000000000000..a84ce8776b368a8b2bccdb173716e342db9a6b36
--- /dev/null
+++ b/installers/charm/pla/mod/operator
@@ -0,0 +1 @@
+Subproject commit a84ce8776b368a8b2bccdb173716e342db9a6b36
diff --git a/installers/charm/pla/src/charm.py b/installers/charm/pla/src/charm.py
new file mode 100755
index 0000000000000000000000000000000000000000..1fc6386fa64270e98667e97fc0abf40115a917ed
--- /dev/null
+++ b/installers/charm/pla/src/charm.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python3
+#   Copyright 2020 Canonical Ltd.
+#
+#   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.
+
+import sys
+import logging
+
+sys.path.append("lib")
+
+from ops.charm import CharmBase
+from ops.framework import StoredState, Object
+from ops.main import main
+from ops.model import (
+    ActiveStatus,
+    MaintenanceStatus,
+    WaitingStatus,
+)
+
+from glob import glob
+from pathlib import Path
+from string import Template
+
+logger = logging.getLogger(__name__)
+
+
+class PLACharm(CharmBase):
+    state = StoredState()
+
+    def __init__(self, framework, key):
+        super().__init__(framework, key)
+        self.state.set_default(spec=None)
+        self.state.set_default(kafka_host=None)
+        self.state.set_default(kafka_port=None)
+        self.state.set_default(mongodb_uri=None)
+
+        # Observe Charm related events
+        self.framework.observe(self.on.config_changed, self.on_config_changed)
+        self.framework.observe(self.on.start, self.on_start)
+        self.framework.observe(self.on.upgrade_charm, self.on_upgrade_charm)
+
+        # Relations
+        self.framework.observe(
+            self.on.kafka_relation_changed, self.on_kafka_relation_changed
+        )
+        self.framework.observe(
+            self.on.mongo_relation_changed, self.on_mongo_relation_changed
+        )
+
+    def _apply_spec(self):
+        # Only apply the spec if this unit is a leader.
+        unit = self.model.unit
+        if not unit.is_leader():
+            unit.status = ActiveStatus("ready")
+            return
+        if not self.state.kafka_host or not self.state.kafka_port:
+            unit.status = WaitingStatus("Waiting for Kafka")
+            return
+        if not self.state.mongodb_uri:
+            unit.status = WaitingStatus("Waiting for MongoDB")
+            return
+
+        unit.status = MaintenanceStatus("Applying new pod spec")
+
+        new_spec = self.make_pod_spec()
+        if new_spec == self.state.spec:
+            unit.status = ActiveStatus("ready")
+            return
+        self.framework.model.pod.set_spec(new_spec)
+        self.state.spec = new_spec
+        unit.status = ActiveStatus("ready")
+
+    def make_pod_spec(self):
+        config = self.framework.model.config
+
+        ports = [
+            {"name": "port", "containerPort": config["port"], "protocol": "TCP", },
+        ]
+
+        config_spec = {
+            "OSMPLA_MESSAGE_DRIVER": "kafka",
+            "OSMPLA_MESSAGE_HOST": self.state.kafka_host,
+            "OSMPLA_MESSAGE_PORT": self.state.kafka_port,
+            "OSMPLA_DATABASE_DRIVER": "mongo",
+            "OSMPLA_DATABASE_URI": self.state.mongodb_uri,
+            "OSMPLA_GLOBAL_LOG_LEVEL": config["log_level"],
+            "OSMPLA_DATABASE_COMMONKEY": config["database_common_key"],
+        }
+
+        spec = {
+            "version": 2,
+            "containers": [
+                {
+                    "name": self.framework.model.app.name,
+                    "image": config["image"],
+                    "ports": ports,
+                    "config": config_spec,
+                }
+            ],
+        }
+
+        return spec
+
+    def on_config_changed(self, event):
+        """Handle changes in configuration"""
+        self._apply_spec()
+
+    def on_start(self, event):
+        """Called when the charm is being installed"""
+        self._apply_spec()
+
+    def on_upgrade_charm(self, event):
+        """Upgrade the charm."""
+        unit = self.model.unit
+        unit.status = MaintenanceStatus("Upgrading charm")
+        self.on_start(event)
+
+    def on_kafka_relation_changed(self, event):
+        unit = self.model.unit
+        if not unit.is_leader():
+            return
+        self.state.kafka_host = event.relation.data[event.unit].get("host")
+        self.state.kafka_port = event.relation.data[event.unit].get("port")
+        self._apply_spec()
+
+    def on_mongo_relation_changed(self, event):
+        unit = self.model.unit
+        if not unit.is_leader():
+            return
+        self.state.mongodb_uri = event.relation.data[event.unit].get(
+            "connection_string"
+        )
+        self._apply_spec()
+
+
+if __name__ == "__main__":
+    main(PLACharm)
diff --git a/installers/charm/pla/tox.ini b/installers/charm/pla/tox.ini
new file mode 100644
index 0000000000000000000000000000000000000000..d2a8c5312c039c5353045578120d5a1a5d14d453
--- /dev/null
+++ b/installers/charm/pla/tox.ini
@@ -0,0 +1,56 @@
+#   Copyright 2020 Canonical Ltd.
+#
+#   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.
+
+[tox]
+envlist = pep8
+skipsdist = True
+
+[testenv]
+setenv = VIRTUAL_ENV={envdir}
+         PYTHONHASHSEED=0
+whitelist_externals = juju
+passenv = HOME TERM CS_API_* OS_* AMULET_*
+deps = -r{toxinidir}/test-requirements.txt
+install_command =
+  pip install {opts} {packages}
+
+[testenv:black]
+basepython = python3
+deps =
+    black
+    yamllint
+commands =
+    black --check --diff src
+    yamllint .
+
+[testenv:pep8]
+basepython = python3
+deps=charm-tools
+commands = charm-proof
+
+[testenv:func-noop]
+basepython = python3
+commands =
+    true
+
+[testenv:func]
+basepython = python3
+commands = functest-run-suite
+
+[testenv:func-smoke]
+basepython = python3
+commands = functest-run-suite --keep-model --smoke
+
+[testenv:venv]
+commands = {posargs}
diff --git a/installers/charm/ui-k8s/reactive/spec_template.yaml b/installers/charm/ui-k8s/reactive/spec_template.yaml
index 2bc6f2303ac359f0d5df87c47ff0c1035ffc2576..b63c210436a89e3f6943b234a7b3deb909496ea1 100644
--- a/installers/charm/ui-k8s/reactive/spec_template.yaml
+++ b/installers/charm/ui-k8s/reactive/spec_template.yaml
@@ -12,8 +12,6 @@
 #     See the License for the specific language governing permissions and
 #     limitations under the License.
 version: 2
-service:
-  scalePolicy: serial
 containers:
   - name: %(name)s
     image: %(docker_image)s
diff --git a/installers/charmed_install.sh b/installers/charmed_install.sh
index b411dbbfdd936c7878b658c25362f7ec016e62db..c1c46e4f301513721f21d5458b53707c587caf77 100755
--- a/installers/charmed_install.sh
+++ b/installers/charmed_install.sh
@@ -35,32 +35,68 @@ function check_arguments(){
 
     # echo $BUNDLE $KUBECONFIG $LXDENDPOINT
 }
+
 function install_snaps(){
-    sudo snap install juju --classic --channel=2.7/stable
-    [ ! -v KUBECFG ] && sudo snap install microk8s --classic && sudo usermod -a -G microk8s `whoami` && mkdir -p ~/.kube && sudo chown -f -R `whoami` ~/.kube
+    if [ ! -v KUBECFG ]; then
+        sudo snap install microk8s --classic
+        sudo usermod -a -G microk8s `whoami`
+        mkdir -p ~/.kube
+        sudo chown -f -R `whoami` ~/.kube
+        KUBEGRP="microk8s"
+    else
+        KUBECTL="kubectl"
+        sudo snap install kubectl --classic
+        export KUBECONFIG=${KUBECFG}
+        KUBEGRP=$(id -g -n)
+    fi
+    sudo snap install juju --classic --channel=2.8/stable
 }
 
 function bootstrap_k8s_lxd(){
     [ -v CONTROLLER ] && ADD_K8S_OPTS="--controller ${CONTROLLER}" && CONTROLLER_NAME=$CONTROLLER
-    [ ! -v CONTROLLER ] && ADD_K8S_OPTS="--client" && BOOTSTRAP_NEEDED="yes" && CONTROLLER_NAME="controller"
+    [ ! -v CONTROLLER ] && ADD_K8S_OPTS="--client" && BOOTSTRAP_NEEDED="yes" && CONTROLLER_NAME="osm-vca"
+
+    if [ -v BOOTSTRAP_NEEDED ]; then
+        CONTROLLER_PRESENT=$(juju controllers 2>/dev/null| grep ${CONTROLLER_NAME} | wc -l)
+        if [ $CONTROLLER_PRESENT -ge 1 ]; then
+            cat << EOF
+Threre is already a VCA present with the installer reserved name of "${CONTROLLER_NAME}".
+You may either explicitly use this VCA with the "--vca ${CONTROLLER_NAME}" option, or remove it
+using this command:
+
+   juju destroy-controller --release-storage --destroy-all-models -y ${CONTROLLER_NAME}
+
+Please retry the installation once this conflict has been resolved.
+EOF
+            exit 1
+        fi
+    fi
 
     if [ -v KUBECFG ]; then
         cat $KUBECFG | juju add-k8s $K8S_CLOUD_NAME $ADD_K8S_OPTS
         [ -v BOOTSTRAP_NEEDED ] && juju bootstrap $K8S_CLOUD_NAME $CONTROLLER_NAME --config controller-service-type=loadbalancer
     else
-        sg microk8s -c "echo ${DEFAULT_IP}-${DEFAULT_IP} | microk8s.enable metallb"
-        sg microk8s -c "microk8s.enable storage dns"
+        sg ${KUBEGRP} -c "echo ${DEFAULT_IP}-${DEFAULT_IP} | microk8s.enable metallb"
+        sg ${KUBEGRP} -c "microk8s.enable storage dns"
+        TIME_TO_WAIT=30
+        start_time="$(date -u +%s)"
         while true
         do
-            sg microk8s -c "microk8s.status" | grep 'storage: enabled'
-            if [ $? -eq 0 ]; then
+            now="$(date -u +%s)"
+            if [[ $(( now - start_time )) -gt $TIME_TO_WAIT ]];then
+                echo "Microk8s storage failed to enable"
+                sg ${KUBEGRP} -c "microk8s.status"
+                exit 1
+            fi
+            storage_status=`sg ${KUBEGRP} -c "microk8s.status -a storage"`
+            if [[ $storage_status == "enabled" ]]; then
                 break
             fi
             sleep 1
         done
 
-        [ ! -v BOOTSTRAP_NEEDED ] && sg microk8s -c "microk8s.config" | juju add-k8s $K8S_CLOUD_NAME $ADD_K8S_OPTS
-        [ -v BOOTSTRAP_NEEDED ] && sg microk8s -c "juju bootstrap microk8s $CONTROLLER_NAME --config controller-service-type=loadbalancer" && K8S_CLOUD_NAME=microk8s
+        [ ! -v BOOTSTRAP_NEEDED ] && sg ${KUBEGRP} -c "microk8s.config" | juju add-k8s $K8S_CLOUD_NAME $ADD_K8S_OPTS
+        [ -v BOOTSTRAP_NEEDED ] && sg ${KUBEGRP} -c "juju bootstrap microk8s $CONTROLLER_NAME --config controller-service-type=loadbalancer" && K8S_CLOUD_NAME=microk8s
     fi
 
     if [ -v LXD_CLOUD ]; then
@@ -118,7 +154,28 @@ EOF
     juju add-cloud -c $CONTROLLER_NAME lxd-cloud $LXD_CLOUD --force
     juju add-credential -c $CONTROLLER_NAME lxd-cloud -f $LXD_CREDENTIALS
     sg lxd -c "lxd waitready"
-    juju add-model test lxd-cloud || true
+    #juju add-model test lxd-cloud || true
+    juju controller-config features=[k8s-operators]
+}
+
+function wait_for_port(){
+    SERVICE=$1
+    INDEX=$2
+    TIME_TO_WAIT=30
+    start_time="$(date -u +%s)"
+    while true
+    do
+        now="$(date -u +%s)"
+        if [[ $(( now - start_time )) -gt $TIME_TO_WAIT ]];then
+            echo "Failed to expose external ${SERVICE} interface port"
+            exit 1
+        fi
+
+        if [ $(sg ${KUBEGRP} -c "${KUBECTL} get ingress -n osm -o json | jq -r '.items[$INDEX].metadata.name'") == ${SERVICE} ] ; then
+            break
+        fi
+        sleep 1
+    done
 }
 
 function deploy_charmed_osm(){
@@ -127,34 +184,67 @@ function deploy_charmed_osm(){
     if [ -v KUBECFG ]; then
         juju add-model osm $K8S_CLOUD_NAME
     else
-        sg microk8s -c "juju add-model osm $K8S_CLOUD_NAME"
+        sg ${KUBEGRP} -c "juju add-model osm $K8S_CLOUD_NAME"
     fi
     echo "Deploying OSM with charms"
-    # echo $BUNDLE
+    images_overlay=""
+    [ -v TAG ] && generate_images_overlay && images_overlay="--overlay $IMAGES_OVERLAY_FILE"
     if [ -v BUNDLE ]; then
-        juju deploy $BUNDLE --overlay ~/.osm/vca-overlay.yaml
+        juju deploy $BUNDLE --overlay ~/.osm/vca-overlay.yaml $images_overlay
     else
-        images_overlay=""
-        [ -v TAG ] && generate_images_overlay && images_overlay="--overlay $IMAGES_OVERLAY_FILE"
         juju deploy cs:osm --overlay ~/.osm/vca-overlay.yaml $images_overlay
     fi
+
     echo "Waiting for deployment to finish..."
-    check_osm_deployed &> /dev/null
+    check_osm_deployed
     echo "OSM with charms deployed"
-    sg microk8s -c "microk8s.enable ingress"
-    juju config ui-k8s juju-external-hostname=osm.$DEFAULT_IP.xip.io
+    if [ ! -v KUBECFG ]; then
+        sg ${KUBEGRP} -c "microk8s.enable ingress"
+        API_SERVER=${DEFAULT_IP}
+    else
+        API_SERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ")
+        proto="$(echo $API_SERVER | grep :// | sed -e's,^\(.*://\).*,\1,g')"
+        url="$(echo ${API_SERVER/$proto/})"
+        user="$(echo $url | grep @ | cut -d@ -f1)"
+        hostport="$(echo ${url/$user@/} | cut -d/ -f1)"
+        API_SERVER="$(echo $hostport | sed -e 's,:.*,,g')"
+    fi
+
+    juju config nbi-k8s juju-external-hostname=nbi.${API_SERVER}.xip.io
+    juju expose nbi-k8s
+
+    wait_for_port nbi-k8s 0
+    sg ${KUBEGRP} -c "${KUBECTL} get ingress -n osm -o json | jq '.items[0].metadata.annotations += {\"nginx.ingress.kubernetes.io/backend-protocol\": \"HTTPS\"}' | ${KUBECTL} --validate=false replace -f -"
+    sg ${KUBEGRP} -c "${KUBECTL} get ingress -n osm -o json | jq '.items[0].metadata.annotations += {\"nginx.ingress.kubernetes.io/proxy-body-size\": \"0\"}' | ${KUBECTL} replace -f -"
+
+    juju config ng-ui juju-external-hostname=ui.${API_SERVER}.xip.io
+    juju expose ng-ui
+
+    wait_for_port ng-ui 1
+    sg ${KUBEGRP} -c "${KUBECTL} get ingress -n osm -o json | jq '.items[2].metadata.annotations += {\"nginx.ingress.kubernetes.io/proxy-body-size\": \"0\"}' | ${KUBECTL} --validate=false replace -f -"
+
+    juju config ui-k8s juju-external-hostname=osm.${API_SERVER}.xip.io
     juju expose ui-k8s
+
+    wait_for_port ui-k8s 2
+    sg ${KUBEGRP} -c "${KUBECTL} get ingress -n osm -o json | jq '.items[1].metadata.annotations += {\"nginx.ingress.kubernetes.io/proxy-body-size\": \"0\"}' | ${KUBECTL} --validate=false replace -f -"
 }
 
 function check_osm_deployed() {
+    TIME_TO_WAIT=600
+    start_time="$(date -u +%s)"
+    total_service_count=14
     while true
     do
-        pod_name=`sg microk8s -c "microk8s.kubectl -n osm get pods | grep ui-k8s | grep -v operator" | awk '{print $1; exit}'`
-
-        if [[ `sg microk8s -c "microk8s.kubectl -n osm wait pod $pod_name --for condition=Ready"` ]]; then
-            if [[ `sg microk8s -c "microk8s.kubectl -n osm wait pod lcm-k8s-0 --for condition=Ready"` ]]; then
-                break
-            fi
+        service_count=$(juju status | grep kubernetes | grep active | wc -l)
+        echo "$service_count / $total_service_count services active"
+        if [ $service_count -eq $total_service_count ]; then
+            break
+        fi
+        now="$(date -u +%s)"
+        if [[ $(( now - start_time )) -gt $TIME_TO_WAIT ]];then
+            echo "Timed out waiting for OSM services to become ready"
+            exit 1
         fi
         sleep 10
     done
@@ -177,7 +267,6 @@ function create_overlay() {
 
     # Calculate the default route of this machine
     local DEFAULT_IF=`ip route list match 0.0.0.0 | awk '{print $5}'`
-    local vca_apiproxy=`ip -o -4 a |grep ${DEFAULT_IF}|awk '{split($4,a,"/"); print a[1]}'`
 
     # Generate a new overlay.yaml, overriding any existing one
     cat << EOF > /tmp/vca-overlay.yaml
@@ -190,8 +279,8 @@ applications:
       vca_port: $vca_port
       vca_pubkey: $vca_pubkey
       vca_cacert: $vca_cacert
-      vca_apiproxy: $vca_apiproxy
       vca_cloud: $vca_cloud
+      vca_k8s_cloud: $K8S_CLOUD_NAME
   mon-k8s:
     options:
       vca_user: $vca_user
@@ -224,6 +313,12 @@ applications:
   ui-k8s:
     options:
       image: opensourcemano/light-ui:$TAG
+  pla:
+    options:
+      image: opensourcemano/pla:$TAG
+  ng-ui:
+    options:
+      image: opensourcemano/ng-ui:$TAG
 
 EOF
     mv /tmp/images-overlay.yaml $IMAGES_OVERLAY_FILE
@@ -270,10 +365,21 @@ DEFAULT_IP=`ip -o -4 a |grep ${DEFAULT_IF}|awk '{split($4,a,"/"); print a[1]}'`
 check_arguments $@
 mkdir -p ~/.osm
 install_snaps
-sleep 5
 bootstrap_k8s_lxd
 deploy_charmed_osm
 install_osmclient
 if [ -v MICROSTACK ]; then
     install_microstack
 fi
+
+echo "Your installation is now complete, follow these steps for configuring the osmclient:"
+echo
+echo "1. Create the OSM_HOSTNAME environment variable with the NBI IP"
+echo
+echo "export OSM_HOSTNAME=nbi.$API_SERVER.xip.io:443"
+echo
+echo "2. Add the previous command to your .bashrc for other Shell sessions"
+echo
+echo "echo \"export OSM_HOSTNAME=nbi.$API_SERVER.xip.io:443\" >> ~/.bashrc"
+echo
+echo "DONE"
diff --git a/installers/charmed_uninstall.sh b/installers/charmed_uninstall.sh
index ef2b293cf3397b86961ce636f50a30741c416377..09305d2ad82cba31a8f4313113b8484688bd2a8d 100755
--- a/installers/charmed_uninstall.sh
+++ b/installers/charmed_uninstall.sh
@@ -14,7 +14,18 @@
 #
 
 
-juju destroy-model osm --destroy-storage -y
-juju destroy-model test --destroy-storage -y
+juju destroy-model osm --destroy-storage -y --force --no-wait
 sudo snap unalias osm
 sudo snap remove osmclient
+CONTROLLER_NAME="osm-vca"
+CONTROLLER_PRESENT=$(juju controllers 2>/dev/null| grep ${CONTROLLER_NAME} | wc -l)
+if [[ $CONTROLLER_PRESENT -ge 1 ]]; then
+    cat << EOF
+The VCA with the name "${CONTROLLER_NAME}" has been left in place to ensure that no other
+applications are using it.  If you are sure you wish to remove this controller,
+please execute the following command:
+
+   juju destroy-controller --release-storage --destroy-all-models -y ${CONTROLLER_NAME}
+
+EOF
+fi
diff --git a/installers/docker/docker-compose-lightui.yaml b/installers/docker/docker-compose-lightui.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1b23edd243e74dfab7fcd04170379b02a2286be3
--- /dev/null
+++ b/installers/docker/docker-compose-lightui.yaml
@@ -0,0 +1,45 @@
+##
+# Copyright 2019 ETSI
+#
+# 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.
+##
+
+########################################################################
+
+version: '3'
+networks:
+  netOSM:
+    external:
+      name: ${OSM_NETWORK:-netosm}
+    #driver: overlay
+    #driver_opts:
+    #  com.docker.network.driver.mtu: "1446"
+services:
+  light-ui:
+    image: ${DOCKER_USER:-opensourcemano}/light-ui:${TAG:-8}
+    networks:
+      - netOSM
+    environment:
+      OSM_SERVER: nbi
+    #depends_on:
+    #  - nbi
+    env_file:
+      - ./lwui.env
+    ports:
+      - "${OSM_UI_PORTS:-80:80}"
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "100m"
+        max-file: "2"
+
diff --git a/installers/docker/docker-compose-ngui.yaml b/installers/docker/docker-compose-ngui.yaml
index 77e3d847afffe25b06af4ac02e6396926f5a59b2..5f52a11e3a85525e852d6411df1d353a1fe0ea6a 100644
--- a/installers/docker/docker-compose-ngui.yaml
+++ b/installers/docker/docker-compose-ngui.yaml
@@ -1,5 +1,5 @@
 ##
-# Copyright 2019 ETSI
+# Copyright 2019-2020 ETSI
 #
 # 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
@@ -17,14 +17,6 @@
 ########################################################################
 
 version: '3'
-volumes:
-  ro:
-  ro_db:
-  mongo_db:
-  mon_db:
-  pol_db:
-  osm_packages:
-  prom_db:
 networks:
   netOSM:
     external:
@@ -33,220 +25,10 @@ networks:
     #driver_opts:
     #  com.docker.network.driver.mtu: "1446"
 services:
-  zookeeper:
-    image: wurstmeister/zookeeper:${ZOOKEEPER_TAG:-latest}
-#    ports:
-#      - "2181:2181"
-    networks:
-      - netOSM
-    healthcheck:
-      test: echo stat | nc localhost 2181
-      interval: 10s
-      timeout: 10s
-      retries: 3
-    logging:
-      driver: "json-file"
-      options:
-        max-size: "100m"
-        max-file: "2"
-  kafka:
-    image: wurstmeister/kafka:${KAFKA_TAG:-latest}
-    ports:
-      - "9092"
-    networks:
-      - netOSM
-    environment:
-      KAFKA_ADVERTISED_HOST_NAME: kafka
-      KAFKA_ADVERTISED_PORT: 9092
-      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
-      KAFKA_LOG_RETENTION_HOURS: 24
-    volumes:
-      - /var/run/docker.sock:/var/run/docker.sock
-    healthcheck:
-      test: zookeeper-shell.sh zookeeper:2181 ls /brokers/ids 2>&1 | grep "Node does not exist" && exit 1 || exit 0
-      interval: 20s
-      timeout: 10s
-      retries: 5
-    logging:
-      driver: "json-file"
-      options:
-        max-size: "100m"
-        max-file: "2"
-    #depends_on:
-    #  - zookeeper
-  mongo:
-    image: mongo
-#    ports:
-#      - "27017:27017"
-    networks:
-      - netOSM
-    volumes:
-      - mongo_db:/data/db
-  prometheus:
-    image: prom/prometheus:${PROMETHEUS_TAG:-latest}
-    hostname: prometheus
-    ports:
-      - "${OSM_PROM_PORTS:-9091:9090}"
-    volumes:
-      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
-      - prom_db:/prometheus
-    networks:
-      - netOSM
-    logging:
-      driver: "json-file"
-      options:
-        max-size: "100m"
-        max-file: "2"
-  prometheus-cadvisor:
-    image: google/cadvisor:${PROMETHEUS_CADVISOR_TAG:-latest}
-    ports:
-      - "${OSM_PROM_CADVISOR_PORTS:-8080:8080}"
-    volumes:
-      - /:/rootfs:ro
-      - /var/run:/var/run:ro
-      - /sys:/sys:ro
-      - /var/lib/docker/:/var/lib/docker:ro
-      - /dev/disk/:/dev/disk:ro
-    networks:
-      - netOSM
-  keystone:
-    image: ${DOCKER_USER:-opensourcemano}/keystone:${TAG:-8}
-    networks:
-      - netOSM
-    environment:
-      DB_HOST: mysql
-    env_file:
-      - ./keystone.env
-    ports:
-      - "${OSM_KEYSTONE_PORTS:-5000:5000}"
-    logging:
-      driver: "json-file"
-      options:
-        max-size: "100m"
-        max-file: "2"
-  nbi:
-    image: ${DOCKER_USER:-opensourcemano}/nbi:${TAG:-8}
-    networks:
-      - netOSM
-    volumes:
-      - osm_packages:/app/storage
-    environment:
-      OSMNBI_DATABASE_HOST: mongo
-      OSMNBI_MESSAGE_HOST: kafka
-    env_file:
-      - ./nbi.env
-    ports:
-      - "${OSM_NBI_PORTS:-9999:9999}"
-    logging:
-      driver: "json-file"
-      options:
-        max-size: "100m"
-        max-file: "2"
-    #depends_on:
-    #  - kafka
-    #  - mongo
-  lcm:
-    image: ${DOCKER_USER:-opensourcemano}/lcm:${TAG:-8}
-    networks:
-      - netOSM
-    volumes:
-      - osm_packages:/app/storage
-    environment:
-      OSMLCM_RO_HOST: ro
-      OSMLCM_DATABASE_HOST: mongo
-      OSMLCM_MESSAGE_HOST: kafka
-    env_file:
-      - ./lcm.env
-    logging:
-      driver: "json-file"
-      options:
-        max-size: "100m"
-        max-file: "2"
-    #depends_on:
-    #  - kafka
-    #  - mongo
-    #  - ro
-  mysql:
-    image: mysql:5
-    networks:
-      netOSM:
-        aliases:
-          - ro-db
-    volumes:
-      - ro_db:/var/lib/mysql
-    env_file:
-      - ./ro-db.env
-    logging:
-      driver: "json-file"
-      options:
-        max-size: "100m"
-        max-file: "2"
-#    ports:
-#      - "3306:3306"
-  ro:
-    image: ${DOCKER_USER:-opensourcemano}/ro:${TAG:-8}
-    networks:
-      - netOSM
-    environment:
-      RO_DB_HOST: mysql
-    env_file:
-      - ./ro.env
-    #depends_on:
-    #  - mysql
-    volumes:
-      - ro:/var/log/osm
-    ports:
-      - "${OSM_RO_PORTS:-9090:9090}"
-    logging:
-      driver: "json-file"
-      options:
-        max-size: "100m"
-        max-file: "2"
-  mon:
-    image: ${DOCKER_USER:-opensourcemano}/mon:${TAG:-8}
-    networks:
-      - netOSM
-    volumes:
-      - mon_db:/app/database
-    environment:
-      OSMMON_MESSAGE_HOST: kafka
-      OSMMON_MESSAGE_PORT: 9092
-    env_file:
-      - ./mon.env
-    ports:
-      - "${OSM_MON_PORTS:-8662:8662}"
-    #depends_on:
-    #  - kafka
-    logging:
-        driver: "json-file"
-        options:
-            max-file: 5
-            max-size: 10m
-  pol:
-    image: ${DOCKER_USER:-opensourcemano}/pol:${TAG:-8}
-    networks:
-      - netOSM
-    volumes:
-      - pol_db:/app/database
-    environment:
-      OSMPOL_MESSAGE_HOST: kafka
-      OSMPOL_MESSAGE_PORT: 9092
-    env_file:
-      - ./pol.env
-    #depends_on:
-    #  - kafka
-    #  - mon
-    logging:
-      driver: "json-file"
-      options:
-        max-file: 5
-        max-size: 10m
   ng-ui:
     image: ${DOCKER_USER:-opensourcemano}/ng-ui:${TAG:-8}
     networks:
       - netOSM
-    #depends_on:
-    #  - nbi
     ports:
       - "${OSM_UI_PORTS:-80:80}"
     logging:
@@ -254,21 +36,4 @@ services:
       options:
         max-size: "100m"
         max-file: "2"
-  grafana:
-    image: grafana/grafana
-    volumes:
-      - ./files/dashboards-osm.yml:/etc/grafana/provisioning/dashboards/dashboards-osm.yml
-      - ./files/osm-sample-dashboard.json:/etc/grafana/provisioning/dashboards/osm-sample-dashboard.json
-      - ./files/osm-system-dashboard.json:/etc/grafana/provisioning/dashboards/osm-system-dashboard.json
-      - ./files/datasource-prometheus.yml:/etc/grafana/provisioning/datasources/datasource-prometheus.yml
-    hostname: grafana
-    ports:
-      - "${OSM_GRAFANA_PORTS:-3000:3000}"
-    networks:
-      - netOSM
-    logging:
-      driver: "json-file"
-      options:
-        max-size: "100m"
-        max-file: "2"
 
diff --git a/installers/docker/osm_pla/docker-compose.yaml b/installers/docker/osm_pla/docker-compose.yaml
index 93699ef53f9f1f378cc4f3158ad1712fc41d6123..aae303ff63769a887525a641a92387831d6778c1 100644
--- a/installers/docker/osm_pla/docker-compose.yaml
+++ b/installers/docker/osm_pla/docker-compose.yaml
@@ -17,9 +17,16 @@
 ########################################################################
 
 version: '3'
+networks:
+  netOSM:
+    external:
+      name: ${OSM_NETWORK:-netosm}
+    #driver: overlay
+    #driver_opts:
+    #  com.docker.network.driver.mtu: "1446"
 services:
   pla:
-    image: ${DOCKER_USER:-opensourcemano}/pla:${TAG:-7}
+    image: ${DOCKER_USER:-opensourcemano}/pla:${TAG:-8}
     networks:
       - netOSM
     logging:
diff --git a/installers/full_install_osm.sh b/installers/full_install_osm.sh
index e1c917562c49cd18703deb92da8a80860cee4ef2..9d1fca1f034928bc77c9b64281c2c136fb97b211 100755
--- a/installers/full_install_osm.sh
+++ b/installers/full_install_osm.sh
@@ -210,7 +210,6 @@ function uninstall_lightweight() {
             fi
             remove_k8s_namespace $OSM_STACK_NAME
         else
-
             remove_stack $OSM_STACK_NAME
             remove_stack osm_elk
         fi
@@ -218,7 +217,6 @@ function uninstall_lightweight() {
         newgrp docker << EONG
         docker image rm ${DOCKER_USER}/ro:${OSM_DOCKER_TAG}
         docker image rm ${DOCKER_USER}/lcm:${OSM_DOCKER_TAG}
-        docker image rm ${DOCKER_USER}/light-ui:${OSM_DOCKER_TAG}
         docker image rm ${DOCKER_USER}/keystone:${OSM_DOCKER_TAG}
         docker image rm ${DOCKER_USER}/nbi:${OSM_DOCKER_TAG}
         docker image rm ${DOCKER_USER}/mon:${OSM_DOCKER_TAG}
@@ -228,14 +226,10 @@ function uninstall_lightweight() {
 EONG
 
         if [ -n "$NGUI" ]; then
-            newgrp docker << EONG
-            docker image rm ${DOCKER_USER}/ng-ui:${OSM_DOCKER_TAG}
-EONG
+            sg docker -c "docker image rm ${DOCKER_USER}/ng-ui:${OSM_DOCKER_TAG}"
         else
-            newgrp docker << EONG
-            docker image rm ${DOCKER_USER}/light-ui:${OSM_DOCKER_TAG}
-EONG
-         fi
+            sg docker -c "docker image rm ${DOCKER_USER}/light-ui:${OSM_DOCKER_TAG}"
+        fi
 
         if [ -n "$KUBERNETES" ]; then
             OSM_NAMESPACE_VOL="${OSM_HOST_VOL}/${OSM_STACK_NAME}"
@@ -250,7 +244,7 @@ EONG
         [ -z "$CONTROLLER_NAME" ] && sg lxd -c "juju destroy-controller --destroy-all-models --yes $OSM_STACK_NAME"
     fi
     remove_crontab_job
-    uninstall_osmclient
+    [ -z "$INSTALL_NOHOSTCLIENT" ] && uninstall_osmclient
     echo "Some docker images will be kept in case they are used by other docker stacks"
     echo "To remove them, just run 'docker image prune' in a terminal"
     return 0
@@ -259,7 +253,7 @@ EONG
 #Safe unattended install of iptables-persistent
 function check_install_iptables_persistent(){
     echo -e "\nChecking required packages: iptables-persistent"
-    if dpkg -l iptables-persistent &>/dev/null; then
+    if ! dpkg -l iptables-persistent &>/dev/null; then
         echo -e "    Not installed.\nInstalling iptables-persistent requires root privileges"
         echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
         echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
@@ -422,7 +416,7 @@ function install_docker_compose() {
 
 function install_juju() {
     echo "Installing juju"
-    sudo snap install juju --classic --channel=2.7/stable
+    sudo snap install juju --classic --channel=2.8/stable
     [[ ":$PATH": != *":/snap/bin:"* ]] && PATH="/snap/bin:${PATH}"
     update_juju_images
     echo "Finished installation of juju"
@@ -436,6 +430,11 @@ function juju_createcontroller() {
         sg lxd -c "juju bootstrap --bootstrap-series=xenial $OSM_VCA_CLOUDNAME $OSM_STACK_NAME"
     fi
     [ $(juju controllers | awk "/^${OSM_STACK_NAME}[\*| ]/{print $1}"|wc -l) -eq 1 ] || FATAL "Juju installation failed"
+    juju controller-config features=[k8s-operators]
+}
+
+function juju_addk8s() {
+    cat $HOME/.kube/config | juju add-k8s $OSM_VCA_K8S_CLOUDNAME --controller $OSM_STACK_NAME --storage openebs-hostpath
 }
 
 function juju_createproxy() {
@@ -581,6 +580,48 @@ function cmp_overwrite() {
     fi
 }
 
+function generate_docker_compose_files() {
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose.yaml $OSM_DOCKER_WORK_DIR/docker-compose.yaml
+    if [ -n "$NGUI" ]; then
+        # For NG-UI
+        $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose-ngui.yaml $OSM_DOCKER_WORK_DIR/docker-compose-ui.yaml
+    else
+        # Docker-compose
+        $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose-lightui.yaml $OSM_DOCKER_WORK_DIR/docker-compose-ui.yaml
+    fi
+    if [ -n "$INSTALL_PLA" ]; then
+        $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_pla/docker-compose.yaml $OSM_DOCKER_WORK_DIR/osm_pla/docker-compose.yaml
+    fi
+}
+
+function generate_k8s_manifest_files() {
+    #Kubernetes resources
+    $WORKDIR_SUDO cp -bR ${OSM_DEVOPS}/installers/docker/osm_pods $OSM_DOCKER_WORK_DIR
+    if [ -n "$NGUI" ]; then
+        $WORKDIR_SUDO rm -f $OSM_K8S_WORK_DIR/light-ui.yaml
+    else
+        $WORKDIR_SUDO rm -f $OSM_K8S_WORK_DIR/ng-ui.yaml
+    fi
+}
+
+function generate_prometheus_grafana_files() {
+    [ -n "$KUBERNETES" ] && return
+    # Prometheus files
+    $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/prometheus
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/prometheus/prometheus.yml $OSM_DOCKER_WORK_DIR/prometheus/prometheus.yml
+
+    # Grafana files
+    $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/grafana
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/dashboards-osm.yml $OSM_DOCKER_WORK_DIR/grafana/dashboards-osm.yml
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/datasource-prometheus.yml $OSM_DOCKER_WORK_DIR/grafana/datasource-prometheus.yml
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/osm-sample-dashboard.json $OSM_DOCKER_WORK_DIR/grafana/osm-sample-dashboard.json
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/osm-system-dashboard.json $OSM_DOCKER_WORK_DIR/grafana/osm-system-dashboard.json
+
+    # Prometheus Exporters files
+    $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/prometheus_exporters
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/prometheus_exporters/node_exporter.service $OSM_DOCKER_WORK_DIR/prometheus_exporters/node_exporter.service
+}
+
 function generate_docker_env_files() {
     echo "Doing a backup of existing env files"
     $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/keystone-db.env{,~}
@@ -594,38 +635,6 @@ function generate_docker_env_files() {
     $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/ro.env{,~}
 
     echo "Generating docker env files"
-    if [ -n "$KUBERNETES" ]; then
-        #Kubernetes resources
-        $WORKDIR_SUDO cp -bR ${OSM_DEVOPS}/installers/docker/osm_pods $OSM_DOCKER_WORK_DIR
-        [ -n "$NGUI" ] && $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_pods/ng-ui.yaml $OSM_K8S_WORK_DIR/ng-ui.yaml && $WORKDIR_SUDO rm $OSM_K8S_WORK_DIR/light-ui.yaml
-    else
-        if [ -n "$NGUI" ]; then
-            # For NG-UI
-            $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose-ngui.yaml $OSM_DOCKER_WORK_DIR/docker-compose.yaml
-        else
-            # Docker-compose
-            $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose.yaml $OSM_DOCKER_WORK_DIR/docker-compose.yaml
-        fi
-        if [ -n "$INSTALL_PLA" ]; then
-            $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_pla/docker-compose.yaml $OSM_DOCKER_WORK_DIR/osm_pla/docker-compose.yaml
-        fi
-
-        # Prometheus files
-        $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/prometheus
-        $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/prometheus/prometheus.yml $OSM_DOCKER_WORK_DIR/prometheus/prometheus.yml
-
-        # Grafana files
-        $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/grafana
-        $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/dashboards-osm.yml $OSM_DOCKER_WORK_DIR/grafana/dashboards-osm.yml
-        $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/datasource-prometheus.yml $OSM_DOCKER_WORK_DIR/grafana/datasource-prometheus.yml
-        $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/osm-sample-dashboard.json $OSM_DOCKER_WORK_DIR/grafana/osm-sample-dashboard.json
-        $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/osm-system-dashboard.json $OSM_DOCKER_WORK_DIR/grafana/osm-system-dashboard.json
-
-        # Prometheus Exporters files
-        $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/prometheus_exporters
-        $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/prometheus_exporters/node_exporter.service $OSM_DOCKER_WORK_DIR/prometheus_exporters/node_exporter.service
-    fi
-
     # LCM
     if [ ! -f $OSM_DOCKER_WORK_DIR/lcm.env ]; then
         echo "OSMLCM_DATABASE_COMMONKEY=${OSM_DATABASE_COMMONKEY}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/lcm.env
@@ -675,6 +684,12 @@ function generate_docker_env_files() {
         $WORKDIR_SUDO sed -i "s|OSMLCM_VCA_CLOUD.*|OSMLCM_VCA_CLOUD=${OSM_VCA_CLOUDNAME}|g" $OSM_DOCKER_WORK_DIR/lcm.env
     fi
 
+    if ! grep -Fq "OSMLCM_VCA_K8S_CLOUD" $OSM_DOCKER_WORK_DIR/lcm.env; then
+        echo "OSMLCM_VCA_K8S_CLOUD=${OSM_VCA_K8S_CLOUDNAME}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/lcm.env
+    else
+        $WORKDIR_SUDO sed -i "s|OSMLCM_VCA_K8S_CLOUD.*|OSMLCM_VCA_K8S_CLOUD=${OSM_VCA_K8S_CLOUDNAME}|g" $OSM_DOCKER_WORK_DIR/lcm.env
+    fi
+
     # RO
     MYSQL_ROOT_PASSWORD=$(generate_secret)
     if [ ! -f $OSM_DOCKER_WORK_DIR/ro-db.env ]; then
@@ -776,6 +791,26 @@ function kube_config_dir() {
     sudo chown $(id -u):$(id -g) $HOME/.kube/config
 }
 
+function install_k8s_storageclass() {
+    kubectl apply -f https://openebs.github.io/charts/openebs-operator-1.6.0.yaml
+    local storageclass_timeout=300
+    local counter=0
+    echo "Waiting for storageclass"
+    while (( counter < storageclass_timeout ))
+    do
+        kubectl get storageclass openebs-hostpath &> /dev/null
+
+        if [ $? -eq 0 ] ; then
+            echo "Storageclass available"
+            break
+        else
+            counter=$((counter + 15))
+            sleep 15
+        fi
+    done
+    kubectl patch storageclass openebs-hostpath -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
+}
+
 #deploys flannel as daemonsets
 function deploy_cni_provider() {
     CNI_DIR="$(mktemp -d -q --tmpdir "flannel.XXXXXX")"
@@ -811,8 +846,6 @@ function deploy_osm_services() {
 }
 
 function deploy_osm_pla_service() {
-    # corresponding to parse_yaml
-    [ ! $OSM_DOCKER_TAG == "7" ] && $WORKDIR_SUDO sed -i "s/opensourcemano\/pla:.*/opensourcemano\/pla:$OSM_DOCKER_TAG/g" $OSM_DOCKER_WORK_DIR/osm_pla/pla.yaml
     # corresponding to namespace_vol
     $WORKDIR_SUDO  sed -i "s#path: /var/lib/osm#path: $OSM_NAMESPACE_VOL#g" $OSM_DOCKER_WORK_DIR/osm_pla/pla.yaml
     # corresponding to deploy_osm_services
@@ -824,6 +857,7 @@ function install_helm() {
     helm > /dev/null 2>&1
     if [ $? != 0 ] ; then
         # Helm is not installed. Install helm
+        echo "Helm is not installed, installing ..."
         curl https://get.helm.sh/helm-v2.15.2-linux-amd64.tar.gz --output helm-v2.15.2.tar.gz
         tar -zxvf helm-v2.15.2.tar.gz
         sudo mv linux-amd64/helm /usr/local/bin/helm
@@ -841,14 +875,17 @@ function install_helm() {
         helm init --service-account tiller
 
         # Wait for Tiller to be up and running. If timeout expires, continue installing
-        tiller_timeout=120; counter=0
+        tiller_timeout=120;
+        counter=0;
+        tiller_status=""
         while (( counter < tiller_timeout ))
         do
             tiller_status=`kubectl -n kube-system get deployment.apps/tiller-deploy --no-headers |  awk '{print $2'}`
-            ( [ ! -z "$tiller_status" ] && [ $tiller_status == "1/1" ] ) && break
-            num=$((counter + 2))
-            sleep 2
+            ( [ ! -z "$tiller_status" ] && [ $tiller_status == "1/1" ] ) && echo "Tiller ready" && break
+            counter=$((counter + 5))
+            sleep 5
         done
+        [ "$tiller_status" != "1/1" ] && echo "Tiller is NOT READY YET. Installation will continue"
     fi
 }
 
@@ -858,6 +895,7 @@ function parse_yaml() {
     for osm in $osm_services; do
         $WORKDIR_SUDO sed -i "s/opensourcemano\/$osm:.*/$DOCKER_USER\/$osm:$TAG/g" $OSM_K8S_WORK_DIR/$osm.yaml
     done
+    $WORKDIR_SUDO sed -i "s/opensourcemano\/pla:.*/$DOCKER_USER\/\/pla:$OSM_DOCKER_TAG/g" $OSM_DOCKER_WORK_DIR/osm_pla/pla.yaml
 }
 
 function namespace_vol() {
@@ -933,9 +971,10 @@ function deploy_lightweight() {
 
     pushd $OSM_DOCKER_WORK_DIR
     if [ -n "$INSTALL_PLA" ]; then
-        sg docker -c ". ./osm_ports.sh; docker stack deploy -c $OSM_DOCKER_WORK_DIR/docker-compose.yaml -c $OSM_DOCKER_WORK_DIR/osm_pla/docker-compose.yaml $OSM_STACK_NAME"
+        track deploy_osm_pla
+        sg docker -c ". ./osm_ports.sh; docker stack deploy -c $OSM_DOCKER_WORK_DIR/docker-compose.yaml -c $OSM_DOCKER_WORK_DIR/docker-compose-ui.yaml -c $OSM_DOCKER_WORK_DIR/osm_pla/docker-compose.yaml $OSM_STACK_NAME"
     else
-        sg docker -c ". ./osm_ports.sh; docker stack deploy -c $OSM_DOCKER_WORK_DIR/docker-compose.yaml $OSM_STACK_NAME"
+        sg docker -c ". ./osm_ports.sh; docker stack deploy -c $OSM_DOCKER_WORK_DIR/docker-compose.yaml -c $OSM_DOCKER_WORK_DIR/docker-compose-ui.yaml $OSM_STACK_NAME"
     fi
     popd
 
@@ -1010,12 +1049,6 @@ function add_local_k8scluster() {
 }
 
 function install_lightweight() {
-    [ "${OSM_STACK_NAME}" == "osm" ] || OSM_DOCKER_WORK_DIR="$OSM_WORK_DIR/stack/$OSM_STACK_NAME"
-    [ -n "$KUBERNETES" ] && OSM_K8S_WORK_DIR="$OSM_DOCKER_WORK_DIR/osm_pods" && OSM_NAMESPACE_VOL="${OSM_HOST_VOL}/${OSM_STACK_NAME}"
-    [ ! -d "$OSM_DOCKER_WORK_DIR" ] && $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR
-    [ ! -d "$OSM_DOCKER_WORK_DIR/osm_pla" -a -n "$INSTALL_PLA" ] && $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/osm_pla
-    [ -n "$KUBERNETES" ] && $WORKDIR_SUDO cp -b $OSM_DEVOPS/installers/docker/cluster-config.yaml $OSM_DOCKER_WORK_DIR/cluster-config.yaml
-
     track checkingroot
     [ "$USER" == "root" ] && FATAL "You are running the installer as root. The installer is prepared to be executed as a normal user with sudo privileges."
     track noroot
@@ -1147,6 +1180,11 @@ EOF
     [ -n "$INSTALL_NODOCKER" ] || install_docker_ce
     track docker_ce
 
+    echo "Creating folders for installation"
+    [ ! -d "$OSM_DOCKER_WORK_DIR" ] && $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR
+    [ ! -d "$OSM_DOCKER_WORK_DIR/osm_pla" -a -n "$INSTALL_PLA" ] && $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/osm_pla
+    [ -n "$KUBERNETES" ] && $WORKDIR_SUDO cp -b $OSM_DEVOPS/installers/docker/cluster-config.yaml $OSM_DOCKER_WORK_DIR/cluster-config.yaml
+
     #Installs Kubernetes and deploys osm services
     if [ -n "$KUBERNETES" ]; then
         install_kube
@@ -1163,7 +1201,15 @@ EOF
     [ -z "$DOCKER_NOBUILD" ] && generate_docker_images
     track docker_build
 
+    if [ -n "$KUBERNETES" ]; then
+        generate_k8s_manifest_files
+    else
+        generate_docker_compose_files
+    fi
+    track manifest_files
+    generate_prometheus_grafana_files
     generate_docker_env_files
+    track env_files
 
     if [ -n "$KUBERNETES" ]; then
         if [ -n "$INSTALL_K8S_MONITOR" ]; then
@@ -1175,13 +1221,14 @@ EOF
         remove_k8s_namespace $OSM_STACK_NAME
         deploy_cni_provider
         kube_secrets
-        [ ! $OSM_DOCKER_TAG == "7" ] && parse_yaml $OSM_DOCKER_TAG
+        [ ! $OSM_DOCKER_TAG == "8" ] && parse_yaml $OSM_DOCKER_TAG
         namespace_vol
         taint_master_node
         deploy_osm_services
         if [ -n "$INSTALL_PLA"]; then
             # optional PLA install
             deploy_osm_pla_service
+            track deploy_osm_pla
         fi
         track deploy_osm_services_k8s
         install_k8s_storageclass
@@ -1210,7 +1257,7 @@ EOF
 
     [ -z "$INSTALL_NOHOSTCLIENT" ] && install_osmclient
     track osmclient
-    
+
     echo -e "Checking OSM health state..."
     if [ -n "$KUBERNETES" ]; then
         $OSM_DEVOPS/installers/osm_health.sh -s ${OSM_STACK_NAME} -k || \
@@ -1228,7 +1275,6 @@ EOF
     [ -n "$KUBERNETES" ] && add_local_k8scluster
     track add_local_k8scluster
 
-
     wget -q -O- https://osm-download.etsi.org/ftp/osm-8.0-eight/README2.txt &> /dev/null
     track end
     return 0
@@ -1404,6 +1450,7 @@ OSM_VCA_HOST=
 OSM_VCA_SECRET=
 OSM_VCA_PUBKEY=
 OSM_VCA_CLOUDNAME="localhost"
+OSM_VCA_K8S_CLOUDNAME="k8scloud"
 OSM_STACK_NAME=osm
 NO_HOST_PORTS=""
 DOCKER_NOBUILD=""
@@ -1605,22 +1652,6 @@ if [ -n "$CHARMED" ]; then
         ${OSM_DEVOPS}/installers/charmed_uninstall.sh -R $RELEASE -r $REPOSITORY -u $REPOSITORY_BASE -D /usr/share/osm-devops -t $DOCKER_TAG "$@"
      else
         ${OSM_DEVOPS}/installers/charmed_install.sh -R $RELEASE -r $REPOSITORY -u $REPOSITORY_BASE -D /usr/share/osm-devops -t $DOCKER_TAG "$@"
-
-        echo "Your installation is now complete, follow these steps for configuring the osmclient:"
-        echo
-        echo "1. Get the NBI IP with the following command:"
-        echo
-        echo NBI_IP='`juju status --format json | jq -rc '"'"'.applications."nbi-k8s".address'"'"'`'
-        echo
-        echo "2. Create the OSM_HOSTNAME environment variable with the NBI IP"
-        echo
-        echo "export OSM_HOSTNAME=\$NBI_IP"
-        echo
-        echo "3. Add the previous command to your .bashrc for other Shell sessions"
-        echo
-        echo "echo \"export OSM_HOSTNAME=\$NBI_IP\" >> ~/.bashrc"
-        echo
-        echo "DONE"
      fi
 
      exit 0
@@ -1670,6 +1701,8 @@ fi
 
 . $OSM_DEVOPS/common/all_funcs
 
+[ "${OSM_STACK_NAME}" == "osm" ] || OSM_DOCKER_WORK_DIR="$OSM_WORK_DIR/stack/$OSM_STACK_NAME"
+[ -n "$KUBERNETES" ] && OSM_K8S_WORK_DIR="$OSM_DOCKER_WORK_DIR/osm_pods" && OSM_NAMESPACE_VOL="${OSM_HOST_VOL}/${OSM_STACK_NAME}"
 [ -n "$INSTALL_LIGHTWEIGHT" ] && [ -n "$UNINSTALL" ] && uninstall_lightweight && echo -e "\nDONE" && exit 0
 [ -n "$INSTALL_ONLY" ] && [ -n "$INSTALL_ELK" ] && deploy_elk
 #[ -n "$INSTALL_ONLY" ] && [ -n "$INSTALL_PERFMON" ] && deploy_perfmon
diff --git a/jenkins/ci-pipelines/ci_stage_3.groovy b/jenkins/ci-pipelines/ci_stage_3.groovy
index 8f79cd47e7fd477b77f4fe7dbe383c9d13fca339..d87ad95b0327f288c3945f28cb546178015cc309 100644
--- a/jenkins/ci-pipelines/ci_stage_3.groovy
+++ b/jenkins/ci-pipelines/ci_stage_3.groovy
@@ -17,7 +17,7 @@
 
 /* Change log:
  * 1. Bug 745 : Jayant Madavi, Mrityunjay Yadav : JM00553988@techmahindra.com : 23-july-2019 : Improvement to the code, typically we have 2 *    or more branches whose build gets triggered, ex master & release branch, the previous code was removing any/all docker.
- *      Now removing previous docker of the same branch, so that the other branch failed docker should not be removed. It also
+ *	  Now removing previous docker of the same branch, so that the other branch failed docker should not be removed. It also
  *    acts as clean-up for previous docker remove failure.
  * 2. Feature 7829 : Mrityunjay Yadav, Jayant Madavi: MY00514913@techmahindra.com : 19-Aug-2019 : Added a parameters & function to invoke Robot test.
  */
@@ -398,15 +398,15 @@ node("${params.NODE}") {
                 if (error) {
                     if ( !params.SAVE_CONTAINER_ON_FAIL ) {
                         uninstall_osm container_name
-                        sh "docker stop ${http_server_name}"
-                        sh "docker rm ${http_server_name}"
+                        sh "docker stop ${http_server_name} || true"
+                        sh "docker rm ${http_server_name} || true"
                     }
                 }
                 else {
                     if ( !params.SAVE_CONTAINER_ON_PASS ) {
                         uninstall_osm container_name
-                        sh "docker stop ${http_server_name}"
-                        sh "docker rm ${http_server_name}"
+                        sh "docker stop ${http_server_name} || true"
+                        sh "docker rm ${http_server_name} || true"
                     }
                 }
             }