diff --git a/ansible/artifacts/sunbird/login/login.ftl b/ansible/artifacts/sunbird/login/login.ftl
index f1c9997d0f84f1d2e0c8a12180e8ba16e9030a6f..5a537fe4ded9fbb5ffe418b2bd67c0df56424590 100644
--- a/ansible/artifacts/sunbird/login/login.ftl
+++ b/ansible/artifacts/sunbird/login/login.ftl
@@ -22,7 +22,7 @@
                     <div id="success-msg" class="ui text success hide">suceess</div>
                     <div id="error-msg" class="ui text error hide">error</div>
                 </div>
-                <form id="kc-form-login" class="ui form" method="POST" action="${url.loginAction}">
+                <form id="kc-form-login" onsubmit="login.disabled = true; return true;" class="ui form" method="POST" action="${url.loginAction}">
                     <div class="field">
                         <label id="usernameLabel" for="username" class="">
                             <#if !realm.loginWithEmailAllowed>${msg("username")}
@@ -59,7 +59,7 @@
                     <div class="field">
                         <button id="login" class="mt-36 ui fluid button">${msg("doSignIn")}</button>
                     </div>
-                    
+
                     <div id="selfSingUp" class="hide">
                         <p class="or mb-30 mt-30 textCenter">OR</p>
                         <div class="field">
diff --git a/ansible/cassandra-deploy-decrypt.yml b/ansible/cassandra-deploy-decrypt.yml
new file mode 100644
index 0000000000000000000000000000000000000000..341631a4bf22ee2dc4a18a8687648935bef63150
--- /dev/null
+++ b/ansible/cassandra-deploy-decrypt.yml
@@ -0,0 +1,11 @@
+- hosts: "{{groups['cassandra'][0]}}"
+  become: yes
+  environment:
+    sunbird_cassandra_host: "{{ groups['cassandra'][0] }}"
+    sunbird_cassandra_port: 9042
+    sunbird_cassandra_keyspace: sunbird
+    sunbird_encryption_key: "{{ core_vault_sunbird_encryption_key }}"
+  vars_files:
+    - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
+  roles:
+    - cassandra-deploy-decrypt
diff --git a/ansible/es.yml b/ansible/es.yml
index ab6aaf2ce8f31aabe84cbca93c0e12a397cd395e..52b9502a2394d6ac4b6bb0535cf2b7c1af057bee 100644
--- a/ansible/es.yml
+++ b/ansible/es.yml
@@ -1,4 +1,5 @@
 - hosts: es-backup
+  gather_facts: no
   become: yes
   vars_files:
     - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
@@ -11,18 +12,21 @@
   tags:
     - es_backup
 
-- hosts: es-backup
+- hosts: "{{remote}}"
+  gather_facts: no
   become: yes
   vars_files:
     - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
   vars:
-    - es_restore_host: "{{app_es_restore_host}}"
+    - es_restore_host: "{{remote}}"
+    - snapshot_base_path: "{{app_snapshot_base_path}}"
   roles:
     - es-azure-restore
   tags:
     - es_restore
 
 - hosts: log-es-backup
+  gather_facts: no
   become: yes
   vars_files:
     - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
@@ -35,18 +39,21 @@
   tags:
     - log_es_backup
 
-- hosts: log-es-backup
+- hosts: "{{remote}}"
+  gather_facts: no
   become: yes
   vars_files:
     - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
   vars:
-    - es_restore_host: "{{log_es_restore_host}}"
+    - es_restore_host: "{{remote}}"
+    - snapshot_base_path: "{{log_snapshot_base_path}}"
   roles:
     - es-azure-restore
   tags:
     - log_es_restore
 
 - hosts: log-es
+  gather_facts: no
   become: yes
   vars_files:
     - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
diff --git a/ansible/inventory/env/group_vars/all.yml b/ansible/inventory/env/group_vars/all.yml
index 17b712b29f496c800622d71a49eef490bb938292..21269d9a3663dcc92bbee5b1324c8e5c0fcaaf6a 100644
--- a/ansible/inventory/env/group_vars/all.yml
+++ b/ansible/inventory/env/group_vars/all.yml
@@ -19,8 +19,8 @@ sunbird_app_name: "{{env}}"
 azure_account_key: "{{core_vault_sunbird_azure_storage_key}}"
 
 #artifact upload
-artifact_azure_account_name: "{{core_artifact_azure_account_name}}"
-artifact_azure_account_key: "{{core_vault_artifact_azure_account_key}}"
+artifact_azure_account_name: "{{azure_account_name}}"
+artifact_azure_account_key: "{{core_vault_sunbird_azure_storage_key}}"
 
 
 #plugins
@@ -84,6 +84,7 @@ kong_postgres_user: "{{core_vault_postgres_username}}"
 kong_postgres_password: "{{core_vault_postgres_password}}"
 enc_postgres_user: "{{core_vault_postgres_username}}"
 badger_postgres_user: "{{core_vault_postgres_username}}"
+user_org_service_postgres_user: "{{core_vault_postgres_username}}"
 sunbird_account_name: "{{azure_account_name}}"
 sunbird_account_key: "{{core_vault_sunbird_azure_storage_key}}"
 ansible_vault_password: "{{ core_vault_ansible_vault_password }}"
@@ -108,6 +109,9 @@ kong_host: api-manager_kong
 
 ## DB address
 application_postgres_host: "{{groups['postgres'][0]}}"  #Private IP of Postgres server
+enc_postgres_host: "{{groups['postgres'][0]}}"  #Private IP of Postgres server
+user_org_service_postgres_host: "{{groups['postgres'][0]}}"  #Private IP of Postgres server
+badger_postgres_host: "{{groups['postgres'][0]}}"  #Private IP of Postgres server
 keycloak_postgres_host: "{{groups['postgres'][0]}}"  #Private IP of Postgres server
 kong_postgres_host: "{{groups['postgres'][0]}}"  #Private IP of Postgres server
 sunbird_cassandra_host: "{{groups['cassandra']|join(',')}}"  #Private IP of Cassandra server
@@ -190,6 +194,7 @@ sunbird_msg_91_auth: "{{core_vault_msg_91_auth_key}}"
 sunbird_telemetry_pdata_id: "{{env}}.sunbird.learning.service"
 sunbird_encryption_key: "{{ core_vault_sunbird_encryption_key }}"
 #player_tenant_dir:
+user_org_service_postgres_database: userorg
 application_postgres_database: quartz
 keycloak_postgres_database: keycloak
 keyclaok_deployer_sudo_pass: "{{core_vault_keyclaok_deployer_sudo_pass}}"
@@ -201,7 +206,7 @@ sunbird_content_repo_api_key: "{{ core_vault_sunbird_ekstep_api_key }}"
 sunbird_search_service_api_key: "{{ core_vault_sunbird_ekstep_api_key }}"
 sunbird_dial_repo_api_base_url: "{{sunbird_ekstep_api_base_url}}"
 sunbird_dial_repo_api_key: "{{ core_vault_sunbird_ekstep_api_key }}"
-sunbird_plugin_repo_api_base_url: "{{sunbird_ekstep_api_base_url}}"
+sunbird_plugin_repo_api_base_url: "http://{{searchservice_ip}}:9000" 
 sunbird_data_service_api_base_url: "{{sunbird_ekstep_api_base_url}}"
 sunbird_data_service_api_key: "{{ core_vault_sunbird_ekstep_api_key }}"
 
@@ -290,7 +295,7 @@ badger_container: badgr
 sunbird_http_orgin: "{{proto}}://{{proxy_server_name}}/badging"
 
 #enc-service
-enc_postgres_database: encryption
+enc_postgres_database: "{{env}}-keys"
 
 #kafka vars
 zk_hosts: "127.0.0.1:2181"
@@ -347,14 +352,6 @@ ep_es_host: "{{ groups['telemetry-search-cluster'][0] }}"     #For kibana pipeli
 
 
 #encryption Service
-encryption_service_user: encryption
-encryption_db_name: encryption
-encryption_db_dialect: postgres
-encryption_reservation_memory: 750MB
-encryption_replicas: 1
-encryption_limit_memory: 750MB
-encryption_limit_cpu: 1
-encryption_reservation_cpu: 1
 sunbird_allowed_login:
 sunbird_course_batch_notification_enabled: 'true'
 sunbird_device_register_api: "{{proto}}://{{api_proxy_name}}/v3/device/register/"
@@ -384,34 +381,88 @@ grafana_dashboards_git_repo_url_with_credentails: "{{core_vault_grafana_dashboar
 monitor_alerts_slack_url: "{{core_vault_monitor_alerts_slack_url}}"
 kong__test_jwt: "{{core_vault_kong__test_jwt}}"
 
-# postgresql_users should only be created in master and replicated to slave
+############# Postgres users and databases ###############
 postgresql_users:
   - name: "{{kong_postgres_user}}"
+    login_host: "{{kong_postgres_host}}"
+    login_password: "{{kong_postgres_password}}"
     password: "{{postgres_password}}"
     db: "{{kong_postgres_database}}"
+    login_user: "{{kong_postgres_user}}"
     priv: "ALL"
   - name: "{{keycloak_postgres_user}}"
+    login_host: "{{keycloak_postgres_host}}"
+    login_password: "{{keycloak_postgres_password}}"
     password: "{{postgres_password}}"
     db: "{{keycloak_postgres_database}}"
+    login_user: "{{keycloak_postgres_user}}"
     priv: "ALL"
   - name: "{{application_postgres_user}}"
+    login_host: "{{application_postgres_host}}"
+    login_password: "{{application_postgres_password}}"
     password: "{{postgres_password}}"
     db: "{{application_postgres_database}}"
+    login_user: "{{application_postgres_user}}"
     priv: "ALL"
   - name: "{{badger_postgres_user}}"
+    login_host: "{{badger_postgres_host}}"
+    login_password: "{{badger_postgres_password}}"
     password: "{{postgres_password}}"
+    login_user: "{{badger_postgres_user}}"
     db: "{{badger_postgres_database}}"
     priv: "ALL"
+  - name: "{{user_org_service_postgres_user}}"
+    login_host: "{{user_org_service_postgres_host}}"
+    login_password: "{{user_org_service_postgres_password}}"
+    password: "{{user_org_service_postgres_password}}"
+    db: "{{user_org_service_postgres_database}}"
+    login_user: "{{user_org_service_postgres_user}}"
+    priv: "ALL"
+  - name: "{{enc_postgres_user}}"
+    login_host: "{{enc_postgres_host}}"
+    login_password: "{{enc_postgres_password}}"
+    password: "{{enc_postgres_password}}"
+    db: "{{enc_postgres_database}}"
+    login_user: "{{enc_postgres_user}}"
+    priv: "ALL"
 
 
 postgresql_databases:
   - name: "{{kong_postgres_database}}"
+    login_host: "{{kong_postgres_host}}"
+    login_password: "{{kong_postgres_password}}"
+    owner: "{{kong_postgres_user}}"
+    login_user: "{{kong_postgres_user}}"
   - name: "{{keycloak_postgres_database}}"
+    login_host: "{{keycloak_postgres_host}}"
+    login_password: "{{keycloak_postgres_password}}"
+    owner: "{{keycloak_postgres_user}}"
+    login_user: "{{keycloak_postgres_user}}"
   - name: "{{application_postgres_database}}"
+    login_host: "{{application_postgres_host}}"
+    login_password: "{{application_postgres_password}}"
+    owner: "{{application_postgres_user}}"
+    login_user: "{{application_postgres_user}}"
   - name: "{{badger_postgres_database}}"
+    login_host: "{{badger_postgres_host}}"
+    login_password: "{{badger_postgres_password}}"
+    owner: "{{badger_postgres_user}}"
+    login_user: "{{badger_postgres_user}}"
+  - name: "{{user_org_service_postgres_database}}"
+    login_host: "{{user_org_service_postgres_host}}"
+    login_password: "{{user_org_service_postgres_password}}"
+    owner: "{{user_org_service_postgres_user}}"
+    login_user: "{{user_org_service_postgres_user}}"
   - name: "{{enc_postgres_database}}"
+    login_host: "{{enc_postgres_host}}"
+    login_password: "{{enc_postgres_password}}"
+    owner: "{{enc_postgres_user}}"
+    login_user: "{{enc_postgres_user}}"
+
+##########################################################
+
+####### App ES ########
 
-#######App ES
 
 app_es_etc_cluster_name: "{{env}}"
 app_es_etc_discovery_zen_minimum_master_nodes: "{{groups['es']| length | int}}"
@@ -424,7 +475,6 @@ app_es_snapshot_base_path: application
 log_es_etc_cluster_name: "{{env}}-log"
 log_es_snapshot_host: "{{ groups['log-es'][0] }}"
 log_es_restore_host: "{{ groups['log-es'][0] }}"
-log_snapshot_base_path: logger
 log_es_host: "{{ groups['log-es'][0] }}"
 
 ####### Advanced Config ##########
@@ -538,11 +588,8 @@ trampoline_secret: "{{core_vault_trampoline_secret}}"
 es_api_host: "{{inventory_hostname}}"
 sunbird_linked_content_base_url: "{{proto}}://{{proxy_server_name}}/play/content/"
 enc_postgres_password: "{{core_vault_postgres_password}}"
-
-# Depricated value ??
+user_org_service_postgres_password: "{{core_vault_postgres_password}}"
 postgres_replication_user_password:  "{{core_vault_postgres_password}}"
-# Content service is calling ekstep ??
-# Config service variables, not required
 sunbird_config_service_url:
 config_refresh_interval: 10
 config_service_enabled: false
@@ -557,6 +604,8 @@ app_es_snapshot_host: "{{ groups['es'][0] }}"
 app_snapshot_base_path: applicationelasticsearch
 
 sunbird_es_host: "{{ groups['es'][0] }}"
+user_org_sunbird_es_host: "{{ sunbird_es_host }}"
+user_org_sunbird_es_port: "{{ sunbird_es_port }}"
 
 #log es backup
 log_es_snapshot_host: "{{ groups['log-es'][0] }}"
@@ -591,3 +640,11 @@ sunbird_portal_offline_app_release_date: ""
 sunbird_portal_offline_app_version: "1.0.0"
 sunbird_portal_offline_app_download_url: ""
 sunbird_portal_log_level: "debug"
+
+### Release 2.2.0 ###
+sunbird_google_android_keycloak_client_id: ''
+sunbird_google_android_keycloak_secret: ''
+sunbird_trampoline_android_keycloak_client_id: ''
+sunbird_trampoline_android_keycloak_secret: ''
+sunbird_android_keycloak_client_id: ''
+sunbird_user_org_api_base_url: http://learner-service:9000
diff --git a/ansible/keycloak.yml b/ansible/keycloak.yml
index b3d704ff666100d6f46ad575912bb76aded8556b..eda7e0d84f6a9353717fae2049ae1e1d1a4a1b91 100644
--- a/ansible/keycloak.yml
+++ b/ansible/keycloak.yml
@@ -1,5 +1,5 @@
 ---
-- hosts: keycloak
+- hosts: "{{host}}"
   become: true
   vars_files:
     - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
@@ -8,7 +8,7 @@
   tags:
     - provision
   
-- hosts: keycloak
+- hosts: "{{host}}"
   become: true
   vars_files:
     - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
diff --git a/ansible/logging.yml b/ansible/logging.yml
index 2aede7bef18f9fb106a78f18900bb194f9bd1a54..e5535104037bf49e13d53613efb8d52f8f2c82bd 100644
--- a/ansible/logging.yml
+++ b/ansible/logging.yml
@@ -15,7 +15,7 @@
     - stack-logger
   run_once: true
 
-- hosts: swarm-agent-dashboard
+- hosts: swarm-dashboard
   become: yes
   vars_files:
     - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
diff --git a/ansible/monitoring-fed.yml b/ansible/monitoring-fed.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a247a8218769f9f3f5512c077879c34359b6736c
--- /dev/null
+++ b/ansible/monitoring-fed.yml
@@ -0,0 +1,6 @@
+- hosts: swarm-dashboard
+  become: yes
+  vars_files:
+    - ['{{ inventory_dir }}/secrets.yml']
+  roles:
+    - prometheus-fed
diff --git a/ansible/postgresql-data-update.yml b/ansible/postgresql-data-update.yml
index e8cbfe28282adabef83ac09a012fabc3827a8385..e8cd6b30f48289e3b121b4324ae8e4147443dc44 100644
--- a/ansible/postgresql-data-update.yml
+++ b/ansible/postgresql-data-update.yml
@@ -1,6 +1,7 @@
-- hosts: postgresql-master
+- hosts: localhost
+  gather_facts: no
   become: yes
   vars_files:
     - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
   roles:
-    - postgresql-data-update
\ No newline at end of file
+    - postgresql-data-update
diff --git a/ansible/roles/artifacts-download-azure/tasks/main.yml b/ansible/roles/artifacts-download-azure/tasks/main.yml
index 820039c25a95700536eadd312038cdd0d7efe0c8..db79bc213fc8cfa87b5dfed18ee5bf39d5149aa9 100644
--- a/ansible/roles/artifacts-download-azure/tasks/main.yml
+++ b/ansible/roles/artifacts-download-azure/tasks/main.yml
@@ -4,5 +4,5 @@
 
 - name: Download from azure blob storage
   command: az storage blob download -c {{ artifacts_container }} --name {{ artifact }} -f {{ artifact_path }}
-  async: 100
+  async: 3600
   poll: 10
diff --git a/ansible/roles/cassandra-deploy-decrypt/defaults/main.yml b/ansible/roles/cassandra-deploy-decrypt/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c38c2c9d3a8f36243fcda9ca224b2856b3d2ecc2
--- /dev/null
+++ b/ansible/roles/cassandra-deploy-decrypt/defaults/main.yml
@@ -0,0 +1,2 @@
+cassandra_jar_path: ../
+cassandra_deploy_path: /home/deployer
diff --git a/ansible/roles/cassandra-deploy-decrypt/tasks/main.yml b/ansible/roles/cassandra-deploy-decrypt/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c26748ff3ff2843d4cd3bd6b32192f02c741d6cb
--- /dev/null
+++ b/ansible/roles/cassandra-deploy-decrypt/tasks/main.yml
@@ -0,0 +1,10 @@
+- name: Copy the jar
+  become: yes
+  copy:
+    src: "{{cassandra_jar_path}}/decryptionUtil-1.0-SNAPSHOT-jar-with-dependencies.jar"
+    dest: "{{cassandra_deploy_path}}"
+  run_once: true
+
+- name: Run the application
+  shell: java -jar decryptionUtil-1.0-SNAPSHOT-jar-with-dependencies.jar
+  run_once: true
diff --git a/ansible/roles/elasticsearch_old/tasks/main.yml b/ansible/roles/elasticsearch_old/tasks/main.yml
index e7cf7cec8c96044c5477c9945dc3b8382626d7df..0b234a1df1aff0b53ac35244c2f7036758a4c6cc 100644
--- a/ansible/roles/elasticsearch_old/tasks/main.yml
+++ b/ansible/roles/elasticsearch_old/tasks/main.yml
@@ -46,6 +46,9 @@
   ignore_errors: yes
   notify: Restart elasticsearch
 
+- name: Install azure plugin for elasticsearch
+  shell: ES_PATH_CONF=/etc/elasticsearch /usr/share/elasticsearch/bin/plugin install cloud-azure
+
 - name: Install plugins
   command: bin/plugin install {{item.name}} {%if item.url is defined %} url {{item.url}}{% endif %}
   args:
diff --git a/ansible/roles/es-azure-restore/defaults/main.yml b/ansible/roles/es-azure-restore/defaults/main.yml
index 49962dba3574e8a5fafa023eace34459e0cd4f17..b5de800802aa2838c5db9758d4981e32d09bff66 100644
--- a/ansible/roles/es-azure-restore/defaults/main.yml
+++ b/ansible/roles/es-azure-restore/defaults/main.yml
@@ -1,2 +1,11 @@
 # Override these values
-es_restore_host: localhost
+snapshot_create_request_body: {
+    type: azure,
+    settings: {
+      container: "elasticsearch-snapshots",
+      base_path: "{{ snapshot_base_path }}"
+    }
+}
+
+es_restore_host: "{{groups['es'][0]}}"
+snapshot_base_path: application
diff --git a/ansible/roles/es-azure-restore/tasks/main.yml b/ansible/roles/es-azure-restore/tasks/main.yml
index 1b1f6200c0de9ac089f254aeca2e1d5153cd4975..f45a97587b2a857fa5971593a180a34791adec35 100644
--- a/ansible/roles/es-azure-restore/tasks/main.yml
+++ b/ansible/roles/es-azure-restore/tasks/main.yml
@@ -1,4 +1,11 @@
 ---
+- name: Set azure snapshot for the first time
+  uri:
+    url: "http://{{ es_restore_host }}:9200/_snapshot/azurebackup"
+    method: PUT
+    body: "{{ snapshot_create_request_body | to_json }}"
+    headers:
+      Content-Type: "application/json"
 
 - name: Restore ES from Azure backup
   uri:
@@ -14,5 +21,5 @@
     body_format: json
   register: result
   until: result.json.snapshots[0].state == 'SUCCESS'
-  retries: 120
+  retries: 1200
   delay: 10
diff --git a/ansible/roles/es6/tasks/azure-plugin.yml b/ansible/roles/es6/tasks/azure-plugin.yml
new file mode 100644
index 0000000000000000000000000000000000000000..aed14050cd77611ed14a0965948dcdd39977455b
--- /dev/null
+++ b/ansible/roles/es6/tasks/azure-plugin.yml
@@ -0,0 +1,3 @@
+- name: Install azure plugin
+  shell: ES_PATH_CONF=/etc/elasticsearch/"{{ es_instance_name }}" /usr/share/elasticsearch/bin/elasticsearch-plugin install repository-azure
+  notify: restart elasticsearch
diff --git a/ansible/roles/es6/tasks/main.yml b/ansible/roles/es6/tasks/main.yml
index bc6a1ba865a0d672e9dbde3c69f7a4243e355d62..bbb2903f083f0ad09fd53761e5b8e5ed340ae3b9 100644
--- a/ansible/roles/es6/tasks/main.yml
+++ b/ansible/roles/es6/tasks/main.yml
@@ -9,12 +9,6 @@
   tags:
       - always
 
-# - name: include java.yml
-#   include: java.yml
-#   when: es_java_install
-#   tags:
-#       - java
-
 - name: include elasticsearch.yml
   include: elasticsearch.yml
   tags:
@@ -37,7 +31,11 @@
   tags:
       - plugins
 
-  #We always execute xpack as we may need to remove features
+# Install Elasticsearch plugin for backups
+- name: include elasticsearch plugin install
+  include: azure-plugin.yml
+
+#We always execute xpack as we may need to remove features
 - name: include xpack/elasticsearch-xpack.yml
   include: xpack/elasticsearch-xpack.yml
   tags:
@@ -75,10 +73,9 @@
   include: ./xpack/security/elasticsearch-security-native.yml
   when: manage_native_realm
 
-#Templates done after restart - handled by flushing the handlers. e.g. suppose user removes security on a running node and doesn't specify es_api_basic_auth_username and es_api_basic_auth_password.  The templates will subsequently not be removed if we don't wait for the node to restart.
 #We also do after the native realm to ensure any changes are applied here first and its denf up.
 - name: include elasticsearch-template.yml
   include: elasticsearch-template.yml
   when: es_templates
   tags:
-      - templates
\ No newline at end of file
+      - templates
diff --git a/ansible/roles/es6/templates/elasticsearch.yml.j2 b/ansible/roles/es6/templates/elasticsearch.yml.j2
index dcf6f7aef10c720acd37751b2c6db6e8144decaf..3cdbe5ab7145df35b8e2a4f028d32d04906455ba 100644
--- a/ansible/roles/es6/templates/elasticsearch.yml.j2
+++ b/ansible/roles/es6/templates/elasticsearch.yml.j2
@@ -50,3 +50,8 @@ network.host: 0.0.0.0
 {% if es_remote_reindex is defined %}
 reindex.remote.whitelist: {{es_remote_host}}:9200
 {% endif %}
+
+{% if backup_azure_storage_account_name is defined and backup_azure_storage_access_key is defined %}
+cloud.azure.storage.default.account: {{ backup_azure_storage_account_name }}
+cloud.azure.storage.default.key: {{ backup_azure_storage_access_key }}
+{% endif %}
diff --git a/ansible/roles/kong-api/defaults/main.yml b/ansible/roles/kong-api/defaults/main.yml
index a69f1e0ad5fb4819967c3ee726dc31cb294a9536..9fa21be7539ef02c9dfaac8d67e225b03e9acf76 100644
--- a/ansible/roles/kong-api/defaults/main.yml
+++ b/ansible/roles/kong-api/defaults/main.yml
@@ -65,6 +65,7 @@ echo_service_url: "http://api-manager_echo:9595"
 am_util_url: http://adminutil_adminutil:4000
 config_service_url: "http://config-service:8080"
 user_org_service_url: "http://user-org-service:9000"
+lms_service_url: "http://lms-service:9000"
 
 premium_consumer_rate_limits:
   - api: createContent
@@ -83,9 +84,9 @@ premium_consumer_rate_limits:
 # Example:
 # kong_apis:
 # - name: "readContent"
-#   request_path: "/v3/public/content/read"
+#   uris: "/v3/public/content/read"
 #   upstream_url: "{{ learning_service_url }}/v3/public/content/read"
-#   strip_request_path: true
+#   strip_uri: true
 #   plugins:
 #    - {name: 'jwt'}
 #    - {name: 'cors'}
@@ -96,9 +97,9 @@ premium_consumer_rate_limits:
 kong_apis:
 
   - name: PrivateContentAPIs
-    request_path: "{{ private_content_prefix }}/v3"
+    uris: "{{ private_content_prefix }}/v3"
     upstream_url: "{{ vm_learning_service_url }}/content/v3"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -112,9 +113,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createContent
-    request_path: "{{ content_service_prefix }}/v1/create"
+    uris: "{{ content_service_prefix }}/v1/create"
     upstream_url: "{{ content_service_url }}/v1/content/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -128,9 +129,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchContent
-    request_path: "{{ content_service_prefix }}/v1/search"
+    uris: "{{ content_service_prefix }}/v1/search"
     upstream_url: "{{ content_service_url }}/v1/content/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: cors
     - "{{ statsd_pulgin }}"
@@ -141,9 +142,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateContent
-    request_path: "{{ content_service_prefix }}/v1/update"
+    uris: "{{ content_service_prefix }}/v1/update"
     upstream_url: "{{ content_service_url }}/v1/content/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -157,9 +158,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readContent
-    request_path: "{{ content_service_prefix }}/v1/read"
+    uris: "{{ content_service_prefix }}/v1/read"
     upstream_url: "{{ content_service_url }}/v1/content/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: cors
     - "{{ statsd_pulgin }}"
@@ -170,9 +171,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: submitContentForReview
-    request_path: "{{ content_service_prefix }}/v1/review"
+    uris: "{{ content_service_prefix }}/v1/review"
     upstream_url: "{{ content_service_url }}/v1/content/review"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -186,9 +187,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: publishContent
-    request_path: "{{ content_service_prefix }}/v1/publish"
+    uris: "{{ content_service_prefix }}/v1/publish"
     upstream_url: "{{ content_service_url }}/v1/content/publish"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -202,9 +203,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: uploadContent
-    request_path: "{{ content_service_prefix }}/v1/upload"
+    uris: "{{ content_service_prefix }}/v1/upload"
     upstream_url: "{{ content_service_url }}/v1/content/upload"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -218,9 +219,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ large_request_size_limit }}"
   - name: retireContent
-    request_path: "{{ content_service_prefix }}/v1/retire"
+    uris: "{{ content_service_prefix }}/v1/retire"
     upstream_url: "{{ content_service_url }}/v1/content/retire"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -234,9 +235,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createCourse
-    request_path: "{{ course_service_prefix }}/v1/create"
+    uris: "{{ course_service_prefix }}/v1/create"
     upstream_url: "{{ content_service_url }}/v1/course/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -250,9 +251,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchCourse
-    request_path: "{{ course_service_prefix }}/v1/search"
+    uris: "{{ course_service_prefix }}/v1/search"
     upstream_url: "{{ content_service_url }}/v1/course/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -266,9 +267,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateCourse
-    request_path: "{{ course_service_prefix }}/v1/update"
+    uris: "{{ course_service_prefix }}/v1/update"
     upstream_url: "{{ content_service_url }}/v1/course/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -282,9 +283,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readCourse
-    request_path: "{{ course_service_prefix }}/v1/read"
+    uris: "{{ course_service_prefix }}/v1/read"
     upstream_url: "{{ content_service_url }}/v1/course/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -298,9 +299,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: submitCourseForReview
-    request_path: "{{ course_service_prefix }}/v1/review"
+    uris: "{{ course_service_prefix }}/v1/review"
     upstream_url: "{{ content_service_url }}/v1/course/review"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -314,9 +315,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: publishCourse
-    request_path: "{{ course_service_prefix }}/v1/publish"
+    uris: "{{ course_service_prefix }}/v1/publish"
     upstream_url: "{{ content_service_url }}/v1/course/publish"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -330,9 +331,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: retireCourse
-    request_path: "{{ course_service_prefix }}/v1/retire"
+    uris: "{{ course_service_prefix }}/v1/retire"
     upstream_url: "{{ content_service_url }}/v1/course/retire"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -346,9 +347,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getCourseHierarchy
-    request_path: "{{ course_service_prefix }}/v1/hierarchy"
+    uris: "{{ course_service_prefix }}/v1/hierarchy"
     upstream_url: "{{ content_service_url }}/v1/course/hierarchy"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: cors
     - "{{ statsd_pulgin }}"
@@ -359,9 +360,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: courseEnrolment
-    request_path: "{{ course_service_prefix }}/v1/enrol"
-    upstream_url: "{{ learning_service_url }}/v1/course/enroll"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/enrol"
+    upstream_url: "{{ lms_service_url }}/v1/course/enroll"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -375,9 +376,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: courseUnEnrolment
-    request_path: "{{ course_service_prefix }}/v1/unenrol"
-    upstream_url: "{{ learning_service_url }}/v1/course/unenroll"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/unenrol"
+    upstream_url: "{{ lms_service_url }}/v1/course/unenroll"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -391,9 +392,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listCourseEnrollments
-    request_path: "{{ course_service_prefix }}/v1/user/enrollment/list"
-    upstream_url: "{{ learning_service_url }}/v1/user/courses/list"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/user/enrollment/list"
+    upstream_url: "{{ lms_service_url }}/v1/user/courses/list"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -407,9 +408,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readContentState
-    request_path: "{{ course_service_prefix }}/v1/content/state/read"
-    upstream_url: "{{ learning_service_url }}/v1/content/state/read"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/content/state/read"
+    upstream_url: "{{ lms_service_url }}/v1/content/state/read"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -423,9 +424,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateContentState
-    request_path: "{{ course_service_prefix }}/v1/content/state/update"
-    upstream_url: "{{ learning_service_url }}/v1/content/state/update"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/content/state/update"
+    upstream_url: "{{ lms_service_url }}/v1/content/state/update"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -439,9 +440,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createUser
-    request_path: "{{ user_service_prefix }}/v1/create"
+    uris: "{{ user_service_prefix }}/v1/create"
     upstream_url: "{{ learning_service_url }}/v1/user/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -455,9 +456,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createUserVersion2
