diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 54cdae77206c0a4de689ff246c7c362edd4bb269..5bea11f07268edad138302f93d387cd0d444de3f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -37,74 +37,6 @@ stages:
 build:
   services:
 
-# Prepares the secret files that we cannot or don't want to share with public
-prepare_secrets_master:
-  stage: prepare
-  image: alpine:latest
-  script: 
-    - cp $ENVFILE .env
-    - cp $SUMAS config/sumas.json
-    - cp $SUMASEN config/sumasEn.json
-    - cp $BLACKLISTURL config/blacklistUrl.txt
-    - cp $BLACKLISTDOMAINS config/blacklistDomains.txt
-    - cp $ADBLACKLISTURL config/adBlacklistUrl.txt
-    - cp $ADBLACKLISTDOMAINS config/adBlacklistDomains.txt
-    - cp $SPAM config/spam.txt
-    - cp $USERSSEEDER database/seeds/UsersSeeder.php
-    - cp database/useragents.sqlite.example database/useragents.sqlite
-    - sed -i 's/^APP_ENV=.*/APP_ENV=production/g' .env
-    - sed -i 's/^REDIS_PASSWORD=.*/REDIS_PASSWORD=null/g' .env
-  artifacts:
-    paths:
-      - .env
-      - config/sumas.json
-      - config/sumasEn.json
-      - config/blacklistUrl.txt
-      - config/blacklistDomains.txt
-      - config/adBlacklistUrl.txt
-      - config/adBlacklistDomains.txt
-      - config/spam.txt
-      - database/seeds/UsersSeeder.php
-      - database/useragents.sqlite
-  only:
-    refs:
-      - master    
-
-prepare_secrets_development:
-  stage: prepare
-  image: alpine:latest
-  script: 
-    - cp $ENVFILE .env
-    - cp $SUMAS config/sumas.json
-    - cp $SUMASEN config/sumasEn.json
-    - cp $BLACKLISTURL config/blacklistUrl.txt
-    - cp $BLACKLISTDOMAINS config/blacklistDomains.txt
-    - cp $ADBLACKLISTURL config/adBlacklistUrl.txt
-    - cp $ADBLACKLISTDOMAINS config/adBlacklistDomains.txt
-    - cp $SPAM config/spam.txt
-    - cp $USERSSEEDER database/seeds/UsersSeeder.php
-    - cp database/useragents.sqlite.example database/useragents.sqlite
-    - sed -i 's/^APP_ENV=.*/APP_ENV=development/g' .env
-    - sed -i 's/^REDIS_PASSWORD=.*/REDIS_PASSWORD=null/g' .env
-  artifacts:
-    paths:
-      - .env
-      - config/sumas.json
-      - config/sumasEn.json
-      - config/blacklistUrl.txt
-      - config/blacklistDomains.txt
-      - config/adBlacklistUrl.txt
-      - config/adBlacklistDomains.txt
-      - config/spam.txt
-      - database/seeds/UsersSeeder.php
-      - database/useragents.sqlite
-  only:
-    - branches
-    - tags
-  except:
-    refs:
-      - master
-
 prepare_node:
   stage: prepare
   image: node:10
@@ -143,20 +75,29 @@ review:
   variables:
     HELM_UPGRADE_VALUES_FILE: .gitlab/review-apps-values.yaml
     ROLLOUT_RESOURCE_TYPE: deployment
-  except:
-    refs:
-      - master
-      - development
-    variables:
-      - $REVIEW_DISABLED
+  rules:
+    - if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
+      when: never
+    - if: '$CI_COMMIT_BRANCH == "master"'
+      when: never
+    - if: '$CI_COMMIT_BRANCH == "development"'
+      when: never
+    - if: '$REVIEW_DISABLED'
+      when: never
+    - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
 
 stop_review:
-  except:
-    refs:
-      - master
-      - development
-    variables:
-      - $REVIEW_DISABLED
+  rules:
+    - if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
+      when: never
+    - if: '$CI_COMMIT_BRANCH == "master"'
+      when: never
+    - if: '$CI_COMMIT_BRANCH == "development"'
+      when: never
+    - if: '$REVIEW_DISABLED'
+      when: never
+    - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
+
 
 .development: &development_template
   extends: .auto-deploy
@@ -211,6 +152,11 @@ integrationtest:
   script:
     # Install Dev Dependencies
     - composer install
+    - cp .env.example .env
+    - echo "WEBDRIVER_USER=\"$WEBDRIVER_KEY\"" >> .env
+    - echo "WEBDRIVER_URL=\"$WEBDRIVER_URL\"" >> .env
+    - echo "WEBDRIVER_KEY=\"$WEBDRIVER_USER\"" >> .env
+    - php artisan key:generate
     - URL=$(cat environment_url.txt | tr -d '\n')
     - sed -i "s#^APP_URL=.*#APP_URL=$URL#g" .env
     - sed -i "s#^BRANCH_NAME=.*#BRANCH_NAME=$CI_COMMIT_REF_NAME#g" .env
diff --git a/.gitlab/development-values.yaml b/.gitlab/development-values.yaml
index 1a756bdf674a82cb4ea5b816851e6bd00bb1dfd8..87dfff8a0dfd9ed3b3dc84415a1d2f9025a5c76b 100644
--- a/.gitlab/development-values.yaml
+++ b/.gitlab/development-values.yaml
@@ -12,9 +12,10 @@ podAnnotations:
   prometheus.io/scrape: "true"
   prometheus.io/path: /metrics
   prometheus.io/port: "80"
+deploymentApiVersion: apps/v1
 ingress:
   annotations:
