diff --git a/README.md b/README.md
index 5107f06d68551c66f4102c2237fd530e34b136c2..d9d7f580b46f92901602e1ba2d483422adc96e1f 100644
--- a/README.md
+++ b/README.md
@@ -183,19 +183,37 @@ Here are variables supported to configure the production environment:
 | `HELM_PROD_VALUES`       | The [Values file](https://helm.sh/docs/chart_template_guide/values_files/) to use with the production environment | _none_ |
 | `HELM_PROD_ENVIRONMENT_URL` | The production environment url **including scheme** (ex: `https://my-application.public.k8s.domain.com`) Do not use variable inside variable definition as it will result in a two level cascade variable and gitlab does not allow that. | _none_ |
 
-#### Dynamic Values
+#### Dynamic Values and Variables
 
 You have to be aware that your deployment (and cleanup) scripts have to be able to cope with various environments
 (`review`, `integration`, `staging` and `production`), each with different application names, exposed routes, settings, ...
 
 Part of this complexity can be handled by the lookup policies described above (ex: one resource per env).
 
-In order to be able to implement some **genericity** in your scripts and templates, you should use generic [values](https://helm.sh/docs/chart_best_practices/values/)
-dynamically set and passed by the template:
+In order to be able to implement some **genericity** in your scripts and templates:
+
+1. you should use generic [values](https://helm.sh/docs/chart_best_practices/values/) dynamically set and passed by the template:
 
 * `env`: the environment type (`review`, `integration`, `staging` or `production`)
 * `hostname`: the environment hostname, extracted from `${CI_ENVIRONMENT_URL}` (got from [`environment:url`](https://docs.gitlab.com/ee/ci/yaml/#environmenturl) - see `OS_REVIEW_ENVIRONMENT_SCHEME`, `OS_REVIEW_ENVIRONMENT_DOMAIN`, `OS_STAGING_ENVIRONMENT_URL` and `OS_PROD_ENVIRONMENT_URL`)
 
+2.  you should use available environment variables:
+  
+  * any [GitLab CI variable](https://docs.gitlab.com/ee/ci/variables/#predefined-environment-variables)
+    (ex: `${CI_ENVIRONMENT_URL}` to retrieve the actual environment exposed route)
+  * any [custom variable](https://docs.gitlab.com/ee/ci/variables/#custom-environment-variables)
+    (ex: `${SECRET_TOKEN}` that you have set in your project CI/CD variables)
+
+> :warning: 
+>
+> In order to be properly replaced, variables in your YAML value file shall be written with curly braces (ex: `${MYVAR}` and not `$MYVAR`).
+>
+> Multiline variables must be surrounded by double quotes and you might have to disable line-length rule of yamllint as they are rewritten on a single line.
+> 
+> ```yaml
+>  tlsKey: "${MYKEY}"  # yamllint disable-line rule:line-length
+> ```
+
 ### `helm-lint` job
 
 This job [examines your chart for possible issues](https://helm.sh/docs/helm/helm_lint/) and uses the following variables:
diff --git a/templates/gitlab-ci-helm.yml b/templates/gitlab-ci-helm.yml
index ed6da4127c7323dbfdee5c6ced1f258c7fec5853..ff96094a209c2af35a848e98c91b1b12f3899b22 100644
--- a/templates/gitlab-ci-helm.yml
+++ b/templates/gitlab-ci-helm.yml
@@ -327,7 +327,7 @@ stages:
   }
 
   function awkenvsubst() {
-    awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1'
+    awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);val=ENVIRON[var];gsub(/["\\]/,"\\\\&", val);gsub("\n", "\\n", val);gsub("\r", "\\r", val);gsub("[$]{"var"}",val)}}1'
   }
 
   # deploy application
@@ -966,4 +966,4 @@ helm-production:
     - if: '$PUBLISH_ON_PROD == "true" || $PUBLISH_ON_PROD == "yes"'
     # else: manual, blocking
     - if: $CI_COMMIT_REF_NAME # useless test, just to prevent GitLab warning
-      when: manual
\ No newline at end of file
+      when: manual