-    request_path: "{{ user_service_prefix }}/v2/create"
+    uris: "{{ user_service_prefix }}/v2/create"
     upstream_url: "{{ learning_service_url }}/v2/user/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -471,9 +472,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateUser
-    request_path: "{{ user_service_prefix }}/v1/update"
+    uris: "{{ user_service_prefix }}/v1/update"
     upstream_url: "{{ learning_service_url }}/v1/user/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -487,9 +488,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getUserProfile
-    request_path: "{{ user_service_prefix }}/v1/read"
+    uris: "{{ user_service_prefix }}/v1/read"
     upstream_url: "{{ learning_service_url }}/v1/user/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -503,9 +504,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getUserProfileV2
-    request_path: "{{ user_service_prefix }}/v2/read"
+    uris: "{{ user_service_prefix }}/v2/read"
     upstream_url: "{{ learning_service_url }}/v2/user/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -519,9 +520,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchUser
-    request_path: "{{ user_service_prefix }}/v1/search"
+    uris: "{{ user_service_prefix }}/v1/search"
     upstream_url: "{{ learning_service_url }}/v1/user/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -535,9 +536,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: retireUser
-    request_path: "{{ user_service_prefix }}/v1/retire"
+    uris: "{{ user_service_prefix }}/v1/retire"
     upstream_url: "{{ learning_service_url }}/v1/user/retire"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -551,9 +552,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createPage
-    request_path: "{{ data_service_prefix }}/v1/page/create"
-    upstream_url: "{{ learning_service_url }}/v1/page/create"
-    strip_request_path: true
+    uris: "{{ data_service_prefix }}/v1/page/create"
+    upstream_url: "{{ lms_service_url }}/v1/page/create"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -567,9 +568,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updatePage
-    request_path: "{{ data_service_prefix }}/v1/page/update"
-    upstream_url: "{{ learning_service_url }}/v1/page/update"
-    strip_request_path: true
+    uris: "{{ data_service_prefix }}/v1/page/update"
+    upstream_url: "{{ lms_service_url }}/v1/page/update"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -583,9 +584,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getPageSettings
-    request_path: "{{ data_service_prefix }}/v1/page/read"
-    upstream_url: "{{ learning_service_url }}/v1/page/read"
-    strip_request_path: true
+    uris: "{{ data_service_prefix }}/v1/page/read"
+    upstream_url: "{{ lms_service_url }}/v1/page/read"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -599,9 +600,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: dialAssemble
-    request_path: "{{ data_service_prefix }}/v1/dial/assemble"
-    upstream_url: "{{ learning_service_url }}/v1/page/assemble"
-    strip_request_path: true
+    uris: "{{ data_service_prefix }}/v1/dial/assemble"
+    upstream_url: "{{ lms_service_url }}/v1/page/assemble"
+    strip_uri: true
     plugins:
     - name: cors
     - "{{ statsd_pulgin }}"
@@ -612,9 +613,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: assemblePage
-    request_path: "{{ data_service_prefix }}/v1/page/assemble"
-    upstream_url: "{{ learning_service_url }}/v1/page/assemble"
-    strip_request_path: true
+    uris: "{{ data_service_prefix }}/v1/page/assemble"
+    upstream_url: "{{ lms_service_url }}/v1/page/assemble"
+    strip_uri: true
     plugins:
     - name: cors
     - "{{ statsd_pulgin }}"
@@ -625,9 +626,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createNote
-    request_path: "{{ notes_service_prefix }}/v1/create"
+    uris: "{{ notes_service_prefix }}/v1/create"
     upstream_url: "{{ learning_service_url }}/v1/note/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -641,9 +642,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateNote
-    request_path: "{{ notes_service_prefix }}/v1/update"
+    uris: "{{ notes_service_prefix }}/v1/update"
     upstream_url: "{{ learning_service_url }}/v1/note/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -657,9 +658,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readNote
-    request_path: "{{ notes_service_prefix }}/v1/read"
+    uris: "{{ notes_service_prefix }}/v1/read"
     upstream_url: "{{ learning_service_url }}/v1/note/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -673,9 +674,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchNotes
-    request_path: "{{ notes_service_prefix }}/v1/search"
+    uris: "{{ notes_service_prefix }}/v1/search"
     upstream_url: "{{ learning_service_url }}/v1/note/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -689,9 +690,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createOrg
-    request_path: "{{ org_service_prefix }}/v1/create"
+    uris: "{{ org_service_prefix }}/v1/create"
     upstream_url: "{{ learning_service_url }}/v1/org/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -705,9 +706,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateOrg
-    request_path: "{{ org_service_prefix }}/v1/update"
+    uris: "{{ org_service_prefix }}/v1/update"
     upstream_url: "{{ learning_service_url }}/v1/org/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -721,9 +722,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readOrg
-    request_path: "{{ org_service_prefix }}/v1/read"
+    uris: "{{ org_service_prefix }}/v1/read"
     upstream_url: "{{ learning_service_url }}/v1/org/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -737,9 +738,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchOrg
-    request_path: "{{ org_service_prefix }}/v1/search"
+    uris: "{{ org_service_prefix }}/v1/search"
     upstream_url: "{{ learning_service_url }}/v1/org/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: cors
     - "{{ statsd_pulgin }}"
@@ -750,9 +751,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: addMember
-    request_path: "{{ org_service_prefix }}/v1/member/add"
+    uris: "{{ org_service_prefix }}/v1/member/add"
     upstream_url: "{{ learning_service_url }}/v1/org/member/add"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -766,9 +767,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: removeMember
-    request_path: "{{ org_service_prefix }}/v1/member/remove"
+    uris: "{{ org_service_prefix }}/v1/member/remove"
     upstream_url: "{{ learning_service_url }}/v1/org/member/remove"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -782,9 +783,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: suspendMember
-    request_path: "{{ org_service_prefix }}/v1/member/suspend"
+    uris: "{{ org_service_prefix }}/v1/member/suspend"
     upstream_url: "{{ learning_service_url }}/v1/org/member/suspend"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -798,9 +799,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateMembership
-    request_path: "{{ org_service_prefix }}/v1/member/update"
+    uris: "{{ org_service_prefix }}/v1/member/update"
     upstream_url: "{{ learning_service_url }}/v1/org/member/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -814,9 +815,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: echo
-    request_path: "{{ echo_service_prefix }}"
+    uris: "{{ echo_service_prefix }}"
     upstream_url: "{{ echo_service_url }}"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -830,9 +831,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createPageSection
-    request_path: "{{ data_service_prefix }}/v1/page/section/create"
-    upstream_url: "{{ learning_service_url }}/v1/page/section/create"
-    strip_request_path: true
+    uris: "{{ data_service_prefix }}/v1/page/section/create"
+    upstream_url: "{{ lms_service_url }}/v1/page/section/create"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -846,9 +847,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updatePageSection
-    request_path: "{{ data_service_prefix }}/v1/page/section/update"
-    upstream_url: "{{ learning_service_url }}/v1/page/section/update"
-    strip_request_path: true
+    uris: "{{ data_service_prefix }}/v1/page/section/update"
+    upstream_url: "{{ lms_service_url }}/v1/page/section/update"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -862,9 +863,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listPageSections
-    request_path: "{{ data_service_prefix }}/v1/page/section/list"
-    upstream_url: "{{ learning_service_url }}/v1/page/section/list"
-    strip_request_path: true
+    uris: "{{ data_service_prefix }}/v1/page/section/list"
+    upstream_url: "{{ lms_service_url }}/v1/page/section/list"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -878,9 +879,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readPageSection
-    request_path: "{{ data_service_prefix }}/v1/page/section/read"
-    upstream_url: "{{ learning_service_url }}/v1/page/section/read"
-    strip_request_path: true
+    uris: "{{ data_service_prefix }}/v1/page/section/read"
+    upstream_url: "{{ lms_service_url }}/v1/page/section/read"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -894,9 +895,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readRoleMapping
-    request_path: "{{ data_service_prefix }}/v1/role/read"
+    uris: "{{ data_service_prefix }}/v1/role/read"
     upstream_url: "{{ learning_service_url }}/v1/role/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -910,9 +911,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateAssessment
-    request_path: "{{ course_service_prefix }}/v1/assessment/update"
+    uris: "{{ course_service_prefix }}/v1/assessment/update"
     upstream_url: "{{ learning_service_url }}/v1/assessment/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -926,9 +927,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readAssessmentResult
-    request_path: "{{ course_service_prefix }}/v1/assessment/result/read"
+    uris: "{{ course_service_prefix }}/v1/assessment/result/read"
     upstream_url: "{{ learning_service_url }}/v1/assessment/result/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -942,9 +943,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateOrgStatus
-    request_path: "{{ org_service_prefix }}/v1/status/update"
+    uris: "{{ org_service_prefix }}/v1/status/update"
     upstream_url: "{{ learning_service_url }}/v1/org/status/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -958,9 +959,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readUserProfile
-    request_path: "{{ user_service_prefix }}/v1/profile/read"
+    uris: "{{ user_service_prefix }}/v1/profile/read"
     upstream_url: "{{ learning_service_url }}/v1/user/getuser"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -974,9 +975,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: registerMobileApp
-    request_path: "{{ api_manager_perfix }}/v1/consumer/mobile_app/credential/register"
+    uris: "{{ api_manager_perfix }}/v1/consumer/mobile_app/credential/register"
     upstream_url: "{{ am_util_url }}/v1/consumer/mobile_app/credential/register"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -990,9 +991,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: registerMobileDevice
-    request_path: "{{ api_manager_perfix }}/v1/consumer/mobile_device/credential/register"
+    uris: "{{ api_manager_perfix }}/v1/consumer/mobile_device/credential/register"
     upstream_url: "{{ am_util_url }}/v1/consumer/mobile_device/credential/register"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1007,9 +1008,9 @@ kong_apis:
       config.allowed_payload_size: "{{ small_request_size_limit }}"
 
   - name: registerMobileAppOpenRAP
-    request_path: "{{ api_manager_perfix }}/v1/consumer/mobile_app_openrap/credential/register"
+    uris: "{{ api_manager_perfix }}/v1/consumer/mobile_app_openrap/credential/register"
     upstream_url: "{{ am_util_url }}/v1/consumer/mobile_app_openrap/credential/register"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1024,9 +1025,9 @@ kong_apis:
       config.allowed_payload_size: "{{ small_request_size_limit }}"
 
   - name: registerMobileDeviceOpenRAP
-    request_path: "{{ api_manager_perfix }}/v1/consumer/mobile_device_openrap/credential/register"
+    uris: "{{ api_manager_perfix }}/v1/consumer/mobile_device_openrap/credential/register"
     upstream_url: "{{ am_util_url }}/v1/consumer/mobile_device_openrap/credential/register"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1041,9 +1042,9 @@ kong_apis:
       config.allowed_payload_size: "{{ small_request_size_limit }}"
 
   - name: compositeSearch
-    request_path: "{{ composite_service_prefix }}/v1/search"
+    uris: "{{ composite_service_prefix }}/v1/search"
     upstream_url: "{{ content_service_url }}/v1/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1057,9 +1058,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listTerms
-    request_path: "{{ meta_service_prefix }}/v1/terms/list"
+    uris: "{{ meta_service_prefix }}/v1/terms/list"
     upstream_url: "{{ content_service_url }}/v1/terms/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1073,9 +1074,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listResourceBundles
-    request_path: "{{ meta_service_prefix }}/v1/resourcebundles/list"
+    uris: "{{ meta_service_prefix }}/v1/resourcebundles/list"
     upstream_url: "{{ content_service_url }}/v1/resourcebundles/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1089,9 +1090,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listOrdinals
-    request_path: "{{ meta_service_prefix }}/v1/ordinals/list"
+    uris: "{{ meta_service_prefix }}/v1/ordinals/list"
     upstream_url: "{{ content_service_url }}/v1/ordinals/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1105,9 +1106,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: telemetry
-    request_path: "{{ data_service_prefix }}/v1/telemetry"
+    uris: "{{ data_service_prefix }}/v1/telemetry"
     upstream_url: "{{ telemetry_service_url }}/v1/telemetry"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1121,9 +1122,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: flagContent
-    request_path: "{{ content_service_prefix }}/v1/flag"
+    uris: "{{ content_service_prefix }}/v1/flag"
     upstream_url: "{{ content_service_url }}/v1/content/flag"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1137,9 +1138,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: acceptContentFlag
-    request_path: "{{ content_service_prefix }}/v1/flag/accept"
+    uris: "{{ content_service_prefix }}/v1/flag/accept"
     upstream_url: "{{ content_service_url }}/v1/content/flag/accept"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1153,9 +1154,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: rejectContentFlag
-    request_path: "{{ content_service_prefix }}/v1/flag/reject"
+    uris: "{{ content_service_prefix }}/v1/flag/reject"
     upstream_url: "{{ content_service_url }}/v1/content/flag/reject"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1169,9 +1170,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getOrgCreationDashboard
-    request_path: "{{ dashboard_service_prefix }}/v1/creation/org"
+    uris: "{{ dashboard_service_prefix }}/v1/creation/org"
     upstream_url: "{{ learning_service_url }}/v1/dashboard/creation/org"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1185,9 +1186,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getOrgConsumptionDashboard
-    request_path: "{{ dashboard_service_prefix }}/v1/consumption/org"
+    uris: "{{ dashboard_service_prefix }}/v1/consumption/org"
     upstream_url: "{{ learning_service_url }}/v1/dashboard/consumption/org"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1201,9 +1202,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getCourseProgressDashboard
-    request_path: "{{ dashboard_service_prefix }}/v1/progress/course"
+    uris: "{{ dashboard_service_prefix }}/v1/progress/course"
     upstream_url: "{{ learning_service_url }}/v1/dashboard/progress/course"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1217,9 +1218,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getCourseProgressDashboardV2
-    request_path: "{{ dashboard_service_prefix }}/v2/progress/course"
+    uris: "{{ dashboard_service_prefix }}/v2/progress/course"
     upstream_url: "{{ learning_service_url }}/v2/dashboard/progress/course"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1233,9 +1234,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getCourseConsumptionDashboard
-    request_path: "{{ dashboard_service_prefix }}/v1/consumption/course"
+    uris: "{{ dashboard_service_prefix }}/v1/consumption/course"
     upstream_url: "{{ learning_service_url }}/v1/dashboard/consumption/course"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1249,9 +1250,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getUserCreationDashboard
-    request_path: "{{ dashboard_service_prefix }}/v1/creation/user"
+    uris: "{{ dashboard_service_prefix }}/v1/creation/user"
     upstream_url: "{{ learning_service_url }}/v1/dashboard/creation/user"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1265,9 +1266,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getUserConsumptionDasbhoard
-    request_path: "{{ dashboard_service_prefix }}/v1/consumption/user"
+    uris: "{{ dashboard_service_prefix }}/v1/consumption/user"
     upstream_url: "{{ learning_service_url }}/v1/dashboard/consumption/user"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1281,9 +1282,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: userBulkUpload
-    request_path: "{{ user_service_prefix }}/v1/upload"
+    uris: "{{ user_service_prefix }}/v1/upload"
     upstream_url: "{{ learning_service_url }}/v1/user/upload"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1297,9 +1298,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: orgBulkUpload
-    request_path: "{{ org_service_prefix }}/v1/upload"
+    uris: "{{ org_service_prefix }}/v1/upload"
     upstream_url: "{{ learning_service_url }}/v1/org/upload"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1313,9 +1314,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: checkUploadJobStatus
-    request_path: "{{ data_service_prefix }}/v1/upload/status"
+    uris: "{{ data_service_prefix }}/v1/upload/status"
     upstream_url: "{{ learning_service_url }}/v1/upload/status"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1329,9 +1330,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getUploadJobStatusLink
-    request_path: "{{ data_service_prefix }}/v1/upload/statusDownloadLink"
+    uris: "{{ data_service_prefix }}/v1/upload/statusDownloadLink"
     upstream_url: "{{ learning_service_url }}/v1/upload/statusDownloadLink"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1345,9 +1346,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createBatch
-    request_path: "{{ course_service_prefix }}/v1/batch/create"
-    upstream_url: "{{ learning_service_url }}/v1/course/batch/create"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/batch/create"
+    upstream_url: "{{ lms_service_url }}/v1/course/batch/create"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1361,9 +1362,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateBatch
-    request_path: "{{ course_service_prefix }}/v1/batch/update"
-    upstream_url: "{{ learning_service_url }}/v1/course/batch/update"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/batch/update"
+    upstream_url: "{{ lms_service_url }}/v1/course/batch/update"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1377,9 +1378,25 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: addUserToBatch
-    request_path: "{{ course_service_prefix }}/v1/batch/user/add"
-    upstream_url: "{{ learning_service_url }}/v1/course/batch/users/add"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/batch/user/add"
+    upstream_url: "{{ lms_service_url }}/v1/course/batch/users/add"
+    strip_uri: true
+    plugins:
+    - name: jwt
+    - name: cors
+    - "{{ statsd_pulgin }}"
+    - name: acl
+      config.whitelist: courseUpdate
+    - name: rate-limiting
+      config.policy: local
+      config.hour: "{{ medium_rate_limit_per_hour }}"
+      config.limit_by: credential
+    - name: request-size-limiting
+      config.allowed_payload_size: "{{ small_request_size_limit }}"
+  - name: removeUserFromBatch
+    uris: "{{ course_service_prefix }}/v1/batch/user/remove"
+    upstream_url: "{{ lms_service_url }}/v1/course/batch/users/remove"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1393,9 +1410,25 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getBatch
-    request_path: "{{ course_service_prefix }}/v1/batch/read"
-    upstream_url: "{{ learning_service_url }}/v1/course/batch/read"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/batch/read"
+    upstream_url: "{{ lms_service_url }}/v1/course/batch/read"
+    strip_uri: true
+    plugins:
+    - name: jwt
+    - name: cors
+    - "{{ statsd_pulgin }}"
+    - name: acl
+      config.whitelist: courseUser
+    - name: rate-limiting
+      config.policy: local
+      config.hour: "{{ medium_rate_limit_per_hour }}"
+      config.limit_by: credential
+    - name: request-size-limiting
+      config.allowed_payload_size: "{{ small_request_size_limit }}"
+  - name: getParticipants
+    uris: "{{ course_service_prefix }}/v1/batch/participants/list"
+    upstream_url: "{{ lms_service_url }}/v1/batch/participants/list"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1409,9 +1442,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: assignRole
-    request_path: "{{ user_service_prefix }}/v1/role/assign"
+    uris: "{{ user_service_prefix }}/v1/role/assign"
     upstream_url: "{{ learning_service_url }}/v1/user/assign/role"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1425,9 +1458,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: indexSync
-    request_path: "{{ data_service_prefix }}/v1/index/sync"
+    uris: "{{ data_service_prefix }}/v1/index/sync"
     upstream_url: "{{ learning_service_url }}/v1/data/sync"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1441,9 +1474,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: blockUser
-    request_path: "{{ user_service_prefix }}/v1/block"
+    uris: "{{ user_service_prefix }}/v1/block"
     upstream_url: "{{ learning_service_url }}/v1/user/block"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1457,9 +1490,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: unblockUser
-    request_path: "{{ user_service_prefix }}/v1/unblock"
+    uris: "{{ user_service_prefix }}/v1/unblock"
     upstream_url: "{{ learning_service_url }}/v1/user/unblock"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1473,9 +1506,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: uploadMedia
-    request_path: "{{ content_service_prefix }}/v1/media/upload"
+    uris: "{{ content_service_prefix }}/v1/media/upload"
     upstream_url: "{{ learning_service_url }}/v1/file/upload"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1489,9 +1522,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: listCourseBatches
-    request_path: "{{ course_service_prefix }}/v1/batch/list"
-    upstream_url: "{{ learning_service_url }}/v1/course/batch/search"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/batch/list"
+    upstream_url: "{{ lms_service_url }}/v1/course/batch/search"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1505,9 +1538,25 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: batchBulkEnrolment
-    request_path: "{{ course_service_prefix }}/v1/batch/bulk/enrollment"
-    upstream_url: "{{ learning_service_url }}/v1/batch/bulk/enrollment"
-    strip_request_path: true
+    uris: "{{ course_service_prefix }}/v1/batch/bulk/enrollment"
+    upstream_url: "{{ lms_service_url }}/v1/batch/bulk/enrollment"
+    strip_uri: true
+    plugins:
+    - name: jwt
+    - name: cors
+    - "{{ statsd_pulgin }}"
+    - name: acl
+      config.whitelist: orgAdmin
+    - name: rate-limiting
+      config.policy: local
+      config.hour: "{{ medium_rate_limit_per_hour }}"
+      config.limit_by: credential
+    - name: request-size-limiting
+      config.allowed_payload_size: "{{ small_request_size_limit }}"
+  - name: batchBulkUnEnrolment
+    uris: "{{ course_service_prefix }}/v1/batch/bulk/unenrollment"
+    upstream_url: "{{ lms_service_url }}/v1/batch/bulk/unenrollment"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1521,9 +1570,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getTenantInfo
-    request_path: "{{ org_service_prefix }}/v1/tenant/info"
+    uris: "{{ org_service_prefix }}/v1/tenant/info"
     upstream_url: "{{ player_service_url }}/v1/tenant/info"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1537,9 +1586,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getContentUploadUrl
-    request_path: "{{ content_service_prefix }}/v1/upload/url/read"
+    uris: "{{ content_service_prefix }}/v1/upload/url/read"
     upstream_url: "{{ content_service_url }}/v1/content/upload/url"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1553,9 +1602,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: rejectContent
-    request_path: "{{ content_service_prefix }}/v1/reject"
+    uris: "{{ content_service_prefix }}/v1/reject"
     upstream_url: "{{ content_service_url }}/v1/content/reject"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1569,9 +1618,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: deleteNote
-    request_path: "{{ notes_service_prefix }}/v1/delete"
+    uris: "{{ notes_service_prefix }}/v1/delete"
     upstream_url: "{{ learning_service_url }}/v1/note/delete"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1585,9 +1634,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: sendEmailNotification
-    request_path: "{{ user_service_prefix }}/v1/notification/email"
+    uris: "{{ user_service_prefix }}/v1/notification/email"
     upstream_url: "{{ learning_service_url }}/v1/notification/email"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1601,9 +1650,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: listAllBadges
-    request_path: "{{ org_service_prefix }}/v1/badges/list"
+    uris: "{{ org_service_prefix }}/v1/badges/list"
     upstream_url: "{{ learning_service_url }}/v1/badges/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1617,9 +1666,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: addBadgeToUser
-    request_path: "{{ user_service_prefix }}/v1/badges/add"
+    uris: "{{ user_service_prefix }}/v1/badges/add"
     upstream_url: "{{ learning_service_url }}/v1/user/badges/add"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1633,9 +1682,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: listOrgTypes
-    request_path: "{{ org_service_prefix }}/v1/type/list"
+    uris: "{{ org_service_prefix }}/v1/type/list"
     upstream_url: "{{ learning_service_url }}/v1/org/type/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1649,9 +1698,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: createOrgType
-    request_path: "{{ org_service_prefix }}/v1/type/create"
+    uris: "{{ org_service_prefix }}/v1/type/create"
     upstream_url: "{{ learning_service_url }}/v1/org/type/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1665,9 +1714,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: updateOrgType
-    request_path: "{{ org_service_prefix }}/v1/type/update"
+    uris: "{{ org_service_prefix }}/v1/type/update"
     upstream_url: "{{ learning_service_url }}/v1/org/type/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1681,9 +1730,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: updateUserloginTime
-    request_path: "{{ user_service_prefix }}/v1/update/logintime"
+    uris: "{{ user_service_prefix }}/v1/update/logintime"
     upstream_url: "{{ learning_service_url }}/v1/user/update/logintime"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1697,9 +1746,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getMediaTypes
-    request_path: "{{ user_service_prefix }}/v1/mediatype/list"
+    uris: "{{ user_service_prefix }}/v1/mediatype/list"
     upstream_url: "{{ learning_service_url }}/v1/user/mediatype/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1713,9 +1762,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: DecryptData
-    request_path: "{{ data_service_prefix }}/v1/user/decrypt"
+    uris: "{{ data_service_prefix }}/v1/user/decrypt"
     upstream_url: "{{ learning_service_url }}/v1/user/data/decrypt"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1729,9 +1778,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: encryptData
-    request_path: "{{ data_service_prefix }}/v1/user/encrypt"
+    uris: "{{ data_service_prefix }}/v1/user/encrypt"
     upstream_url: "{{ learning_service_url }}/v1/user/data/encrypt"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1745,9 +1794,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: searchAuditHistory
-    request_path: "{{ data_service_prefix }}/v1/audit/history"
+    uris: "{{ data_service_prefix }}/v1/audit/history"
     upstream_url: "{{ learning_service_url }}/v1/audit/history"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1761,9 +1810,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: addUserSkill
-    request_path: "{{ user_service_prefix }}/v1/skill/add"
+    uris: "{{ user_service_prefix }}/v1/skill/add"
     upstream_url: "{{ learning_service_url }}/v1/user/skill/add"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1777,9 +1826,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getUserSkill
-    request_path: "{{ user_service_prefix }}/v1/skill/read"
+    uris: "{{ user_service_prefix }}/v1/skill/read"
     upstream_url: "{{ learning_service_url }}/v1/user/skill/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1793,9 +1842,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getSkills
-    request_path: "{{ data_service_prefix }}/v1/skills"
+    uris: "{{ data_service_prefix }}/v1/skills"
     upstream_url: "{{ learning_service_url }}/v1/skills"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1809,9 +1858,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: updateUserSkill
-    request_path: "{{ user_service_prefix }}/v1/skill/update"
+    uris: "{{ user_service_prefix }}/v1/skill/update"
     upstream_url: "{{ learning_service_url }}/v1/user/skill/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1825,9 +1874,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: addUserSkillEndorsement
-    request_path: "{{ user_service_prefix }}/v1/skill/endorse/add"
+    uris: "{{ user_service_prefix }}/v1/skill/endorse/add"
     upstream_url: "{{ learning_service_url }}/v1/user/skill/endorse/add"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1841,9 +1890,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getAllData
-    request_path: "{{ data_service_prefix }}/v1/object/read/list"
+    uris: "{{ data_service_prefix }}/v1/object/read/list"
     upstream_url: "{{ learning_service_url }}/v1/object/read/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1857,9 +1906,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getData
-    request_path: "{{ data_service_prefix }}/v1/object/read"
+    uris: "{{ data_service_prefix }}/v1/object/read"
     upstream_url: "{{ learning_service_url }}/v1/object/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1873,9 +1922,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: createData
-    request_path: "{{ data_service_prefix }}/v1/object/create"
+    uris: "{{ data_service_prefix }}/v1/object/create"
     upstream_url: "{{ learning_service_url }}/v1/object/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1889,9 +1938,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ large_request_size_limit }}"
   - name: updateData
-    request_path: "{{ data_service_prefix }}/v1/object/update"
+    uris: "{{ data_service_prefix }}/v1/object/update"
     upstream_url: "{{ learning_service_url }}/v1/object/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1905,9 +1954,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: deleteData
-    request_path: "{{ data_service_prefix }}/v1/object/delete"
+    uris: "{{ data_service_prefix }}/v1/object/delete"
     upstream_url: "{{ learning_service_url }}/v1/object/delete"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1921,9 +1970,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: searchData
-    request_path: "{{ data_service_prefix }}/v1/object/search"
+    uris: "{{ data_service_prefix }}/v1/object/search"
     upstream_url: "{{ learning_service_url }}/v1/object/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1937,9 +1986,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getAnnouncementDefinitions
-    request_path: "{{announcement_service_prefix}}/v1/definitions"
+    uris: "{{announcement_service_prefix}}/v1/definitions"
     upstream_url: "{{ player_service_url }}/announcement/v1/definitions"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1953,9 +2002,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createAnnouncement
-    request_path: "{{announcement_service_prefix}}/v1/create"
+    uris: "{{announcement_service_prefix}}/v1/create"
     upstream_url: "{{ player_service_url }}/announcement/v1/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1969,9 +2018,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: cancelAnnouncement
-    request_path: "{{announcement_service_prefix}}/v1/cancel"
+    uris: "{{announcement_service_prefix}}/v1/cancel"
     upstream_url: "{{ player_service_url }}/announcement/v1/cancel"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -1985,9 +2034,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getAnnouncementInbox
-    request_path: "{{announcement_service_prefix}}/v1/user/inbox"
+    uris: "{{announcement_service_prefix}}/v1/user/inbox"
     upstream_url: "{{ player_service_url }}/announcement/v1/user/inbox"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2001,9 +2050,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getAnnouncementOutbox
-    request_path: "{{announcement_service_prefix}}/v1/user/outbox"
+    uris: "{{announcement_service_prefix}}/v1/user/outbox"
     upstream_url: "{{ player_service_url }}/announcement/v1/user/outbox"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2017,9 +2066,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getAnnouncement
-    request_path: "{{announcement_service_prefix}}/v1/get"
+    uris: "{{announcement_service_prefix}}/v1/get"
     upstream_url: "{{ player_service_url }}/announcement/v1/get"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2034,9 +2083,9 @@ kong_apis:
       config.allowed_payload_size: "{{ small_request_size_limit }}"
 
   - name: registerClient
-    request_path: "{{ data_service_prefix }}/v1/client/register"
+    uris: "{{ data_service_prefix }}/v1/client/register"
     upstream_url: "{{ learning_service_url }}/v1/client/register"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2050,9 +2099,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateClientKey
-    request_path: "{{ data_service_prefix }}/v1/client/key/update"
+    uris: "{{ data_service_prefix }}/v1/client/key/update"
     upstream_url: "{{ learning_service_url }}/v1/client/key/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2066,9 +2115,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getClientKey
-    request_path: "{{ data_service_prefix }}/v1/client/key/read"
+    uris: "{{ data_service_prefix }}/v1/client/key/read"
     upstream_url: "{{ learning_service_url }}/v1/client/key/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2082,9 +2131,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getTenantPreference
-    request_path: "{{ org_service_prefix }}/v1/tc/read"
+    uris: "{{ org_service_prefix }}/v1/tc/read"
     upstream_url: "{{ learning_service_url }}/v1/org/tc/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2098,9 +2147,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createTenantPreference
-    request_path: "{{ org_service_prefix }}/v1/tc/create"
+    uris: "{{ org_service_prefix }}/v1/tc/create"
     upstream_url: "{{ learning_service_url }}/v1/org/tc/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2114,9 +2163,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateTenantPreference
-    request_path: "{{ org_service_prefix }}/v1/tc/update"
+    uris: "{{ org_service_prefix }}/v1/tc/update"
     upstream_url: "{{ learning_service_url }}/v1/org/tc/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2130,9 +2179,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateUserTcStatus
-    request_path: "{{ user_service_prefix }}/v1/tc/update"
+    uris: "{{ user_service_prefix }}/v1/tc/update"
     upstream_url: "{{ learning_service_url }}/v1/user/tc/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2146,9 +2195,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createLocation
-    request_path: "{{ org_service_prefix }}/v1/location/create"
+    uris: "{{ org_service_prefix }}/v1/location/create"
     upstream_url: "{{ learning_service_url }}/v1/notification/location/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2162,9 +2211,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getLocation
-    request_path: "{{ org_service_prefix }}/v1/location/read"
+    uris: "{{ org_service_prefix }}/v1/location/read"
     upstream_url: "{{ learning_service_url }}/v1/notification/location/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2178,9 +2227,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: deleteLocation
-    request_path: "{{ org_service_prefix }}/v1/location/delete"
+    uris: "{{ org_service_prefix }}/v1/location/delete"
     upstream_url: "{{ learning_service_url }}/v1/notification/location/delete"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2194,9 +2243,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateLocation
-    request_path: "{{ org_service_prefix }}/v1/location/update"
+    uris: "{{ org_service_prefix }}/v1/location/update"
     upstream_url: "{{ learning_service_url }}/v1/notification/location/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2210,9 +2259,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: profileVisibility
-    request_path: "{{ user_service_prefix }}/v1/profile/visibility"
+    uris: "{{ user_service_prefix }}/v1/profile/visibility"
     upstream_url: "{{ learning_service_url }}/v1/user/profile/visibility"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2226,9 +2275,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: sendNotification
-    request_path: "{{ data_service_prefix }}/v1/notification/send"
+    uris: "{{ data_service_prefix }}/v1/notification/send"
     upstream_url: "{{ learning_service_url }}/v1/notification/send"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2242,9 +2291,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: announcementResend
-    request_path: "{{ announcement_service_prefix }}/v1/resend"
+    uris: "{{ announcement_service_prefix }}/v1/resend"
     upstream_url: "{{ player_service_url }}/announcement/v1/resend"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2258,9 +2307,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: announcementReceived
-    request_path: "{{ announcement_service_prefix }}/v1/received"
+    uris: "{{ announcement_service_prefix }}/v1/received"
     upstream_url: "{{ player_service_url }}/announcement/v1/received"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2274,9 +2323,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: announcementRead
-    request_path: "{{ announcement_service_prefix }}/v1/read"
+    uris: "{{ announcement_service_prefix }}/v1/read"
     upstream_url: "{{ player_service_url }}/announcement/v1/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2290,9 +2339,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: metricsSearchData
-    request_path: "{{ data_service_prefix }}/v1/object/metrics"
+    uris: "{{ data_service_prefix }}/v1/object/metrics"
     upstream_url: "{{ learning_service_url }}/v1/object/metrics"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2306,9 +2355,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateSystemSettings
-    request_path: "{{ data_service_prefix }}/v1/system/settings/list"
+    uris: "{{ data_service_prefix }}/v1/system/settings/list"
     upstream_url: "{{ learning_service_url }}/v1/system/settings/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2322,9 +2371,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getAudienceCount
-    request_path: "{{ data_service_prefix }}/v1/notification/audience"
+    uris: "{{ data_service_prefix }}/v1/notification/audience"
     upstream_url: "{{ learning_service_url }}/v1/notification/audience"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2338,9 +2387,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: generateDialcodes
-    request_path: "{{ dialcode_service_prefix }}/v1/generate"
+    uris: "{{ dialcode_service_prefix }}/v1/generate"
     upstream_url: "{{ content_service_url }}/v1/dialcode/generate"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2354,9 +2403,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readDialcode
-    request_path: "{{ dialcode_service_prefix }}/v1/read"
+    uris: "{{ dialcode_service_prefix }}/v1/read"
     upstream_url: "{{ content_service_url }}/v1/dialcode/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2370,9 +2419,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateDialcode
-    request_path: "{{ dialcode_service_prefix }}/v1/update"
+    uris: "{{ dialcode_service_prefix }}/v1/update"
     upstream_url: "{{ content_service_url }}/v1/dialcode/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2386,9 +2435,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listDialcodes
-    request_path: "{{ dialcode_service_prefix }}/v1/list"
+    uris: "{{ dialcode_service_prefix }}/v1/list"
     upstream_url: "{{ content_service_url }}/v1/dialcode/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2402,9 +2451,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: publishDialcode
-    request_path: "{{ dialcode_service_prefix }}/v1/publish"
+    uris: "{{ dialcode_service_prefix }}/v1/publish"
     upstream_url: "{{ content_service_url }}/v1/dialcode/publish"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2418,9 +2467,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchDialcodes
-    request_path: "{{ dialcode_service_prefix }}/v1/search"
+    uris: "{{ dialcode_service_prefix }}/v1/search"
     upstream_url: "{{ content_service_url }}/v1/dialcode/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2434,9 +2483,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: qrCodeBatchProcessStatus
-    request_path: "{{ dialcode_service_prefix }}/v1/process/status"
+    uris: "{{ dialcode_service_prefix }}/v1/process/status"
     upstream_url: "{{ content_service_url }}/v1/dialcode/process/status"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2450,9 +2499,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: qrCodeBatchProcessRetry
-    request_path: "{{ dialcode_service_prefix }}/v1/process/retry"
+    uris: "{{ dialcode_service_prefix }}/v1/process/retry"
     upstream_url: "{{ content_service_url }}/v1/dialcode/process/retry"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2466,9 +2515,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createPublisher
-    request_path: "{{ dialcode_service_prefix }}/v1/publisher/create"
+    uris: "{{ dialcode_service_prefix }}/v1/publisher/create"
     upstream_url: "{{ content_service_url }}/v1/dialcode/publisher/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2482,9 +2531,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updatePublisher
-    request_path: "{{ dialcode_service_prefix }}/v1/publisher/update"
+    uris: "{{ dialcode_service_prefix }}/v1/publisher/update"
     upstream_url: "{{ content_service_url }}/v1/dialcode/publisher/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2498,9 +2547,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readPublisher
-    request_path: "{{ dialcode_service_prefix }}/v1/publisher/read"
+    uris: "{{ dialcode_service_prefix }}/v1/publisher/read"
     upstream_url: "{{ content_service_url }}/v1/dialcode/publisher/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2514,9 +2563,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: linkDialcodeContent
-    request_path: "{{ dialcode_service_prefix }}/v1/content/link"
+    uris: "{{ dialcode_service_prefix }}/v1/content/link"
     upstream_url: "{{ content_service_url }}/v1/dialcode/content/link"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2530,9 +2579,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readChannel
-    request_path: "{{ channel_service_prefix }}/v1/read"
+    uris: "{{ channel_service_prefix }}/v1/read"
     upstream_url: "{{ content_service_url }}/v1/channel/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: cors
     - "{{ statsd_pulgin }}"
@@ -2543,9 +2592,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listChannel
-    request_path: "{{ channel_service_prefix }}/v1/list"
+    uris: "{{ channel_service_prefix }}/v1/list"
     upstream_url: "{{ content_service_url }}/v1/channel/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2559,9 +2608,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchChannel
-    request_path: "{{ channel_service_prefix }}/v1/search"
+    uris: "{{ channel_service_prefix }}/v1/search"
     upstream_url: "{{ content_service_url }}/v1/channel/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2575,9 +2624,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createChannel
-    request_path: "{{ channel_service_prefix }}/v1/create"
+    uris: "{{ channel_service_prefix }}/v1/create"
     upstream_url: "{{ content_service_url }}/v1/channel/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2591,9 +2640,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateChannel
-    request_path: "{{ channel_service_prefix }}/v1/update"
+    uris: "{{ channel_service_prefix }}/v1/update"
     upstream_url: "{{ content_service_url }}/v1/channel/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2607,9 +2656,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readFramework
-    request_path: "{{ framework_service_prefix }}/v1/read"
+    uris: "{{ framework_service_prefix }}/v1/read"
     upstream_url: "{{ content_service_url }}/v1/framework/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: cors
     - "{{ statsd_pulgin }}"
@@ -2620,9 +2669,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listFramework
-    request_path: "{{ framework_service_prefix }}/v1/list"
+    uris: "{{ framework_service_prefix }}/v1/list"
     upstream_url: "{{ content_service_url }}/v1/framework/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2636,9 +2685,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createFramework
-    request_path: "{{ framework_service_prefix }}/v1/create"
+    uris: "{{ framework_service_prefix }}/v1/create"
     upstream_url: "{{ content_service_url }}/v1/framework/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2652,9 +2701,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateFramework
-    request_path: "{{ framework_service_prefix }}/v1/update"
+    uris: "{{ framework_service_prefix }}/v1/update"
     upstream_url: "{{ content_service_url }}/v1/framework/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2668,9 +2717,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: copyFramework
-    request_path: "{{ framework_service_prefix }}/v1/copy"
+    uris: "{{ framework_service_prefix }}/v1/copy"
     upstream_url: "{{ content_service_url }}/v1/framework/copy"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2684,9 +2733,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readFrameworkTerm
-    request_path: "{{ framework_service_prefix }}/v1/term/read"
+    uris: "{{ framework_service_prefix }}/v1/term/read"
     upstream_url: "{{ content_service_url }}/v1/framework/term/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2700,9 +2749,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchFrameworkTerm
-    request_path: "{{ framework_service_prefix }}/v1/term/search"
+    uris: "{{ framework_service_prefix }}/v1/term/search"
     upstream_url: "{{ content_service_url }}/v1/framework/term/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2716,9 +2765,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createFrameworkTerm
-    request_path: "{{ framework_service_prefix }}/v1/term/create"
+    uris: "{{ framework_service_prefix }}/v1/term/create"
     upstream_url: "{{ content_service_url }}/v1/framework/term/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2732,9 +2781,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateFrameworkTerm
-    request_path: "{{ framework_service_prefix }}/v1/term/update"
+    uris: "{{ framework_service_prefix }}/v1/term/update"
     upstream_url: "{{ content_service_url }}/v1/framework/term/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2748,9 +2797,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readFrameworkCategory
-    request_path: "{{ framework_service_prefix }}/v1/category/read"
+    uris: "{{ framework_service_prefix }}/v1/category/read"
     upstream_url: "{{ content_service_url }}/v1/framework/category/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2764,9 +2813,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchFrameworkCategory
-    request_path: "{{ framework_service_prefix }}/v1/category/search"
+    uris: "{{ framework_service_prefix }}/v1/category/search"
     upstream_url: "{{ content_service_url }}/v1/framework/category/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2780,9 +2829,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createFrameworkCategory
-    request_path: "{{ framework_service_prefix }}/v1/category/create"
+    uris: "{{ framework_service_prefix }}/v1/category/create"
     upstream_url: "{{ content_service_url }}/v1/framework/category/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2796,9 +2845,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateFrameworkCategory
-    request_path: "{{ framework_service_prefix }}/v1/category/update"
+    uris: "{{ framework_service_prefix }}/v1/category/update"
     upstream_url: "{{ content_service_url }}/v1/framework/category/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2812,9 +2861,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateCourseHierarchy
-    request_path: '{{ course_service_prefix }}/v1/hierarchy/update'
+    uris: '{{ course_service_prefix }}/v1/hierarchy/update'
     upstream_url: '{{ content_service_url }}/v1/course/hierarchy/update'
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2828,9 +2877,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: '{{ small_request_size_limit }}'
   - name: submitDatasetRequest
-    request_path: "{{ data_service_prefix }}/v1/dataset/request/submit"
+    uris: "{{ data_service_prefix }}/v1/dataset/request/submit"
     upstream_url: "{{ content_service_url }}/v1/dataset/request/submit"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2844,9 +2893,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listDatasetRequest
-    request_path: "{{ data_service_prefix }}/v1/dataset/request/list"
+    uris: "{{ data_service_prefix }}/v1/dataset/request/list"
     upstream_url: "{{ content_service_url }}/v1/dataset/request/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2860,9 +2909,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readDatasetRequest
-    request_path: "{{ data_service_prefix }}/v1/dataset/request/read"
+    uris: "{{ data_service_prefix }}/v1/dataset/request/read"
     upstream_url: "{{ content_service_url }}/v1/dataset/request/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2876,9 +2925,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: channelDatasetRequest
-    request_path: "{{ data_service_prefix }}/v1/dataset/request"
+    uris: "{{ data_service_prefix }}/v1/dataset/request"
     upstream_url: "{{ content_service_url }}/v1/dataset/request"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2892,9 +2941,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createAssertion
-    request_path: "{{ badge_service_prefix }}/v1/issuer/badge/assertion/create"
+    uris: "{{ badge_service_prefix }}/v1/issuer/badge/assertion/create"
     upstream_url: "{{ learning_service_url }}/v1/issuer/badge/assertion/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2908,9 +2957,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getAssertion
-    request_path: "{{ badge_service_prefix }}/v1/issuer/badge/assertion/read"
+    uris: "{{ badge_service_prefix }}/v1/issuer/badge/assertion/read"
     upstream_url: "{{ learning_service_url }}/v1/issuer/badge/assertion/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2924,9 +2973,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getAssertionList
-    request_path: "{{ badge_service_prefix }}/v1/issuer/badge/assertion/search"
+    uris: "{{ badge_service_prefix }}/v1/issuer/badge/assertion/search"
     upstream_url: "{{ learning_service_url }}/v1/issuer/badge/assertion/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2940,9 +2989,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: revokeAssertion
-    request_path: "{{ badge_service_prefix }}/v1/issuer/badge/assertion/delete"
+    uris: "{{ badge_service_prefix }}/v1/issuer/badge/assertion/delete"
     upstream_url: "{{ learning_service_url }}/v1/issuer/badge/assertion/delete"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2956,9 +3005,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: createBadgeClass
-    request_path: "{{ badge_service_prefix }}/v1/issuer/badge/create"
+    uris: "{{ badge_service_prefix }}/v1/issuer/badge/create"
     upstream_url: "{{ learning_service_url }}/v1/issuer/badge/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2972,9 +3021,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getBadgeClass
-    request_path: "{{ badge_service_prefix }}/v1/issuer/badge/read"
+    uris: "{{ badge_service_prefix }}/v1/issuer/badge/read"
     upstream_url: "{{ learning_service_url }}/v1/issuer/badge/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -2988,9 +3037,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: searchBadgeClass
-    request_path: "{{ badge_service_prefix }}/v1/issuer/badge/search"
+    uris: "{{ badge_service_prefix }}/v1/issuer/badge/search"
     upstream_url: "{{ learning_service_url }}/v1/issuer/badge/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3004,9 +3053,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: deleteBadgeClass
-    request_path: "{{ badge_service_prefix }}/v1/issuer/badge/delete"
+    uris: "{{ badge_service_prefix }}/v1/issuer/badge/delete"
     upstream_url: "{{ learning_service_url }}/v1/issuer/badge/delete"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3020,9 +3069,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: createissuer
-    request_path: "{{ badge_service_prefix }}/v1/issuer/create"
+    uris: "{{ badge_service_prefix }}/v1/issuer/create"
     upstream_url: "{{ learning_service_url }}/v1/issuer/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3036,9 +3085,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getIssuerDetails
-    request_path: "{{ badge_service_prefix }}/v1/issuer/read"
+    uris: "{{ badge_service_prefix }}/v1/issuer/read"
     upstream_url: "{{ learning_service_url }}/v1/issuer/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3052,9 +3101,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: getAllIssuer
-    request_path: "{{ badge_service_prefix }}/v1/issuer/list"
+    uris: "{{ badge_service_prefix }}/v1/issuer/list"
     upstream_url: "{{ learning_service_url }}/v1/issuer/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3068,9 +3117,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: deleteIssuer
-    request_path: "{{ badge_service_prefix }}/v1/issuer/delete"
+    uris: "{{ badge_service_prefix }}/v1/issuer/delete"
     upstream_url: "{{ learning_service_url }}/v1/issuer/delete"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3084,9 +3133,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: createForm
-    request_path: "{{ data_service_prefix }}/v1/form/create"
+    uris: "{{ data_service_prefix }}/v1/form/create"
     upstream_url: "{{ player_service_url }}/plugin/v1/form/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3100,9 +3149,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: updateForm
-    request_path: "{{ data_service_prefix }}/v1/form/update"
+    uris: "{{ data_service_prefix }}/v1/form/update"
     upstream_url: "{{ player_service_url }}/plugin/v1/form/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3116,9 +3165,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: announcementtypeCreate
-    request_path: "{{ announcement_service_prefix }}/v1/manage/announcement-type/create"
+    uris: "{{ announcement_service_prefix }}/v1/manage/announcement-type/create"
     upstream_url: "{{ player_service_url }}/announcement/v1/manage/announcement-type/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3132,9 +3181,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: announcementtypeUpdate
-    request_path: "{{ announcement_service_prefix }}/v1/manage/announcement-type/update"
+    uris: "{{ announcement_service_prefix }}/v1/manage/announcement-type/update"
     upstream_url: "{{ player_service_url }}/announcement/v1/manage/announcement-type/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3148,9 +3197,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: announcementtypeList
-    request_path: "{{ announcement_service_prefix }}/v1/manage/announcement-type/list"
+    uris: "{{ announcement_service_prefix }}/v1/manage/announcement-type/list"
     upstream_url: "{{ player_service_url }}/announcement/v1/manage/announcement-type/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3164,9 +3213,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readForm
-    request_path: "{{ data_service_prefix }}/v1/form/read"
+    uris: "{{ data_service_prefix }}/v1/form/read"
     upstream_url: "{{ player_service_url }}/plugin/v1/form/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: cors
     - "{{ statsd_pulgin }}"
@@ -3177,9 +3226,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: masterLocationCreate
-    request_path: "{{ data_service_prefix }}/v1/location/create"
+    uris: "{{ data_service_prefix }}/v1/location/create"
     upstream_url: "{{ learning_service_url }}/v1/location/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3193,9 +3242,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: masterLocationUpdate
-    request_path: "{{ data_service_prefix }}/v1/location/update"
+    uris: "{{ data_service_prefix }}/v1/location/update"
     upstream_url: "{{ learning_service_url }}/v1/location/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3209,9 +3258,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: masterLocationSearch
-    request_path: "{{ data_service_prefix }}/v1/location/search"
+    uris: "{{ data_service_prefix }}/v1/location/search"
     upstream_url: "{{ learning_service_url }}/v1/location/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3225,9 +3274,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: masterLocationUpload
-    request_path: "{{ data_service_prefix }}/v1/bulk/location/upload"
+    uris: "{{ data_service_prefix }}/v1/bulk/location/upload"
     upstream_url: "{{ learning_service_url }}/v1/bulk/location/upload"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3242,9 +3291,9 @@ kong_apis:
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: copyContent
-    request_path: "{{ content_service_prefix }}/v1/copy"
+    uris: "{{ content_service_prefix }}/v1/copy"
     upstream_url: "{{ content_service_url }}/v1/content/copy"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3259,9 +3308,9 @@ kong_apis:
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: fetchURLMetaInformation
-    request_path: "{{ content_service_prefix }}/v1/fetchmeta"
+    uris: "{{ content_service_prefix }}/v1/fetchmeta"
     upstream_url: "{{ content_service_url }}/v1/url/fetchmeta"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3275,9 +3324,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: publishFramework
-    request_path: "{{ framework_service_prefix }}/v1/publish"
+    uris: "{{ framework_service_prefix }}/v1/publish"
     upstream_url: "{{ content_service_url }}/v1/framework/publish"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3291,9 +3340,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: pluginSearch
-    request_path: "{{ plugin_service_prefix }}/v1/search"
+    uris: "{{ plugin_service_prefix }}/v1/search"
     upstream_url: "{{ content_service_url }}/v1/plugins/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3307,9 +3356,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateCollaborators
-    request_path: "{{ content_service_prefix }}/v1/collaborator/update"
+    uris: "{{ content_service_prefix }}/v1/collaborator/update"
     upstream_url: "{{ content_service_url }}/v1/content/collaborator/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3323,9 +3372,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: reserveDialcode
-    request_path: "{{ dialcode_service_prefix }}/v1/reserve"
+    uris: "{{ dialcode_service_prefix }}/v1/reserve"
     upstream_url: "{{ content_service_url }}/v1/dialcode/reserve"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3339,9 +3388,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: releaseDialcode
-    request_path: "{{ dialcode_service_prefix }}/v1/release"
+    uris: "{{ dialcode_service_prefix }}/v1/release"
     upstream_url: "{{ content_service_url }}/v1/dialcode/release"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3355,9 +3404,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createLock
-    request_path: "{{ lock_service_prefix }}/v1/create"
+    uris: "{{ lock_service_prefix }}/v1/create"
     upstream_url: "{{ content_service_url }}/v1/lock/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3371,9 +3420,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: refreshLock
-    request_path: "{{ lock_service_prefix }}/v1/refresh"
+    uris: "{{ lock_service_prefix }}/v1/refresh"
     upstream_url: "{{ content_service_url }}/v1/lock/refresh"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3387,9 +3436,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: retireLock
-    request_path: "{{ lock_service_prefix }}/v1/retire"
+    uris: "{{ lock_service_prefix }}/v1/retire"
     upstream_url: "{{ content_service_url }}/v1/lock/retire"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3403,9 +3452,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listLock
-    request_path: "{{ lock_service_prefix }}/v1/list"
+    uris: "{{ lock_service_prefix }}/v1/list"
     upstream_url: "{{ content_service_url }}/v1/lock/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3419,9 +3468,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createSession
-    request_path: "{{ sso_service_prefix }}/v1/create/session"
+    uris: "{{ sso_service_prefix }}/v1/create/session"
     upstream_url: "{{ player_service_url }}/v1/sso/create/session"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3437,9 +3486,9 @@ kong_apis:
 
   # Data pipeline
   - name: "datasetSubmitRequest"
-    request_path: "{{ data_service_prefix }}/v3/dataset/request/submit"
+    uris: "{{ data_service_prefix }}/v3/dataset/request/submit"
     upstream_url: "{{ sunbird_analytics_api_base_url }}/dataset/request/submit"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3448,9 +3497,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "datasetReadRequest"
-    request_path: "{{ data_service_prefix }}/v3/dataset/request/read"
+    uris: "{{ data_service_prefix }}/v3/dataset/request/read"
     upstream_url: "{{ sunbird_analytics_api_base_url }}/dataset/request/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3459,9 +3508,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "datasetListRequest"
-    request_path: "{{ data_service_prefix }}/v3/dataset/request/list"
+    uris: "{{ data_service_prefix }}/v3/dataset/request/list"
     upstream_url: "{{ sunbird_analytics_api_base_url }}/dataset/request/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3470,18 +3519,18 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "deviceRegister"
-    request_path: "/v3/device/register"
+    uris: "/v3/device/register"
     upstream_url: "{{ sunbird_analytics_api_base_url }}/v1/device/register"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'cors'}
      - "{{ statsd_pulgin }}"
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "channelSpecificTelemetryExhaust"
-    request_path: "{{ data_service_prefix }}/v3/dataset/get"
+    uris: "{{ data_service_prefix }}/v3/dataset/get"
     upstream_url: "{{ sunbird_analytics_api_base_url }}/dataset/get"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3491,9 +3540,9 @@ kong_apis:
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
 
   - name: "dataproductsCumulativeMetrics"
-    request_path: "{{ data_service_prefix }}/v3/metrics"
+    uris: "{{ data_service_prefix }}/v3/metrics"
     upstream_url: "{{ sunbird_analytics_api_base_url }}/metrics"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3503,9 +3552,9 @@ kong_apis:
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
 
   - name: "configRefresh"
-    request_path: "{{ config_service_prefix }}/v1/refresh"
+    uris: "{{ config_service_prefix }}/v1/refresh"
     upstream_url: "{{ config_service_url }}/config-service/v1/refresh"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3515,9 +3564,9 @@ kong_apis:
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
 
   - name: "getConfigByKey"
-    request_path: "{{ config_service_prefix }}/v1/read"
+    uris: "{{ config_service_prefix }}/v1/read"
     upstream_url: "{{ config_service_url }}/config-service/v1/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3526,9 +3575,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ large_rate_limit_per_hour }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "addSystemSettings"
-    request_path: "{{ data_service_prefix }}/v1/system/settings/set"
+    uris: "{{ data_service_prefix }}/v1/system/settings/set"
     upstream_url: "{{ learning_service_url }}/v1/system/settings/set"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3537,9 +3586,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{  medium_rate_limit_per_hour }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "getSystemSettings"
-    request_path: "{{ data_service_prefix }}/v1/system/settings/get"
+    uris: "{{ data_service_prefix }}/v1/system/settings/get"
     upstream_url: "{{ learning_service_url }}/v1/system/settings/get"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3548,9 +3597,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{  medium_rate_limit_per_hour }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "getConfigStatus"
-    request_path: "{{ config_service_prefix }}/v1/status"
+    uris: "{{ config_service_prefix }}/v1/status"
     upstream_url: "{{ config_service_url }}/config-service/v1/status"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3559,9 +3608,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ small_rate_limit_per_hour }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "getConfigHealth"
-    request_path: "{{ config_service_prefix }}/v1/health"
+    uris: "{{ config_service_prefix }}/v1/health"
     upstream_url: "{{ config_service_url }}/config-service/v1/health"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3570,9 +3619,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ small_rate_limit_per_hour }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: onboardConsumer
-    request_path: "{{ api_manager_perfix }}/v1/consumer/create/jwt"
+    uris: "{{ api_manager_perfix }}/v1/consumer/create/jwt"
     upstream_url: "{{ am_util_url }}/v1/consumer/create/jwt"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3586,9 +3635,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: KongConsumerApi
-    request_path: "{{ api_manager_perfix }}/v1/consumer"
+    uris: "{{ api_manager_perfix }}/v1/consumer"
     upstream_url: "{{ am_util_url }}/v1/consumer"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3602,9 +3651,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: uploadTOC
-    request_path: "{{ textbook_service_prefix }}/v1/toc/upload"
-    upstream_url: "{{ learning_service_url }}/v1/textbook/toc/upload"
-    strip_request_path: true
+    uris: "{{ textbook_service_prefix }}/v1/toc/upload"
+    upstream_url: "{{ lms_service_url }}/v1/textbook/toc/upload"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3618,9 +3667,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: downloadTOC
-    request_path: "{{ textbook_service_prefix }}/v1/toc/download"
-    upstream_url: "{{ learning_service_url }}/v1/textbook/toc/download"
-    strip_request_path: true
+    uris: "{{ textbook_service_prefix }}/v1/toc/download"
+    upstream_url: "{{ lms_service_url }}/v1/textbook/toc/download"
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3634,9 +3683,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: acceptTermsAndCondition
-    request_path: "{{ user_service_prefix }}/v1/tnc/accept"
+    uris: "{{ user_service_prefix }}/v1/tnc/accept"
     upstream_url: "{{ learning_service_url }}/v1/user/tnc/accept"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3650,9 +3699,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: generateOtp
-    request_path: "{{ otp_service_prefix }}/v1/generate"
+    uris: "{{ otp_service_prefix }}/v1/generate"
     upstream_url: "{{ learning_service_url }}/v1/otp/generate"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3666,9 +3715,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: verifyOtp
-    request_path: "{{ otp_service_prefix }}/v1/verify"
+    uris: "{{ otp_service_prefix }}/v1/verify"
     upstream_url: "{{ learning_service_url }}/v1/otp/verify"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3682,9 +3731,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getUserByKey
-    request_path: "{{ user_service_prefix  }}/v1/get"
+    uris: "{{ user_service_prefix  }}/v1/get"
     upstream_url: "{{ learning_service_url }}/v1/user/get"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3699,9 +3748,9 @@ kong_apis:
       config.allowed_payload_size: "{{ small_request_size_limit }}"
 
   - name: registerMobileAppTeacherAid
-    request_path: "{{ api_manager_perfix }}/v1/consumer/mobile_app_teacheraid/credential/register"
+    uris: "{{ api_manager_perfix }}/v1/consumer/mobile_app_teacheraid/credential/register"
     upstream_url: "{{ am_util_url }}/v1/consumer/mobile_app_teacheraid/credential/register"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3716,9 +3765,9 @@ kong_apis:
       config.allowed_payload_size: "{{ small_request_size_limit }}"
 
   - name: registerMobileDeviceTeacherAid
-    request_path: "{{ api_manager_perfix }}/v1/consumer/mobile_device_teacheraid/credential/register"
+    uris: "{{ api_manager_perfix }}/v1/consumer/mobile_device_teacheraid/credential/register"
     upstream_url: "{{ am_util_url }}/v1/consumer/mobile_device_teacheraid/credential/register"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3732,9 +3781,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: "contentBadgeLink"
-    request_path: "{{ badge_service_prefix }}/v1/content/link"
-    upstream_url: "{{ learning_service_url }}/v1/content/link"
-    strip_request_path: true
+    uris: "{{ badge_service_prefix }}/v1/content/link"
+    upstream_url: "{{ lms_service_url }}/v1/content/link"
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3743,9 +3792,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" } 
   - name: "contentBadgeUnLink"
-    request_path: "{{ badge_service_prefix }}/v1/content/unlink"
-    upstream_url: "{{ learning_service_url }}/v1/content/unlink"
-    strip_request_path: true
+    uris: "{{ badge_service_prefix }}/v1/content/unlink"
+    upstream_url: "{{ lms_service_url }}/v1/content/unlink"
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3754,9 +3803,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" } 
   - name: "privateUserUpdate"
-    request_path: "{{ user_service_prefix }}/private/v1/update"
+    uris: "{{ user_service_prefix }}/private/v1/update"
     upstream_url: "{{ learning_service_url }}/private/user/v1/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3765,9 +3814,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }   
   - name: "getUserType"
-    request_path: "{{ user_service_prefix }}/v1/type/list"
+    uris: "{{ user_service_prefix }}/v1/type/list"
     upstream_url: "{{ learning_service_url }}/v1/user/type/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3776,9 +3825,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "masterLocationDelete"
-    request_path: "{{data_service_prefix }}/v1/location/delete"
+    uris: "{{data_service_prefix }}/v1/location/delete"
     upstream_url: "{{ learning_service_url }}/v1/location/delete"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3787,9 +3836,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "migrateUser"
-    request_path: "{{ user_service_prefix }}/v1/migrate"
+    uris: "{{ user_service_prefix }}/v1/migrate"
     upstream_url: "{{ learning_service_url }}/private/user/v1/migrate"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3798,9 +3847,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "privateUserRead"
-    request_path: "{{ user_service_prefix }}/private/v1/read"
+    uris: "{{ user_service_prefix }}/private/v1/read"
     upstream_url: "{{ learning_service_url }}/private/user/v1/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3809,9 +3858,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: "privateUserAssignRole"
-    request_path: "{{ user_service_prefix }}/private/v1/assign/role"
+    uris: "{{ user_service_prefix }}/private/v1/assign/role"
     upstream_url: "{{ learning_service_url }}/private/user/v1/assign/role"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3820,9 +3869,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: createUserV3