-    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
+    cert-manager.io/cluster-issuer: letsencrypt-prod
     nginx.ingress.kubernetes.io/configuration-snippet: |
       if ($host = "www.metager3.de") {
           return 301 https://metager3.de$request_uri;
diff --git a/.gitlab/production-values.yaml b/.gitlab/production-values.yaml
index e4f3fb44ae2aa6b16a8dc958c4b85a35c7fe702c..6957184b5045a8e99002899647d690348255d13c 100644
--- a/.gitlab/production-values.yaml
+++ b/.gitlab/production-values.yaml
@@ -19,9 +19,10 @@ podAnnotations:
   prometheus.io/scrape: "true"
   prometheus.io/path: /metrics
   prometheus.io/port: "80"
+deploymentApiVersion: apps/v1
 ingress:
   annotations:
-    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
+    cert-manager.io/cluster-issuer: letsencrypt-prod
     nginx.ingress.kubernetes.io/configuration-snippet: |
       if ($host = "www.metager.de") {
           return 301 https://metager.de$request_uri;
diff --git a/.gitlab/review-apps-values.yaml b/.gitlab/review-apps-values.yaml
index f13b3784d6a276f15cb0e0a72001ea976580c908..81eb62cecff6ed6b1b29aa3321cb1f2b7e911237 100644
--- a/.gitlab/review-apps-values.yaml
+++ b/.gitlab/review-apps-values.yaml
@@ -11,3 +11,4 @@ service:
   commonName: ""
   externalPort: 80
   internalPort: 80
+deploymentApiVersion: apps/v1
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 7bfbc1866a1f3b39b5a057fbaac0c42e7fa298c9..a74f916b948735b21b1bc4ae838d4f2a515dae5d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -69,7 +69,11 @@ COPY --chown=root:nginx . /html
 WORKDIR /html
 EXPOSE 80
 
-CMD chown -R root:nginx storage/logs/metager bootstrap/cache && \
+CMD cp /root/.env .env && \
+    sed -i 's/^REDIS_PASSWORD=.*/REDIS_PASSWORD=null/g' .env && \
+    if [ "$GITLAB_ENVIRONMENT_NAME" = "production" ]; then sed -i 's/^APP_ENV=.*/APP_ENV=production/g' .env; else sed -i 's/^APP_ENV=.*/APP_ENV=development/g' .env; fi && \
+    cp database/useragents.sqlite.example database/useragents.sqlite && \
+    chown -R root:nginx storage/logs/metager bootstrap/cache && \
     chmod -R g+w storage/logs/metager bootstrap/cache && \
     crond -L /dev/stdout && \
     php-fpm7
diff --git a/app/Http/Controllers/MailController.php b/app/Http/Controllers/MailController.php
index 9ff957dede09aec132a570cfdd8f5b6ee108e70f..86afc3ceb49cb6df4e9d3a8f1267bcf2fa17dae0 100644
--- a/app/Http/Controllers/MailController.php
+++ b/app/Http/Controllers/MailController.php
@@ -8,9 +8,10 @@ use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use LaravelLocalization;
 use Mail;
+use Log;
 use Validator;
-use \PHP_IBAN\IBAN;
-use \PHP_IBAN\IBANCountry;
+use \IBAN;
+use \IBANCountry;
 
 class MailController extends Controller
 {
@@ -148,6 +149,7 @@ class MailController extends Controller
                 $messageType = "success";
                 $messageToUser = "Herzlichen Dank!! Wir haben Ihre Spendenbenachrichtigung erhalten.";
             } catch (\Swift_TransportException $e) {
+                Log::error($e->getMessage());
                 $messageType = "error";
                 $messageToUser = 'Beim Senden Ihrer Spendenbenachrichtigung ist ein Fehler auf unserer Seite aufgetreten. Bitte schicken Sie eine E-Mail an: office@suma-ev.de, damit wir uns darum kümmern können.';
             }
diff --git a/app/Http/Controllers/MetaGerSearch.php b/app/Http/Controllers/MetaGerSearch.php
index 4d594cb5b85cdfd1dc1735fdb0320fb200b551d5..55589b09cd032fcb5454049a6deb038bf6ff6d43 100644
--- a/app/Http/Controllers/MetaGerSearch.php
+++ b/app/Http/Controllers/MetaGerSearch.php
@@ -7,6 +7,7 @@ use App\MetaGer;
 use Cache;
 use Illuminate\Http\Request;
 use LaravelLocalization;
+use Log;
 use View;
 
 class MetaGerSearch extends Controller
@@ -63,7 +64,7 @@ class MetaGerSearch extends Controller
 
         # Search query can be empty after parsing the formdata
         # we will cancel the search in that case and show an error to the user
-        if(empty($metager->getQ())){
+        if (empty($metager->getQ())) {
             return $metager->createView();
         }
 
@@ -109,7 +110,11 @@ class MetaGerSearch extends Controller
             }
         }
 
-        Cache::put("loader_" . $metager->getSearchUid(), $metager->getEngines(), 60 * 60);
+        try {
+            Cache::put("loader_" . $metager->getSearchUid(), $metager->getEngines(), 60 * 60);
+        } catch (\Exception $e) {
+            Log::error($e->getMessage());
+        }
         if (!empty($timings)) {
             $timings["Filled resultloader Cache"] = microtime(true) - $time;
         }
@@ -117,7 +122,11 @@ class MetaGerSearch extends Controller
         # Die Ausgabe erstellen:
         $resultpage = $metager->createView();
         if ($spamEntry !== null) {
-            Cache::put('spam.' . $metager->getFokus() . "." . md5($spamEntry), $resultpage->render(), 604800);
+            try {
+                Cache::put('spam.' . $metager->getFokus() . "." . md5($spamEntry), $resultpage->render(), 604800);
+            } catch (\Exception $e) {
+                Log::error($e->getMessage());
+            }
         }
 
         if (!empty($timings)) {
@@ -133,7 +142,7 @@ class MetaGerSearch extends Controller
         $counter->incBy(sizeof($metager->getResults()));
         $counter = $registry->getOrRegisterCounter('metager', 'query_counter', 'counts total number of search queries', []);
         $counter->inc();
-        
+
         return $resultpage;
     }
 
@@ -225,7 +234,7 @@ class MetaGerSearch extends Controller
 
         $result["finished"] = $finished;
 
-        if($newResults > 0){
+        if ($newResults > 0) {
             $registry = \Prometheus\CollectorRegistry::getDefault();
             $counter = $registry->getOrRegisterCounter('metager', 'result_counter', 'counts total number of returned results', []);
             $counter->incBy($newResults);
@@ -290,7 +299,7 @@ class MetaGerSearch extends Controller
     {
         $search = $request->input('search', '');
         $quotes = $request->input('quotes', 'on');
-        if(empty($search)){
+        if (empty($search)) {
             abort(404);
         }
 
diff --git a/app/Http/Middleware/HumanVerification.php b/app/Http/Middleware/HumanVerification.php
index a39debc384ccfb8a86bbc3f7a3c99311431f4054..5599671c6102f335ee32d1c2e3b9f8b8eefa2453 100644
--- a/app/Http/Middleware/HumanVerification.php
+++ b/app/Http/Middleware/HumanVerification.php
@@ -7,6 +7,7 @@ use Captcha;
 use Closure;
 use Cookie;
 use Illuminate\Http\Response;
+use Log;
 use URL;
 
 class HumanVerification
@@ -66,7 +67,6 @@ class HumanVerification
             } else {
                 $user = $users[$uid];
             }
-
             # Lock out everyone in a Bot network
             # Find out how many requests this IP has made
             $sum = 0;
@@ -128,16 +128,23 @@ class HumanVerification
                 if ($user["unusedResultPages"] === 50 || ($user["unusedResultPages"] > 50 && $user["unusedResultPages"] % 25 === 0)) {
                     $user["locked"] = true;
                 }
-
             }
+            \App\PrometheusExporter::HumanVerificationSuccessfull();
+        } catch (\Exception $e) {
+            Log::error($e->getMessage());
+            \App\PrometheusExporter::HumanVerificationError();
         } finally {
-            if ($update) {
+            if ($update && $user != null) {
                 if ($user["whitelist"]) {
                     $user["expiration"] = now()->addWeeks(2);
                 } else {
                     $user["expiration"] = now()->addHours(72);
                 }
-                $this->setUser($prefix, $user);
+                try {
+                    $this->setUser($prefix, $user);
+                } catch (\Exception $e) {
+                    Log::error($e->getMessage());
+                }
             }
         }
 
@@ -148,7 +155,6 @@ class HumanVerification
 
     public function setUser($prefix, $user)
     {
-        // Lock must be acquired within 2 seconds
         $userList = Cache::get($prefix . "." . $user["id"], []);
         $userList[$user["uid"]] = $user;
         Cache::put($prefix . "." . $user["id"], $userList, 2 * 7 * 24 * 60 * 60);
diff --git a/app/Models/Quicktips/Quicktips.php b/app/Models/Quicktips/Quicktips.php
index ba558afcf9dd0f498c2ae3bf15dec2686f2784f2..1210568fe193be1f0f8295598e6249d8627d0fba 100644
--- a/app/Models/Quicktips/Quicktips.php
+++ b/app/Models/Quicktips/Quicktips.php
@@ -32,12 +32,23 @@ class Quicktips
         $url = $this->quicktipUrl . "?search=" . $this->normalize_search($search) . "&locale=" . $locale . "&quotes=" . $quotes;
         $this->hash = md5($url);
 
-        if (!Cache::has($this->hash)) {
+        $results = null;
+
+        try {
+            if (!Cache::has($this->hash)) {
+                $results = file_get_contents($url);
+                Cache::put($this->hash, $results, Quicktips::CACHE_DURATION);
+            } else {
+                $results = Cache::get($this->hash);
+            }
+        } catch (\Exception $e) {
+            Log::error($e->getMessage());
+        }
+
+        if ($results === null) {
             $results = file_get_contents($url);
-            Cache::put($this->hash, $results, Quicktips::CACHE_DURATION);
-        } else {
-            $results = Cache::get($this->hash);
         }
+
         $this->results = $this->loadResults($results);
     }
 
diff --git a/app/Models/Searchengine.php b/app/Models/Searchengine.php
index eba7c83bd86e4a2104b17fd5a165de4c43fc3570..9cafcf0c61aa5b5d1542b6054ae25ec13127b327 100644
--- a/app/Models/Searchengine.php
+++ b/app/Models/Searchengine.php
@@ -5,6 +5,7 @@ namespace App\Models;
 use App\MetaGer;
 use Cache;
 use Illuminate\Support\Facades\Redis;
+use Log;
 
 abstract class Searchengine
 {
@@ -94,7 +95,7 @@ abstract class Searchengine
             $tmpPara = true;
             $engineParameterKey = $filter->sumas->{$name}->{"get-parameter"};
             $engineParameterValue = $filter->sumas->{$name}->values->{$inputParameter};
-            if(stripos($engineParameterValue, "dyn-") === 0){
+            if (stripos($engineParameterValue, "dyn-") === 0) {
                 $functionname = substr($engineParameterValue, stripos($engineParameterValue, "dyn-") + 4);
                 $engineParameterValue = \App\DynamicEngineParameters::$functionname();
             }
@@ -207,7 +208,11 @@ abstract class Searchengine
         }
 
         if ($body !== null) {
-            Cache::put($this->hash, $body, $this->cacheDuration * 60);
+            try {
+                Cache::put($this->hash, $body, $this->cacheDuration * 60);
+            } catch (\Exception $e) {
+                Log::error($e->getMessage());
+            }
             $this->loadResults($body);
             $this->getNext($metager, $body);
             $this->markNew();
diff --git a/app/PrometheusExporter.php b/app/PrometheusExporter.php
index 1332e1cf2f5176fbcd91e6b8c704ac7cc692fa9c..dd70db4e0a2c3a240aab2675bd5f718486faed46 100644
--- a/app/PrometheusExporter.php
+++ b/app/PrometheusExporter.php
@@ -2,24 +2,41 @@
 
 namespace App;
 
-class PrometheusExporter {
+class PrometheusExporter
+{
 
-    public static function CaptchaShown() {
+    public static function CaptchaShown()
+    {
         $registry = \Prometheus\CollectorRegistry::getDefault();
         $counter = $registry->getOrRegisterCounter('metager', 'captcha_shown', 'counts how often the captcha was shown', []);
         $counter->inc();
     }
 
-    public static function CaptchaCorrect() {
+    public static function CaptchaCorrect()
+    {
         $registry = \Prometheus\CollectorRegistry::getDefault();
         $counter = $registry->getOrRegisterCounter('metager', 'captcha_correct', 'counts how often the captcha was solved correctly', []);
         $counter->inc();
     }
 
-    public static function CaptchaAnswered() {
+    public static function CaptchaAnswered()
+    {
         $registry = \Prometheus\CollectorRegistry::getDefault();
         $counter = $registry->getOrRegisterCounter('metager', 'captcha_answered', 'counts how often the captcha was answered', []);
         $counter->inc();
     }
 
-}
\ No newline at end of file
+    public static function HumanVerificationSuccessfull()
+    {
+        $registry = \Prometheus\CollectorRegistry::getDefault();
+        $counter = $registry->getOrRegisterCounter('metager', 'humanverification_success', 'counts how often humanverification middleware was successfull', []);
+        $counter->inc();
+    }
+
+    public static function HumanVerificationError()
+    {
+        $registry = \Prometheus\CollectorRegistry::getDefault();
+        $counter = $registry->getOrRegisterCounter('metager', 'humanverification_error', 'counts how often humanverification middleware had an error', []);
+        $counter->inc();
+    }
+}
diff --git a/chart/.gitignore b/chart/.gitignore
deleted file mode 100644
index e6b3ed643d846953e94118ea579d3ee30eda8c9e..0000000000000000000000000000000000000000
--- a/chart/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-charts/*
diff --git a/chart/.gitlab-ci.yml b/chart/.gitlab-ci.yml
deleted file mode 100644
index a20ff2750f793aa68a7aec7fb624f0c6aef7874e..0000000000000000000000000000000000000000
--- a/chart/.gitlab-ci.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-image: "registry.gitlab.com/gitlab-org/gitlab-build-images:alpine-helm"
-
-stages:
-  - test
-  - release
-
-lint:
-  stage: test
-  script:
-    - helm lint .
-
-release-chart:
-  stage: release
-  script:
-    - curl --fail --request POST --form "token=$CI_JOB_TOKEN" --form ref=master https://gitlab.com/api/v4/projects/2860651/trigger/pipeline
-  only:
-    - master@gitlab-org/charts/auto-deploy-app
diff --git a/chart/.helmignore b/chart/.helmignore
deleted file mode 100644
index f0c13194444163d1cba5c67d9e79231a62bc8f44..0000000000000000000000000000000000000000
--- a/chart/.helmignore
+++ /dev/null
@@ -1,21 +0,0 @@
-# Patterns to ignore when building packages.
-# This supports shell glob matching, relative path matching, and
-# negation (prefixed with !). Only one pattern per line.
-.DS_Store
-# Common VCS dirs
-.git/
-.gitignore
-.bzr/
-.bzrignore
-.hg/
-.hgignore
-.svn/
-# Common backup files
-*.swp
-*.bak
-*.tmp
-*~
-# Various IDEs
-.project
-.idea/
-*.tmproj
diff --git a/chart/CONTRIBUTING.md b/chart/CONTRIBUTING.md
index 589986f81fb88cbe8fb80647b6eb2bc1e1cfd89a..2354acbbc56c5570432f50fa7327eac208bba6e1 100644
--- a/chart/CONTRIBUTING.md
+++ b/chart/CONTRIBUTING.md
@@ -23,4 +23,31 @@ _This notice should stay as the first item in the CONTRIBUTING.md file._
 We want to create a welcoming environment for everyone who is interested
 in contributing. Please visit our [Code of Conduct
 page](https://about.gitlab.com/contributing/code-of-conduct) to learn
-more about our committment to an open and welcoming environment.
+more about our commitment to an open and welcoming environment.
+
+## Merge request guidelines
+
+Below are some guidelines for merge requests:
+
+- Any new configuration option should be documented in
+  the `Configuration` section in README.md.
+- For any template changes, we encourage a test case be added or
+  updated in the
+  [template tests](https://gitlab.com/gitlab-org/charts/auto-deploy-app/-/blob/master/test/template_test.go).
+
+### Working with the tests
+
+The tests are written in [Go](https://golang.org) (version 1.13 or later,
+with [modules enabled](https://golang.org/cmd/go/#hdr-Module_support)) using
+the [Terratest](https://github.com/gruntwork-io/terratest) library. To work
+on the tests, you need to have [Helm 2](https://v2.helm.sh/docs/) and
+[Go](https://golang.org) installed.
+
+To run the tests, run the following commands from the root of your copy of `auto-deploy-app`:
+
+```shell
+helm init --client-only               # required only once
+helm dependency build .               # required only once
+cd test
+GO111MODULE=auto go test .            # required for every change to the tests or the template
+```
diff --git a/chart/Chart.yaml b/chart/Chart.yaml
index 66468482be5abf74f69cc3071985aaca34e77b52..87e9a4cf8d0b3c539b3a34fd333fce0335ec5058 100644
--- a/chart/Chart.yaml
+++ b/chart/Chart.yaml
@@ -1,5 +1,5 @@
 apiVersion: v1
 description: GitLab's Auto-deploy Helm Chart
 name: auto-deploy-app
-version: 0.4.0
+version: 1.0.3
 icon: https://gitlab.com/gitlab-com/gitlab-artwork/raw/master/logo/logo-square.png
diff --git a/chart/README.md b/chart/README.md
index a56d2c0167abf8722fb5353f9b24f203a421c101..095df11e46134d8d0a0602ea6a774e41b0375c8b 100644
--- a/chart/README.md
+++ b/chart/README.md
@@ -1,5 +1,14 @@
 # GitLab's Auto-deploy Helm Chart
 
+## Deprecation Notice
+
+GitLab is moving all development for `auto-deploy-app` into [`auto-deploy-image`](https://gitlab.com/gitlab-org/cluster-integration/auto-deploy-image). 
+Going forward, the `auto-deploy-app` Helm chart will be bundled with `auto-deploy-image`
+and will no longer released as a stand-alone Helm chart. Existing releases of `auto-deploy-app`
+will remain in [GitLab's chart registry](http://charts.gitlab.io/).
+
+If you have any questions, please ask in <https://gitlab.com/gitlab-org/charts/auto-deploy-app/-/issues/70>.
+
 ## Requirements
 
 - Helm `2.9.0` and above is required in order support `"helm.sh/hook-delete-policy": before-hook-creation` for migrations
@@ -9,6 +18,9 @@
 | Parameter                     | Description | Default                            |
 | ---                           | ---         | ---                                |
 | replicaCount                  |             | `1`                                |
+| strategyType                  | Pod deployment [strategy](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy) | `nil` |
+| enableSelector                | If `true`, enables selector field for the deployment. Only applicable for `extensions/v1beta1`, as selector field will always be included for `apps/v1` | `nil` |
+| deploymentApiVersion          | Sets `apiVersion` field for the deployment. Can be set to either `extensions/v1beta1` or `apps/v1`. | `extensions/v1beta1` |
 | image.repository              |             | `gitlab.example.com/group/project` |
 | image.tag                     |             | `stable`                           |
 | image.pullPolicy              |             | `Always`                           |
@@ -17,7 +29,7 @@
 | application.track             |             | `stable`                           |
 | application.tier              |             | `web`                              |
 | application.migrateCommand    | If present, this variable will run as a shell command within an application Container as a Helm pre-upgrade Hook. Intended to run migration commands. | `nil` |
-| application.initializeCommand | If present, this variable will run as shall command within an application Container as a Helm post-install Hook. Intended to run database initialization commands. | `nil` |
+| application.initializeCommand | If present, this variable will run as shell command within an application Container as a Helm post-install Hook. Intended to run database initialization commands. When set, the Deployment resource will be skipped.| `nil` |
 | application.secretName        | Pass in the name of a Secret which the deployment will [load all key-value pairs from the Secret as environment variables](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables) in the application container. | `nil` |
 | application.secretChecksum    | Pass in the checksum of the secrets referenced by `application.secretName`. | `nil` |
 | hpa.enabled                   | If true, enables horizontal pod autoscaler. A resource request is also required to be set, such as `resources.requests.cpu: 200m`.| `false` |
@@ -37,21 +49,25 @@
 | service.commonName            | If present, this will define the ssl certificate common name to be used by CertManager. `service.url` and `service.additionalHosts` will be added as Subject Alternative Names (SANs) | `nil` |
 | service.externalPort          |             | `5000`                             |
 | service.internalPort          |             | `5000`                             |
+| ingress.enabled               | If true, enables ingress | `true`                |
 | ingress.tls.enabled           | If true, enables SSL | `true`                    |
 | ingress.tls.secretName        | Name of the secret used to terminate SSL traffic | `""` |
 | ingress.modSecurity.enabled | Enable custom configuration for modsecurity, defaulting to [the Core Rule Set](https://coreruleset.org) | `false` |
 | ingress.modSecurity.secRuleEngine | Configuration for [ModSecurity's rule engine](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecRuleEngine) | `DetectionOnly` |
+| ingress.modSecurity.secRules | Configuration for custom [ModSecurity's rules](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#secrule) | `nil` |
 | ingress.annotations           | Ingress annotations | `{kubernetes.io/tls-acme: "true", kubernetes.io/ingress.class: "nginx"}` |
 | livenessProbe.path            | Path to access on the HTTP server on periodic probe of container liveness. | `/`                                |
 | livenessProbe.scheme          | Scheme to access the HTTP server (HTTP or HTTPS). | `HTTP`                                |
 | livenessProbe.initialDelaySeconds | # of seconds after the container has started before liveness probes are initiated. | `15`                               |
 | livenessProbe.timeoutSeconds  | # of seconds after which the liveness probe times out. | `15`                               |
 | livenessProbe.probeType       | Type of [liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes) to use. | `httpGet`
+| livenessProbe.command         | Commands for use with probe type 'exec'. | `{}`
 | readinessProbe.path           | Path to access on the HTTP server on periodic probe of container readiness. | `/`                                |
 | readinessProbe.scheme         | Scheme to access the HTTP server (HTTP or HTTPS). | `HTTP`                                |
 | readinessProbe.initialDelaySeconds | # of seconds after the container has started before readiness probes are initiated. | `5`                                |
 | readinessProbe.timeoutSeconds | # of seconds after which the readiness probe times out. | `3`                                |
 | readinessProbe.probeType     | Type of [readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes) to use. | `httpGet`
+| readinessProbe.command       | Commands for use with probe type 'exec'. | `{}`
 | postgresql.enabled            |             | `true`                             |
 | postgresql.managed            | If true, this will provision a managed Postgres instance via crossplane.            | `false`                             |
 | postgresql.managedClassSelector            | This will allow provisioning a Postgres instance based on label selectors via Crossplane, eg: `managedClassSelector.matchLabels.stack: gitlab`. The `postgresql.managed` value should be true as well for this to be honoured. [Crossplane Configuration](https://docs.gitlab.com/ee/user/clusters/applications.html#crossplane)            | `{}`                             |
@@ -59,3 +75,10 @@
 | podDisruptionBudget.maxUnavailable |             | `1`                            |
 | podDisruptionBudget.minAvailable | If present, this variable will configure minAvailable in the PodDisruptionBudget. :warning: if you have `replicaCount: 1` and `podDisruptionBudget.minAvailable: 1` `kubectl drain` will be blocked.              | `nil`                            |
 | prometheus.metrics            | Annotates the service for prometheus auto-discovery. Also denies access to the `/metrics` endpoint from external addresses with Ingress. | `false` |
+| networkPolicy.enabled         | Enable container network policy | `false` |
+| networkPolicy.spec            | [Network policy](https://kubernetes.io/docs/concepts/services-networking/network-policies/) definition | `{ podSelector: { matchLabels: {} }, ingress: [{ from: [{ podSelector: { matchLabels: {} } }, { namespaceSelector: { matchLabels: { app.gitlab.com/managed_by: gitlab } } }] }] }` |
+
+## PostgreSQL
+
+This chart depends on version 0.7.1 of the `stable/postgresql` chart.
+For reference the source code for this specific version can be found at https://github.com/helm/charts/tree/b90ad657e1a226eb52c3eb6a2a95ba3d6d494f58/stable/postgresql
\ No newline at end of file
diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt
index 0ef42bbda93bc99a87ed5b4cd0ba6c86497be815..5491ce9318e4fd2578c6c86de79f2bd268d00739 100644
--- a/chart/templates/NOTES.txt
+++ b/chart/templates/NOTES.txt
@@ -1,5 +1,12 @@
-{{- if .Values.service.enabled -}}
-Application should be accessible at: {{ .Values.service.url }}
+{{- if and .Values.ingress.enabled .Values.service.enabled -}}
+Application should be accessible at
+
+    {{ .Values.service.url }}
 {{- else -}}
-Application will be accessible at: {{ .Values.service.url }} when you deploy stable track.
+Application was deployed reusing the service at
+
+    {{ .Values.service.url }}
+
+It will share a load balancer with the previous release (or be unavailable if
+no service or ingress was previously deployed).
 {{- end -}}
diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl
index 913145e6ae42383d3f2810a035fc750dd1b0c7b4..add519dae35c3fa7a8f8dd4c67c1bd45b2641594 100644
--- a/chart/templates/_helpers.tpl
+++ b/chart/templates/_helpers.tpl
@@ -20,6 +20,14 @@ We truncate at 63 chars because some Kubernetes name fields are limited to this
 {{- printf "%s" $releaseName | trunc 63 | trimSuffix "-" -}}
 {{- end -}}
 
+{{- define "imagename" -}}
+{{- if eq .Values.image.tag "" -}}
+{{- .Values.image.repository -}}
+{{- else -}}
+{{- printf "%s:%s" .Values.image.repository .Values.image.tag -}}
+{{- end -}}
+{{- end -}}
+
 {{- define "trackableappname" -}}
 {{- $trackableName := printf "%s-%s" (include "appname" .) .Values.application.track -}}
 {{- $trackableName | trimSuffix "-stable" | trunc 63 | trimSuffix "-" -}}
@@ -29,5 +37,14 @@ We truncate at 63 chars because some Kubernetes name fields are limited to this
 Get a hostname from URL
 */}}
 {{- define "hostname" -}}
-{{- . | trimPrefix "http://" |  trimPrefix "https://" | trimSuffix "/" | quote -}}
+{{- . | trimPrefix "http://" |  trimPrefix "https://" | trimSuffix "/" | trim | quote -}}
 {{- end -}}
+
+{{/*
+Get SecRule's arguments with unescaped single&double quotes
+*/}}
+{{- define "secrule" -}}
+{{- $operator := .operator | quote | replace "\"" "\\\"" | replace "'" "\\'" -}}
+{{- $action := .action | quote | replace "\"" "\\\"" | replace "'" "\\'" -}}
+{{- printf "SecRule %s %s %s" .variable $operator $action -}}
+{{- end -}}
\ No newline at end of file
diff --git a/chart/templates/db-initialize-job.yaml b/chart/templates/db-initialize-job.yaml
index 12fd5112744e2ae3504a71c1bdd5edabd2685657..535731a51a2093396cb212f1b865234dd93ec395 100644
--- a/chart/templates/db-initialize-job.yaml
+++ b/chart/templates/db-initialize-job.yaml
@@ -24,7 +24,7 @@ spec:
 {{ toYaml .Values.image.secrets | indent 10 }}
       containers:
       - name: {{ .Chart.Name }}
-        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        image: {{ template "imagename" . }}
         command: ["/bin/sh"]
         args: ["-c", "{{ .Values.application.initializeCommand }}"]
         imagePullPolicy: {{ .Values.image.pullPolicy }}
@@ -36,4 +36,8 @@ spec:
         env:
         - name: DATABASE_URL
           value: {{ .Values.application.database_url | quote }}
+        - name: GITLAB_ENVIRONMENT_NAME
+          value: {{ .Values.gitlab.envName | quote }}
+        - name: GITLAB_ENVIRONMENT_URL
+          value: {{ .Values.gitlab.envURL | quote }}
 {{- end -}}
diff --git a/chart/templates/db-migrate-hook.yaml b/chart/templates/db-migrate-hook.yaml
index b2d5aa7f613ad27fd728b48dcc0f83f23bdf9d56..78b871fea1421f5051acd415954d204c0316d1cf 100644
--- a/chart/templates/db-migrate-hook.yaml
+++ b/chart/templates/db-migrate-hook.yaml
@@ -24,7 +24,7 @@ spec:
 {{ toYaml .Values.image.secrets | indent 10 }}
       containers:
       - name: {{ .Chart.Name }}
-        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        image: {{ template "imagename" . }}
         command: ["/bin/sh"]
         args: ["-c", "{{ .Values.application.migrateCommand }}"]
         imagePullPolicy: {{ .Values.image.pullPolicy }}
@@ -36,4 +36,8 @@ spec:
         env:
         - name: DATABASE_URL
           value: {{ .Values.application.database_url | quote }}
+        - name: GITLAB_ENVIRONMENT_NAME
+          value: {{ .Values.gitlab.envName | quote }}
+        - name: GITLAB_ENVIRONMENT_URL
+          value: {{ .Values.gitlab.envURL | quote }}
 {{- end -}}
diff --git a/chart/templates/deployment.yaml b/chart/templates/deployment.yaml
index b790fdcba3e3bb955c5c11bbdb36f56de234240a..25bf29e5e87ae243868f6199f8477b10c6f308db 100644
--- a/chart/templates/deployment.yaml
+++ b/chart/templates/deployment.yaml
@@ -1,5 +1,5 @@
 {{- if not .Values.application.initializeCommand -}}
-apiVersion: extensions/v1beta1
+apiVersion: {{ default "extensions/v1beta1" .Values.deploymentApiVersion }}
 kind: Deployment
 metadata:
   name: {{ template "trackableappname" . }}
@@ -14,7 +14,19 @@ metadata:
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
+{{- if or .Values.enableSelector (eq (default "extensions/v1beta1" .Values.deploymentApiVersion) "apps/v1") }}
+  selector:
+    matchLabels:
+      app: {{ template "appname" . }}
+      track: "{{ .Values.application.track }}"
+      tier: "{{ .Values.application.tier }}"
+      release: {{ .Release.Name }}
+{{- end }}
   replicas: {{ .Values.replicaCount }}
+{{- if .Values.strategyType }}
+  strategy:
+    type: {{ .Values.strategyType | quote }}
+{{- end }}
   template:
     metadata:
       annotations:
@@ -30,25 +42,28 @@ spec:
         tier: "{{ .Values.application.tier }}"
         release: {{ .Release.Name }}
     spec:
-      affinity:
-        nodeAffinity:
-          requiredDuringSchedulingIgnoredDuringExecution:
-            nodeSelectorTerms:
-            - matchExpressions:
-              - key: worker
-                operator: NotIn
-                values:
-                - temp
       imagePullSecrets:
 {{ toYaml .Values.image.secrets | indent 10 }}
-      securityContext:
-        fsGroup: 2000
       volumes:
       - name: mglogs-persistent-storage
         persistentVolumeClaim:
           claimName: mg-logs
+      - name: env-files
+        secret:
+          secretName: metager-env
+      - name: sumas
+        secret:
+          secretName: metager-sumas
+      - name: sumas-en
+        secret:
+          secretName: metager-sumas-en
+      - name: blacklist
+        secret:
+          secretName: metager-blacklist
+      - name: blacklist-ad
+        secret:
+          secretName: metager-ad-blacklist
       containers:
-      # Main PHP-FPM Container
       - name: {{ .Chart.Name }}-phpfpm
         image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
         imagePullPolicy: {{ .Values.image.pullPolicy }}
@@ -81,6 +96,42 @@ spec:
         - name: mglogs-persistent-storage
           mountPath: /html/storage/logs/metager
           readOnly: false
+        - name: env-files
+          mountPath: /root/.env
+          subPath: .env
+          readOnly: true
+        - name: env-files
+          mountPath: /html/database/seeds/UsersSeeder.php
+          subPath: UsersSeeder.php
+          readOnly: true
+        - name: env-files
+          mountPath: /html/config/spam.txt
+          subPath: spam.txt
+          readOnly: true
+        - name: sumas
+          mountPath: /html/config/sumas.json
+          subPath: sumas.json
+          readOnly: true
+        - name: sumas-en
+          mountPath: /html/config/sumasEn.json
+          subPath: sumasEn.json
+          readOnly: true
+        - name: blacklist
+          mountPath: /html/config/blacklistUrl.txt
+          subPath: blacklistUrl.txt
+          readOnly: true
+        - name: blacklist
+          mountPath: /html/config/blacklistDomains.txt
+          subPath: blacklistDomains.txt
+          readOnly: true
+        - name: blacklist-ad
+          mountPath: /html/config/adBlacklistUrl.txt
+          subPath: adBlacklistUrl.txt
+          readOnly: true
+        - name: blacklist-ad
+          mountPath: /html/config/adBlacklistDomains.txt
+          subPath: adBlacklistDomains.txt
+          readOnly: true
         resources:
           requests:
             cpu: 500m
diff --git a/chart/templates/ingress.yaml b/chart/templates/ingress.yaml
index ec7cba476deee3d8e013c663c8da077cffda1d9e..b315cdbbd8db857965369e30427064371dc7df55 100644
--- a/chart/templates/ingress.yaml
+++ b/chart/templates/ingress.yaml
@@ -1,4 +1,4 @@
-{{- if .Values.service.enabled -}}
+{{- if and (.Values.service.enabled) (eq .Values.application.track "stable") (or (.Values.ingress.enabled) (not (hasKey .Values.ingress "enabled"))) -}}
 apiVersion: extensions/v1beta1
 kind: Ingress
 metadata:
@@ -12,10 +12,15 @@ metadata:
 {{- if .Values.ingress.annotations }}
 {{ toYaml .Values.ingress.annotations | indent 4 }}
 {{- end }}
-{{- if and .Values.ingress.modSecurity .Values.ingress.modSecurity.enabled }}
+{{- with .Values.ingress.modSecurity }}
+{{- if .enabled }}
+    nginx.ingress.kubernetes.io/modsecurity-transaction-id: "$server_name-$request_id"
     nginx.ingress.kubernetes.io/modsecurity-snippet: |
-      SecRuleEngine {{ .Values.ingress.modSecurity.secRuleEngine | default "DetectionOnly" | title }}
-
+      SecRuleEngine {{ .secRuleEngine | default "DetectionOnly" | title }}
+{{- range $rule := .secRules }}
+{{ (include "secrule" $rule) | indent 6 }}
+{{- end }}
+{{- end }}
 {{- end }}
 {{- if .Values.prometheus.metrics }}
     nginx.ingress.kubernetes.io/server-snippet: |-
@@ -34,7 +39,7 @@ spec:
     - {{ template "hostname" .Values.service.url }}
 {{- if .Values.service.additionalHosts }}
 {{- range $host := .Values.service.additionalHosts }}
-    - {{ $host }}
+    - {{ template "hostname" $host }}
 {{- end -}}
 {{- end }}
     secretName: {{ .Values.ingress.tls.secretName | default (printf "%s-tls" (include "fullname" .)) }}
@@ -48,10 +53,6 @@ spec:
         backend:
           serviceName: {{ template "fullname" . }}
           servicePort: {{ .Values.service.externalPort }}
-      - path: /wsb
-        backend:
-          serviceName: wsb
-          servicePort: 80
 {{- if .Values.service.commonName }}
   - host: {{ template "hostname" .Values.service.commonName }}
     http:
@@ -59,7 +60,7 @@ spec:
 {{- end -}}
 {{- if .Values.service.additionalHosts }}
 {{- range $host := .Values.service.additionalHosts }}
-  - host: {{ $host }}
+  - host: {{ template "hostname" $host }}
     http:
       <<: *httpRule
 {{- end -}}
diff --git a/chart/templates/network-policy.yaml b/chart/templates/network-policy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..79c0ed662514d8deb99bb19382105f8f445ce288
--- /dev/null
+++ b/chart/templates/network-policy.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.networkPolicy.enabled -}}
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: {{ template "fullname" . }}
+  labels:
+    app: {{ template "appname" . }}
+    chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+spec:
+{{ toYaml .Values.networkPolicy.spec | indent 2 }}
+{{- end -}}
diff --git a/chart/templates/service.yaml b/chart/templates/service.yaml
index 47c59e2c25f19ed1440bd6b142746c932f2c3f92..676406be11de5feedd801876627055405ac51670 100644
--- a/chart/templates/service.yaml
+++ b/chart/templates/service.yaml
@@ -1,4 +1,4 @@
-{{- if .Values.service.enabled -}}
+{{- if and (.Values.service.enabled) (eq .Values.application.track "stable") -}}
 apiVersion: v1
 kind: Service
 metadata:
diff --git a/chart/templates/worker-deployment.yaml b/chart/templates/worker-deployment.yaml
index c59e78efa578deebe1742eea34b71e3271bc1312..050e234195e1064dc1ace110946719a1444aded2 100644
--- a/chart/templates/worker-deployment.yaml
+++ b/chart/templates/worker-deployment.yaml
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: List
 items:
 {{- range $workerName, $workerConfig :=  .Values.workers }}
-- apiVersion: extensions/v1beta1
+- apiVersion: {{ default "extensions/v1beta1" $.Values.deploymentApiVersion }}
   kind: Deployment
   metadata:
     name: {{ template "trackableappname" $ }}-{{ $workerName }}
@@ -17,7 +17,18 @@ items:
       release: {{ $.Release.Name }}
       heritage: {{ $.Release.Service }}
   spec:
+  {{- if or $.Values.enableSelector (eq (default "extensions/v1beta1" $.Values.deploymentApiVersion) "apps/v1") }}
+    selector:
+      matchLabels:
+        track: "{{ $.Values.application.track }}"
+        tier: worker
+        release: {{ $.Release.Name }}
+  {{- end }}
     replicas: {{ $workerConfig.replicaCount }}
+  {{- if $workerConfig.strategyType }}
+    strategy:
+      type: {{ $workerConfig.strategyType | quote }}
+  {{- end  }}
     template:
       metadata:
         annotations:
@@ -37,7 +48,7 @@ items:
         terminationGracePeriodSeconds: {{ $workerConfig.terminationGracePeriodSeconds }}
         containers:
         - name: {{ $.Chart.Name }}-{{ $workerName }}
-          image: "{{ $.Values.image.repository }}:{{ $.Values.image.tag }}"
+          image: {{ template "imagename" $ }}
           command:
           {{- range $workerConfig.command }}
           - {{ . }}
@@ -52,7 +63,7 @@ items:
           - name: DATABASE_URL
             value: {{ $.Values.application.database_url | quote }}
           - name: GITLAB_ENVIRONMENT_NAME
-            value: {{ $.Values.gitlab.envName }}
+            value: {{ $.Values.gitlab.envName | quote }}
           livenessProbe:
 {{- if eq $.Values.livenessProbe.probeType "httpGet" }}
             httpGet:
@@ -72,7 +83,7 @@ items:
               scheme: {{ $.Values.readinessProbe.scheme }}
               port: {{ $.Values.service.internalPort }}
 {{- else if eq $.Values.readinessProbe.probeType "tcpSocket" }}
-          tcpSocket:
+            tcpSocket:
               port: {{ $.Values.service.internalPort }}
 {{- end }}
             initialDelaySeconds: {{ $.Values.readinessProbe.initialDelaySeconds }}
@@ -87,6 +98,6 @@ items:
                 {{- end }}
           {{- end }}
           resources:
-  {{ toYaml $.Values.resources | indent 14 }}
+{{ toYaml $.Values.resources | indent 12 }}
 {{- end -}}
 {{- end -}}
diff --git a/chart/test/go.mod b/chart/test/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..4754f016d43ac382520197869527dc51191fb013
--- /dev/null
+++ b/chart/test/go.mod
@@ -0,0 +1,10 @@
+module gitlab.com/gitlab-org/charts/auto-deploy-app/test
+
+go 1.13
+
+require (
+	github.com/gruntwork-io/terratest v0.23.0
+	github.com/stretchr/testify v1.4.0
+	k8s.io/api v0.0.0-20181110191121-a33c8200050f
+	k8s.io/apimachinery v0.0.0-20190704094520-6f131bee5e2c
+)
diff --git a/chart/test/go.sum b/chart/test/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..8b5b570079168ea0282e9f6e0a576479efc4fd86
--- /dev/null
+++ b/chart/test/go.sum
@@ -0,0 +1,218 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+github.com/Azure/azure-sdk-for-go v32.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
+github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
+github.com/Azure/go-autorest/autorest v0.9.1/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
+github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
+github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
+github.com/Azure/go-autorest/autorest/azure/auth v0.3.0/go.mod h1:CI4BQYBct8NS7BXNBBX+RchsFsUu5+oz+OSyR/ZIi7U=
+github.com/Azure/go-autorest/autorest/azure/cli v0.3.0/go.mod h1:rNYMNAefZMRowqCV0cVhr/YDW5dD7afFq9nXAXL4ykE=
+github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
+github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
+github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
+github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
+github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
+github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
+github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/aws/aws-sdk-go v1.23.8 h1:G/azJoBN0pnhB3B+0eeC4yyVFYIIad6bbzg6wwtImqk=
+github.com/aws/aws-sdk-go v1.23.8/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
+github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
+github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c h1:ZfSZ3P3BedhKGUhzj7BQlPSU4OvT6tfOKe3DVHzOA7s=
+github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
+github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
+github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1 h1:yY9rWGoXv1U5pl4gxqlULARMQD7x0QG85lqEXTWysik=
+github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM=
+github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
+github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 h1:skJKxRtNmevLqnayafdLe2AsenqRupVmzZSqrvb5caU=
+github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
+github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c h1:jWtZjFEUE/Bz0IeIhqCnyZ3HG6KRXSntXe4SjtuTH7c=
+github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
+github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
+github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
+github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/gruntwork-io/gruntwork-cli v0.5.1 h1:mVmVsFubUSLSCO8bGigI63HXzvzkC0uWXzm4dd9pXRg=
+github.com/gruntwork-io/gruntwork-cli v0.5.1/go.mod h1:IBX21bESC1/LGoV7jhXKUnTQTZgQ6dYRsoj/VqxUSZQ=
+github.com/gruntwork-io/terratest v0.23.0 h1:JmGeqO0r5zRLAV55T67NEmPZArz9lN3RKd0moAKhIT4=
+github.com/gruntwork-io/terratest v0.23.0/go.mod h1:+fVff0FQYuRzCF3LKpKF9ac+4w384LDcwLZt7O/KmEE=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI=
+github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
+github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
+github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok=
+github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
+github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
+github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
+github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4 h1:Hynbrlo6LbYI3H1IqXpkVDOcX/3HiPdhVEuyj5a59RM=
+golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.9.1-0.20190821000710-329ecc3c9c34/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+k8s.io/api v0.0.0-20181110191121-a33c8200050f h1:BH667AnNr487/iTtY35X+m6c2S8HL02Rft1PFK93kmw=
+k8s.io/api v0.0.0-20181110191121-a33c8200050f/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
+k8s.io/apimachinery v0.0.0-20190704094520-6f131bee5e2c h1:vdEIiO5B0/3EVwZboF6qyYn5kVDdvCbaGSzr7Rcx18A=
+k8s.io/apimachinery v0.0.0-20190704094520-6f131bee5e2c/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
+k8s.io/client-go v0.0.0-20190704095228-386e588352a4 h1:hqylj4/yit+/eO496/Yhgy2YxxumFpSY94YDFX6lBoU=
+k8s.io/client-go v0.0.0-20190704095228-386e588352a4/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
diff --git a/chart/test/template_test.go b/chart/test/template_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..aa69a959abd869b5e9ada5d4f2b472aa85db3ea2
--- /dev/null
+++ b/chart/test/template_test.go
@@ -0,0 +1,845 @@
+package main
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/gruntwork-io/terratest/modules/helm"
+	"github.com/gruntwork-io/terratest/modules/k8s"
+	"github.com/gruntwork-io/terratest/modules/random"
+	"github.com/stretchr/testify/require"
+	appsV1 "k8s.io/api/apps/v1"
+	coreV1 "k8s.io/api/core/v1"
+	extensions "k8s.io/api/extensions/v1beta1"
+	netV1 "k8s.io/api/networking/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+const (
+	chartName     = "auto-deploy-app-1.0.3"
+	helmChartPath = ".."
+)
+
+func TestDeploymentTemplate(t *testing.T) {
+	for _, tc := range []struct {
+		CaseName string
+		Release  string
+		Values   map[string]string
+
+		ExpectedName         string
+		ExpectedRelease      string
+		ExpectedStrategyType extensions.DeploymentStrategyType
+		ExpectedSelector     *metav1.LabelSelector
+	}{
+		{
+			CaseName: "happy",
+			Release:  "production",
+			Values: map[string]string{
+				"releaseOverride": "productionOverridden",
+			},
+			ExpectedName:         "productionOverridden",
+			ExpectedRelease:      "production",
+			ExpectedStrategyType: extensions.DeploymentStrategyType(""),
+		},
+		{
+			CaseName:             "long release name",
+			Release:              strings.Repeat("r", 80),
+			ExpectedName:         strings.Repeat("r", 63),
+			ExpectedRelease:      strings.Repeat("r", 80),
+			ExpectedStrategyType: extensions.DeploymentStrategyType(""),
+		},
+		{
+			CaseName: "strategyType",
+			Release:  "production",
+			Values: map[string]string{
+				"strategyType": "Recreate",
+			},
+			ExpectedName:         "production",
+			ExpectedRelease:      "production",
+			ExpectedStrategyType: extensions.RecreateDeploymentStrategyType,
+		},
+		{
+			CaseName: "enableSelector",
+			Release:  "production",
+			Values: map[string]string{
+				"enableSelector": "true",
+			},
+			ExpectedName:         "production",
+			ExpectedRelease:      "production",
+			ExpectedStrategyType: extensions.DeploymentStrategyType(""),
+			ExpectedSelector: &metav1.LabelSelector{
+				MatchLabels: map[string]string{
+					"app":     "production",
+					"release": "production",
+					"tier":    "web",
+					"track":   "stable",
+				},
+			},
+		},
+	} {
+		t.Run(tc.CaseName, func(t *testing.T) {
+			namespaceName := "minimal-ruby-app-" + strings.ToLower(random.UniqueId())
+
+			values := map[string]string{
+				"gitlab.app": "auto-devops-examples/minimal-ruby-app",
+				"gitlab.env": "prod",
+			}
+
+			mergeStringMap(values, tc.Values)
+
+			options := &helm.Options{
+				SetValues:      values,
+				KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
+			}
+
+			output := helm.RenderTemplate(t, options, helmChartPath, tc.Release, []string{"templates/deployment.yaml"})
+
+			var deployment extensions.Deployment
+			helm.UnmarshalK8SYaml(t, output, &deployment)
+
+			require.Equal(t, tc.ExpectedName, deployment.Name)
+			require.Equal(t, tc.ExpectedStrategyType, deployment.Spec.Strategy.Type)
+
+			require.Equal(t, map[string]string{
+				"app.gitlab.com/app": "auto-devops-examples/minimal-ruby-app",
+				"app.gitlab.com/env": "prod",
+			}, deployment.Annotations)
+			require.Equal(t, map[string]string{
+				"app":      tc.ExpectedName,
+				"chart":    chartName,
+				"heritage": "Tiller",
+				"release":  tc.ExpectedRelease,
+				"tier":     "web",
+				"track":    "stable",
+			}, deployment.Labels)
+
+			require.Equal(t, tc.ExpectedSelector, deployment.Spec.Selector)
+
+			require.Equal(t, map[string]string{
+				"app.gitlab.com/app":           "auto-devops-examples/minimal-ruby-app",
+				"app.gitlab.com/env":           "prod",
+				"checksum/application-secrets": "",
+			}, deployment.Spec.Template.Annotations)
+			require.Equal(t, map[string]string{
+				"app":     tc.ExpectedName,
+				"release": tc.ExpectedRelease,
+				"tier":    "web",
+				"track":   "stable",
+			}, deployment.Spec.Template.Labels)
+		})
+	}
+
+	for _, tc := range []struct {
+		CaseName                string
+		Release                 string
+		Values                  map[string]string
+		ExpectedImageRepository string
+	}{
+		{
+			CaseName: "skaffold",
+			Release:  "production",
+			Values: map[string]string{
+				"image.repository": "skaffold",
+				"image.tag":        "",
+			},
+			ExpectedImageRepository: "skaffold",
+		},
+		{
+			CaseName: "skaffold",
+			Release:  "production",
+			Values: map[string]string{
+				"image.repository": "skaffold",
+				"image.tag":        "stable",
+			},
+			ExpectedImageRepository: "skaffold:stable",
+		},
+	} {
+		t.Run(tc.CaseName, func(t *testing.T) {
+			namespaceName := "minimal-ruby-app-" + strings.ToLower(random.UniqueId())
+
+			values := map[string]string{
+				"gitlab.app": "auto-devops-examples/minimal-ruby-app",
+				"gitlab.env": "prod",
+			}
+
+			mergeStringMap(values, tc.Values)
+
+			options := &helm.Options{
+				SetValues:      values,
+				KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
+			}
+
+			output := helm.RenderTemplate(t, options, helmChartPath, tc.Release, []string{"templates/deployment.yaml"})
+
+			var deployment appsV1.Deployment
+			helm.UnmarshalK8SYaml(t, output, &deployment)
+
+			require.Equal(t, tc.ExpectedImageRepository, deployment.Spec.Template.Spec.Containers[0].Image)
+		})
+	}
+
+	for _, tc := range []struct {
+		CaseName string
+		Release  string
+		Values   map[string]string
+
+		ExpectedName         string
+		ExpectedRelease      string
+		ExpectedStrategyType appsV1.DeploymentStrategyType
+		ExpectedSelector     *metav1.LabelSelector
+	}{
+		{
+			CaseName: "appsv1",
+			Release:  "production",
+			Values: map[string]string{
+				"deploymentApiVersion": "apps/v1",
+			},
+			ExpectedName:         "production",
+			ExpectedRelease:      "production",
+			ExpectedStrategyType: appsV1.DeploymentStrategyType(""),
+			ExpectedSelector: &metav1.LabelSelector{
+				MatchLabels: map[string]string{
+					"app":     "production",
+					"release": "production",
+					"tier":    "web",
+					"track":   "stable",
+				},
+			},
+		},
+	} {
+		t.Run(tc.CaseName, func(t *testing.T) {
+			namespaceName := "minimal-ruby-app-" + strings.ToLower(random.UniqueId())
+
+			values := map[string]string{
+				"gitlab.app": "auto-devops-examples/minimal-ruby-app",
+				"gitlab.env": "prod",
+			}
+
+			mergeStringMap(values, tc.Values)
+
+			options := &helm.Options{
+				SetValues:      values,
+				KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
+			}
+
+			output := helm.RenderTemplate(t, options, helmChartPath, tc.Release, []string{"templates/deployment.yaml"})
+
+			var deployment appsV1.Deployment
+			helm.UnmarshalK8SYaml(t, output, &deployment)
+
+			require.Equal(t, tc.ExpectedName, deployment.Name)
+			require.Equal(t, tc.ExpectedStrategyType, deployment.Spec.Strategy.Type)
+			require.Equal(t, map[string]string{
+				"app.gitlab.com/app": "auto-devops-examples/minimal-ruby-app",
+				"app.gitlab.com/env": "prod",
+			}, deployment.Annotations)
+			require.Equal(t, map[string]string{
+				"app":      tc.ExpectedName,
+				"chart":    chartName,
+				"heritage": "Tiller",
+				"release":  tc.ExpectedRelease,
+				"tier":     "web",
+				"track":    "stable",
+			}, deployment.Labels)
+
+			require.Equal(t, tc.ExpectedSelector, deployment.Spec.Selector)
+
+			require.Equal(t, map[string]string{
+				"app.gitlab.com/app":           "auto-devops-examples/minimal-ruby-app",
+				"app.gitlab.com/env":           "prod",
+				"checksum/application-secrets": "",
+			}, deployment.Spec.Template.Annotations)
+			require.Equal(t, map[string]string{
+				"app":     tc.ExpectedName,
+				"release": tc.ExpectedRelease,
+				"tier":    "web",
+				"track":   "stable",
+			}, deployment.Spec.Template.Labels)
+		})
+	}
+}
+
+func TestWorkerDeploymentTemplate(t *testing.T) {
+	for _, tc := range []struct {
+		CaseName string
+		Release  string
+		Values   map[string]string
+
+		ExpectedName        string
+		ExpectedRelease     string
+		ExpectedDeployments []workerDeploymentTestCase
+	}{
+		{
+			CaseName: "happy",
+			Release:  "production",
+			Values: map[string]string{
+				"releaseOverride":            "productionOverridden",
+				"workers.worker1.command[0]": "echo",
+				"workers.worker1.command[1]": "worker1",
+				"workers.worker2.command[0]": "echo",
+				"workers.worker2.command[1]": "worker2",
+			},
+			ExpectedName:    "productionOverridden",
+			ExpectedRelease: "production",
+			ExpectedDeployments: []workerDeploymentTestCase{
+				{
+					ExpectedName:         "productionOverridden-worker1",
+					ExpectedCmd:          []string{"echo", "worker1"},
+					ExpectedStrategyType: extensions.DeploymentStrategyType(""),
+				},
+				{
+					ExpectedName:         "productionOverridden-worker2",
+					ExpectedCmd:          []string{"echo", "worker2"},
+					ExpectedStrategyType: extensions.DeploymentStrategyType(""),
+				},
+			},
+		},
+		{
+			CaseName: "long release name",
+			Release:  strings.Repeat("r", 80),
+			Values: map[string]string{
+				"workers.worker1.command[0]": "echo",
+				"workers.worker1.command[1]": "worker1",
+			},
+			ExpectedName:    strings.Repeat("r", 63),
+			ExpectedRelease: strings.Repeat("r", 80),
+			ExpectedDeployments: []workerDeploymentTestCase{
+				{
+					ExpectedName:         strings.Repeat("r", 63) + "-worker1",
+					ExpectedCmd:          []string{"echo", "worker1"},
+					ExpectedStrategyType: extensions.DeploymentStrategyType(""),
+				},
+			},
+		},
+		{
+			CaseName: "strategyType",
+			Release:  "production",
+			Values: map[string]string{
+				"workers.worker1.command[0]":   "echo",
+				"workers.worker1.command[1]":   "worker1",
+				"workers.worker1.strategyType": "Recreate",
+			},
+			ExpectedName:    "production",
+			ExpectedRelease: "production",
+			ExpectedDeployments: []workerDeploymentTestCase{
+				{
+					ExpectedName:         "production" + "-worker1",
+					ExpectedCmd:          []string{"echo", "worker1"},
+					ExpectedStrategyType: extensions.RecreateDeploymentStrategyType,
+				},
+			},
+		},
+		{
+			CaseName: "enableSelector",
+			Release:  "production",
+			Values: map[string]string{
+				"enableSelector":             "true",
+				"workers.worker1.command[0]": "echo",
+				"workers.worker1.command[1]": "worker1",
+				"workers.worker2.command[0]": "echo",
+				"workers.worker2.command[1]": "worker2",
+			},
+			ExpectedName:    "production",
+			ExpectedRelease: "production",
+			ExpectedDeployments: []workerDeploymentTestCase{
+				{
+					ExpectedName:         "production-worker1",
+					ExpectedCmd:          []string{"echo", "worker1"},
+					ExpectedStrategyType: extensions.DeploymentStrategyType(""),
+					ExpectedSelector: &metav1.LabelSelector{
+						MatchLabels: map[string]string{
+							"release": "production",
+							"tier":    "worker",
+							"track":   "stable",
+						},
+					},
+				},
+				{
+					ExpectedName:         "production-worker2",
+					ExpectedCmd:          []string{"echo", "worker2"},
+					ExpectedStrategyType: extensions.DeploymentStrategyType(""),
+					ExpectedSelector: &metav1.LabelSelector{
+						MatchLabels: map[string]string{
+							"release": "production",
+							"tier":    "worker",
+							"track":   "stable",
+						},
+					},
+				},
+			},
+		},
+	} {
+		t.Run(tc.CaseName, func(t *testing.T) {
+			namespaceName := "minimal-ruby-app-" + strings.ToLower(random.UniqueId())
+
+			values := map[string]string{
+				"gitlab.app": "auto-devops-examples/minimal-ruby-app",
+				"gitlab.env": "prod",
+			}
+
+			mergeStringMap(values, tc.Values)
+
+			options := &helm.Options{
+				SetValues:      values,
+				KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
+			}
+
+			output := helm.RenderTemplate(t, options, helmChartPath, tc.Release, []string{"templates/worker-deployment.yaml"})
+
+			var deployments deploymentList
+			helm.UnmarshalK8SYaml(t, output, &deployments)
+
+			require.Len(t, deployments.Items, len(tc.ExpectedDeployments))
+			for i, expectedDeployment := range tc.ExpectedDeployments {
+				deployment := deployments.Items[i]
+
+				require.Equal(t, expectedDeployment.ExpectedName, deployment.Name)
+				require.Equal(t, expectedDeployment.ExpectedStrategyType, deployment.Spec.Strategy.Type)
+
+				require.Equal(t, map[string]string{
+					"app.gitlab.com/app": "auto-devops-examples/minimal-ruby-app",
+					"app.gitlab.com/env": "prod",
+				}, deployment.Annotations)
+				require.Equal(t, map[string]string{
+					"chart":    chartName,
+					"heritage": "Tiller",
+					"release":  tc.ExpectedRelease,
+					"tier":     "worker",
+					"track":    "stable",
+				}, deployment.Labels)
+
+				require.Equal(t, expectedDeployment.ExpectedSelector, deployment.Spec.Selector)
+
+				require.Equal(t, map[string]string{
+					"app.gitlab.com/app":           "auto-devops-examples/minimal-ruby-app",
+					"app.gitlab.com/env":           "prod",
+					"checksum/application-secrets": "",
+				}, deployment.Spec.Template.Annotations)
+				require.Equal(t, map[string]string{
+					"release": tc.ExpectedRelease,
+					"tier":    "worker",
+					"track":   "stable",
+				}, deployment.Spec.Template.Labels)
+
+				require.Len(t, deployment.Spec.Template.Spec.Containers, 1)
+				require.Equal(t, expectedDeployment.ExpectedCmd, deployment.Spec.Template.Spec.Containers[0].Command)
+			}
+		})
+	}
+
+	for _, tc := range []struct {
+		CaseName string
+		Release  string
+		Values   map[string]string
+
+		ExpectedName        string
+		ExpectedRelease     string
+		ExpectedDeployments []workerDeploymentAppsV1TestCase
+	}{
+		{
+			CaseName: "appsv1",
+			Release:  "production",
+			Values: map[string]string{
+				"deploymentApiVersion":       "apps/v1",
+				"workers.worker1.command[0]": "echo",
+				"workers.worker1.command[1]": "worker1",
+				"workers.worker2.command[0]": "echo",
+				"workers.worker2.command[1]": "worker2",
+			},
+			ExpectedName:    "production",
+			ExpectedRelease: "production",
+			ExpectedDeployments: []workerDeploymentAppsV1TestCase{
+				{
+					ExpectedName:         "production-worker1",
+					ExpectedCmd:          []string{"echo", "worker1"},
+					ExpectedStrategyType: appsV1.DeploymentStrategyType(""),
+					ExpectedSelector: &metav1.LabelSelector{
+						MatchLabels: map[string]string{
+							"release": "production",
+							"tier":    "worker",
+							"track":   "stable",
+						},
+					},
+				},
+				{
+					ExpectedName:         "production-worker2",
+					ExpectedCmd:          []string{"echo", "worker2"},
+					ExpectedStrategyType: appsV1.DeploymentStrategyType(""),
+					ExpectedSelector: &metav1.LabelSelector{
+						MatchLabels: map[string]string{
+							"release": "production",
+							"tier":    "worker",
+							"track":   "stable",
+						},
+					},
+				},
+			},
+		},
+	} {
+		t.Run(tc.CaseName, func(t *testing.T) {
+			namespaceName := "minimal-ruby-app-" + strings.ToLower(random.UniqueId())
+
+			values := map[string]string{
+				"gitlab.app": "auto-devops-examples/minimal-ruby-app",
+				"gitlab.env": "prod",
+			}
+
+			mergeStringMap(values, tc.Values)
+
+			options := &helm.Options{
+				SetValues:      values,
+				KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
+			}
+
+			output := helm.RenderTemplate(t, options, helmChartPath, tc.Release, []string{"templates/worker-deployment.yaml"})
+
+			var deployments deploymentAppsV1List
+			helm.UnmarshalK8SYaml(t, output, &deployments)
+
+			require.Len(t, deployments.Items, len(tc.ExpectedDeployments))
+			for i, expectedDeployment := range tc.ExpectedDeployments {
+				deployment := deployments.Items[i]
+
+				require.Equal(t, expectedDeployment.ExpectedName, deployment.Name)
+				require.Equal(t, expectedDeployment.ExpectedStrategyType, deployment.Spec.Strategy.Type)
+
+				require.Equal(t, map[string]string{
+					"app.gitlab.com/app": "auto-devops-examples/minimal-ruby-app",
+					"app.gitlab.com/env": "prod",
+				}, deployment.Annotations)
+				require.Equal(t, map[string]string{
+					"chart":    chartName,
+					"heritage": "Tiller",
+					"release":  tc.ExpectedRelease,
+					"tier":     "worker",
+					"track":    "stable",
+				}, deployment.Labels)
+
+				require.Equal(t, expectedDeployment.ExpectedSelector, deployment.Spec.Selector)
+
+				require.Equal(t, map[string]string{
+					"app.gitlab.com/app":           "auto-devops-examples/minimal-ruby-app",
+					"app.gitlab.com/env":           "prod",
+					"checksum/application-secrets": "",
+				}, deployment.Spec.Template.Annotations)
+				require.Equal(t, map[string]string{
+					"release": tc.ExpectedRelease,
+					"tier":    "worker",
+					"track":   "stable",
+				}, deployment.Spec.Template.Labels)
+
+				require.Len(t, deployment.Spec.Template.Spec.Containers, 1)
+				require.Equal(t, expectedDeployment.ExpectedCmd, deployment.Spec.Template.Spec.Containers[0].Command)
+			}
+		})
+	}
+}
+
+func TestNetworkPolicyDeployment(t *testing.T) {
+	releaseName := "network-policy-test"
+	templates := []string{"templates/network-policy.yaml"}
+	expectedLabels := map[string]string{
+		"app":      releaseName,
+		"chart":    chartName,
+		"release":  releaseName,
+		"heritage": "Tiller",
+	}
+
+	tcs := []struct {
+		name       string
+		valueFiles []string
+		values     map[string]string
+
+		meta        metav1.ObjectMeta
+		podSelector metav1.LabelSelector
+		policyTypes []netV1.PolicyType
+		ingress     []netV1.NetworkPolicyIngressRule
+		egress      []netV1.NetworkPolicyEgressRule
+	}{
+		{
+			name: "defaults",
+		},
+		{
+			name:        "with default policy",
+			values:      map[string]string{"networkPolicy.enabled": "true"},
+			meta:        metav1.ObjectMeta{Name: releaseName + "-auto-deploy", Labels: expectedLabels},
+			podSelector: metav1.LabelSelector{MatchLabels: map[string]string{}},
+			ingress: []netV1.NetworkPolicyIngressRule{
+				{
+					From: []netV1.NetworkPolicyPeer{
+						{PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{}}},
+						{NamespaceSelector: &metav1.LabelSelector{
+							MatchLabels: map[string]string{"app.gitlab.com/managed_by": "gitlab"},
+						}},
+					},
+				},
+			},
+		},
+		{
+			name:        "with custom policy",
+			valueFiles:  []string{"./testdata/custom-policy.yaml"},
+			meta:        metav1.ObjectMeta{Name: releaseName + "-auto-deploy", Labels: expectedLabels},
+			podSelector: metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
+			ingress: []netV1.NetworkPolicyIngressRule{
+				{
+					From: []netV1.NetworkPolicyPeer{
+						{PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{}}},
+						{NamespaceSelector: &metav1.LabelSelector{
+							MatchLabels: map[string]string{"name": "foo"},
+						}},
+					},
+				},
+			},
+		},
+		{
+			name:        "with full spec policy",
+			valueFiles:  []string{"./testdata/full-spec-policy.yaml"},
+			meta:        metav1.ObjectMeta{Name: releaseName + "-auto-deploy", Labels: expectedLabels},
+			podSelector: metav1.LabelSelector{MatchLabels: map[string]string{}},
+			policyTypes: []netV1.PolicyType{"Ingress", "Egress"},
+			ingress: []netV1.NetworkPolicyIngressRule{
+				{
+					From: []netV1.NetworkPolicyPeer{
+						{PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{}}},
+					},
+				},
+			},
+			egress: []netV1.NetworkPolicyEgressRule{
+				{
+					To: []netV1.NetworkPolicyPeer{
+						{NamespaceSelector: &metav1.LabelSelector{
+							MatchLabels: map[string]string{"name": "gitlab-managed-apps"},
+						}},
+					},
+				},
+			},
+		},
+	}
+
+	for _, tc := range tcs {
+		t.Run(tc.name, func(t *testing.T) {
+			opts := &helm.Options{
+				ValuesFiles: tc.valueFiles,
+				SetValues:   tc.values,
+			}
+			output := helm.RenderTemplate(t, opts, helmChartPath, releaseName, templates)
+
+			policy := new(netV1.NetworkPolicy)
+			helm.UnmarshalK8SYaml(t, output, policy)
+
+			require.Equal(t, tc.meta, policy.ObjectMeta)
+			require.Equal(t, tc.podSelector, policy.Spec.PodSelector)
+			require.Equal(t, tc.policyTypes, policy.Spec.PolicyTypes)
+			require.Equal(t, tc.ingress, policy.Spec.Ingress)
+			require.Equal(t, tc.egress, policy.Spec.Egress)
+		})
+	}
+}
+
+func TestIngressTemplate_ModSecurity(t *testing.T) {
+	templates := []string{"templates/ingress.yaml"}
+	modSecuritySnippet := "SecRuleEngine DetectionOnly\n"
+	modSecuritySnippetWithSecRules := modSecuritySnippet + `SecRule REQUEST_HEADERS:User-Agent \"scanner\" \"log,deny,id:107,status:403,msg:\'Scanner Identified\'\"
+SecRule REQUEST_HEADERS:Content-Type \"text/plain\" \"log,deny,id:\'20010\',status:403,msg:\'Text plain not allowed\'\"
+`
+	defaultAnnotations := map[string]string{
+		"kubernetes.io/ingress.class": "nginx",
+		"kubernetes.io/tls-acme":      "true",
+	}
+	defaultModSecurityAnnotations := map[string]string{
+		"nginx.ingress.kubernetes.io/modsecurity-transaction-id": "$server_name-$request_id",
+	}
+	modSecurityAnnotations := make(map[string]string)
+	secRulesAnnotations := make(map[string]string)
+	mergeStringMap(modSecurityAnnotations, defaultAnnotations)
+	mergeStringMap(modSecurityAnnotations, defaultModSecurityAnnotations)
+	mergeStringMap(secRulesAnnotations, defaultAnnotations)
+	mergeStringMap(secRulesAnnotations, defaultModSecurityAnnotations)
+	modSecurityAnnotations["nginx.ingress.kubernetes.io/modsecurity-snippet"] = modSecuritySnippet
+	secRulesAnnotations["nginx.ingress.kubernetes.io/modsecurity-snippet"] = modSecuritySnippetWithSecRules
+
+	tcs := []struct {
+		name       string
+		valueFiles []string
+		values     map[string]string
+		meta       metav1.ObjectMeta
+	}{
+		{
+			name: "defaults",
+			meta: metav1.ObjectMeta{Annotations: defaultAnnotations},
+		},
+		{
+			name:   "with modSecurity enabled without custom secRules",
+			values: map[string]string{"ingress.modSecurity.enabled": "true"},
+			meta:   metav1.ObjectMeta{Annotations: modSecurityAnnotations},
+		},
+		{
+			name:       "with custom secRules",
+			valueFiles: []string{"./testdata/modsecurity-ingress.yaml"},
+			meta:       metav1.ObjectMeta{Annotations: secRulesAnnotations},
+		},
+	}
+
+	for _, tc := range tcs {
+		t.Run(tc.name, func(t *testing.T) {
+			opts := &helm.Options{
+				ValuesFiles: tc.valueFiles,
+				SetValues:   tc.values,
+			}
+			output := helm.RenderTemplate(t, opts, helmChartPath, "", templates)
+
+			ingress := new(extensions.Ingress)
+			helm.UnmarshalK8SYaml(t, output, ingress)
+
+			require.Equal(t, tc.meta.Annotations, ingress.ObjectMeta.Annotations)
+		})
+	}
+}
+
+func TestIngressTemplate_Disable(t *testing.T) {
+	templates := []string{"templates/ingress.yaml"}
+	releaseName := "ingress-disable-test"
+	tcs := []struct {
+		name   string
+		values map[string]string
+
+		expectedrelease string
+	}{
+		{
+			name:            "defaults",
+			expectedrelease: releaseName + "-auto-deploy",
+		},
+		{
+			name:            "with ingress.enabled key undefined, but service is enabled",
+			values:          map[string]string{"ingress.enabled": "null", "service.enabled": "true"},
+			expectedrelease: releaseName + "-auto-deploy",
+		},
+		{
+			name:            "with service enabled and track non-stable",
+			values:          map[string]string{"service.enabled": "true", "application.track": "non-stable"},
+			expectedrelease: "",
+		},
+		{
+			name:            "with service disabled and track stable",
+			values:          map[string]string{"service.enabled": "false", "application.track": "stable"},
+			expectedrelease: "",
+		},
+		{
+			name:            "with service disabled and track non-stable",
+			values:          map[string]string{"service.enabled": "false", "application.track": "non-stable"},
+			expectedrelease: "",
+		},
+		{
+			name:            "with ingress disabled",
+			values:          map[string]string{"ingress.enabled": "false"},
+			expectedrelease: "",
+		},
+		{
+			name:            "with ingress enabled and track non-stable",
+			values:          map[string]string{"ingress.enabled": "true", "application.track": "non-stable"},
+			expectedrelease: "",
+		},
+		{
+			name:            "with ingress enabled and service disabled",
+			values:          map[string]string{"ingress.enabled": "true", "service.enabled": "false"},
+			expectedrelease: "",
+		},
+		{
+			name:            "with ingress disabled and service enabled and track stable",
+			values:          map[string]string{"ingress.enabled": "false", "service.enabled": "true", "application.track": "stable"},
+			expectedrelease: "",
+		},
+	}
+
+	for _, tc := range tcs {
+		t.Run(tc.name, func(t *testing.T) {
+			opts := &helm.Options{
+				SetValues: tc.values,
+			}
+			output := helm.RenderTemplate(t, opts, helmChartPath, releaseName, templates)
+
+			ingress := new(extensions.Ingress)
+
+			helm.UnmarshalK8SYaml(t, output, ingress)
+			require.Equal(t, tc.expectedrelease, ingress.ObjectMeta.Name)
+		})
+	}
+}
+
+func TestServiceTemplate_Disable(t *testing.T) {
+	templates := []string{"templates/service.yaml"}
+	releaseName := "service-disable-test"
+	tcs := []struct {
+		name   string
+		values map[string]string
+
+		expectedrelease string
+	}{
+		{
+			name:            "defaults",
+			expectedrelease: releaseName + "-auto-deploy",
+		},
+		{
+			name:            "with service enabled and track non-stable",
+			values:          map[string]string{"service.enabled": "true", "application.track": "non-stable"},
+			expectedrelease: "",
+		},
+		{
+			name:            "with service disabled and track stable",
+			values:          map[string]string{"service.enabled": "false", "application.track": "stable"},
+			expectedrelease: "",
+		},
+		{
+			name:            "with service disabled and track non-stable",
+			values:          map[string]string{"service.enabled": "false", "application.track": "non-stable"},
+			expectedrelease: "",
+		},
+	}
+
+	for _, tc := range tcs {
+		t.Run(tc.name, func(t *testing.T) {
+			opts := &helm.Options{
+				SetValues: tc.values,
+			}
+			output := helm.RenderTemplate(t, opts, helmChartPath, releaseName, templates)
+
+			service := new(coreV1.Service)
+
+			helm.UnmarshalK8SYaml(t, output, service)
+
+			require.Equal(t, tc.expectedrelease, service.ObjectMeta.Name)
+		})
+	}
+}
+
+type workerDeploymentTestCase struct {
+	ExpectedName         string
+	ExpectedCmd          []string
+	ExpectedStrategyType extensions.DeploymentStrategyType
+	ExpectedSelector     *metav1.LabelSelector
+}
+
+type workerDeploymentAppsV1TestCase struct {
+	ExpectedName         string
+	ExpectedCmd          []string
+	ExpectedStrategyType appsV1.DeploymentStrategyType
+	ExpectedSelector     *metav1.LabelSelector
+}
+
+type deploymentList struct {
+	metav1.TypeMeta `json:",inline"`
+
+	Items []extensions.Deployment `json:"items" protobuf:"bytes,2,rep,name=items"`
+}
+
+type deploymentAppsV1List struct {
+	metav1.TypeMeta `json:",inline"`
+
+	Items []appsV1.Deployment `json:"items" protobuf:"bytes,2,rep,name=items"`
+}
+
+func mergeStringMap(dst, src map[string]string) {
+	for k, v := range src {
+		dst[k] = v
+	}
+}
diff --git a/chart/test/testdata/custom-policy.yaml b/chart/test/testdata/custom-policy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8cc487aa725b2bb91a704caf5e39c3a3882be055
--- /dev/null
+++ b/chart/test/testdata/custom-policy.yaml
@@ -0,0 +1,13 @@
+networkPolicy:
+  enabled: true
+  spec:
+    podSelector:
+      matchLabels:
+        foo: bar
+    ingress:
+    - from:
+      - podSelector:
+          matchLabels: {}
+      - namespaceSelector:
+          matchLabels:
+            name: foo
diff --git a/chart/test/testdata/full-spec-policy.yaml b/chart/test/testdata/full-spec-policy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..25254b5d2c51802230fd383f206e1848a9517879
--- /dev/null
+++ b/chart/test/testdata/full-spec-policy.yaml
@@ -0,0 +1,17 @@
+networkPolicy:
+  enabled: true
+  spec:
+    podSelector:
+      matchLabels: {}
+    policyTypes:
+    - Ingress
+    - Egress
+    ingress:
+    - from:
+      - podSelector:
+          matchLabels: {}
+    egress:
+    - to:
+      - namespaceSelector:
+          matchLabels:
+            name: gitlab-managed-apps
diff --git a/chart/test/testdata/modsecurity-ingress.yaml b/chart/test/testdata/modsecurity-ingress.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5b8b469c1ece14cd1fdbdda8b503b5a38026141f
--- /dev/null
+++ b/chart/test/testdata/modsecurity-ingress.yaml
@@ -0,0 +1,10 @@
+ingress:
+  modSecurity:
+    enabled: true
+    secRules:
+      - variable: "REQUEST_HEADERS:User-Agent"
+        operator: "scanner"
+        action: "log,deny,id:107,status:403,msg:'Scanner Identified'"
+      - variable: "REQUEST_HEADERS:Content-Type"
+        operator: "text/plain"
+        action: "log,deny,id:'20010',status:403,msg:'Text plain not allowed'"
\ No newline at end of file
diff --git a/chart/values.yaml b/chart/values.yaml
index 0641dce2ad6efb74a0e22bf123e485308987a060..b7b44df77f6c48c420767fd2cd446cfe6aea0e44 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -2,10 +2,13 @@
 # This is a YAML-formatted file.
 # Declare variables to be passed into your templates.
 replicaCount: 1
+strategyType:
+enableSelector:
+deploymentApiVersion: extensions/v1beta1
 image:
   repository: gitlab.example.com/group/project
   tag: stable
-  pullPolicy: Always
+  pullPolicy: IfNotPresent
   secrets:
     - name: gitlab-registry
 podAnnotations: {}
@@ -17,9 +20,9 @@ application:
   secretName:
   secretChecksum:
 hpa:
-  enabled: true
-  minReplicas: 2
-  maxReplicas: 20
+  enabled: false
+  minReplicas: 1
+  maxReplicas: 5
   targetCPUUtilizationPercentage: 80
 gitlab:
   app:
@@ -37,6 +40,7 @@ service:
   externalPort: 5000
   internalPort: 5000
 ingress:
+  enabled: true
   tls:
     enabled: true
     secretName: ""
@@ -46,34 +50,38 @@ ingress:
   modSecurity:
     enabled: false
     secRuleEngine: "DetectionOnly"
+    # secRules:
+    #   - variable: ""
+    #     operator: ""
+    #     action: ""
 prometheus:
   metrics: false
 livenessProbe:
   path: "/"
-  initialDelaySeconds: 20
+  initialDelaySeconds: 15
   timeoutSeconds: 15
   scheme: "HTTP"
   probeType: "httpGet"
 readinessProbe:
   path: "/"
-  initialDelaySeconds: 15
-  timeoutSeconds: 15
+  initialDelaySeconds: 5
+  timeoutSeconds: 3
   scheme: "HTTP"
   probeType: "httpGet"
 postgresql:
-  enabled: false
+  enabled: true
   managed: false
   managedClassSelector:
     #   matchLabels:
     #     stack: gitlab (This is an example. The labels should match the labels on the CloudSQLInstanceClass)
 
 resources:
-  limits:
-    cpu: 1
-    memory: 1Gi
+#  limits:
+#    cpu: 100m
+#    memory: 128Mi
   requests:
-    cpu: 1
-    memory: 1Gi
+#    cpu: 100m
+#    memory: 128Mi
 
 ## Configure PodDisruptionBudget
 ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/
@@ -83,7 +91,23 @@ podDisruptionBudget:
   # minAvailable: 1
   maxUnavailable: 1
 
-workers:
+## Configure NetworkPolicy
+## ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/
+#
+networkPolicy:
+  enabled: false
+  spec:
+    podSelector:
+      matchLabels: {}
+    ingress:
+    - from:
+      - podSelector:
+          matchLabels: {}
+      - namespaceSelector:
+          matchLabels:
+            app.gitlab.com/managed_by: gitlab
+
+workers: {}
   # worker:
   #   replicaCount: 1
   #   terminationGracePeriodSeconds: 60
diff --git a/resources/lang/de/impressum.php b/resources/lang/de/impressum.php
index c5a9b7ae1857b1070a10aa5d2bf5fe2d47743c63..f41ffa6f7ade39a6df31b748d3d29a55c729bfc1 100644
--- a/resources/lang/de/impressum.php
+++ b/resources/lang/de/impressum.php
@@ -15,7 +15,7 @@ Deutschland/Germany',
 Tel.: ++49-(0)511-34000070
 EMail: <a href="mailto:office@suma-ev.de">office@suma-ev.de</a><a href="/kontakt/"> - Public-PGP-Key</a>
 <a href="/kontakt/">Verschlüsselndes Kontaktformular</a>',
-    'info.4' => 'Vorstand: Dominik Hebeler, Carsten Riel, <a href="https://www.ostfalia.de/cms/de/pws/jensen/index.html">Prof.Dr. Nils Jensen</a>',
+    'info.4' => 'Vorstand: Dominik Hebeler, Carsten Riel',
     'info.6' => 'Jugendschutzbeauftragte: Manuela Branz <a href="mailto:jugendschutz@metager.de">jugendschutz@metager.de</a>',
     'info.8' => '"SUMA-EV - Verein für freien Wissenszugang" ist ein gemeinnütziger
 Verein, eingetragen in das Vereinsregister beim Amtsgericht Hannover
diff --git a/resources/lang/en/impressum.php b/resources/lang/en/impressum.php
index ba88f17dd67bb27fdb40f07c25d8a140e6e53126..31c36493521a5fedf42082b37bf0c915abd6b0f5 100644
--- a/resources/lang/en/impressum.php
+++ b/resources/lang/en/impressum.php
@@ -14,7 +14,7 @@ Deutschland/Germany',
 Tel.: ++49-(0)511-34000070
 EMail: <a href="mailto:office@suma-ev.de">office@suma-ev.de</a><a href="/kontakt/"> - Public-PGP-Key</a>
 <a href="/kontakt/">encrypted contact form</a>',
-    'info.4' => 'Board: Dominik Hebeler, Carsten Riel, <a href="https://www.ostfalia.de/cms/de/pws/jensen/index.html">Prof.Dr. Nils Jensen</a>',
+    'info.4' => 'Board: Dominik Hebeler, Carsten Riel',
     'info.6' => 'Youth Protection Commissioner: Manuela Branz <a href="mailto:jugendschutz@metager.de">jugendschutz@metager.de</a>',
     'info.8' => '"SUMA-EV - Verein für freien Wissenszugang" is a charitable association, registered in the register of associations at the Amtsgericht Hannover
 under VR200033.
diff --git a/resources/lang/es/impressum.php b/resources/lang/es/impressum.php
index 2d7e5a036c5d425beef9d6b7fe2b508d9af09723..9035a55ac5fed77351a0e2ab908e14a8a082243d 100644
--- a/resources/lang/es/impressum.php
+++ b/resources/lang/es/impressum.php
@@ -6,7 +6,7 @@ return [
     "info.1" => "Articulo de Wikipedia de <a href=\"http://de.wikipedia.org/wiki/Suma_e.V.\" target=\"_blank\" rel=\"noopener\">SUMA-EV</a>",
     "info.2" => " SUMA-EV Röselerstr. 3 D-30159 Hannover Deutschland/Germany",
     "info.3" => "Contacto: Tel.: ++49-(0)511-34000070 EMail: <a href=\"mailto:office@suma-ev.de\">office@suma-ev.de</a><a href=\"/kontakt/\"> - Public-PGP-Key</a> <a href=\"/kontakt/\">Formulario encriptado</a>",
-    "info.4" => "Junta directiva: Dominik Hebeler, Carsten Riel, <a href=\"https://www2.ostfalia.de/cms/de/pws/jensenn/index.html\">Prof.Dr. Nils Jensen</a>",
+    "info.4" => "Junta directiva: Dominik Hebeler, Carsten Riel",
     "info.6" => "Encargado de protección de menores: Manuela Branz <a href=\"mailto:jugendschutz@metager.de\">jugendschutz@metager.de</a>",
     "info.8" => "\"SUMA-EV - Verein für freien Wissenszugang\" es una asociación sin fines de lucro, registrado en el registro de asociaciones del Amtsgericht Hannover bajo numero VR200033. Número de identificación a efectos del IVA:  DE 300 464 091 La \"Gottfried Wilhelm Leibniz Universität Hannover\" es una entidad del derecho publico.",
     "info.9" => "Exención de responsabilidad",