-    request_path: "{{ user_service_prefix }}/v1.3/create"
+    uris: "{{ user_service_prefix }}/v1.3/create"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3836,9 +3885,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: createUserVersion2V3
-    request_path: "{{ user_service_prefix }}/v2.3/create"
+    uris: "{{ user_service_prefix }}/v2.3/create"
     upstream_url: "{{ user_org_service_url }}/v2.3/user/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3852,9 +3901,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getUserProfileV3
-    request_path: "{{ user_service_prefix }}/v1.3/read"
+    uris: "{{ user_service_prefix }}/v1.3/read"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3868,9 +3917,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getUserProfileV2V3
-    request_path: "{{ user_service_prefix }}/v2.3/read"
+    uris: "{{ user_service_prefix }}/v2.3/read"
     upstream_url: "{{ user_org_service_url }}/v2.3/user/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3884,9 +3933,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readUserProfileV3
-    request_path: "{{ user_service_prefix }}/v1.3/profile/read"
+    uris: "{{ user_service_prefix }}/v1.3/profile/read"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/getuser"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3900,9 +3949,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getUserByKeyV3
-    request_path: "{{ user_service_prefix  }}/v1.3/get"
+    uris: "{{ user_service_prefix  }}/v1.3/get"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/get"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3916,9 +3965,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchUserV3
-    request_path: "{{ user_service_prefix }}/v1.3/search"
+    uris: "{{ user_service_prefix }}/v1.3/search"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3932,9 +3981,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: getMediaTypesV3
-    request_path: "{{ user_service_prefix }}/v1.3/mediatype/list"
+    uris: "{{ user_service_prefix }}/v1.3/mediatype/list"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/mediatype/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3948,9 +3997,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: profileVisibilityV3
-    request_path: "{{ user_service_prefix }}/v1.3/profile/visibility"
+    uris: "{{ user_service_prefix }}/v1.3/profile/visibility"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/profile/visibility"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3964,9 +4013,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: "getUserTypeV3"
-    request_path: "{{ user_service_prefix }}/v1.3/type/list"
+    uris: "{{ user_service_prefix }}/v1.3/type/list"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/type/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -3975,9 +4024,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: blockUserV3
-    request_path: "{{ user_service_prefix }}/v1.3/block"
+    uris: "{{ user_service_prefix }}/v1.3/block"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/block"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -3991,9 +4040,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: unblockUserV3
-    request_path: "{{ user_service_prefix }}/v1.3/unblock"
+    uris: "{{ user_service_prefix }}/v1.3/unblock"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/unblock"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4007,9 +4056,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readRoleMappingV3
-    request_path: "{{ data_service_prefix }}/v1.3/role/read"
+    uris: "{{ data_service_prefix }}/v1.3/role/read"
     upstream_url: "{{ user_org_service_url }}/v1.3/role/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4023,9 +4072,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: assignRoleV3
-    request_path: "{{ user_service_prefix }}/v1.3/role/assign"
+    uris: "{{ user_service_prefix }}/v1.3/role/assign"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/assign/role"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4039,9 +4088,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: "privateUserAssignRoleV3"
-    request_path: "{{ user_service_prefix }}/private/v1.3/assign/role"
+    uris: "{{ user_service_prefix }}/private/v1.3/assign/role"
     upstream_url: "{{ user_org_service_url }}/private/user/v1.3/assign/role"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -4050,9 +4099,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }
   - name: updateUserV3
-    request_path: "{{ user_service_prefix }}/v1.3/update"
+    uris: "{{ user_service_prefix }}/v1.3/update"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4066,9 +4115,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: "privateUserUpdateV3"
-    request_path: "{{ user_service_prefix }}/private/v1.3/update"
+    uris: "{{ user_service_prefix }}/private/v1.3/update"
     upstream_url: "{{ user_org_service_url }}/private/user/v1.3/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
      - {name: 'jwt'}
      - {name: 'cors'}
@@ -4077,9 +4126,9 @@ kong_apis:
      - {name: 'rate-limiting', config.policy: "local", config.hour: "{{ medium_rate_limit_per_hour  }}"}
      - {name: 'request-size-limiting', config.allowed_payload_size: "{{ small_request_size_limit }}" }   
   - name: updateUserloginTimeV3
-    request_path: "{{ user_service_prefix }}/v1.3/update/logintime"
+    uris: "{{ user_service_prefix }}/v1.3/update/logintime"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/update/logintime"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4093,9 +4142,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: acceptTermsAndConditionV3
-    request_path: "{{ user_service_prefix }}/v1.3/tnc/accept"
+    uris: "{{ user_service_prefix }}/v1.3/tnc/accept"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/tnc/accept"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4109,9 +4158,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: DecryptDataV3
-    request_path: "{{ data_service_prefix }}/v1.3/user/decrypt"
+    uris: "{{ data_service_prefix }}/v1.3/user/decrypt"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/data/decrypt"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4125,9 +4174,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: encryptDataV3
-    request_path: "{{ data_service_prefix }}/v1.3/user/encrypt"
+    uris: "{{ data_service_prefix }}/v1.3/user/encrypt"
     upstream_url: "{{ user_org_service_url }}/v1.3/user/data/encrypt"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4141,9 +4190,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: createOrgV3
-    request_path: "{{ org_service_prefix }}/v1.3/create"
+    uris: "{{ org_service_prefix }}/v1.3/create"
     upstream_url: "{{ user_org_service_url }}/v1.3/org/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4157,9 +4206,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateOrgV3
-    request_path: "{{ org_service_prefix }}/v1.3/update"
+    uris: "{{ org_service_prefix }}/v1.3/update"
     upstream_url: "{{ user_org_service_url }}/v1.3/org/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4173,9 +4222,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: readOrgV3
-    request_path: "{{ org_service_prefix }}/v1.3/read"
+    uris: "{{ org_service_prefix }}/v1.3/read"
     upstream_url: "{{ user_org_service_url }}/v1.3/org/read"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4189,9 +4238,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: searchOrgV3
-    request_path: "{{ org_service_prefix }}/v1.3/search"
+    uris: "{{ org_service_prefix }}/v1.3/search"
     upstream_url: "{{ user_org_service_url }}/v1.3/org/search"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: cors
     - "{{ statsd_pulgin }}"
@@ -4202,9 +4251,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: addMemberV3
-    request_path: "{{ org_service_prefix }}/v1.3/member/add"
+    uris: "{{ org_service_prefix }}/v1.3/member/add"
     upstream_url: "{{ user_org_service_url }}/v1.3/org/member/add"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4218,9 +4267,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: removeMemberV3
-    request_path: "{{ org_service_prefix }}/v1.3/member/remove"
+    uris: "{{ org_service_prefix }}/v1.3/member/remove"
     upstream_url: "{{ user_org_service_url }}/v1.3/org/member/remove"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4234,9 +4283,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: updateOrgStatusV3
-    request_path: "{{ org_service_prefix }}/v1.3/status/update"
+    uris: "{{ org_service_prefix }}/v1.3/status/update"
     upstream_url: "{{ user_org_service_url }}/v1.3/org/status/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4250,9 +4299,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ small_request_size_limit }}"
   - name: listOrgTypesV3
-    request_path: "{{ org_service_prefix }}/v1.3/type/list"
+    uris: "{{ org_service_prefix }}/v1.3/type/list"
     upstream_url: "{{ user_org_service_url }}/v1.3/org/type/list"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4266,9 +4315,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: createOrgTypeV3
-    request_path: "{{ org_service_prefix }}/v1.3/type/create"
+    uris: "{{ org_service_prefix }}/v1.3/type/create"
     upstream_url: "{{ user_org_service_url }}/v1.3/org/type/create"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4282,9 +4331,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: updateOrgTypeV3
-    request_path: "{{ org_service_prefix }}/v1.3/type/update"
+    uris: "{{ org_service_prefix }}/v1.3/type/update"
     upstream_url: "{{ user_org_service_url }}/v1.3/org/type/update"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - name: jwt
     - name: cors
@@ -4298,9 +4347,9 @@ kong_apis:
     - name: request-size-limiting
       config.allowed_payload_size: "{{ medium_request_size_limit }}"
   - name: "telemetryErrorLogging"
-    request_path: "/data/v1/client/logs"
+    uris: "/data/v1/client/logs"
     upstream_url: "{{ sunbird_analytics_api_base_url }}/data/v1/client/logs"
-    strip_request_path: true
+    strip_uri: true
     plugins:
     - {name: 'cors'}
     - "{{ statsd_pulgin }}"
diff --git a/ansible/roles/kong-consumer/defaults/main.yml b/ansible/roles/kong-consumer/defaults/main.yml
index f98eec6c82b29427e5e5dd9e07d7934363ae2506..2f2d88b41fd17d9bc065028847ee3554728e4a46 100644
--- a/ansible/roles/kong-consumer/defaults/main.yml
+++ b/ansible/roles/kong-consumer/defaults/main.yml
@@ -18,6 +18,7 @@ mobile_device_groups:
   - domainUser
   - dataUpdate
   - dialcodeUser
+  - echoUser
 
 integration_partner_groups:
   - echoUser
diff --git a/ansible/roles/postgresql-data-update/defaults/main.yml b/ansible/roles/postgresql-data-update/defaults/main.yml
index 89a61af55a2306dc9294c40cf3835ab0151da7b2..9a65ac5302933af96d37380712a49341c03a1fb7 100755
--- a/ansible/roles/postgresql-data-update/defaults/main.yml
+++ b/ansible/roles/postgresql-data-update/defaults/main.yml
@@ -4,8 +4,89 @@ postgresql_group: postgres
 postgresql_unix_socket_directories:
   - /var/run/postgresql
 
+############# Postgres users and databases ###############
+postgresql_users:
+  - name: "{{kong_postgres_user}}"
+    login_host: "{{kong_postgres_host}}"
+    login_password: "{{kong_postgres_password}}"
+    password: "{{postgres_password}}"
+    db: "{{kong_postgres_database}}"
+    login_user: "{{kong_postgres_user}}"
+    priv: "ALL"
+  - name: "{{keycloak_postgres_user}}"
+    login_host: "{{keycloak_postgres_host}}"
+    login_password: "{{keycloak_postgres_password}}"
+    password: "{{postgres_password}}"
+    db: "{{keycloak_postgres_database}}"
+    login_user: "{{keycloak_postgres_user}}"
+    priv: "ALL"
+  - name: "{{application_postgres_user}}"
+    login_host: "{{application_postgres_host}}"
+    login_password: "{{application_postgres_password}}"
+    password: "{{postgres_password}}"
+    db: "{{application_postgres_database}}"
+    login_user: "{{application_postgres_user}}"
+    priv: "ALL"
+  - name: "{{badger_postgres_user}}"
+    login_host: "{{badger_postgres_host}}"
+    login_password: "{{badger_postgres_password}}"
+    password: "{{postgres_password}}"
+    login_user: "{{badger_postgres_user}}"
+    db: "{{badger_postgres_database}}"
+    priv: "ALL"
+  - name: "{{user_org_service_postgres_user}}"
+    login_host: "{{user_org_service_postgres_host}}"
+    login_password: "{{user_org_service_postgres_password}}"
+    password: "{{user_org_service_postgres_password}}"
+    db: "{{user_org_service_postgres_database}}"
+    login_user: "{{user_org_service_postgres_user}}"
+    priv: "ALL"
+  - name: "{{enc_postgres_user}}"
+    login_host: "{{enc_postgres_host}}"
+    login_password: "{{enc_postgres_password}}"
+    password: "{{enc_postgres_password}}"
+    db: "{{enc_postgres_database}}"
+    login_user: "{{enc_postgres_user}}"
+    priv: "ALL"
+
+
+postgresql_databases:
+  - name: "{{kong_postgres_database}}"
+    login_host: "{{kong_postgres_host}}"
+    login_password: "{{kong_postgres_password}}"
+    owner: "{{kong_postgres_user}}"
+    login_user: "{{kong_postgres_user}}"
+  - name: "{{keycloak_postgres_database}}"
+    login_host: "{{keycloak_postgres_host}}"
+    login_password: "{{keycloak_postgres_password}}"
+    owner: "{{keycloak_postgres_user}}"
+    login_user: "{{keycloak_postgres_user}}"
+  - name: "{{application_postgres_database}}"
+    login_host: "{{application_postgres_host}}"
+    login_password: "{{application_postgres_password}}"
+    owner: "{{application_postgres_user}}"
+    login_user: "{{application_postgres_user}}"
+  - name: "{{badger_postgres_database}}"
+    login_host: "{{badger_postgres_host}}"
+    login_password: "{{badger_postgres_password}}"
+    owner: "{{badger_postgres_user}}"
+    login_user: "{{badger_postgres_user}}"
+  - name: "{{user_org_service_postgres_database}}"
+    login_host: "{{user_org_service_postgres_host}}"
+    login_password: "{{user_org_service_postgres_password}}"
+    owner: "{{user_org_service_postgres_user}}"
+    login_user: "{{user_org_service_postgres_user}}"
+  - name: "{{enc_postgres_database}}"
+    login_host: "{{enc_postgres_host}}"
+    login_password: "{{enc_postgres_password}}"
+    owner: "{{enc_postgres_user}}"
+    login_user: "{{enc_postgres_user}}"
+
+##########################################################
+
+
 # Databases to ensure exist.
-postgresql_databases: []
+#postgresql_databases: []
   # - name: exampledb # required; the rest are optional
   #   lc_collate: # defaults to 'en_US.UTF-8'
   #   lc_ctype: # defaults to 'en_US.UTF-8'
@@ -19,7 +100,7 @@ postgresql_databases: []
   #   state: # defaults to 'present'
 
 # Users to ensure exist.
-postgresql_users: []
+#postgresql_users: []
   # - name: jdoe #required; the rest are optional
   #   password: # defaults to not set
   #   priv: # defaults to not set
diff --git a/ansible/roles/postgresql-data-update/tasks/databases.yml b/ansible/roles/postgresql-data-update/tasks/databases.yml
index fa782ea9f602de806abac6e6672b8f90356708b2..dc96ae4cc9766ebaef55cef0c0fe3e991436daf1 100644
--- a/ansible/roles/postgresql-data-update/tasks/databases.yml
+++ b/ansible/roles/postgresql-data-update/tasks/databases.yml
@@ -2,20 +2,13 @@
 - name: Ensure PostgreSQL databases are present.
   postgresql_db:
     name: "{{ item.name }}"
-    lc_collate: "{{ item.lc_collate | default('en_US.UTF-8') }}"
-    lc_ctype: "{{ item.lc_ctype | default('en_US.UTF-8') }}"
-    encoding: "{{ item.encoding | default('UTF-8') }}"
-    template: "{{ item.template | default('template0') }}"
     login_host: "{{ item.login_host | default('localhost') }}"
     login_password: "{{ item.login_password | default(omit) }}"
     login_user: "{{ item.login_user | default(postgresql_user) }}"
     login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}"
     port: "{{ item.port | default(omit) }}"
-    owner: "{{ item.owner | default(postgresql_user) }}"
+    owner: '{{ item.owner.split("@")[0] | default(postgresql_user) }}'
     state: "{{ item.state | default('present') }}"
   with_items: "{{ postgresql_databases }}"
-  become: yes
-  become_user: "{{ postgresql_user }}"
-  # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509
   vars:
     ansible_ssh_pipelining: true
diff --git a/ansible/roles/postgresql-data-update/tasks/main.yml b/ansible/roles/postgresql-data-update/tasks/main.yml
index 615f9188cfdaf7ab74f6930561aa9976ac283c05..250de30d7d2a50ab150106d29cbf23dfa7eab7df 100644
--- a/ansible/roles/postgresql-data-update/tasks/main.yml
+++ b/ansible/roles/postgresql-data-update/tasks/main.yml
@@ -1,3 +1,8 @@
+- name: install psycopg2
+  package:
+    name: python-psycopg2
+    state: present
+
 - name: Verifying db users are present else creating them
   include: databases.yml
 
@@ -9,9 +14,28 @@
   template: src={{item}} dest=/tmp/{{item}}
   with_items:
     - tables_postgres.sql
+    - enc_postgres.sql
 
-- name: Run the postgresql command
-  become: yes
-  environment:
-    PGPASSWORD: "{{ application_postgres_password }}"
-  command: "psql -h 127.0.0.1 -U {{application_postgres_user}} -d {{application_postgres_database}} -a -f /tmp/tables_postgres.sql"
+- name: Install postgres client to create schema from file
+  apt:
+    name: postgresql-client
+    state: present
+    update_cache: yes
+
+- name: Dump api manager database to a file
+  postgresql_db:
+    login_user: "{{ application_postgres_user }}"
+    login_password: "{{ application_postgres_password }}"
+    login_host: "{{ application_postgres_host }}"
+    name: "{{ application_postgres_database }}"
+    state: restore
+    target: "/tmp/tables_postgres.sql"
+
+- name: Create the schema for encryption service
+  postgresql_db:
+    login_user: "{{ enc_postgres_user }}"
+    login_password: "{{ enc_postgres_password }}"
+    login_host: "{{ enc_postgres_host }}"
+    name: "{{ enc_postgres_database }}"
+    state: restore
+    target: "/tmp/enc_postgres.sql"
diff --git a/ansible/roles/postgresql-data-update/tasks/users.yml b/ansible/roles/postgresql-data-update/tasks/users.yml
index 33e5ebdbba049e54d20d48c12695b279608d01a3..fdbb3b43dcc32ab4ebfbc9ae2e77ac0290441971 100755
--- a/ansible/roles/postgresql-data-update/tasks/users.yml
+++ b/ansible/roles/postgresql-data-update/tasks/users.yml
@@ -9,13 +9,9 @@
     login_host: "{{ item.login_host | default('localhost') }}"
     login_password: "{{ item.login_password | default(omit) }}"
     login_user: "{{ item.login_user | default(postgresql_user) }}"
-    login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}"
-    port: "{{ item.port | default(omit) }}"
+    encrypted: "{{ item.encrypted | default('yes')}}"
     state: "{{ item.state | default('present') }}"
   with_items: "{{ postgresql_users }}"
-  no_log: true
-  become: yes
-  become_user: "{{ postgresql_user }}"
-  # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509
   vars:
     ansible_ssh_pipelining: true
+
diff --git a/ansible/roles/postgresql-data-update/templates/enc_postgres.sql b/ansible/roles/postgresql-data-update/templates/enc_postgres.sql
new file mode 100644
index 0000000000000000000000000000000000000000..1d9c68310dce42815b59e52b88704a07dda24c67
--- /dev/null
+++ b/ansible/roles/postgresql-data-update/templates/enc_postgres.sql
@@ -0,0 +1,13 @@
+
+CREATE TYPE "enum_Keys_type" AS ENUM ('MASTER','OTHER');
+
+CREATE TABLE "Keys" (
+  id SERIAL PRIMARY KEY,
+  public text NOT NULL,
+  private text NOT NULL,
+  type "enum_Keys_type" NOT NULL,
+  active boolean DEFAULT true NOT NULL,
+  "createdAt" timestamp with time zone NOT NULL,
+  "updatedAt" timestamp with time zone NOT NULL
+);
+commit;
diff --git a/ansible/roles/postgresql-data-update/templates/tables_postgres.sql b/ansible/roles/postgresql-data-update/templates/tables_postgres.sql
index 9c5beaa1cdfdd4f60b755be7735f5f709572789a..e2da042a1abd9abd74ea7f8f4bbf1102dd3ae1dd 100644
--- a/ansible/roles/postgresql-data-update/templates/tables_postgres.sql
+++ b/ansible/roles/postgresql-data-update/templates/tables_postgres.sql
@@ -178,5 +178,4 @@ create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
 create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
 create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);
 
-
 commit;
diff --git a/ansible/roles/prometheus-backup-v2/tasks/main.yml b/ansible/roles/prometheus-backup-v2/tasks/main.yml
index 20206806ee6eccc4b4ee0cc23033f9ad3ac184b9..af34edddad3ccd8d7163fcf7d467fa36d443308a 100644
--- a/ansible/roles/prometheus-backup-v2/tasks/main.yml
+++ b/ansible/roles/prometheus-backup-v2/tasks/main.yml
@@ -1,12 +1,6 @@
 ---
 # tasks file for ansible/roles/prometheus-backup-v2
 # Issue: https://github.com/prometheus/prometheus/issues/5686
-- name: preparing snapshot
-  uri:
-    url: "{{ prometheus_url }}/api/v1/admin/tsdb/snapshot"
-    method: POST
-  register: temp_snap
-
 - name: taking snapshot
   uri:
     url: "{{ prometheus_url }}/api/v1/admin/tsdb/snapshot?skip_head=True"
@@ -32,11 +26,8 @@
 
 - name: Deleting snapshot
   file:
-    path: "{{ prometheus_data_dir }}/snapshots/{{ item }}"
+    path: "{{ prometheus_data_dir }}/snapshots/{{ snapshot_name }}"
     state: absent
-  with_items:
-    - "{{ snapshot_name }}"
-    - "{{ temp_snap.json.data.name }}"
 
 - name: Deleting archive snapshot
   file:
diff --git a/ansible/roles/prometheus-fed/defaults/main.yml b/ansible/roles/prometheus-fed/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..870313d517c4d022fba820671a8931c4582dd99b
--- /dev/null
+++ b/ansible/roles/prometheus-fed/defaults/main.yml
@@ -0,0 +1,19 @@
+prometheus_reservation_memory: 1G
+prometheus_limit_memory: 1G
+prometheus_storage_retention_time: 90d
+
+enable_scraping_docker_metrics: false
+docker_metrics_port: "2377"
+monitor_stack_files_dest_dir: /opt/docker/stacks/prom_fed/stacks
+monitor_config_files_dest_dir: /opt/docker/stacks/prom_fed/config
+
+monitor_config_templates:
+  - prometheus.yml
+
+prometheus_route_prefix: prometheus
+prometheus_web_external_url: "{{proto}}://{{api__host}}:29090/{{ prometheus_route_prefix }}"
+
+root_group: root
+root_owner: root
+backup_storage_name: prometheus_backup
+prometheus_storage_location: /root/dockerdata/prometheus_fed/data/
diff --git a/ansible/roles/prometheus-fed/tasks/main.yml b/ansible/roles/prometheus-fed/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9962dafc0aa93681aeb5686bb64eb3c12fdf6a60
--- /dev/null
+++ b/ansible/roles/prometheus-fed/tasks/main.yml
@@ -0,0 +1,54 @@
+---
+- name: Create prometheus data dir
+  file:
+    path: "{{ prometheus_storage_location }}"
+    state: directory
+    mode: 0755
+    owner: 'nobody'
+    group: 'nogroup'
+
+- name: Ensure stack directory exists
+  file:
+    path: "{{ monitor_stack_files_dest_dir }}"
+    state: directory
+    owner: '{{ root_owner }}'
+    group: '{{ root_group }}'
+
+- name: Ensure config directory exists
+  file:
+    path: "{{ monitor_config_files_dest_dir }}"
+    state: directory
+    owner: '{{ root_owner }}'
+    group: '{{ root_group }}'
+
+- name: Save stack file
+  template:
+    src: stack-monitor.yml
+    dest: "{{ monitor_stack_files_dest_dir }}/monitor.yml"
+    mode: 0644
+
+- name: Save prometheus config fed_{{ item }}
+  template:
+    src="{{ item }}"
+    dest="{{ monitor_config_files_dest_dir }}/{{ item }}" 
+    mode=0644
+  with_items: 
+    - "{{ monitor_config_templates }}"
+
+- name: Remove monitor stack
+  shell: "docker stack rm prometheus_fed"
+  ignore_errors: yes
+
+- name: Remove old docker config fed_{{ item }}
+  shell: "docker config rm fed_{{ item }}"
+  with_items: "{{ monitor_config_templates }}"
+  ignore_errors: yes
+
+- name: Save docker config fed_{{ item }}
+  shell: "docker config create fed_{{ item }} {{ monitor_config_files_dest_dir }}/{{ item }}"
+  with_items: "{{ monitor_config_templates }}"
+
+- name: Deploy stack
+  shell: "docker stack deploy -c monitor.yml prometheus_fed"
+  args:
+    chdir: "{{ monitor_stack_files_dest_dir }}"
diff --git a/ansible/roles/prometheus-fed/templates/prometheus.yml b/ansible/roles/prometheus-fed/templates/prometheus.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6857f3f4c1cb9877dbb7b2bf3ae0ba1fd790b3a1
--- /dev/null
+++ b/ansible/roles/prometheus-fed/templates/prometheus.yml
@@ -0,0 +1,45 @@
+global:
+  scrape_interval: 1m
+  scrape_timeout: 10s
+  evaluation_interval: 1m
+  # Clustername is defined for multi swarm cluster
+  # can name first cluster as DS1 and 2nd as DS2 ... DSn
+  # all metrics will have label as cluster: < value >
+  # This value won't be accessible from GUI but for external tools like
+  # federation or alertmanager
+  external_labels:
+    federation: fed1
+
+
+scrape_configs:
+
+  {% if enable_scraping_docker_metrics %}
+  # This empty line ensures indentation is correct after ansible jinja2 template is materialized
+  - job_name: 'docker'
+    static_configs:
+      - targets: {{ groups['swarm-manager'] | map('regex_replace', '^(.*)$', '\\1:' + docker_metrics_port ) | list | to_yaml }}
+    metric_relabel_configs:
+      - source_labels: [__name__]
+        regex: 'grpc_.*'
+        action: drop
+  {% endif %}
+
+
+  - job_name: 'federate'
+    metrics_path: /prometheus/federate
+    honor_labels: true
+    params:
+      match[]:
+        - '{__name__=~"nginx_.*"}'
+        - '{__name__=~"kong_.*"}'
+        - '{__name__=~"node_.*"}'
+    static_configs:
+      {# groups[alertmanager] and prometheus are same machines #}
+      {# and alertmanagers will be unique per swarm #}
+      # This empty line make sure the indentation is correct
+      - targets: [ '{{groups['alertmanager']|join(':9090\', \'')}}:9090', '{{groups['alertmanager_stateful']|join(':19090\', \'')}}:19090' ]
+
+  - job_name: 'vm-node-exporter'
+    static_configs:
+      - targets: ["{{ansible_host}}:9100"]
+
diff --git a/ansible/roles/prometheus-fed/templates/stack-monitor.yml b/ansible/roles/prometheus-fed/templates/stack-monitor.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f9795b5ee2f925fe378441dcc94bfa1295ffcdbb
--- /dev/null
+++ b/ansible/roles/prometheus-fed/templates/stack-monitor.yml
@@ -0,0 +1,31 @@
+version: "3.3"
+
+services:
+    prometheus:
+        image: quay.io/prometheus/prometheus:v2.8.1
+        ports:
+            - "29090:9090"
+        networks:
+            - application_default
+        volumes:
+            - {{prometheus_storage_location}}:/prometheus
+        command: "--config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --web.console.libraries=/etc/prometheus/console_libraries  --storage.tsdb.retention.time={{prometheus_storage_retention_time}} --web.console.templates=/etc/prometheus/consoles --web.route-prefix={{prometheus_route_prefix}} --web.external-url={{prometheus_web_external_url}} --web.enable-admin-api"
+        configs:
+            - source: fed_prometheus.yml
+              target: /etc/prometheus/prometheus.yml
+        deploy:
+            replicas: 1
+            resources:
+              reservations:
+                memory: "{{ prometheus_reservation_memory }}"
+              limits:
+                memory: "{{ prometheus_limit_memory }}"
+
+configs:
+  fed_prometheus.yml:
+    external: true
+
+networks:
+    application_default:
+        external: true
+
diff --git a/ansible/roles/reset-docker/tasks/main.yml b/ansible/roles/reset-docker/tasks/main.yml
index 636997729b1fc3e459daeb5c1a137d6f1fdba42c..bdc4ebc59f6fce5f748cafee2ce2a9972311044f 100644
--- a/ansible/roles/reset-docker/tasks/main.yml
+++ b/ansible/roles/reset-docker/tasks/main.yml
@@ -10,8 +10,8 @@
   shell: "docker stack rm player"
   ignore_errors: yes
 
-- name: Remove learner service
-  shell: "docker stack rm player"
+- name: Remove lms service
+  shell: "docker stack rm lms-service"
   ignore_errors: yes
  
 - name: Copy the restart command script
diff --git a/ansible/roles/stack-monitor-stateful/defaults/main.yml b/ansible/roles/stack-monitor-stateful/defaults/main.yml
index edcae49b98bdb0c7b65e4501970f3a573b64f27b..09f83cce2b129a7396300ef60e6fd8509f930436 100644
--- a/ansible/roles/stack-monitor-stateful/defaults/main.yml
+++ b/ansible/roles/stack-monitor-stateful/defaults/main.yml
@@ -107,6 +107,7 @@ service_teams:
     services:
       - actor-service
       - learner-service
+      - lms-service
       - content-service
       - player_player
       - cassandra
diff --git a/ansible/roles/stack-monitor/defaults/main.yml b/ansible/roles/stack-monitor/defaults/main.yml
index e67189b8b95a943c20b16186c1aa02b9e4118a8c..457e201b7697ea9b4dd7c33b0d38b766fe07e4bb 100644
--- a/ansible/roles/stack-monitor/defaults/main.yml
+++ b/ansible/roles/stack-monitor/defaults/main.yml
@@ -96,6 +96,7 @@ service_teams:
     services:
       - actor-service
       - learner-service
+      - lms-service
       - content-service
       - player_player
       - cassandra
diff --git a/ansible/roles/stack-monitor/templates/prometheus.yml b/ansible/roles/stack-monitor/templates/prometheus.yml
index 862b9e728d0cbc7f9f0bbd794b795d91bf209227..ec159d9afd55cd1b961855767a548f6cf0f78151 100644
--- a/ansible/roles/stack-monitor/templates/prometheus.yml
+++ b/ansible/roles/stack-monitor/templates/prometheus.yml
@@ -62,6 +62,16 @@ scrape_configs:
         action: drop
   {% endif %}
 
+  - job_name: 'nginx'
+    metrics_path: /metrics
+    scrape_interval: 10s
+    scrape_timeout: 5s
+    dns_sd_configs:
+    - names:
+      - 'tasks.proxy_proxy'
+      type: 'A'
+      port: 9145
+
   - job_name: 'statsd-exporter'
     static_configs:
       - targets: ['monitor_statsd_exporter:9102']
diff --git a/ansible/roles/stack-proxy/defaults/main.yml b/ansible/roles/stack-proxy/defaults/main.yml
index 5b28734638d255d299ec78695934681caa4ebbc7..0ae31363be77f3393c7285701bfbd2bf7edd406f 100644
--- a/ansible/roles/stack-proxy/defaults/main.yml
+++ b/ansible/roles/stack-proxy/defaults/main.yml
@@ -3,7 +3,8 @@ hub_org: sunbird
 
 proxy_replicas: 1
 proxy_reservation_memory: 32M
-proxy_limit_memory: 128M
+proxy_limit_memory: 64M
+nginx_per_ip_connection_limit: 400
 
 proxy_prometheus: false
 
diff --git a/ansible/roles/stack-proxy/templates/nginx.conf b/ansible/roles/stack-proxy/templates/nginx.conf
index baa921306d769b04152a5d98d5fcb3b6515da768..ff5ee83d09534cf212f10531956deb7aad6e19a9 100644
--- a/ansible/roles/stack-proxy/templates/nginx.conf
+++ b/ansible/roles/stack-proxy/templates/nginx.conf
@@ -5,7 +5,7 @@ error_log  /var/log/nginx/error.log warn;
 pid        /var/run/nginx.pid;
 
 events {
-    worker_connections  2048;
+    worker_connections  10000;
 }
 
 
@@ -13,29 +13,66 @@ http {
     include       /etc/nginx/mime.types;
     default_type  application/octet-stream;
 
-    log_format  main  '$http_x_forwarded_for - $remote_addr - $remote_user [$time_local] '
+    lua_load_resty_core off;
+    log_format  main  '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $body_bytes_sent '
                       '$request_time $upstream_response_time $pipe'
                       '"$http_referer" "$http_user_agent"';
 
     access_log  /var/log/nginx/access.log  main;
 
+    # Shared dictionary to store metrics
+    lua_shared_dict prometheus_metrics 10M;
+    lua_package_path "/etc/nginx/lua_modules/?.lua";
+    # Defining metrics
+    init_by_lua '
+      prometheus = require("prometheus").init("prometheus_metrics")
+      metric_requests = prometheus:counter(
+        "nginx_http_requests_total", "Number of HTTP requests", {"host", "status", "request_method"})
+      metric_latency = prometheus:histogram(
+        "nginx_http_request_duration_seconds", "HTTP request latency", {"host"})
+      metric_connections = prometheus:gauge(
+        "nginx_http_connections", "Number of HTTP connections", {"state"})
+    ';
+
+    # Collecting metrics
+    log_by_lua '
+      metric_requests:inc(1, {ngx.var.server_name, ngx.var.status, ngx.var.request_method})
+      metric_latency:observe(tonumber(ngx.var.request_time), {ngx.var.server_name})
+    ';
+
     sendfile        on;
     #tcp_nopush     on;
     client_max_body_size 60M;
 
-    keepalive_timeout  65;
+    keepalive_timeout  65s;
+    keepalive_requests 200;
+
+    # Nginx connection limit per ip
+    limit_conn_zone $binary_remote_addr zone=limitbyaddr:10m;
+    limit_conn_status 429;
 
     upstream kong {
         server api-manager_kong:8000;
         keepalive 1000;
     }
 
-    #gzip  on;
     upstream player {
         server player_player:3000;
         keepalive 1000;
     }
 
     include /etc/nginx/conf.d/*.conf;
+
+   server {
+     listen 9145;
+     location /metrics {
+       content_by_lua '
+         metric_connections:set(ngx.var.connections_reading, {"reading"})
+         metric_connections:set(ngx.var.connections_waiting, {"waiting"})
+         metric_connections:set(ngx.var.connections_writing, {"writing"})
+         prometheus:collect()
+       ';
+     }
+   }
 }
diff --git a/ansible/roles/stack-proxy/templates/proxy-default.conf b/ansible/roles/stack-proxy/templates/proxy-default.conf
index d462b95b990080bd1874289cd899f6903d3c14bc..c489c283da8f7a323d7ad53c5c164a02a5547027 100644
--- a/ansible/roles/stack-proxy/templates/proxy-default.conf
+++ b/ansible/roles/stack-proxy/templates/proxy-default.conf
@@ -3,6 +3,8 @@ server {
   listen 80;
   listen [::]:80;
   server_name {{ proxy_server_name }};
+  # Limitting open connection per ip
+  limit_conn limitbyaddr {{ nginx_per_ip_connection_limit }};
 
   return 301 https://{{ proxy_server_name }}$request_uri;
 }
@@ -18,6 +20,8 @@ server {
 {% endif  %}
   server_name           {{ proxy_server_name }};
 
+  # Limitting open connection per ip
+  limit_conn limitbyaddr {{ nginx_per_ip_connection_limit }};
   proxy_set_header    Host              $host;
   proxy_set_header    X-Real-IP         $remote_addr;
   proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
@@ -45,7 +49,20 @@ server {
   location ~* ^/auth/realms/(.+)/clients-registrations/ {
     return 301 {{proto}}://$host/api/auth/v1/realms/$1/clients-registrations/;
   }
-  
+
+  location ~* ^/auth/v1/refresh/token  {
+    set $target http://player:3000;
+    rewrite ^/auth/(.*) /auth/$1 break;
+    proxy_pass $target;
+    
+    proxy_set_header Host $host;
+    proxy_set_header X-Real-IP $remote_addr;
+    proxy_set_header X-Scheme $scheme;
+    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
+    proxy_set_header X-Forwarded-Proto $scheme;
+
+  }
+ 
   location ~* ^/auth/admin/master/console/ {
     return 301 {{proto}}://{{ proxy_server_name }};
   }
diff --git a/ansible/roles/stack-proxy/templates/stack-proxy.yml b/ansible/roles/stack-proxy/templates/stack-proxy.yml
index eee187d9721e0b8eefed5119dabccf1489024ae1..cd155ba14a2e41b90d90de2e20cd05f94747bad5 100644
--- a/ansible/roles/stack-proxy/templates/stack-proxy.yml
+++ b/ansible/roles/stack-proxy/templates/stack-proxy.yml
@@ -3,11 +3,18 @@ version: '3.3'
 services:
   proxy:
     image: "{{hub_org}}/{{image_name}}:{{image_tag}}"
+    # This is a workaround for remote ip address is not visible nginx
     ports:
-      - "443:443"
-      - "80:80"
+      - mode: host
+        target: 80
+        published: 80
+        protocol: TCP
+      - mode: host
+        target: 443
+        published: 443
+        protocol: TCP
     deploy:
-      replicas: {{ proxy_replicas }}
+      mode: global
       resources:
         reservations:
           memory: "{{ proxy_reservation_memory }}"
diff --git a/ansible/roles/stack-sunbird/defaults/main.yml b/ansible/roles/stack-sunbird/defaults/main.yml
index 43cb794b51d82d803451e17076505b1234b64523..167c9ab312d3f90cfaf7effe61ef78967d43d136 100644
--- a/ansible/roles/stack-sunbird/defaults/main.yml
+++ b/ansible/roles/stack-sunbird/defaults/main.yml
@@ -75,11 +75,21 @@ content_limit_cpu: 1
 content_reservation_cpu: 1
 
 user_org_replicas: 1
-user_org_reservation_memory: 750m
-user_org_limit_memory: 1g
+user_org_reservation_memory: 750MB
+user_org_limit_memory: 800MB
 user_org_limit_cpu: 1
 user_org_reservation_cpu: 1
 
+# Encryption service vars
+enc_replicas: 1
+enc_reservation_memory: 750MB
+enc_limit_memory: 800MB
+enc_limit_cpu: 1
+enc_reservation_cpu: 1
+postgres_port: 5432
+enc_dialect: postgres
+enc_entry_passwod: password
+
 
 telemetry_service_threads:
 telemetry_local_storage_enabled:
@@ -88,10 +98,6 @@ telemetry_kafka_broker_list:
 telemetry_kafka_topic:
 
 # Encryption service
-encryption_replicas: 1
-encryption_reservation_memory: "256M"
-encryption_limit_memory: "512M"
-
 # Learner
 sunbird_keycloak_required_action_link_expiration_seconds: 2592000
 sunbird_time_zone: "Asia/Kolkata"
diff --git a/ansible/roles/stack-sunbird/tasks/enc_service.yml b/ansible/roles/stack-sunbird/tasks/enc_service.yml
new file mode 100644
index 0000000000000000000000000000000000000000..495a9ad6cbb093d51b8e260c391dfa3bdf68c380
--- /dev/null
+++ b/ansible/roles/stack-sunbird/tasks/enc_service.yml
@@ -0,0 +1,7 @@
+---
+- name: Remove enc service
+  shell: "docker service rm enc-service"
+  ignore_errors: yes
+
+- name: Deploy enc service
+  shell: "docker service create --with-registry-auth --replicas {{ enc_replicas }} -p 9010:8013  --name enc-service --hostname enc-service --reserve-memory {{ enc_reservation_memory }} --limit-memory {{ enc_limit_memory }} --limit-cpu {{ enc_limit_cpu }} --reserve-cpu {{ enc_reservation_cpu }} --network application_default --env-file /home/deployer/env/sunbird_enc-service.env  {{hub_org}}/{{image_name}}:{{image_tag}}"
diff --git a/ansible/roles/stack-sunbird/tasks/encryption_service.yml b/ansible/roles/stack-sunbird/tasks/encryption_service.yml
deleted file mode 100644
index c687e3b386d7d73ab4b40c204a52c8dcef206817..0000000000000000000000000000000000000000
--- a/ansible/roles/stack-sunbird/tasks/encryption_service.yml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-- name: Remove encryption service
-  shell: "docker service rm encryption-service"
-  ignore_errors: yes
-
-- name: Deploy encryption service
-  shell: "docker service create --replicas {{ encryption_replicas }} -p 8013:8013  --name encryption-service --hostname encryption-service --reserve-memory {{ encryption_reservation_memory }} --limit-memory {{ encryption_limit_memory }} --network application_default --env-file /home/deployer/env/sunbird_encryption-service.env  {{hub_org}}/{{image_name}}:{{image_tag}} {{application_postgres_password}}"
-  args:
-    chdir: /home/deployer/stack
diff --git a/ansible/roles/stack-sunbird/tasks/lms_service.yml b/ansible/roles/stack-sunbird/tasks/lms_service.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f99ef4502ac4b4334c63f00f06a785ee1cd6d20f
--- /dev/null
+++ b/ansible/roles/stack-sunbird/tasks/lms_service.yml
@@ -0,0 +1,9 @@
+---
+- name: Remove lms service
+  shell: "docker service rm lms-service"
+  ignore_errors: yes
+
+- name: Deploy lms service
+  shell: "docker service create --with-registry-auth --replicas {{ learner_replicas }} -p 9005:9000  --name lms-service --hostname lms-service --reserve-memory {{ learner_reservation_memory }} --limit-memory {{ learner_limit_memory }} --limit-cpu {{ learner_limit_cpu }} --reserve-cpu {{ learner_reservation_cpu }} --health-cmd 'wget -qO- lms-service:9000/service/health || exit 1' --health-timeout 3s --health-retries 3  --network application_default --env-file /home/deployer/env/sunbird_lms-service.env  {{hub_org}}/{{image_name}}:{{image_tag}}"
+  args:
+    chdir: /home/deployer/stack
\ No newline at end of file
diff --git a/ansible/roles/stack-sunbird/tasks/main.yml b/ansible/roles/stack-sunbird/tasks/main.yml
index 95c6ab235a9863ffe943b78ab5e2f0a2ad48d7dc..d400460d96f780da824ae79c0299115d3867137b 100644
--- a/ansible/roles/stack-sunbird/tasks/main.yml
+++ b/ansible/roles/stack-sunbird/tasks/main.yml
@@ -6,6 +6,12 @@
 
   - include: learner_service.yml
     when: deploy_learner is defined
+  
+  - include: lms_service.yml
+    when: deploy_lms is defined
+
+  - include: enc_service.yml
+    when: deploy_enc is defined
 
   - include: user_org_service.yml
     when: deploy_user_org is defined
@@ -24,6 +30,3 @@
 
   - include: telemetry_logstash_datapipeline.yml
     when: deploy_telemetry_logstash_datapipeline is defined
-
-  - include: encryption_service.yml
-    when: deploy_encryption is defined
diff --git a/ansible/roles/stack-sunbird/tasks/user_org_service.yml b/ansible/roles/stack-sunbird/tasks/user_org_service.yml
index b317978c03ab2e21ffe2bb889fcd881f07345777..fcc0cc1f85497e8d564c3bb4776ddbbf0bf4a7bf 100644
--- a/ansible/roles/stack-sunbird/tasks/user_org_service.yml
+++ b/ansible/roles/stack-sunbird/tasks/user_org_service.yml
@@ -5,5 +5,3 @@
 
 - name: Deploy user org service
   shell: "docker service create --with-registry-auth --replicas {{ user_org_replicas }} -p 9009:9000  --name user-org-service --hostname user-org-service --reserve-memory {{ user_org_reservation_memory }} --limit-memory {{ user_org_limit_memory }} --limit-cpu {{ user_org_limit_cpu }} --reserve-cpu {{ user_org_reservation_cpu }} --network application_default --env-file /home/deployer/env/sunbird_user-org-service.env  {{hub_org}}/{{image_name}}:{{image_tag}}"
-  args:
-    chdir: /home/deployer/stack
diff --git a/ansible/roles/stack-sunbird/templates/stack_encryption_service.yml b/ansible/roles/stack-sunbird/templates/stack_encryption_service.yml
deleted file mode 100644
index ec54a3b4be34f22c5071399f2eab2e02bd4ebe50..0000000000000000000000000000000000000000
--- a/ansible/roles/stack-sunbird/templates/stack_encryption_service.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-version: '3.1'
-services:
-  encryption-service:
-    image: "{{hub_org}}/{{image_name}}:{{image_tag}}"
-    env_file:
-      /home/deployer/env/sunbird_encryption_service.env
-    deploy:
-      args:
-        DB_PASSWORD: "{{application_postgres_password}}"
-      replicas: "{{ encryption_replicas | default(1) }}"
-      resources:
-        reservations:
-          memory: "{{ encryption_reservation_memory  | default('256M') }}"
-        limits:
-          memory: "{{ encryption_limit_memory  | default('512M') }}"
-      interval: 10s
-      timeout: 5s
-      retries: 5
-    ports:
-     - "8013:8013"
-    networks:
-      - application_default
-networks:
-  application_default:
-    external: true
diff --git a/ansible/roles/stack-sunbird/templates/sunbird_enc-service.env b/ansible/roles/stack-sunbird/templates/sunbird_enc-service.env
new file mode 100644
index 0000000000000000000000000000000000000000..ba645fc11972dc320a0e047ebe4af5a9e5159dbd
--- /dev/null
+++ b/ansible/roles/stack-sunbird/templates/sunbird_enc-service.env
@@ -0,0 +1,8 @@
+DB_HOST={{enc_postgres_host}}
+DB_PORT={{postgres_port}}
+DB_USER={{enc_postgres_user}}
+DB_PASSWORD={{enc_postgres_password}}
+DB_NAME={{enc_postgres_database}}
+DB_DIALECT={{enc_dialect}}
+DB_SSL=True
+ENTRY_PASS={{enc_entry_password}}
diff --git a/ansible/roles/stack-sunbird/templates/sunbird_encryption-service.env b/ansible/roles/stack-sunbird/templates/sunbird_encryption-service.env
deleted file mode 100644
index 7d2959184baf13013392ae5ed0080040d7f7014b..0000000000000000000000000000000000000000
--- a/ansible/roles/stack-sunbird/templates/sunbird_encryption-service.env
+++ /dev/null
@@ -1,6 +0,0 @@
-DB_HOST={{application_postgres_host}}
-DB_USER={{encryption_service_user}}
-DB_PASSWORD={{application_postgres_password}}
-DB_NAME={{encryption_db_name}}
-DB_DIALECT={{encryption_db_dialect}}
-DB_SSL=True
diff --git a/ansible/roles/stack-sunbird/templates/sunbird_lms-service.env b/ansible/roles/stack-sunbird/templates/sunbird_lms-service.env
new file mode 100644
index 0000000000000000000000000000000000000000..65a97a3c6f639edfb95ca5e37048915ad5e6743e
--- /dev/null
+++ b/ansible/roles/stack-sunbird/templates/sunbird_lms-service.env
@@ -0,0 +1,102 @@
+sunbird_sso_publickey={{sunbird_sso_publickey}}
+sunbird_sso_url={{keycloak_auth_server_url}}/
+sunbird_sso_realm={{keycloak_realm}}
+sunbird_sso_username={{sunbird_sso_username}}
+sunbird_sso_password={{sunbird_sso_password}}
+sunbird_sso_client_id={{sunbird_sso_client_id}}
+sunbird_es_host={{sunbird_es_host}}
+sunbird_es_port={{sunbird_es_port}}
+sunbird_cassandra_username=cassandra
+sunbird_cassandra_password=password
+actor_hostname=actor-service
+bind_hostname=0.0.0.0
+ekstep_authorization={{sunbird_ekstep_api_key}}
+sunbird_pg_host={{sunbird_pg_host}}
+sunbird_pg_port={{sunbird_pg_port}}
+sunbird_pg_db={{sunbird_pg_db}}
+sunbird_pg_user={{sunbird_pg_user}}
+sunbird_pg_password={{sunbird_pg_password}}
+sunbird_installation={{sunbird_installation}}
+sunbird_analytics_api_base_url={{sunbird_analytics_api_base_url}}
+sunbird_search_service_api_base_url={{sunbird_search_service_api_base_url}}
+ekstep_api_base_url={{sunbird_content_repo_api_base_url}}
+sunbird_mail_server_host={{sunbird_mail_server_host}}
+sunbird_mail_server_port={{sunbird_mail_server_port}}
+sunbird_mail_server_username={{sunbird_mail_server_username}}
+sunbird_mail_server_password={{sunbird_mail_server_password}}
+sunbird_mail_server_from_email={{sunbird_mail_server_from_email}}
+sunbird_encryption_key={{sunbird_encryption_key}}
+sunbird_encryption_mode={{sunbird_encryption_mode}}
+sunbird_account_name={{sunbird_account_name}}
+sunbird_account_key={{sunbird_account_key}}
+sunbird_quartz_mode={{sunbird_sunbird_quartz_mode}}
+sunbird_env_logo_url={{sunbird_env_logo_url}}
+sunbird_web_url={{sunbird_web_url}}
+sunbird_fcm_account_key={{sunbird_fcm_account_key}}
+sunbird_msg_91_auth={{sunbird_msg_91_auth}}
+sunbird_msg_sender={{sunbird_msg_sender}}
+sunbird_installation_email={{sunbird_installation_email}}
+{% if groups['cassandra-2'] is defined %}
+sunbird_cassandra_host={{groups['cassandra']|join(',')}}
+sunbird_cassandra_port=9042,9042,9042
+sunbird_cassandra_consistency_level=quorum
+{% else %}
+sunbird_cassandra_host={{sunbird_cassandra_host}}
+sunbird_cassandra_port=9042
+sunbird_cassandra_consistency_level={{sunbird_cassandra_consistency_level}}
+{% endif %}
+
+sunbird_mw_system_host=lms-service
+sunbird_mw_system_port=8088
+background_actor_provider=local
+api_actor_provider=local
+badging_authorization_key={{vault_badging_authorization_key}}
+sunbird_badger_baseurl=http://badger-service:8004
+sunbird_remote_req_router_path=akka.tcp://SunbirdMWSystem@actor-service:8088/user/RequestRouter
+sunbird_remote_bg_req_router_path=akka.tcp://SunbirdMWSystem@actor-service:8088/user/BackgroundRequestRouter
+sunbird_api_base_url=http://content-service:5000
+sunbird_authorization={{sunbird_api_auth_token}}
+telemetry_pdata_id={{sunbird_telemetry_pdata_id}}
+telemetry_pdata_pid=lms-service
+sunbird_telemetry_base_url=http://telemetry-service:9001
+telemetry_queue_threshold_value=100
+sunbird_default_channel={{sunbird_default_channel}}
+sunbird_api_mgr_base_url=http://content-service:5000
+sunbird_cs_base_url={{sunbird_cs_base_url}}
+sunbird_cs_search_path=/v1/content/search
+
+sunbird_env_logo_url={{sunbird_env_logo_url}}
+sunbird_user_bulk_upload_size={{sunbird_user_bulk_upload_size}}
+sunbird_installation_display_name={{sunbird_installation_display_name}}
+
+sunbird_app_name={{sunbird_app_name|default('Sunbird')}}
+sunbird_registry_service_baseurl=http://registry_registry:8080/
+sunbird_open_saber_bridge_enable={{sunbird_open_saber_bridge_enable|default('false')}}
+sunbird_environment={{sunbird_environment}}
+sunbird_instance={{sunbird_instance}}
+sunbird_email_max_recipients_limit={{sunbird_email_max_recipients_limit}}
+sunbird_url_shortner_access_token={{sunbird_url_shortner_access_token}}
+sunbird_url_shortner_enable={{sunbird_url_shortner_enable}}
+sunbird_user_profile_field_default_visibility={{sunbird_user_profile_field_default_visibility}}
+sunbird_keycloak_required_action_link_expiration_seconds={{sunbird_keycloak_required_action_link_expiration_seconds}}
+sunbird_course_batch_notification_enabled={{sunbird_course_batch_notification_enabled}}
+sunbird_course_batch_notification_signature={{sunbird_course_batch_notification_signature}}
+sunbird_otp_expiration={{sunbird_otp_expiration}}
+sunbird_otp_length={{sunbird_otp_length}}
+sunbird_content_azure_storage_container={{sunbird_content_azure_storage_container}}
+# Release-1.14
+sunbird_time_zone={{sunbird_time_zone}}
+# Release-1.15
+sunbird_health_check_enable={{sunbird_health_check_enable}}
+sunbird_keycloak_user_federation_provider_id={{core_vault_sunbird_keycloak_user_federation_provider_id}}
+sunbird_gzip_enable={{sunbird_gzip_enable}}
+sunbird_course_metrics_base_url={{sunbird_course_metrics_base_url}}
+sunbird_gzip_size_threshold={{sunbird_gzip_size_threshold | default(262144)}}
+sunbird_analytics_blob_account_name={{sunbird_analytics_blob_account_name}}
+sunbird_analytics_blob_account_key={{sunbird_analytics_blob_account_key}}
+# Optional for caching
+sunbird_cache_enable={{sunbird_cache_enable | default(false)}}
+# Set below variables if above true
+sunbird_redis_host={{sunbird_redis_host}}
+sunbird_redis_port={{sunbird_redis_port|default(6379)}}
+sunbird_user_org_api_base_url={{sunbird_user_org_api_base_url}}
diff --git a/ansible/roles/stack-sunbird/templates/sunbird_player.env b/ansible/roles/stack-sunbird/templates/sunbird_player.env
index fc5329fa1d5f53b0518b131c8e7d83fcb5b748ac..352d77634e7a6845e474a75861350351a03ca483 100644
--- a/ansible/roles/stack-sunbird/templates/sunbird_player.env
+++ b/ansible/roles/stack-sunbird/templates/sunbird_player.env
@@ -66,3 +66,8 @@ sunbird_portal_offline_app_release_date={{sunbird_portal_offline_app_release_dat
 sunbird_portal_offline_app_version={{sunbird_portal_offline_app_version}}
 sunbird_portal_offline_app_download_url={{sunbird_portal_offline_app_download_url}}
 sunbird_portal_log_level={{sunbird_portal_log_level}}
+sunbird_google_android_keycloak_client_id={{sunbird_google_android_keycloak_client_id}}
+sunbird_google_android_keycloak_secret={{sunbird_google_android_keycloak_secret}}
+sunbird_trampoline_android_keycloak_client_id={{sunbird_trampoline_android_keycloak_client_id}}
+sunbird_trampoline_android_keycloak_secret={{sunbird_trampoline_android_keycloak_secret}}
+sunbird_android_keycloak_client_id={{sunbird_android_keycloak_client_id}}
diff --git a/ansible/roles/stack-sunbird/templates/sunbird_user-org-service.env b/ansible/roles/stack-sunbird/templates/sunbird_user-org-service.env
index dc01bec09652afb252f37caf83d554ffa9548876..0a54d2ff2443e41c2c959d3f7a395fd0e472dcc4 100644
--- a/ansible/roles/stack-sunbird/templates/sunbird_user-org-service.env
+++ b/ansible/roles/stack-sunbird/templates/sunbird_user-org-service.env
@@ -1,3 +1,18 @@
-pg_user:
-pg_host:
-pg_password:
+sunbird_es_host={{user_org_sunbird_es_host}}
+sunbird_es_port={{user_org_sunbird_es_port}}
+########## Shards For Postgres ##########
+database_connectionInfo_0_shardId={{user_org_database_connectionInfo_0_shardId}}
+database_connectionInfo_0_shardLabel={{user_org_database_connectionInfo_0_shardLabel}}
+database_connectionInfo_0_username={{user_org_database_connectionInfo_0_username}}
+database_connectionInfo_0_password={{user_org_database_connectionInfo_0_password}}
+database_connectionInfo_0_uri={{user_org_database_connectionInfo_0_uri}}
+database_connectionInfo_1_shardId={{user_org_database_connectionInfo_1_shardId}}
+database_connectionInfo_1_shardLabel={{user_org_database_connectionInfo_1_shardLabel}}
+database_connectionInfo_1_username={{user_org_database_connectionInfo_1_username}}
+database_connectionInfo_1_password={{user_org_database_connectionInfo_1_password}}
+database_connectionInfo_1_uri={{user_org_database_connectionInfo_1_uri}}
+database_connectionInfo_2_shardId_={{user_org_database_connectionInfo_2_shardId}}
+database_connectionInfo_2_shardLabel={{user_org_database_connectionInfo_2_shardLabel}}
+database_connectionInfo_2_username={{user_org_database_connectionInfo_2_username}}
+database_connectionInfo_2_password={{user_org_database_connectionInfo_2_password}}
+database_connectionInfo_2_uri={{user_org_database_connectionInfo_2_uri}}
diff --git a/ansible/roles/sunbird-auth-deploy/files/python-keycloak-0.12.0/keycloak/keycloak_main.py b/ansible/roles/sunbird-auth-deploy/files/python-keycloak-0.12.0/keycloak/keycloak_main.py
index bb859c405d33a4b344be3a38c2e14f42784ca1fd..992aedfc9a30b7dee5f5e766c297555b5118d88b 100644
--- a/ansible/roles/sunbird-auth-deploy/files/python-keycloak-0.12.0/keycloak/keycloak_main.py
+++ b/ansible/roles/sunbird-auth-deploy/files/python-keycloak-0.12.0/keycloak/keycloak_main.py
@@ -80,8 +80,11 @@ if  __name__ == "__main__":
         # Update user roles for SSO
         config['clientId'] = "admin-cli"
         update_user_roles(config)
-
-    except urllib2.HTTPError as e:
-        error_message = e.read()
-        print error_message
+    # If keycloak is returning the error realm does exists
+    except Exception as e:
+        if "409" in str(e):
+            print "Skipping error: " + str(e)
+            pass
+    except Exception as e:
         raise
+
diff --git a/ansible/roles/sunbird-auth-deploy/files/python-keycloak-0.12.0/keycloak/keycloak_patch.py b/ansible/roles/sunbird-auth-deploy/files/python-keycloak-0.12.0/keycloak/keycloak_patch.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c0e811f6f862c9f42f680b3c3252363bfd71f48
--- /dev/null
+++ b/ansible/roles/sunbird-auth-deploy/files/python-keycloak-0.12.0/keycloak/keycloak_patch.py
@@ -0,0 +1,54 @@
+import json
+
+from keycloak import KeycloakOpenID
+from keycloak import KeycloakAdmin
+import urllib2, argparse, json
+
+# Create client
+def keycloak_create_client(config):
+    data = json.load(open(config['keycloak_clients']))
+    
+    # Get the existing clients
+    keycloak_admin.realm_name = config['keycloak_realm']    
+    clients = keycloak_admin.get_clients()
+    
+    # 1. Read the clients to be added from json
+    # 2. Check if client already exists in keycloak
+    # 3. Add the client if not exist
+    for rec in data['clients']:
+        client_exist_falg = 0
+        for client in clients:
+            if rec['clientId'] == client['clientId']:
+                client_exist_falg = 1
+                break
+        if (client_exist_falg == 0):
+            keycloak_admin.create_client(rec)
+            print rec['clientId'] + " client created"
+        else :
+            print rec['clientId'] + " client already exist"
+
+if  __name__ == "__main__":
+    parser = argparse.ArgumentParser(description='Configure keycloak user apis')
+    parser.add_argument('keycloak_bootstrap_config', help='configuration json file that is needed for keycloak bootstrap')
+    args = parser.parse_args()
+
+    with open(args.keycloak_bootstrap_config) as keycloak_bootstrap_config:
+        config = json.load(keycloak_bootstrap_config)
+
+    try:
+        # Get access token
+        keycloak_admin = KeycloakAdmin(server_url=config['keycloak_auth_server_url'],
+                            username=config['keycloak_management_user'],
+                            password=config['keycloak_management_password'],
+                            realm_name="master",
+                            client_id='admin-cli',
+                            verify=False)
+        
+
+        # Create clients
+        keycloak_create_client(config)
+
+    except urllib2.HTTPError as e:
+        error_message = e.read()
+        print(error_message)
+        raise
diff --git a/ansible/roles/sunbird-auth-deploy/tasks/custom.yml b/ansible/roles/sunbird-auth-deploy/tasks/custom.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9a5f580fe6dbbd0d1f5f46d062502450a484fe63
--- /dev/null
+++ b/ansible/roles/sunbird-auth-deploy/tasks/custom.yml
@@ -0,0 +1,44 @@
+- name: Install dependencies for keycloak
+  apt:
+    name: "{{item}}"
+    update_cache: yes
+  with_items:
+    - python-pip
+    - python-setuptools
+  run_once: true
+
+- name: Copying python libraries
+  copy: src={{ role_path }}/files/python-keycloak-0.12.0 dest=/tmp/
+  run_once: true
+
+- name: Initialize python library to run keycloak paython script
+  shell: cd /tmp/python-keycloak-0.12.0 && python setup.py install
+  run_once: true
+
+- name: Save keycloak vars to json
+  template: src="keycloak-bootstrap.conf.j2" dest="/tmp/keycloak-bootstrap.conf.json" mode="0644"
+  run_once: true
+
+- name: Copy realm json file to tmp location
+  template: src="keycloak-realm.j2" dest="/tmp/keycloak-realm.json" mode="0644"
+  run_once: true
+
+- name: Copy clients file to tmp location
+  template: src="clients.j2" dest="/tmp/clients.json" mode="0644"
+  run_once: true
+
+- name: Copy user manager roles file to tmp location
+  copy: src="files/python-keycloak-0.12.0/roles.json" dest="/tmp/roles.json" mode="0644"
+  run_once: true
+
+- name: Copy the keycloak paython script
+  copy:  src={{ role_path }}/files/python-keycloak-0.12.0/keycloak dest=/tmp
+  run_once: true
+
+- name: Run the keycloak paython script
+  shell:  cd /tmp/keycloak/ && python keycloak_patch.py /tmp/keycloak-bootstrap.conf.json
+  register: out
+  until: '"404" not in out.stderr'
+  retries: 2
+  delay: 10
+  run_once: true
diff --git a/ansible/roles/sunbird-auth-deploy/tasks/deploy.yml b/ansible/roles/sunbird-auth-deploy/tasks/deploy.yml
index 06102a1980122bc64c7d9628a97cd0fbc8fbacf2..79309f38151f74b1822f5e57af3b998147c83bdb 100644
--- a/ansible/roles/sunbird-auth-deploy/tasks/deploy.yml
+++ b/ansible/roles/sunbird-auth-deploy/tasks/deploy.yml
@@ -156,3 +156,4 @@
   command: /etc/init.d/keycloak start
   poll: 5
   async: 5
+
diff --git a/ansible/roles/sunbird-auth-deploy/tasks/main.yml b/ansible/roles/sunbird-auth-deploy/tasks/main.yml
index 3c5bbefeb390b51ad834672ff328e1abcf960c7a..79d4e859b8bd698ec6516572303223ac5fc37a7f 100644
--- a/ansible/roles/sunbird-auth-deploy/tasks/main.yml
+++ b/ansible/roles/sunbird-auth-deploy/tasks/main.yml
@@ -5,3 +5,7 @@
 - include: bootstrap.yml
   tags:
     - bootstrap
+
+- include: custom.yml
+  tags:
+    - custom
diff --git a/ansible/roles/sunbird-auth-deploy/templates/clients.j2 b/ansible/roles/sunbird-auth-deploy/templates/clients.j2
new file mode 100644
index 0000000000000000000000000000000000000000..c34437cf68d7fb35e234663e90dc26ed09fcf486
--- /dev/null
+++ b/ansible/roles/sunbird-auth-deploy/templates/clients.j2
@@ -0,0 +1,262 @@
+{
+    "clients": [
+        {
+            "clientId": "google-auth-android",
+            "rootUrl": "{{proto}}://{{proxy_server_name}}",
+            "adminUrl": "",
+            "baseUrl": "/",
+            "surrogateAuthRequired": false,
+            "enabled": true,
+            "clientAuthenticatorType": "client-secret",
+            "redirectUris": [
+                "{{proto}}://{{proxy_server_name}}/*"
+            ],
+            "webOrigins": [],
+            "notBefore": 0,
+            "bearerOnly": false,
+            "consentRequired": false,
+            "standardFlowEnabled": false,
+            "implicitFlowEnabled": false,
+            "directAccessGrantsEnabled": true,
+            "serviceAccountsEnabled": false,
+            "publicClient": false,
+            "frontchannelLogout": false,
+            "protocol": "openid-connect",
+            "attributes": {
+                "saml.assertion.signature": "false",
+                "saml.force.post.binding": "false",
+                "saml.multivalued.roles": "false",
+                "saml.encrypt": "false",
+                "saml_force_name_id_format": "false",
+                "saml.client.signature": "false",
+                "saml.authnstatement": "false",
+                "saml.server.signature": "false",
+                "saml.server.signature.keyinfo.ext": "false",
+                "saml.onetimeuse.condition": "false"
+            },
+            "fullScopeAllowed": true,
+            "nodeReRegistrationTimeout": -1,
+            "protocolMappers": [
+                {
+                    "name": "full name",
+                    "protocol": "openid-connect",
+                    "protocolMapper": "oidc-full-name-mapper",
+                    "consentRequired": true,
+                    "consentText": "${fullName}",
+                    "config": {
+                        "id.token.claim": "true",
+                        "access.token.claim": "true",
+                        "userinfo.token.claim": "true"
+                    }
+                },
+                {
+                    "name": "username",
+                    "protocol": "openid-connect",
+                    "protocolMapper": "oidc-usermodel-property-mapper",
+                    "consentRequired": true,
+                    "consentText": "${username}",
+                    "config": {
+                        "userinfo.token.claim": "true",
+                        "user.attribute": "username",
+                        "id.token.claim": "true",
+                        "access.token.claim": "true",
+                        "claim.name": "preferred_username",
+                        "jsonType.label": "String"
+                    }
+                },
+                {
+                    "name": "family name",
+                    "protocol": "openid-connect",
+                    "protocolMapper": "oidc-usermodel-property-mapper",
+                    "consentRequired": true,
+                    "consentText": "${familyName}",
+                    "config": {
+                        "userinfo.token.claim": "true",
+                        "user.attribute": "lastName",
+                        "id.token.claim": "true",
+                        "access.token.claim": "true",
+                        "claim.name": "family_name",
+                        "jsonType.label": "String"
+                    }
+                },
+                {
+                    "name": "role list",
+                    "protocol": "saml",
+                    "protocolMapper": "saml-role-list-mapper",
+                    "consentRequired": false,
+                    "config": {
+                        "single": "false",
+                        "attribute.nameformat": "Basic",
+                        "attribute.name": "Role"
+                    }
+                },
+                {
+                    "name": "given name",
+                    "protocol": "openid-connect",
+                    "protocolMapper": "oidc-usermodel-property-mapper",
+                    "consentRequired": true,
+                    "consentText": "${givenName}",
+                    "config": {
+                        "userinfo.token.claim": "true",
+                        "user.attribute": "firstName",
+                        "id.token.claim": "true",
+                        "access.token.claim": "true",
+                        "claim.name": "given_name",
+                        "jsonType.label": "String"
+                    }
+                },
+                {
+                    "name": "email",
+                    "protocol": "openid-connect",
+                    "protocolMapper": "oidc-usermodel-property-mapper",
+                    "consentRequired": true,
+                    "consentText": "${email}",
+                    "config": {
+                        "userinfo.token.claim": "true",
+                        "user.attribute": "email",
+                        "id.token.claim": "true",
+                        "access.token.claim": "true",
+                        "claim.name": "email",
+                        "jsonType.label": "String"
+                    }
+                }
+            ],
+            "useTemplateConfig": false,
+            "useTemplateScope": false,
+            "useTemplateMappers": false,
+            "access": {
+                "view": true,
+                "configure": true,
+                "manage": true
+            }
+        },
+        {
+            "clientId": "trampoline-android",
+            "rootUrl": "{{proto}}://{{proxy_server_name}}",
+            "adminUrl": "",
+            "baseUrl": "/",
+            "surrogateAuthRequired": false,
+            "enabled": true,
+            "clientAuthenticatorType": "client-secret",
+            "redirectUris": [],
+            "webOrigins": [],
+            "notBefore": 0,
+            "bearerOnly": false,
+            "consentRequired": false,
+            "standardFlowEnabled": false,
+            "implicitFlowEnabled": false,
+            "directAccessGrantsEnabled": true,
+            "serviceAccountsEnabled": false,
+            "publicClient": false,
+            "frontchannelLogout": false,
+            "protocol": "openid-connect",
+            "attributes": {
+                "saml.assertion.signature": "false",
+                "saml.force.post.binding": "false",
+                "saml.multivalued.roles": "false",
+                "saml.encrypt": "false",
+                "saml_force_name_id_format": "false",
+                "saml.client.signature": "false",
+                "saml.authnstatement": "false",
+                "saml.server.signature": "false",
+                "saml.server.signature.keyinfo.ext": "false",
+                "saml.onetimeuse.condition": "false"
+            },
+            "fullScopeAllowed": true,
+            "nodeReRegistrationTimeout": -1,
+            "protocolMappers": [
+                {
+                    "name": "role list",
+                    "protocol": "saml",
+                    "protocolMapper": "saml-role-list-mapper",
+                    "consentRequired": false,
+                    "config": {
+                        "single": "false",
+                        "attribute.nameformat": "Basic",
+                        "attribute.name": "Role"
+                    }
+                },
+                {
+                    "name": "family name",
+                    "protocol": "openid-connect",
+                    "protocolMapper": "oidc-usermodel-property-mapper",
+                    "consentRequired": true,
+                    "consentText": "${familyName}",
+                    "config": {
+                        "userinfo.token.claim": "true",
+                        "user.attribute": "lastName",
+                        "id.token.claim": "true",
+                        "access.token.claim": "true",
+                        "claim.name": "family_name",
+                        "jsonType.label": "String"
+                    }
+                },
+                {
+                    "name": "full name",
+                    "protocol": "openid-connect",
+                    "protocolMapper": "oidc-full-name-mapper",
+                    "consentRequired": true,
+                    "consentText": "${fullName}",
+                    "config": {
+                        "id.token.claim": "true",
+                        "access.token.claim": "true",
+                        "userinfo.token.claim": "true"
+                    }
+                },
+                {
+                    "name": "username",
+                    "protocol": "openid-connect",
+                    "protocolMapper": "oidc-usermodel-property-mapper",
+                    "consentRequired": true,
+                    "consentText": "${username}",
+                    "config": {
+                        "userinfo.token.claim": "true",
+                        "user.attribute": "username",
+                        "id.token.claim": "true",
+                        "access.token.claim": "true",
+                        "claim.name": "preferred_username",
+                        "jsonType.label": "String"
+                    }
+                },
+                {
+                    "name": "email",
+                    "protocol": "openid-connect",
+                    "protocolMapper": "oidc-usermodel-property-mapper",
+                    "consentRequired": true,
+                    "consentText": "${email}",
+                    "config": {
+                        "userinfo.token.claim": "true",
+                        "user.attribute": "email",
+                        "id.token.claim": "true",
+                        "access.token.claim": "true",
+                        "claim.name": "email",
+                        "jsonType.label": "String"
+                    }
+                },
+                {
+                    "name": "given name",
+                    "protocol": "openid-connect",
+                    "protocolMapper": "oidc-usermodel-property-mapper",
+                    "consentRequired": true,
+                    "consentText": "${givenName}",
+                    "config": {
+                        "userinfo.token.claim": "true",
+                        "user.attribute": "firstName",
+                        "id.token.claim": "true",
+                        "access.token.claim": "true",
+                        "claim.name": "given_name",
+                        "jsonType.label": "String"
+                    }
+                }
+            ],
+            "useTemplateConfig": false,
+            "useTemplateScope": false,
+            "useTemplateMappers": false,
+            "access": {
+                "view": true,
+                "configure": true,
+                "manage": true
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/ansible/roles/sunbird-auth-deploy/templates/keycloak-bootstrap.conf.j2 b/ansible/roles/sunbird-auth-deploy/templates/keycloak-bootstrap.conf.j2
index 32b567707b26463c5e1d1d791a26033049a39772..0e400efb8266c3e73ef4e885e0ff6168ab71c488 100644
--- a/ansible/roles/sunbird-auth-deploy/templates/keycloak-bootstrap.conf.j2
+++ b/ansible/roles/sunbird-auth-deploy/templates/keycloak-bootstrap.conf.j2
@@ -9,5 +9,6 @@
     "keycloak_api_management_user_email": "{{ keycloak_api_management_user_email }}",
     "keycloak_api_management_user_first_name": "{{ keycloak_api_management_user_first_name }}",
     "keycloak_api_management_user_last_name": "{{ keycloak_api_management_user_last_name }}",
-    "keycloak_api_management_user_password": "{{ keycloak_api_management_user_password }}"
+    "keycloak_api_management_user_password": "{{ keycloak_api_management_user_password }}",
+    "keycloak_clients": "/tmp/clients.json"
 }
diff --git a/ansible/static-files/health.sh b/ansible/static-files/health.sh
index 932a9a02f834daac045071ef182e9be4978fa0ec..575fd669e270382be9f1da100e8e44960244567d 100755
--- a/ansible/static-files/health.sh
+++ b/ansible/static-files/health.sh
@@ -7,6 +7,7 @@
 outpt1=$(curl -s content-service:5000/health | jq '.result.healthy')
 outpt2=$(curl -s player_player:3000/health| jq '.result.healthy')
 outpt3=$(curl -s learner-service:9000/health | jq '.result.response.checks[0].healthy')
+outpt4=$(curl -s lms-service:9005/health | jq '.result.response.checks[0].healthy')
 echo ""
 echo ""
 if [ "$outpt1" == "true" ];then
@@ -32,3 +33,12 @@ if [ "$outpt3" == "true" ];then
 else
         echo "Learner Service is unhealthy"
 fi
+
+echo ""
+echo ""
+
+if [ "$outpt4" == "true" ];then
+        echo "Lms Service is Healthy"
+else
+        echo "Lms Service is unhealthy"
+fi
diff --git a/ansible/sunbird-auth-deploy.yml b/ansible/sunbird-auth-deploy.yml
index b37ad6970c3b39b3828854d68580e3a7a3e40dec..f6d34635697fe56ac025bcf70cc77136d698a517 100644
--- a/ansible/sunbird-auth-deploy.yml
+++ b/ansible/sunbird-auth-deploy.yml
@@ -1,5 +1,5 @@
 ---
-- hosts: keycloak
+- hosts: "{{host}}"
   become: true
   vars_files:
     - ['{{inventory_dir}}/secrets.yml', 'secrets/{{env}}.yml']
diff --git a/deploy/gitOPS/README.md b/deploy/gitOPS/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..65e8cdf33dcb97c528e60ae565895a68edbc944c
--- /dev/null
+++ b/deploy/gitOPS/README.md
@@ -0,0 +1,10 @@
+# Using scripts:
+
+- All the scripts are using the github api's.
+- All the scripts will take github.csv file as input and read each line to get the values of all variables
+- First udpate github.csv file row wise and run the scripts
+- In github.csv there are 4 variables with comma seperated 
+
+     REPO_NAME,BRANCH_NAME,MERGE_ACCESS_USERS(;),CHECKS
+     
+     MERGE_ACCESS_USERS and CHECKS: These variables are required only by disableBranchProtection.sh script.
diff --git a/deploy/gitOPS/deleteBranches.sh b/deploy/gitOPS/deleteBranches.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b635d0388683ab2beb19f3ae64ac8b4acc013518
--- /dev/null
+++ b/deploy/gitOPS/deleteBranches.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+read -p "Enter Github Username: " user
+read -sp "Enter Github Password: " pass
+echo " "
+IFS=','
+grep -v -e '#' -e "^$" github.csv | while read -ra LINE
+do
+   repo_name="${LINE[0]}"
+   branch_name="${LINE[1]}"
+   echo "----------------------------------------------------"
+   echo -e '\033[0;32m'$repo_name' '$branch_name'\033[0m'
+   echo "----------------------------------------------------"
+   curl -u $user:$pass -XDELETE https://api.github.com/repos/project-sunbird/$repo_name/git/refs/heads/$branch_name
+done
diff --git a/deploy/gitOPS/disableBranchProtection.sh b/deploy/gitOPS/disableBranchProtection.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1e4e040281f708cb64118693b66c3bb0cd71da29
--- /dev/null
+++ b/deploy/gitOPS/disableBranchProtection.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+read -p "Enter Github Username: " user
+read -sp "Enter Github Password: " pass
+echo " "   
+IFS=','
+grep -v -e '#' -e "^$" github.csv | while read -ra LINE
+do
+   repo_name="${LINE[0]}"
+   branch_name="${LINE[1]}"
+   echo "----------------------------------------------------"
+   echo -e '\033[0;32m'$repo_name' '$branch_name'\033[0m'
+   echo "----------------------------------------------------"
+   curl -u $user:$pass -XDELETE \
+      -H "Accept: application/vnd.github.loki-preview+json" \
+      -d '{
+      "protection": {
+        "enabled": null
+      },
+        "restrictions": null,
+        "required_status_checks": null,
+        "enforce_admins": null,
+        "required_pull_request_reviews": null
+    }' "https://api.github.com/repos/project-sunbird/$repo_name/branches/$branch_name/protection"
+done
diff --git a/deploy/gitOPS/enableBranchProtection.sh b/deploy/gitOPS/enableBranchProtection.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1eda8d728bc3b657258d7c63a1ca342fe08c0d2b
--- /dev/null
+++ b/deploy/gitOPS/enableBranchProtection.sh
@@ -0,0 +1,62 @@
+#!/bin/bash -xv
+read -p "Enter the github username: " user
+read -sp "Enter the password: " pass
+echo " "
+statusChecks=0
+IFS=','
+#read input from a file
+grep -v -e '#' -e "^$" github.csv | while read -ra LINE
+do
+   repo_name="${LINE[0]}"
+   branch_name="${LINE[1]}"
+   users="${LINE[2]}"
+   check="${LINE[3]}"
+unset IFS
+Users=\"$users\"
+githubUsers=$(echo $Users | sed 's/;/\",\"/g')
+echo "------------------------------------------------------------------"
+echo -e '\033[0;32m'$repo_name $branch_name $githubUsers $check'\033[0m'
+echo "------------------------------------------------------------------"
+IFS=','
+if [[ $check == "1" ]]; then
+        statusChecks='"Codacy/PR Quality Review"'
+elif [[ $check == "2" ]]; then
+        statusChecks='"ci/circleci: build"'
+elif [[ $check == "3" ]]; then
+        statusChecks='"Codacy/PR Quality Review",
+                      "ci/circleci: build"'
+else
+        echo "Provide correct value!"
+fi
+
+curl -u $user:$pass -XPUT \
+     -H 'Accept: application/vnd.github.luke-cage-preview+json' \
+     -d '{
+      "protection": {
+        "enabled": true
+      },
+
+      "enforce_admins": true,
+      "required_pull_request_reviews": {
+          "dismiss_stale_reviews": true,
+          "require_code_owner_reviews": false,
+          "required_approving_review_count": 1
+      },
+
+      "required_status_checks": {
+          "strict": true,
+            "contexts": [
+              '"$statusChecks"'
+            ]
+      },
+      
+      "restrictions": {
+          "users": [
+            '"$githubUsers"'
+          ],
+          "teams": [
+            "null"
+          ]
+      }
+    }' "https://api.github.com/repos/project-sunbird/$repo_name/branches/$branch_name/protection"
+done
diff --git a/deploy/gitOPS/enableBranchProtection.sh_bak b/deploy/gitOPS/enableBranchProtection.sh_bak
new file mode 100644
index 0000000000000000000000000000000000000000..4073fea0742c17c4668c14e3940cacc5fe668669
--- /dev/null
+++ b/deploy/gitOPS/enableBranchProtection.sh_bak
@@ -0,0 +1,57 @@
+#!/bin/bash
+read -p "Enter the username: " user
+read -sp "Enter the password:" pass
+echo " "
+read -p "Enter the repo name:" repo_name
+read -p "Enter the branch name:" branch_name
+echo -e "status check: \n 1. codacy \n 2. circleci \n 3. both"
+read -p "enter number:" check
+check=${check:-3}
+statusChecks=0
+read -p "enter username for merge access:" users
+Users=\"$users\"
+githubUsers=$(echo $Users | sed 's/,/\",\"/g')
+
+if [[ $check == "1" ]]; then
+        statusChecks='"Codacy/PR Quality Review"'
+elif [[ $check == "2" ]]; then
+	statusChecks='"ci/circleci: build"'
+elif [[ $check == "3" ]]; then
+	statusChecks='"Codacy/PR Quality Review",
+                      "ci/circleci: build"'
+else
+	echo "Select correct option!"
+fi
+echo $statusChecks
+echo $githubUsers
+
+curl -u $user:$pass -XPUT \
+     -H 'Accept: application/vnd.github.luke-cage-preview+json' \
+     -d '{
+      "protection": {
+        "enabled": true
+      },
+
+      "enforce_admins": true,
+      "required_pull_request_reviews": {
+          "dismiss_stale_reviews": true,
+          "require_code_owner_reviews": false,
+          "required_approving_review_count": 1
+      },
+
+      "required_status_checks": {
+          "strict": true,
+            "contexts": [
+              '"$statusChecks"'
+            ]
+      },
+      
+      "restrictions": {
+          "users": [
+            '"$githubUsers"'
+          ],
+          "teams": [
+            "null"
+          ]
+      }
+    }' "https://api.github.com/repos/project-sunbird/$repo_name/branches/$branch_name/protection"
diff --git a/deploy/gitOPS/getBranchProtection.sh b/deploy/gitOPS/getBranchProtection.sh
new file mode 100644
index 0000000000000000000000000000000000000000..a9f0c206bb7a9a10dbc6750fcc409a5cf181c924
--- /dev/null
+++ b/deploy/gitOPS/getBranchProtection.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+read -p "Enter Github Username: " user
+read -sp "Enter Github Password: " pass
+echo " "
+IFS=','
+grep -v -e '#' -e "^$" github.csv | while read -ra LINE
+do
+   repo_name="${LINE[0]}"
+   branch_name="${LINE[1]}"
+   echo "----------------------------------------------------"
+   echo -e '\033[0;32m'$repo_name' '$branch_name'\033[0m'
+   echo "----------------------------------------------------"
+   curl -u $user:$pass -XGET https://api.github.com/repos/project-sunbird/$repo_name/branches/$branch_name/protection
+done
diff --git a/deploy/gitOPS/getBranches.sh b/deploy/gitOPS/getBranches.sh
new file mode 100644
index 0000000000000000000000000000000000000000..caffb6a1a4482ef1beecff588ff46c7d5729360f
--- /dev/null
+++ b/deploy/gitOPS/getBranches.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+read -p "Enter Github Username: " user
+read -sp "Enter Github Password: " pass
+echo " "
+IFS=','
+grep -v -e '#' -e "^$" github.csv | while read -ra LINE
+do
+   repo_name="${LINE[0]}"
+   echo "----------------------------------------------------"
+   echo -e '\033[0;32m'$repo_name'\033[0m'
+   echo "----------------------------------------------------"
+   curl -u $user:$pass -s -N https://api.github.com/repos/project-sunbird/$repo_name/branches | jq '.[].name' -r
+done
diff --git a/deploy/gitOPS/getRepos.sh b/deploy/gitOPS/getRepos.sh
new file mode 100644
index 0000000000000000000000000000000000000000..509400d7d6d763f0b20cec9c9054b3d9213591d9
--- /dev/null
+++ b/deploy/gitOPS/getRepos.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+read -p "Enter Github Username: " user
+read -sp "Enter Github Password: " pass
+echo " "
+read -p "Enter Github Account Name: " acc_name
+echo "---------------------------------------------"
+echo -e '\033[0;32m'$acc_name'\033[0m'
+echo "---------------------------------------------"
+curl -s -N https://api.github.com/users/$acc_name/repos\?per_page=100 | jq '.[].name' -r
diff --git a/deploy/gitOPS/github.csv b/deploy/gitOPS/github.csv
new file mode 100644
index 0000000000000000000000000000000000000000..64bf495ac6bda48ed71b3d6163cecaaa9fe8f2b8
--- /dev/null
+++ b/deploy/gitOPS/github.csv
@@ -0,0 +1,13 @@
+#REPO_NAME,BRANCH_NAME,MERGE_ACCESS_USERS(;),CHECKS
+sunbird-lms-service,jenkins-test,harshavardhanc;abcb,3
+
+
+
+
+
+
+
+
+#NOTE:
+#MERGE_ACCESS_USERS SHOULD BE (;) seperated
+#CHECKS: 1.codacy 2.cirleci 3.both
diff --git a/deploy/jenkins/jenkins-server-setup.sh b/deploy/jenkins/jenkins-server-setup.sh
index c7dd7d61ac9eb69b6a5351bb865fef7249c1b206..fd10cc99254012c2ebb07509e33775eba08590ef 100755
--- a/deploy/jenkins/jenkins-server-setup.sh
+++ b/deploy/jenkins/jenkins-server-setup.sh
@@ -81,5 +81,6 @@ usermod -aG docker jenkins
 
 echo -e "\n\e[0;32m${bold}Creating bashrc for jenkins user ${normal}"
 cp /etc/skel/.bashrc /var/lib/jenkins
+chown jenkins:jenkins /var/lib/jenkins/.bashrc
 
 echo -e "\n\e[0;32m${bold}Installation complete. Please go to your jenkins URL and continue setup if this first run..${normal}"
diff --git a/deploy/jenkins/jobs/Deploy/jobs/dev/jobs/Core/jobs/Keycloak/config.xml b/deploy/jenkins/jobs/Deploy/jobs/dev/jobs/Core/jobs/Keycloak/config.xml
index 5e532b85d9e8b1b6ed1dc2a2f59dd965340e028f..13e49b2c4021ba42d6ce691377b3d439a8f13ce4 100644
--- a/deploy/jenkins/jobs/Deploy/jobs/dev/jobs/Core/jobs/Keycloak/config.xml
+++ b/deploy/jenkins/jobs/Deploy/jobs/dev/jobs/Core/jobs/Keycloak/config.xml
@@ -1,5 +1,5 @@
 <?xml version='1.1' encoding='UTF-8'?>
-<flow-definition plugin="workflow-job@2.31">
+<flow-definition plugin="workflow-job@2.32">
   <actions/>
   <description></description>
   <keepDependencies>false</keepDependencies>
@@ -13,7 +13,7 @@
       </strategy>
     </jenkins.model.BuildDiscarderProperty>
     <org.jenkinsci.plugins.workflow.job.properties.DisableConcurrentBuildsJobProperty/>
-    <com.sonyericsson.rebuild.RebuildSettings plugin="rebuild@1.29">
+    <com.sonyericsson.rebuild.RebuildSettings plugin="rebuild@1.30">
       <autoRebuild>false</autoRebuild>
       <rebuildDisabled>false</rebuildDisabled>
     </com.sonyericsson.rebuild.RebuildSettings>
@@ -32,14 +32,14 @@ ArtifactRepo - Download the artifact from azure blob, JenkinsJob - Use the atrif
           <randomName>choice-parameter-9600649228560</randomName>
           <visibleItemCount>1</visibleItemCount>
           <script class="org.biouno.unochoice.model.GroovyScript">
-            <secureScript plugin="script-security@1.53">
+            <secureScript plugin="script-security@1.58">
               <script>return[
 &apos;JenkinsJob&apos;,
 &apos;ArtifactRepo&apos;
 ]</script>
               <sandbox>false</sandbox>
             </secureScript>
-            <secureFallbackScript plugin="script-security@1.53">
+            <secureFallbackScript plugin="script-security@1.58">
               <script></script>
               <sandbox>false</sandbox>
             </secureFallbackScript>
@@ -57,7 +57,7 @@ ArtifactRepo - Download the artifact from azure blob, JenkinsJob - Use the atrif
           <randomName>choice-parameter-9600651313765</randomName>
           <visibleItemCount>1</visibleItemCount>
           <script class="org.biouno.unochoice.model.GroovyScript">
-            <secureScript plugin="script-security@1.53">
+            <secureScript plugin="script-security@1.58">
               <script>if (artifact_source.equals(&quot;JenkinsJob&quot;)) {
 return &quot;&quot;&quot;&lt;input name=&quot;value&quot; value=&quot;lastSuccessfulBuild&quot; class=&quot;setting-input&quot;  type=&quot;text&quot;&gt;&lt;br&gt; &lt;font color=darkgreen size=2&gt;&lt;b&gt;OPTIONAL: Specify the build number of ArtifactUpload job from which the artifact will be copied and deployed.&lt;/b&gt;&lt;/font&gt;&quot;&quot;&quot;
 }
@@ -67,7 +67,7 @@ return &quot;&lt;b&gt;Not Applicable&lt;/b&gt;&quot;
 }</script>
               <sandbox>false</sandbox>
             </secureScript>
-            <secureFallbackScript plugin="script-security@1.53">
+            <secureFallbackScript plugin="script-security@1.58">
               <script></script>
               <sandbox>false</sandbox>
             </secureFallbackScript>
@@ -84,7 +84,7 @@ return &quot;&lt;b&gt;Not Applicable&lt;/b&gt;&quot;
           <randomName>choice-parameter-9600653373369</randomName>
           <visibleItemCount>1</visibleItemCount>
           <script class="org.biouno.unochoice.model.GroovyScript">
-            <secureScript plugin="script-security@1.53">
+            <secureScript plugin="script-security@1.58">
               <script>if (artifact_source.equals(&quot;ArtifactRepo&quot;)) {
 return &quot;&quot;&quot;&lt;input name=&quot;value&quot; value=&quot;&quot; class=&quot;setting-input&quot;  type=&quot;text&quot;&gt; &lt;br&gt; &lt;font color=red size=2&gt;&lt;b&gt;CAUTION: If the value is blank, artifact version will be taken from the latest metadata.json.&lt;/b&gt;&lt;/font&gt;&quot;&quot;&quot;
 } 
@@ -93,7 +93,7 @@ return &quot;&lt;b&gt;Not Applicable&lt;/b&gt;&quot;
 }</script>
               <sandbox>false</sandbox>
             </secureScript>
-            <secureFallbackScript plugin="script-security@1.53">
+            <secureFallbackScript plugin="script-security@1.58">
               <script></script>
               <sandbox>false</sandbox>
             </secureFallbackScript>
@@ -110,7 +110,7 @@ return &quot;&lt;b&gt;Not Applicable&lt;/b&gt;&quot;
           <randomName>choice-parameter-2544395024638227</randomName>
           <visibleItemCount>1</visibleItemCount>
           <script class="org.biouno.unochoice.model.GroovyScript">
-            <secureScript plugin="script-security@1.53">
+            <secureScript plugin="script-security@1.58">
               <script>if (override_private_branch.equals(&quot;true&quot;)) {
 return &quot;&quot;&quot;&lt;input name=&quot;value&quot; value=&quot;${private_repo_branch}&quot; class=&quot;setting-input&quot;  type=&quot;text&quot;&gt;&lt;br&gt; &lt;font color=dimgray size=2&gt;&lt;b&gt;Change this value to checkout a different branch from private repository.&lt;/b&gt;&lt;/font&gt;&quot;&quot;&quot;
 }
@@ -118,7 +118,7 @@ else
 return &quot;&quot;&quot;&lt;b&gt;This parameter is not used&lt;/b&gt;&quot;&quot;&quot;</script>
               <sandbox>false</sandbox>
             </secureScript>
-            <secureFallbackScript plugin="script-security@1.53">
+            <secureFallbackScript plugin="script-security@1.58">
               <script>return &quot;&quot;&quot;&lt;b&gt;This parameter is not used&lt;/b&gt;&quot;&quot;&quot;</script>
               <sandbox>false</sandbox>
             </secureFallbackScript>
@@ -135,7 +135,7 @@ return &quot;&quot;&quot;&lt;b&gt;This parameter is not used&lt;/b&gt;&quot;&quo
           <randomName>choice-parameter-2620434998790477</randomName>
           <visibleItemCount>1</visibleItemCount>
           <script class="org.biouno.unochoice.model.GroovyScript">
-            <secureScript plugin="script-security@1.53">
+            <secureScript plugin="script-security@1.58">
               <script>if (override_public_branch.equals(&quot;true&quot;)) {
 return &quot;&quot;&quot;&lt;input name=&quot;value&quot; value=&quot;&quot; class=&quot;setting-input&quot;  type=&quot;text&quot;&gt;&lt;br&gt; &lt;font color=dimgray size=2&gt;&lt;b&gt;Provide the tag or branch name to checkout the Jenkinsfile and codebase.&lt;br&gt;Note: The tag or branch name for this job should be taken from &lt;a href=&quot;https://github.com/project-sunbird/sunbird-devops&quot;&gt;project-sunbird/sunbird-devops&lt;/a&gt;&lt;/b&gt;&lt;/font&gt;&lt;/b&gt;&lt;/font&gt;&quot;&quot;&quot;;
 
@@ -144,7 +144,7 @@ else
 return &quot;&quot;&quot;&lt;b&gt;This parameter is not used&lt;/b&gt;&quot;&quot;&quot;</script>
               <sandbox>false</sandbox>
             </secureScript>
-            <secureFallbackScript plugin="script-security@1.53">
+            <secureFallbackScript plugin="script-security@1.58">
               <script>return &quot;&quot;&quot;&lt;b&gt;This parameter is not used&lt;/b&gt;&quot;&quot;&quot;</script>
               <sandbox>false</sandbox>
             </secureFallbackScript>
@@ -155,6 +155,12 @@ return &quot;&quot;&quot;&lt;b&gt;This parameter is not used&lt;/b&gt;&quot;&quo
           <choiceType>ET_FORMATTED_HTML</choiceType>
           <omitValueField>true</omitValueField>
         </org.biouno.unochoice.DynamicReferenceParameter>
+        <hudson.model.StringParameterDefinition>
+          <name>sunbird_auth_branch_or_tag</name>
+          <description>&lt;font color=dimgray size=2&gt;&lt;b&gt;Provide the branch or tag of sunbird auth repo.&lt;/b&gt;&lt;/font&gt;</description>
+          <defaultValue></defaultValue>
+          <trim>false</trim>
+        </hudson.model.StringParameterDefinition>
       </parameterDefinitions>
     </hudson.model.ParametersDefinitionProperty>
     <hudson.plugins.throttleconcurrents.ThrottleJobProperty plugin="throttle-concurrents@2.0.1">
@@ -181,7 +187,7 @@ return &quot;&quot;&quot;&lt;b&gt;This parameter is not used&lt;/b&gt;&quot;&quo
       </triggers>
     </org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
   </properties>
-  <definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition" plugin="workflow-cps@2.63">
+  <definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition" plugin="workflow-cps@2.67">
     <scm class="hudson.plugins.git.GitSCM" plugin="git@3.9.3">
       <configVersion>2</configVersion>
       <userRemoteConfigs>
diff --git a/deploy/utilities/getEsData.sh b/deploy/utilities/getEsData.sh
new file mode 100644
index 0000000000000000000000000000000000000000..48041b2849258708194f5c8cbb45c5dc94c9b0fd
--- /dev/null
+++ b/deploy/utilities/getEsData.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+####################################################
+#  Author S M Y ALTAMASH <smy.altamash@gmail.com>  #
+# Script gets the Latest Logs of proxy from Log-es #
+####################################################
+# NOTE: Have jq installed before running this script
+for index in $(curl -s localhost:9200/_cat/indices | grep -v kibana | awk '{print $3}' | tr "\n" " ");
+do
+        echo "Index:$index"
+        # Get the Total Hits for the Proxy Container
+        hits=$(curl -s -X GET "http://localhost:9200/$index/_search?pretty" -H 'Content-Type: application/json' -d'{"query":{"match":{"program":"proxy_proxy*"}}}' | jq '.hits.total')
+
+        # Increase the query size
+        curl -XPUT "http://localhost:9200/$index/_settings" -d "{ \"index\" : { \"max_result_window\" : \"$hits\" } }" -H "Content-Type: application/json"
+
+        # Save the Logs in the file
+        curl -s -X GET "http://localhost:9200/$index/_search?size=$hits" -H 'Content-Type: application/json' -d'{"query":{"match":{"program":"proxy_proxy*"}}}' > $index.json
+        echo "################################"
+done
+
diff --git a/images/proxy/Dockerfile b/images/proxy/Dockerfile
index 0896451336941b3dff597eef72139ad574683f5b..7bdb2cae33dcb635e8d12409fdd23e3b19d54dfc 100644
--- a/images/proxy/Dockerfile
+++ b/images/proxy/Dockerfile
@@ -1,5 +1,163 @@
-FROM nginx:1.13.8-alpine
+FROM alpine:3.9
 
-RUN rm -rf /etc/nginx/conf.d
+LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
 
-RUN rm -rf /usr/share/nginx/html
+ENV NGINX_VERSION 1.15.8
+
+ENV LUAJIT_LIB=/usr/local/lib
+ENV LUAJIT_INC=/usr/local/include/luajit-2.1
+
+COPY nginx_devel_kit /opt/nginx_devel_kit
+COPY luajit /usr/src/luajit
+COPY nginx_lua /opt/nginx_lua
+
+RUN GPG_KEYS=B0F4253373F8F6F510D42178520A9993A1C052F8 \
+    && CONFIG="\
+        --prefix=/etc/nginx \
+        --sbin-path=/usr/sbin/nginx \
+        --modules-path=/usr/lib/nginx/modules \
+        --with-ld-opt='-Wl,-rpath,/usr/local/lib' \
+        --add-module=/opt/nginx_devel_kit \
+        --add-module=/opt/nginx_lua \
+        --conf-path=/etc/nginx/nginx.conf \
+        --error-log-path=/var/log/nginx/error.log \
+        --http-log-path=/var/log/nginx/access.log \
+        --pid-path=/var/run/nginx.pid \
+        --lock-path=/var/run/nginx.lock \
+        --http-client-body-temp-path=/var/cache/nginx/client_temp \
+        --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
+        --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
+        --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
+        --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
+        --user=nginx \
+        --group=nginx \
+        --with-http_ssl_module \
+        --with-http_realip_module \
+        --with-http_addition_module \
+        --with-http_sub_module \
+        --with-http_dav_module \
+        --with-http_flv_module \
+        --with-http_mp4_module \
+        --with-http_gunzip_module \
+        --with-http_gzip_static_module \
+        --with-http_random_index_module \
+        --with-http_secure_link_module \
+        --with-http_stub_status_module \
+        --with-http_auth_request_module \
+        --with-http_xslt_module=dynamic \
+        --with-http_image_filter_module=dynamic \
+        --with-http_geoip_module=dynamic \
+        --with-threads \
+        --with-stream \
+        --with-stream_ssl_module \
+        --with-stream_ssl_preread_module \
+        --with-stream_realip_module \
+        --with-stream_geoip_module=dynamic \
+        --with-http_slice_module \
+        --with-mail \
+        --with-mail_ssl_module \
+        --with-compat \
+        --with-file-aio \
+        --with-http_v2_module " \
+    && addgroup -S nginx \
+    && adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx nginx \
+    && apk add --no-cache libgcc \
+    && apk add --no-cache --virtual .build-deps \
+        gcc \
+        libc-dev \
+        make \
+        openssl-dev \
+        pcre-dev \
+        zlib-dev \
+        linux-headers \
+        curl \
+        gnupg1 \
+        libxslt-dev \
+        gd-dev \
+        geoip-dev \
+    && curl -fSL https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz -o nginx.tar.gz \
+    && curl -fSL https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz.asc  -o nginx.tar.gz.asc \
+    && export GNUPGHOME="$(mktemp -d)" \
+    && found=''; \
+    for server in \
+        ha.pool.sks-keyservers.net \
+        hkp://keyserver.ubuntu.com:80 \
+        hkp://p80.pool.sks-keyservers.net:80 \
+        pgp.mit.edu \
+    ; do \
+        echo "Fetching GPG key $GPG_KEYS from $server"; \
+        gpg --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$GPG_KEYS" && found=yes && break; \
+    done; \
+    test -z "$found" && echo >&2 "error: failed to fetch GPG key $GPG_KEYS" && exit 1; \
+    gpg --batch --verify nginx.tar.gz.asc nginx.tar.gz \
+    && rm -rf "$GNUPGHOME" nginx.tar.gz.asc \
+    && mkdir -p /usr/src \
+    && tar -zxC /usr/src -f nginx.tar.gz \
+    && rm nginx.tar.gz \
+    && cd /usr/src/luajit \
+    && export LUAJIT_LIB=/usr/local/lib \
+    && export LUAJIT_INC=/usr/local/include/luajit-2.1 \
+    && cd /usr/src/luajit \
+    && make -j$(getconf _NPROCESSORS_ONLN) \
+    && make install \
+    && ls /usr/local/lib /usr/local/include/luajit-2.1 \
+    && cd /usr/src/nginx-$NGINX_VERSION \
+    && ./configure $CONFIG --with-debug \
+    && make -j$(getconf _NPROCESSORS_ONLN) \
+    && mv objs/nginx objs/nginx-debug \
+    && mv objs/ngx_http_xslt_filter_module.so objs/ngx_http_xslt_filter_module-debug.so \
+    && mv objs/ngx_http_image_filter_module.so objs/ngx_http_image_filter_module-debug.so \
+    && mv objs/ngx_http_geoip_module.so objs/ngx_http_geoip_module-debug.so \
+    && mv objs/ngx_stream_geoip_module.so objs/ngx_stream_geoip_module-debug.so \
+    && ./configure $CONFIG \
+    && make -j$(getconf _NPROCESSORS_ONLN) \
+    && make install \
+    && rm -rf /etc/nginx/html/ \
+    && mkdir /etc/nginx/conf.d/ \
+    && mkdir -p /usr/share/nginx/html/ \
+    && install -m644 html/index.html /usr/share/nginx/html/ \
+    && install -m644 html/50x.html /usr/share/nginx/html/ \
+    && install -m755 objs/nginx-debug /usr/sbin/nginx-debug \
+    && install -m755 objs/ngx_http_xslt_filter_module-debug.so /usr/lib/nginx/modules/ngx_http_xslt_filter_module-debug.so \
+    && install -m755 objs/ngx_http_image_filter_module-debug.so /usr/lib/nginx/modules/ngx_http_image_filter_module-debug.so \
+    && install -m755 objs/ngx_http_geoip_module-debug.so /usr/lib/nginx/modules/ngx_http_geoip_module-debug.so \
+    && install -m755 objs/ngx_stream_geoip_module-debug.so /usr/lib/nginx/modules/ngx_stream_geoip_module-debug.so \
+    && ln -s ../../usr/lib/nginx/modules /etc/nginx/modules \
+    && strip /usr/sbin/nginx* \
+    && strip /usr/lib/nginx/modules/*.so \
+    && rm -rf /usr/src/nginx-$NGINX_VERSION \
+    \
+    # Bring in gettext so we can get `envsubst`, then throw
+    # the rest away. To do this, we need to install `gettext`
+    # then move `envsubst` out of the way so `gettext` can
+    # be deleted completely, then move `envsubst` back.
+    && apk add --no-cache --virtual .gettext gettext \
+    && mv /usr/bin/envsubst /tmp/ \
+    \
+    && runDeps="$( \
+        scanelf --needed --nobanner --format '%n#p' /usr/sbin/nginx /usr/lib/nginx/modules/*.so /tmp/envsubst \
+            | tr ',' '\n' \
+            | sort -u \
+            | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
+    )" \
+    && apk add --no-cache --virtual .nginx-rundeps $runDeps \
+    && apk del .build-deps \
+    && apk del .gettext \
+    && mv /tmp/envsubst /usr/local/bin/ \
+    \
+    # Bring in tzdata so users could set the timezones through the environment
+    # variables
+    && apk add --no-cache tzdata \
+    \
+    # forward request and error logs to docker log collector
+    && ln -sf /dev/stdout /var/log/nginx/access.log \
+    && ln -sf /dev/stderr /var/log/nginx/error.log
+
+COPY nginx.conf /etc/nginx/nginx.conf
+copy prometheus.lua /etc/nginx/lua_modules/
+
+EXPOSE 80
+
+STOPSIGNAL SIGTERM
+
+CMD ["nginx", "-g", "daemon off;"]
diff --git a/images/proxy/Jenkinsfile b/images/proxy/Jenkinsfile
index e00c08357f3bb19e327405bbb143be5376d129c5..1d80a01f5d887e65f43b50f2217c1bc11141ebda 100644
--- a/images/proxy/Jenkinsfile
+++ b/images/proxy/Jenkinsfile
@@ -32,10 +32,10 @@ node('build-slave') {
             stage('Build') {
                 env.NODE_ENV = "build"
                 print "Environment will be : ${env.NODE_ENV}"
-                sh("./images/proxy/build.sh ${build_tag} ${env.NODE_NAME} ${hub_org}")
+                sh("cd ./images/proxy && ./build.sh ${build_tag} ${env.NODE_NAME} ${hub_org}")
             }
             stage('ArchiveArtifacts') {
-                archiveArtifacts "metadata.json"
+                archiveArtifacts "images/proxy/metadata.json"
                 currentBuild.description = "${build_tag}"
             }
         }
diff --git a/images/proxy/build.sh b/images/proxy/build.sh
index ebf64006ed41f04b25fe8ced503b18d2aafdc6a1..b7d6a3c9fa4aa4567c62dc00af1b02577a0e6ade 100755
--- a/images/proxy/build.sh
+++ b/images/proxy/build.sh
@@ -1,10 +1,24 @@
 #!/bin/bash
+
 # Build script
 set -eo pipefail
+
+# Downloading deps
+wget https://codeload.github.com/simplresty/ngx_devel_kit/tar.gz/v0.3.0 -O ngx_devel_kit_0_3_0.tar.gz
+wget https://codeload.github.com/openresty/luajit2/tar.gz/v2.1-20190626 -O luajit_2_1.tar.gz
+wget https://codeload.github.com/openresty/lua-nginx-module/tar.gz/v0.10.15 -O ngx_lua.tar.gz
+
+# Creating deps directory
+mkdir nginx_devel_kit luajit nginx_lua
+tar --strip-components=1 -xf ngx_devel_kit_0_3_0.tar.gz -C nginx_devel_kit
+tar --strip-components=1 -xf luajit_2_1.tar.gz -C luajit
+tar --strip-components=1 -xf ngx_lua.tar.gz -C nginx_lua
+
+# Creating nginx
 build_tag=$1
 name=proxy
 node=$2
 org=$3
 
-docker build -f ./images/proxy/Dockerfile -t ${org}/${name}:${build_tag} .
+docker build -t ${org}/${name}:${build_tag} .
 echo {\"image_name\" : \"${name}\", \"image_tag\" : \"${build_tag}\", \"node_name\" : \"$node\"} > metadata.json
diff --git a/images/proxy/nginx.conf b/images/proxy/nginx.conf
new file mode 100644
index 0000000000000000000000000000000000000000..dfdcc8d79971e83b6f322377e889a52d5447d80c
--- /dev/null
+++ b/images/proxy/nginx.conf
@@ -0,0 +1,70 @@
+user  nginx;
+worker_processes  1;
+load_module modules/ndk_http_module.so;
+load_module modules/ngx_http_lua_module.so;
+
+
+error_log  /var/log/nginx/error.log warn;
+pid        /var/run/nginx.pid;
+
+events {
+    worker_connections  1024;
+}
+
+
+http {
+    include       /etc/nginx/mime.types;
+    # Don't need complete openresty
+    lua_load_resty_core off;
+    default_type  application/octet-stream;
+
+    log_format  main  '$remote_addr - $remote_user [$time_local] '
+                      '"$request" $status $body_bytes_sent '
+                      '$request_time $upstream_response_time $pipe'
+                      '"$http_referer" "$http_user_agent"';
+
+    access_log  /var/log/nginx/access.log  main;
+
+    # Shared dictionary to store metrics
+    lua_shared_dict prometheus_metrics 10M;
+    lua_package_path "/etc/nginx/lua_modules/?.lua";
+    # Collecting metrics
+	init_by_lua '
+      prometheus = require("prometheus").init("prometheus_metrics")
+      metric_requests = prometheus:counter(
+        "nginx_http_requests_total", "Number of HTTP requests", {"host", "status", "request_method"})
+      metric_latency = prometheus:histogram(
+        "nginx_http_request_duration_seconds", "HTTP request latency", {"host"})
+      metric_connections = prometheus:gauge(
+        "nginx_http_connections", "Number of HTTP connections", {"state"})
+    ';
+
+    # Collecting metrics
+    log_by_lua '
+      metric_requests:inc(1, {ngx.var.server_name, ngx.var.status, ngx.var.request_method})
+      metric_latency:observe(tonumber(ngx.var.request_time), {ngx.var.server_name})
+    ';
+
+
+    sendfile        on;
+    #tcp_nopush     on;
+
+    keepalive_timeout  500s;
+    keepalive_requests 200;
+
+    #gzip  on;
+
+    include /etc/nginx/conf.d/*.conf;
+
+    server {
+      listen 9145;
+      location /metrics {
+        content_by_lua '
+          metric_connections:set(ngx.var.connections_reading, {"reading"})
+          metric_connections:set(ngx.var.connections_waiting, {"waiting"})
+          metric_connections:set(ngx.var.connections_writing, {"writing"})
+          prometheus:collect()
+        ';
+      }
+    }
+}
diff --git a/images/proxy/prometheus.lua b/images/proxy/prometheus.lua
new file mode 100644
index 0000000000000000000000000000000000000000..e627012f95be535f0ab841dd285cdd433ded8e99
--- /dev/null
+++ b/images/proxy/prometheus.lua
@@ -0,0 +1,570 @@
+-- vim: ts=2:sw=2:sts=2:expandtab
+--
+-- This module uses a single dictionary shared between Nginx workers to keep
+-- all metrics. Each counter is stored as a separate entry in that dictionary,
+-- which allows us to increment them using built-in `incr` method.
+--
+-- Prometheus requires that (a) all samples for a given metric are presented
+-- as one uninterrupted group, and (b) buckets of a histogram appear in
+-- increasing numerical order. We satisfy that by carefully constructing full
+-- metric names (i.e. metric name along with all labels) so that they meet
+-- those requirements while being sorted alphabetically. In particular:
+--
+--  * all labels for a given metric are presented in reproducible order (the one
+--    used when labels were declared). "le" label for histogram metrics always
+--    goes last;
+--  * bucket boundaries (which are exposed as values of the "le" label) are
+--    presented as floating point numbers with leading and trailing zeroes.
+--    Number of of zeroes is determined for each bucketer automatically based on
+--    bucket boundaries;
+--  * internally "+Inf" bucket is stored as "Inf" (to make it appear after
+--    all numeric buckets), and gets replaced by "+Inf" just before we
+--    expose the metrics.
+--
+-- For example, if you define your bucket boundaries as {0.00005, 10, 1000}
+-- then we will keep the following samples for a metric `m1` with label
+-- `site` set to `site1`:
+--
+--   m1_bucket{site="site1",le="0000.00005"}
+--   m1_bucket{site="site1",le="0010.00000"}
+--   m1_bucket{site="site1",le="1000.00000"}
+--   m1_bucket{site="site1",le="Inf"}
+--   m1_count{site="site1"}
+--   m1_sum{site="site1"}
+--
+-- "Inf" will be replaced by "+Inf" while publishing metrics.
+--
+-- You can find the latest version and documentation at
+-- https://github.com/knyar/nginx-lua-prometheus
+-- Released under MIT license.
+
+
+-- Default set of latency buckets, 5ms to 10s:
+local DEFAULT_BUCKETS = {0.005, 0.01, 0.02, 0.03, 0.05, 0.075, 0.1, 0.2, 0.3,
+                         0.4, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 10}
+
+-- Metric is a "parent class" for all metrics.
+local Metric = {}
+function Metric:new(o)
+  o = o or {}
+  setmetatable(o, self)
+  self.__index = self
+  return o
+end
+
+-- Checks that the right number of labels values have been passed.
+--
+-- Args:
+--   label_values: an array of label values.
+--
+-- Returns:
+--   an error message or nil
+function Metric:check_label_values(label_values)
+  if self.label_names == nil and label_values == nil then
+    return
+  elseif self.label_names == nil and label_values ~= nil then
+    return "Expected no labels for " .. self.name .. ", got " ..  #label_values
+  elseif label_values == nil and self.label_names ~= nil then
+    return "Expected " .. #self.label_names .. " labels for " ..
+           self.name .. ", got none"
+  elseif #self.label_names ~= #label_values then
+    return "Wrong number of labels for " .. self.name .. ". Expected " ..
+           #self.label_names .. ", got " .. #label_values
+  else
+    for i, k in ipairs(self.label_names) do
+      if label_values[i] == nil then
+        return "Unexpected nil value for label " .. k ..  " of " .. self.name
+      end
+    end
+  end
+end
+
+local Counter = Metric:new()
+-- Increase a given counter by `value`
+--
+-- Args:
+--   value: (number) a value to add to the counter. Defaults to 1 if skipped.
+--   label_values: an array of label values. Can be nil (i.e. not defined) for
+--     metrics that have no labels.
+function Counter:inc(value, label_values)
+  local err = self:check_label_values(label_values)
+  if err ~= nil then
+    self.prometheus:log_error(err)
+    return
+  end
+  if value ~= nil and value < 0 then
+    self.prometheus:log_error_kv(self.name, value, "Value should not be negative")
+    return
+  end
+
+  self.prometheus:inc(self.name, self.label_names, label_values, value or 1)
+end
+
+local Gauge = Metric:new()
+-- Set a given gauge to `value`
+--
+-- Args:
+--   value: (number) a value to set the gauge to. Should be defined.
+--   label_values: an array of label values. Can be nil (i.e. not defined) for
+--     metrics that have no labels.
+function Gauge:set(value, label_values)
+  if value == nil then
+    self.prometheus:log_error("No value passed for " .. self.name)
+    return
+  end
+  local err = self:check_label_values(label_values)
+  if err ~= nil then
+    self.prometheus:log_error(err)
+    return
+  end
+  self.prometheus:set(self.name, self.label_names, label_values, value)
+end
+
+
+-- Increase a given gauge by `value`
+--
+-- Args:
+--   value: (number) a value to add to the gauge (a negative value when you
+--     need to decrease the value of the gauge). Defaults to 1 if skipped.
+--   label_values: an array of label values. Can be nil (i.e. not defined) for
+--     metrics that have no labels.
+function Gauge:inc(value, label_values)
+  local err = self:check_label_values(label_values)
+  if err ~= nil then
+    self.prometheus:log_error(err)
+    return
+  end
+  self.prometheus:inc(self.name, self.label_names, label_values, value or 1)
+end
+
+local Histogram = Metric:new()
+-- Record a given value in a histogram.
+--
+-- Args:
+--   value: (number) a value to record. Should be defined.
+--   label_values: an array of label values. Can be nil (i.e. not defined) for
+--     metrics that have no labels.
+function Histogram:observe(value, label_values)
+  if value == nil then
+    self.prometheus:log_error("No value passed for " .. self.name)
+    return
+  end
+  local err = self:check_label_values(label_values)
+  if err ~= nil then
+    self.prometheus:log_error(err)
+    return
+  end
+  self.prometheus:histogram_observe(self.name, self.label_names, label_values, value)
+end
+
+local Prometheus = {}
+Prometheus.__index = Prometheus
+Prometheus.initialized = false
+
+-- Generate full metric name that includes all labels.
+--
+-- Args:
+--   name: string
+--   label_names: (array) a list of label keys.
+--   label_values: (array) a list of label values.
+-- Returns:
+--   (string) full metric name.
+local function full_metric_name(name, label_names, label_values)
+  if not label_names then
+    return name
+  end
+  local label_parts = {}
+  for idx, key in ipairs(label_names) do
+    local label_value = (string.format("%s", label_values[idx])
+      :gsub("[^\032-\126]", "")  -- strip non-printable characters
+      :gsub("\\", "\\\\")
+      :gsub('"', '\\"'))
+    table.insert(label_parts, key .. '="' .. label_value .. '"')
+  end
+  return name .. "{" .. table.concat(label_parts, ",") .. "}"
+end
+
+-- Construct bucket format for a list of buckets.
+--
+-- This receives a list of buckets and returns a sprintf template that should
+-- be used for bucket boundaries to make them come in increasing order when
+-- sorted alphabetically.
+--
+-- To re-phrase, this is where we detect how many leading and trailing zeros we
+-- need.
+--
+-- Args:
+--   buckets: a list of buckets
+--
+-- Returns:
+--   (string) a sprintf template.
+local function construct_bucket_format(buckets)
+  local max_order = 1
+  local max_precision = 1
+  for _, bucket in ipairs(buckets) do
+    assert(type(bucket) == "number", "bucket boundaries should be numeric")
+    -- floating point number with all trailing zeros removed
+    local as_string = string.format("%f", bucket):gsub("0*$", "")
+    local dot_idx = as_string:find(".", 1, true)
+    max_order = math.max(max_order, dot_idx - 1)
+    max_precision = math.max(max_precision, as_string:len() - dot_idx)
+  end
+  return "%0" .. (max_order + max_precision + 1) .. "." .. max_precision .. "f"
+end
+
+-- Extract short metric name from the full one.
+--
+-- Args:
+--   full_name: (string) full metric name that can include labels.
+--
+-- Returns:
+--   (string) short metric name with no labels. For a `*_bucket` metric of
+--     histogram the _bucket suffix will be removed.
+local function short_metric_name(full_name)
+  local labels_start, _ = full_name:find("{")
+  if not labels_start then
+    -- no labels
+    return full_name
+  end
+  local suffix_idx, _ = full_name:find("_bucket{")
+  if suffix_idx and full_name:find("le=") then
+    -- this is a histogram metric
+    return full_name:sub(1, suffix_idx - 1)
+  end
+  -- this is not a histogram metric
+  return full_name:sub(1, labels_start - 1)
+end
+
+-- Makes a shallow copy of a table
+local function copy_table(table)
+  local new = {}
+  if table ~= nil then
+    for k, v in ipairs(table) do
+      new[k] = v
+    end
+  end
+  return new
+end
+
+-- Check metric name and label names for correctness.
+--
+-- Regular expressions to validate metric and label names are
+-- documented in https://prometheus.io/docs/concepts/data_model/
+--
+-- Args:
+--   metric_name: (string) metric name.
+--   label_names: label names (array of strings).
+--
+-- Returns:
+--   Either an error string, or nil of no errors were found.
+local function check_metric_and_label_names(metric_name, label_names)
+  if not metric_name:match("^[a-zA-Z_:][a-zA-Z0-9_:]*$") then
+    return "Metric name '" .. metric_name .. "' is invalid"
+  end
+  for _, label_name in ipairs(label_names or {}) do
+    if label_name == "le" then
+      return "Invalid label name 'le' in " .. metric_name
+    end
+    if not label_name:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then
+      return "Metric '" .. metric_name .. "' label name '" .. label_name ..
+             "' is invalid"
+    end
+  end
+end
+
+-- Initialize the module.
+--
+-- This should be called once from the `init_by_lua` section in nginx
+-- configuration.
+--
+-- Args:
+--   dict_name: (string) name of the nginx shared dictionary which will be
+--     used to store all metrics
+--   prefix: (optional string) if supplied, prefix is added to all
+--   metric names on output
+--
+-- Returns:
+--   an object that should be used to register metrics.
+function Prometheus.init(dict_name, prefix)
+  local self = setmetatable({}, Prometheus)
+  dict_name = dict_name or "prometheus_metrics"
+  self.dict = ngx.shared[dict_name]
+  if self.dict == nil then
+    ngx.log(ngx.ERR,
+      "Dictionary '", dict_name, "' does not seem to exist. ",
+      "Please define the dictionary using `lua_shared_dict`.")
+    return self
+  end
+  self.help = {}
+  if prefix then
+    self.prefix = prefix
+  else
+    self.prefix = ''
+  end
+  self.type = {}
+  self.registered = {}
+  self.buckets = {}
+  self.bucket_format = {}
+  self.initialized = true
+
+  self:counter("nginx_metric_errors_total",
+    "Number of nginx-lua-prometheus errors")
+  self.dict:set("nginx_metric_errors_total", 0)
+  return self
+end
+
+function Prometheus:log_error(...)
+  ngx.log(ngx.ERR, ...)
+  self.dict:incr("nginx_metric_errors_total", 1)
+end
+
+function Prometheus:log_error_kv(key, value, err)
+  self:log_error(
+    "Error while setting '", key, "' to '", value, "': '", err, "'")
+end
+
+-- Register a counter.
+--
+-- Args:
+--   name: (string) name of the metric. Required.
+--   description: (string) description of the metric. Will be used for the HELP
+--     comment on the metrics page. Optional.
+--   label_names: array of strings, defining a list of metrics. Optional.
+--
+-- Returns:
+--   a Counter object.
+function Prometheus:counter(name, description, label_names)
+  if not self.initialized then
+    ngx.log(ngx.ERR, "Prometheus module has not been initialized")
+    return
+  end
+
+  local err = check_metric_and_label_names(name, label_names)
+  if err ~= nil then
+    self:log_error(err)
+    return
+  end
+
+  if self.registered[name] then
+    self:log_error("Duplicate metric " .. name)
+    return
+  end
+  self.registered[name] = true
+  self.help[name] = description
+  self.type[name] = "counter"
+
+  return Counter:new{name=name, label_names=label_names, prometheus=self}
+end
+
+-- Register a gauge.
+--
+-- Args:
+--   name: (string) name of the metric. Required.
+--   description: (string) description of the metric. Will be used for the HELP
+--     comment on the metrics page. Optional.
+--   label_names: array of strings, defining a list of metrics. Optional.
+--
+-- Returns:
+--   a Gauge object.
+function Prometheus:gauge(name, description, label_names)
+  if not self.initialized then
+    ngx.log(ngx.ERR, "Prometheus module has not been initialized")
+    return
+  end
+
+  local err = check_metric_and_label_names(name, label_names)
+  if err ~= nil then
+    self:log_error(err)
+    return
+  end
+
+  if self.registered[name] then
+    self:log_error("Duplicate metric " .. name)
+    return
+  end
+  self.registered[name] = true
+  self.help[name] = description
+  self.type[name] = "gauge"
+
+  return Gauge:new{name=name, label_names=label_names, prometheus=self}
+end
+
+
+-- Register a histogram.
+--
+-- Args:
+--   name: (string) name of the metric. Required.
+--   description: (string) description of the metric. Will be used for the HELP
+--     comment on the metrics page. Optional.
+--   label_names: array of strings, defining a list of metrics. Optional.
+--   buckets: array if numbers, defining bucket boundaries. Optional.
+--
+-- Returns:
+--   a Histogram object.
+function Prometheus:histogram(name, description, label_names, buckets)
+  if not self.initialized then
+    ngx.log(ngx.ERR, "Prometheus module has not been initialized")
+    return
+  end
+
+  local err = check_metric_and_label_names(name, label_names)
+  if err ~= nil then
+    self:log_error(err)
+    return
+  end
+
+  for _, suffix in ipairs({"", "_bucket", "_count", "_sum"}) do
+    if self.registered[name .. suffix] then
+      self:log_error("Duplicate metric " .. name .. suffix)
+      return
+    end
+    self.registered[name .. suffix] = true
+  end
+  self.help[name] = description
+  self.type[name] = "histogram"
+
+  self.buckets[name] = buckets or DEFAULT_BUCKETS
+  self.bucket_format[name] = construct_bucket_format(self.buckets[name])
+
+  return Histogram:new{name=name, label_names=label_names, prometheus=self}
+end
+
+-- Set a given dictionary key.
+-- This overwrites existing values, so it should only be used when initializing
+-- metrics or when explicitely overwriting the previous value of a metric.
+function Prometheus:set_key(key, value)
+  local ok, err = self.dict:safe_set(key, value)
+  if not ok then
+    self:log_error_kv(key, value, err)
+  end
+end
+
+-- Increment a given metric by `value`.
+--
+-- Args:
+--   name: (string) short metric name without any labels.
+--   label_names: (array) a list of label keys.
+--   label_values: (array) a list of label values.
+--   value: (number) value to add (a negative value when you need to decrease
+--     the value of the gauge). Optional, defaults to 1.
+function Prometheus:inc(name, label_names, label_values, value)
+  local key = full_metric_name(name, label_names, label_values)
+  if value == nil then value = 1 end
+
+  local newval, err = self.dict:incr(key, value)
+  if newval then
+    return
+  end
+  -- Yes, this looks like a race, so I guess we might under-report some values
+  -- when multiple workers simultaneously try to create the same metric.
+  -- Hopefully this does not happen too often (shared dictionary does not get
+  -- reset during configuation reload).
+  if err == "not found" then
+    self:set_key(key, value)
+    return
+  end
+  -- Unexpected error
+  self:log_error_kv(key, value, err)
+end
+
+-- Set the current value of a gauge to `value`
+--
+-- Args:
+--   name: (string) short metric name without any labels.
+--   label_names: (array) a list of label keys.
+--   label_values: (array) a list of label values.
+--   value: (number) the new value for the gauge.
+function Prometheus:set(name, label_names, label_values, value)
+  local key = full_metric_name(name, label_names, label_values)
+  self:set_key(key, value)
+end
+
+-- Record a given value into a histogram metric.
+--
+-- Args:
+--   name: (string) short metric name without any labels.
+--   label_names: (array) a list of label keys.
+--   label_values: (array) a list of label values.
+--   value: (number) value to observe.
+function Prometheus:histogram_observe(name, label_names, label_values, value)
+  self:inc(name .. "_count", label_names, label_values, 1)
+  self:inc(name .. "_sum", label_names, label_values, value)
+
+  -- we are going to mutate arrays of label names and values, so create a copy.
+  local l_names = copy_table(label_names)
+  local l_values = copy_table(label_values)
+
+  -- Last bucket. Note, that the label value is "Inf" rather than "+Inf"
+  -- required by Prometheus. This is necessary for this bucket to be the last
+  -- one when all metrics are lexicographically sorted. "Inf" will get replaced
+  -- by "+Inf" in Prometheus:collect().
+  table.insert(l_names, "le")
+  table.insert(l_values, "Inf")
+  self:inc(name .. "_bucket", l_names, l_values, 1)
+
+  local label_count = #l_names
+  for _, bucket in ipairs(self.buckets[name]) do
+    if value <= bucket then
+      -- last label is now "le"
+      l_values[label_count] = self.bucket_format[name]:format(bucket)
+      self:inc(name .. "_bucket", l_names, l_values, 1)
+    end
+  end
+end
+
+-- Prometheus compatible metric data as an array of strings.
+--
+-- Returns:
+--   Array of strings with all metrics in a text format compatible with
+--   Prometheus.
+function Prometheus:metric_data()
+  if not self.initialized then
+    ngx.log(ngx.ERR, "Prometheus module has not been initialized")
+    return
+  end
+
+  local keys = self.dict:get_keys(0)
+  -- Prometheus server expects buckets of a histogram to appear in increasing
+  -- numerical order of their label values.
+  table.sort(keys)
+
+  local seen_metrics = {}
+  local output = {}
+  for _, key in ipairs(keys) do
+    local value, err = self.dict:get(key)
+    if value then
+      local short_name = short_metric_name(key)
+      if not seen_metrics[short_name] then
+        if self.help[short_name] then
+          table.insert(output, string.format("# HELP %s%s %s\n",
+            self.prefix, short_name, self.help[short_name]))
+        end
+        if self.type[short_name] then
+          table.insert(output, string.format("# TYPE %s%s %s\n",
+            self.prefix, short_name, self.type[short_name]))
+        end
+        seen_metrics[short_name] = true
+      end
+      -- Replace "Inf" with "+Inf" in each metric's last bucket 'le' label.
+      if key:find('le="Inf"', 1, true) then
+        key = key:gsub('le="Inf"', 'le="+Inf"')
+      end
+      table.insert(output, string.format("%s%s %s\n", self.prefix, key, value))
+    else
+      self:log_error("Error getting '", key, "': ", err)
+    end
+  end
+  return output
+end
+
+-- Present all metrics in a text format compatible with Prometheus.
+--
+-- This function should be used to expose the metrics on a separate HTTP page.
+-- It will get the metrics from the dictionary, sort them, and expose them
+-- aling with TYPE and HELP comments.
+function Prometheus:collect()
+  ngx.header.content_type = "text/plain"
+  ngx.print(self:metric_data())
+end
+
+return Prometheus
diff --git a/pipelines/backup/es-restore/Jenkinsfile b/pipelines/backup/es-restore/Jenkinsfile
index a6c7c7d8b349e04569e0782121edb677027a5813..f069b6dd54200561e86c2b35299dd2af3b24fd16 100644
--- a/pipelines/backup/es-restore/Jenkinsfile
+++ b/pipelines/backup/es-restore/Jenkinsfile
@@ -1,16 +1,12 @@
 @Library('deploy-conf') _
 node() {
-    try {
+      try {  
         String ANSI_GREEN = "\u001B[32m"
         String ANSI_NORMAL = "\u001B[0m"
         String ANSI_BOLD = "\u001B[1m"
         String ANSI_RED = "\u001B[31m"
         String ANSI_YELLOW = "\u001B[33m"
 
-        triggers {
-            cron('H 0 * * *')
-        }
-
         stage('checkout public repo') {
             cleanWs()
             checkout scm
@@ -19,12 +15,12 @@ node() {
         ansiColor('xterm') {
             stage('deploy'){
                 values = [:]
-                currentWs = sh(returnStdout: true, script: 'pwd').trim()
                 envDir = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-3].trim()
                 module = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-2].trim()
                 jobName = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-1].trim()
+                currentWs = sh(returnStdout: true, script: 'pwd').trim()
                 ansiblePlaybook = "${currentWs}/ansible/es.yml"
-                ansibleExtraArgs = "--tags \"es_restore\" --extra-vars \"snapshot_number=${snapshot_number}\" -v --vault-password-file /var/lib/jenkins/secrets/vault-pass"
+                ansibleExtraArgs = "--tags \"es_restore\" --extra-vars \"remote=${params.host} snapshot_number=${params.snapshot_name}\" -v --vault-password-file /var/lib/jenkins/secrets/vault-pass"
                 values.put('currentWs', currentWs)
                 values.put('env', envDir)
                 values.put('module', module)
@@ -35,8 +31,9 @@ node() {
                 ansible_playbook_run(values)
             }
         }
-    }
-    catch (err) {
+      }           
+        catch (err) {
+        currentBuild.result = "FAILURE"
         throw err
     }
 }
diff --git a/pipelines/backup/logger-es-restore/Jenkinsfile b/pipelines/backup/logger-es-restore/Jenkinsfile
index fd2bbaf06300fd18e4f5560c9e43b76acb3b4ad4..f069b6dd54200561e86c2b35299dd2af3b24fd16 100644
--- a/pipelines/backup/logger-es-restore/Jenkinsfile
+++ b/pipelines/backup/logger-es-restore/Jenkinsfile
@@ -1,16 +1,12 @@
 @Library('deploy-conf') _
 node() {
-    try {
+      try {  
         String ANSI_GREEN = "\u001B[32m"
         String ANSI_NORMAL = "\u001B[0m"
         String ANSI_BOLD = "\u001B[1m"
         String ANSI_RED = "\u001B[31m"
         String ANSI_YELLOW = "\u001B[33m"
 
-        triggers {
-            cron('H 0 * * *')
-        }
-
         stage('checkout public repo') {
             cleanWs()
             checkout scm
@@ -19,12 +15,12 @@ node() {
         ansiColor('xterm') {
             stage('deploy'){
                 values = [:]
-                currentWs = sh(returnStdout: true, script: 'pwd').trim()
                 envDir = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-3].trim()
                 module = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-2].trim()
                 jobName = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-1].trim()
+                currentWs = sh(returnStdout: true, script: 'pwd').trim()
                 ansiblePlaybook = "${currentWs}/ansible/es.yml"
-                ansibleExtraArgs = "--tags \"log_es_restore\" --extra-vars \"snapshot_number=${snapshot_number}\" -v --vault-password-file /var/lib/jenkins/secrets/vault-pass"
+                ansibleExtraArgs = "--tags \"es_restore\" --extra-vars \"remote=${params.host} snapshot_number=${params.snapshot_name}\" -v --vault-password-file /var/lib/jenkins/secrets/vault-pass"
                 values.put('currentWs', currentWs)
                 values.put('env', envDir)
                 values.put('module', module)
@@ -35,8 +31,9 @@ node() {
                 ansible_playbook_run(values)
             }
         }
-    }
-    catch (err) {
+      }           
+        catch (err) {
+        currentBuild.result = "FAILURE"
         throw err
     }
 }
diff --git a/pipelines/deploy/cassandra-deploy/Jenkinsfile.decrypt b/pipelines/deploy/cassandra-deploy/Jenkinsfile.decrypt
new file mode 100644
index 0000000000000000000000000000000000000000..503efa7f12cdc162888dbf269b71193ca3f42737
--- /dev/null
+++ b/pipelines/deploy/cassandra-deploy/Jenkinsfile.decrypt
@@ -0,0 +1,59 @@
+@Library('deploy-conf') _
+node() {
+    try {
+        String ANSI_GREEN = "\u001B[32m"
+        String ANSI_NORMAL = "\u001B[0m"
+        String ANSI_BOLD = "\u001B[1m"
+        String ANSI_RED = "\u001B[31m"
+        String ANSI_YELLOW = "\u001B[33m"
+
+        stage('checkout public repo') {
+            cleanWs()
+            checkout scm
+        }
+            ansiColor('xterm') {
+                stage('get artifact') {
+                    values = lp_dp_params()
+                    currentWs = sh(returnStdout: true, script: 'pwd').trim()
+                    artifact = values.artifact_name + ":" + values.artifact_version
+                    values.put('currentWs', currentWs)
+                    if (params.artifact_source == "ArtifactRepo") {
+                        println(ANSI_BOLD + ANSI_YELLOW + '''\
+                    Option chosen is ArtifactRepo, ignoring any previously copied artifacts and new artifacts will be downloaded from remote source
+                    '''.stripIndent().replace("\n", " ") + ANSI_NORMAL)
+                        ansiblePlaybook = "${currentWs}/ansible/artifacts-download.yml"
+                        ansibleExtraArgs = """\
+                               --extra-vars "artifact=${artifact}
+                               artifact_path=${currentWs}/${artifact}"
+                               --vault-password-file /var/lib/jenkins/secrets/vault-pass
+                               """.stripIndent().replace("\n", " ")
+                        values.put('ansiblePlaybook', ansiblePlaybook)
+                        values.put('ansibleExtraArgs', ansibleExtraArgs)
+                        ansible_playbook_run(values)
+                    } else {
+                        println(ANSI_BOLD + ANSI_YELLOW + '''\
+                    Option chosen is JenkinsJob, using the artifacts copied
+                    '''.stripIndent().replace("\n", " ") + ANSI_NORMAL)
+                    }
+                }
+                stage('deploy artifact') {
+                    sh """
+                       unzip ${artifact}
+                    """
+                    ansiblePlaybook = "${currentWs}/ansible/cassandra-deploy-decrypt.yml"
+                    ansibleExtraArgs = "--vault-password-file /var/lib/jenkins/secrets/vault-pass -v"
+                    values.put('ansiblePlaybook', ansiblePlaybook)
+                    values.put('ansibleExtraArgs', ansibleExtraArgs)
+                    println values
+                    ansible_playbook_run(values)
+                    archiveArtifacts artifacts: "${artifact}", fingerprint: true, onlyIfSuccessful: true
+                    archiveArtifacts artifacts: 'metadata.json', onlyIfSuccessful: true
+                    currentBuild.description = "${values.artifact_version}"
+                }
+            }
+    }
+    catch (err) {
+        currentBuild.result = "FAILURE"
+        throw err
+    }
+}
diff --git a/pipelines/deploy/enc/Jenkinsfile b/pipelines/deploy/enc/Jenkinsfile
new file mode 100644
index 0000000000000000000000000000000000000000..567f57bdf61e13a9035f1d3d2872d5a33a98dc2e
--- /dev/null
+++ b/pipelines/deploy/enc/Jenkinsfile
@@ -0,0 +1,26 @@
+@Library('deploy-conf') _
+node() {
+    try {
+        stage('checkout public repo') {
+            cleanWs()
+            checkout scm
+        }
+
+        stage('deploy') {
+            values = docker_params()
+            currentWs = sh(returnStdout: true, script: 'pwd').trim()
+            ansiblePlaybook = "$currentWs/ansible/deploy.yml"
+            ansibleExtraArgs = "--tags \"stack-sunbird\" --extra-vars \"hub_org=$hub_org image_name=$values.image_name image_tag=$values.image_tag service_name=enc-service deploy_enc=True\" --vault-password-file /var/lib/jenkins/secrets/vault-pass"
+            values.put('currentWs', currentWs)
+            values.put('ansiblePlaybook', ansiblePlaybook)
+            values.put('ansibleExtraArgs', ansibleExtraArgs)
+            ansible_playbook_run(values)
+            archiveArtifacts 'metadata.json'
+            currentBuild.description = "${values.image_tag}"
+        }
+    }
+    catch (err) {
+        currentBuild.result = "FAILURE"
+        throw err
+    }
+}
diff --git a/pipelines/deploy/keycloak-realm/Jenkinsfile b/pipelines/deploy/keycloak-realm/Jenkinsfile
index 3cb499eeca40fc5b1a39ed50d66c5b41910b59fa..ae189621001e706382d7fb49ccb5bade429aa2e9 100644
--- a/pipelines/deploy/keycloak-realm/Jenkinsfile
+++ b/pipelines/deploy/keycloak-realm/Jenkinsfile
@@ -20,7 +20,7 @@ node() {
                 module = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-2].trim()
                 jobName = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-1].trim()
                 ansiblePlaybook = "${currentWs}/ansible/sunbird-auth-deploy.yml"
-                ansibleExtraArgs = "--tags bootstrap --vault-password-file  /var/lib/jenkins/secrets/vault-pass"
+                ansibleExtraArgs = "--extra-vars \"host=keycloak\" --tags bootstrap --vault-password-file  /var/lib/jenkins/secrets/vault-pass"
                 values.put('currentWs', currentWs)
                 values.put('env', envDir)
                 values.put('module', module)
diff --git a/pipelines/deploy/keycloak-realm/Jenkinsfile.user b/pipelines/deploy/keycloak-realm/Jenkinsfile.user
new file mode 100644
index 0000000000000000000000000000000000000000..8203b5fe9f9bbc908f722dac255452566230f9cf
--- /dev/null
+++ b/pipelines/deploy/keycloak-realm/Jenkinsfile.user
@@ -0,0 +1,38 @@
+@Library('deploy-conf') _
+node() {
+    try {
+        String ANSI_GREEN = "\u001B[32m"
+        String ANSI_NORMAL = "\u001B[0m"
+        String ANSI_BOLD = "\u001B[1m"
+        String ANSI_RED = "\u001B[31m"
+        String ANSI_YELLOW = "\u001B[33m"
+
+        stage('checkout public repo') {
+            cleanWs()
+            checkout scm
+        }
+
+        ansiColor('xterm') {
+            stage('deploy') {
+                values = [:]
+                currentWs = sh(returnStdout: true, script: 'pwd').trim()
+                envDir = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-3].trim()
+                module = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-2].trim()
+                jobName = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-1].trim()
+                ansiblePlaybook = "${currentWs}/ansible/sunbird-auth-deploy.yml"
+                ansibleExtraArgs = "--extra-vars \"host=user-keycloak\" --tags bootstrap --vault-password-file  /var/lib/jenkins/secrets/vault-pass"
+                values.put('currentWs', currentWs)
+                values.put('env', envDir)
+                values.put('module', module)
+                values.put('jobName', jobName)
+                values.put('ansiblePlaybook', ansiblePlaybook)
+                values.put('ansibleExtraArgs', ansibleExtraArgs)
+                println values
+                ansible_playbook_run(values)
+            }
+        }
+    }
+    catch (err) {
+        throw err
+    }
+}
diff --git a/pipelines/deploy/keycloak/Jenkinsfile b/pipelines/deploy/keycloak/Jenkinsfile
index 442a707ef84eb9164f70a692f24eeff5105e44c2..b42f1df2842d510658bd9f3ccbcd5d92053c7de0 100644
--- a/pipelines/deploy/keycloak/Jenkinsfile
+++ b/pipelines/deploy/keycloak/Jenkinsfile
@@ -42,6 +42,7 @@ node() {
                     ansibleExtraArgs = """\
                             --limit keycloak
                             --tags deploy
+			    --extra-vars "host=keycloak"
                             --extra-vars "artifact=${artifact}
                             artifact_path=${currentWs}/${artifact}"
                             --vault-password-file /var/lib/jenkins/secrets/vault-pass
diff --git a/pipelines/deploy/keycloak/Jenkinsfile.custom b/pipelines/deploy/keycloak/Jenkinsfile.custom
new file mode 100644
index 0000000000000000000000000000000000000000..20d80486828e9a60017890b3d1a4ef934f79f9de
--- /dev/null
+++ b/pipelines/deploy/keycloak/Jenkinsfile.custom
@@ -0,0 +1,38 @@
+@Library('deploy-conf') _
+node() {
+    try {
+        String ANSI_GREEN = "\u001B[32m"
+        String ANSI_NORMAL = "\u001B[0m"
+        String ANSI_BOLD = "\u001B[1m"
+        String ANSI_RED = "\u001B[31m"
+        String ANSI_YELLOW = "\u001B[33m"
+
+        stage('checkout public repo') {
+            cleanWs()
+            checkout scm
+        }
+
+        ansiColor('xterm') {    
+            stage('deploy custom changes'){
+                values = [:]
+                currentWs = sh(returnStdout: true, script: 'pwd').trim()
+                envDir = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-3].trim()
+                module = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-2].trim()
+                jobName = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-1].trim()
+                ansiblePlaybook = "${currentWs}/ansible/sunbird-auth-deploy.yml"
+                ansibleExtraArgs = "--extra-vars \"host=keycloak\" --tags custom --vault-password-file  /var/lib/jenkins/secrets/vault-pass"
+                values.put('currentWs', currentWs)
+                values.put('env', envDir)
+                values.put('module', module)
+                values.put('jobName', jobName)
+                values.put('ansiblePlaybook', ansiblePlaybook)
+                values.put('ansibleExtraArgs', ansibleExtraArgs)
+                println values
+                ansible_playbook_run(values)
+            }
+        }
+    }
+    catch (err) {
+        throw err
+    }
+}
diff --git a/pipelines/deploy/keycloak/Jenkinsfile.user b/pipelines/deploy/keycloak/Jenkinsfile.user
new file mode 100644
index 0000000000000000000000000000000000000000..883e62398c392297de00ac44a594ee23ef6f68ab
--- /dev/null
+++ b/pipelines/deploy/keycloak/Jenkinsfile.user
@@ -0,0 +1,64 @@
+@Library('deploy-conf') _
+node() {
+    try {
+        String ANSI_GREEN = "\u001B[32m"
+        String ANSI_NORMAL = "\u001B[0m"
+        String ANSI_BOLD = "\u001B[1m"
+        String ANSI_RED = "\u001B[31m"
+        String ANSI_YELLOW = "\u001B[33m"
+
+        stage('checkout public repo') {
+            cleanWs()
+            checkout scm
+              sh "git clone https://github.com/project-sunbird/sunbird-auth.git -b release-2.0.0"
+        }
+            ansiColor('xterm') {
+                stage('get artifact') {
+                    values = lp_dp_params()
+                    currentWs = sh(returnStdout: true, script: 'pwd').trim()
+                    artifact = values.artifact_name + ":" + values.artifact_version
+                    values.put('currentWs', currentWs)
+                    if (params.artifact_source == "ArtifactRepo") {
+                        println(ANSI_BOLD + ANSI_YELLOW + '''\
+                    Option chosen is ArtifactRepo, ignoring any previously copied artifacts and new artifacts will be downloaded from remote source
+                    '''.stripIndent().replace("\n", " ") + ANSI_NORMAL)
+                        ansiblePlaybook = "${currentWs}/ansible/artifacts-download.yml"
+                        ansibleExtraArgs = """\
+                               --extra-vars "artifact=${artifact}
+                               artifact_path=${currentWs}/${artifact}"
+                               --vault-password-file /var/lib/jenkins/secrets/vault-pass
+                               """.stripIndent().replace("\n", " ")
+                        values.put('ansiblePlaybook', ansiblePlaybook)
+                        values.put('ansibleExtraArgs', ansibleExtraArgs)
+                        ansible_playbook_run(values)
+                    } else {
+                        println(ANSI_BOLD + ANSI_YELLOW + '''\
+                    Option chosen is JenkinsJob, using the artifacts copied
+                    '''.stripIndent().replace("\n", " ") + ANSI_NORMAL)
+                    }
+                }
+                    stage('deploy artifact') {
+                    ansiblePlaybook = "${currentWs}/ansible/sunbird-auth-deploy.yml"
+                    ansibleExtraArgs = """\
+                            --tags deploy
+                            --extra-vars "host={{groups['user-keycloak']}}"
+                            --extra-vars "artifact=${artifact}
+                            artifact_path=${currentWs}/${artifact}"
+                            --vault-password-file /var/lib/jenkins/secrets/vault-pass
+                            """.stripIndent().replace("\n", " ")
+                                                
+                    values.put('ansiblePlaybook', ansiblePlaybook)
+                    values.put('ansibleExtraArgs', ansibleExtraArgs)
+                    println values
+                    ansible_playbook_run(values)
+                    archiveArtifacts artifacts: "${artifact}", fingerprint: true, onlyIfSuccessful: true
+                    archiveArtifacts artifacts: 'metadata.json', onlyIfSuccessful: true
+                    currentBuild.description = "${values.artifact_version}"
+                }
+            }
+    }
+    catch (err) {
+        currentBuild.result = "FAILURE"
+        throw err
+    }
+}
diff --git a/pipelines/deploy/lms/Jenkinsfile b/pipelines/deploy/lms/Jenkinsfile
new file mode 100644
index 0000000000000000000000000000000000000000..fc8ab4cd2e447f174dfeed5b9e2cb2a667116a4f
--- /dev/null
+++ b/pipelines/deploy/lms/Jenkinsfile
@@ -0,0 +1,26 @@
+@Library('deploy-conf') _
+node() {
+    try {
+        stage('checkout public repo') {
+            cleanWs()
+            checkout scm
+        }
+
+        stage('deploy') {
+            values = docker_params()
+            currentWs = sh(returnStdout: true, script: 'pwd').trim()
+            ansiblePlaybook = "$currentWs/ansible/deploy.yml"
+            ansibleExtraArgs = "--tags \"stack-sunbird\" --extra-vars \"hub_org=$hub_org image_name=$values.image_name image_tag=$values.image_tag service_name=lms-service deploy_lms=True\" --vault-password-file /var/lib/jenkins/secrets/vault-pass"
+            values.put('currentWs', currentWs)
+            values.put('ansiblePlaybook', ansiblePlaybook)
+            values.put('ansibleExtraArgs', ansibleExtraArgs)
+            ansible_playbook_run(values)
+            archiveArtifacts 'metadata.json'
+            currentBuild.description = "${values.image_tag}"
+        }
+    }
+    catch (err) {
+        currentBuild.result = "FAILURE"
+        throw err
+    }
+}
\ No newline at end of file
diff --git a/pipelines/deploy/monitor/prom-fed/Jenkinsfile b/pipelines/deploy/monitor/prom-fed/Jenkinsfile
new file mode 100644
index 0000000000000000000000000000000000000000..0294ea7c2127e02abc5ee26b1882e3d629ece38a
--- /dev/null
+++ b/pipelines/deploy/monitor/prom-fed/Jenkinsfile
@@ -0,0 +1,38 @@
+@Library('deploy-conf') _
+node() {
+    try {
+        String ANSI_GREEN = "\u001B[32m"
+        String ANSI_NORMAL = "\u001B[0m"
+        String ANSI_BOLD = "\u001B[1m"
+        String ANSI_RED = "\u001B[31m"
+        String ANSI_YELLOW = "\u001B[33m"
+
+        stage('checkout public repo') {
+            cleanWs()
+            checkout scm
+        }
+
+        ansiColor('xterm') {
+            stage('deploy'){
+                values = [:]
+                currentWs = sh(returnStdout: true, script: 'pwd').trim()
+                envDir = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-3].trim()
+                module = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-2].trim()
+                jobName = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-1].trim()
+                ansiblePlaybook = "${currentWs}/ansible/monitoring-fed.yml"
+                ansibleExtraArgs = "--vault-password-file /var/lib/jenkins/secrets/vault-pass -v"
+		values.put('currentWs', currentWs)
+                values.put('env', envDir)
+                values.put('module', module)
+                values.put('jobName', jobName)
+                values.put('ansiblePlaybook', ansiblePlaybook)
+                values.put('ansibleExtraArgs', ansibleExtraArgs)
+                println values
+                ansible_playbook_run(values)
+            }
+        }
+    }
+    catch (err) {
+        throw err
+    }
+}
\ No newline at end of file
diff --git a/pipelines/deploy/player-cdn/Jenkinsfile b/pipelines/deploy/player-cdn/Jenkinsfile
index 8a7e23bfa341418cdf7c158ab082d577b26f9250..d8258c9643bb6e2b00f5fb9cbf0936647f9aa29a 100644
--- a/pipelines/deploy/player-cdn/Jenkinsfile
+++ b/pipelines/deploy/player-cdn/Jenkinsfile
@@ -1,6 +1,7 @@
 @Library('deploy-conf') _
 node() {
     try {
+     timestamps {
         ansiColor('xterm') {
             String ANSI_GREEN = "\u001B[32m"
             String ANSI_NORMAL = "\u001B[0m"
@@ -10,7 +11,7 @@ node() {
 
             if (params.cdn_enable == "true") {
                 stage('Initialize repos') {
-                    cleanWs()
+//                    cleanWs()
                     checkout scm
                     values = docker_params()
                     currentWs = sh(returnStdout: true, script: 'pwd').trim()
@@ -33,11 +34,8 @@ node() {
                         println cdnUrl
                         commitHash = sh(script: "jq -r '.commit_hash' metadata.json", returnStdout: true).trim()
                         dir('sunbird-portal') {
-                            sunbirdPortalUrl = 'https://github.com/Sunbird-Ed/SunbirdEd-portal.git'
-                            checkout([$class: 'GitSCM', branches: [[name: "$commitHash"]], userRemoteConfigs: [[url: "$sunbirdPortalUrl"]]])
-                            timestamps {
-                                sh("docker run -v /etc/passwd:/etc/passwd -u `id -u`:`id -g` -v `pwd`:/var/lib/jenkins -w /var/lib/jenkins circleci/node:8.11-stretch sh ./build-cdn.sh ${cdnUrl} ${commitHash} ")
-                            }
+                            checkout changelog: false, poll: false, scm: [$class: 'GitSCM', branches: [[name: commitHash]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/Sunbird-Ed/SunbirdEd-portal.git']]]
+                            sh "./build-cdn.sh ${cdnUrl} ${commitHash}"
                         }
                         ansibleExtraArgs = "--extra-vars assets=$currentWs/sunbird-portal/src/app/dist --extra-vars cdn_file_path=$currentWs/sunbird-portal/src/app/dist/index_cdn.ejs --vault-password-file /var/lib/jenkins/secrets/vault-pass"
                         values.put('ansibleExtraArgs', ansibleExtraArgs)
@@ -55,6 +53,7 @@ node() {
             }
         }
     }
+}
     catch (err) {
         currentBuild.result = "FAILURE"
         throw err
diff --git a/pipelines/provision/keycloak/Jenkinsfile b/pipelines/provision/keycloak/Jenkinsfile
index 80eb9281fb1237231477f95910ea1c95f77ef5fa..02b8c25db9262174c59043bbf1562868b58d648e 100644
--- a/pipelines/provision/keycloak/Jenkinsfile
+++ b/pipelines/provision/keycloak/Jenkinsfile
@@ -20,7 +20,7 @@ node() {
                 module = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-2].trim()
                 jobName = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-1].trim()
                 ansiblePlaybook = "${currentWs}/ansible/keycloak.yml"
-                ansibleExtraArgs = "--tags provision --vault-password-file  /var/lib/jenkins/secrets/vault-pass"
+                ansibleExtraArgs = "--extra-vars \"host=keycloak\" --tags provision --vault-password-file  /var/lib/jenkins/secrets/vault-pass"
                 values.put('currentWs', currentWs)
                 values.put('env', envDir)
                 values.put('module', module)
diff --git a/pipelines/provision/keycloak/Jenkinsfile.user b/pipelines/provision/keycloak/Jenkinsfile.user
new file mode 100644
index 0000000000000000000000000000000000000000..65ebd13d12e4ee6a95db47cce0d0ab6909be0d2b
--- /dev/null
+++ b/pipelines/provision/keycloak/Jenkinsfile.user
@@ -0,0 +1,38 @@
+@Library('deploy-conf') _
+node() {
+    try {
+        String ANSI_GREEN = "\u001B[32m"
+        String ANSI_NORMAL = "\u001B[0m"
+        String ANSI_BOLD = "\u001B[1m"
+        String ANSI_RED = "\u001B[31m"
+        String ANSI_YELLOW = "\u001B[33m"
+
+        stage('checkout public repo') {
+            cleanWs()
+            checkout scm
+        }
+
+        ansiColor('xterm') {
+            stage('deploy'){
+                values = [:]
+                currentWs = sh(returnStdout: true, script: 'pwd').trim()
+                envDir = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-3].trim()
+                module = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-2].trim()
+                jobName = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-1].trim()
+                ansiblePlaybook = "${currentWs}/ansible/keycloak.yml"
+                ansibleExtraArgs = "--extra-vars \"host=keycloak-user\" --tags provision --vault-password-file  /var/lib/jenkins/secrets/vault-pass"
+                values.put('currentWs', currentWs)
+                values.put('env', envDir)
+                values.put('module', module)
+                values.put('jobName', jobName)
+                values.put('ansiblePlaybook', ansiblePlaybook)
+                values.put('ansibleExtraArgs', ansibleExtraArgs)
+                println values
+                ansible_playbook_run(values)
+            }
+        }
+    }
+    catch (err) {
+        throw err
+    }
+}
diff --git a/pipelines/provision/postgres-db-update/Jenkinsfile b/pipelines/provision/postgres-db-update/Jenkinsfile
index f17d40c89dea7488edf6fe2a146f0e1e498e59a2..b7a209b5090255d68b7632454c5aefa83302d63f 100644
--- a/pipelines/provision/postgres-db-update/Jenkinsfile
+++ b/pipelines/provision/postgres-db-update/Jenkinsfile
@@ -20,7 +20,7 @@ node() {
                 module = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-2].trim()
                 jobName = sh(returnStdout: true, script: "echo $JOB_NAME").split('/')[-1].trim()
                 ansiblePlaybook = "${currentWs}/ansible/postgresql-data-update.yml"
-                ansibleExtraArgs = "--vault-password-file /var/lib/jenkins/secrets/vault-pass -v"
+                ansibleExtraArgs = "--vault-password-file /var/lib/jenkins/secrets/vault-pass"
                 values.put('currentWs', currentWs)
                 values.put('env', envDir)
                 values.put('module', module)