fix(provision): improve single host installation and documentation
authorJavier Bértoli <jbertoli@curii.com>
Mon, 22 Mar 2021 15:56:44 +0000 (12:56 -0300)
committerJavier Bértoli <jbertoli@curii.com>
Mon, 22 Mar 2021 15:56:44 +0000 (12:56 -0300)
Also improved single host installation options (single, multiple hostnames)

refs #17246
Arvados-DCO-1.1-Signed-off-by: Javier Bértoli <jbertoli@curii.com>

doc/install/salt-single-host.html.textile.liquid
doc/install/salt.html.textile.liquid
tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/postgresql.sls
tools/salt-install/config_examples/single_host/single_hostname/pillars/postgresql.sls
tools/salt-install/local.params.example.single_host_multiple_hostnames
tools/salt-install/local.params.example.single_host_single_hostname
tools/salt-install/provision.sh

index 48b26e83aa4f3a6af5d6863aea2d9fffc3853a6a..f8e1310e7b3b7d34c0291d5929bf1602fa0c966f 100644 (file)
@@ -9,67 +9,86 @@ Copyright (C) The Arvados Authors. All rights reserved.
 SPDX-License-Identifier: CC-BY-SA-3.0
 {% endcomment %}
 
-# "Install Saltstack":#saltstack
 # "Single host install using the provision.sh script":#single_host
-# "Final steps":#final_steps
-## "DNS configuration":#dns_configuration
-## "Install root certificate":#ca_root_certificate
+# "Choose the desired configuration":#choose_configuration
+## "Single host / single hostname":#single_host_single_hostnames
+## "Single host / multiple hostnames (Alternative configuration)":#single_host_multiple_hostnames
+## "Further customization of the installation (modifying the salt pillars and states)":#further_customization
+# "Run the provision.sh script":#run_provision_script
+# "Final configuration steps":#final_steps
+## "Install the CA root certificate (required in both alternatives)":#ca_root_certificate
+## "DNS configuration (single host / multiple hostnames)":#single_host_multiple_hostnames_dns_configuration
 # "Initial user and login":#initial_user
 # "Test the installed cluster running a simple workflow":#test_install
 
-h2(#saltstack). Install Saltstack
+h2(#single_host). Single host install using the provision.sh script
+
+<b>NOTE: The single host installation is not recommended for production use.</b>
+
+This is a package-based installation method. The Salt scripts are available from the "tools/salt-install":https://github.com/arvados/arvados/tree/master/tools/salt-install directory in the Arvados git repository.
+
+This procedure will install all the main Arvados components to get you up and running in a single host. The whole installation procedure takes somewhere between 15 to 60 minutes, depending on the host resources and its network bandwidth. As a reference, on a virtual machine with 1 core and 1 GB RAM, it takes ~25 minutes to do the initial install.
+
+We suggest you to use the @provision.sh@ script to deploy Arvados, which is implemented with the @arvados-formula@ in a Saltstack master-less setup. After setting up a few variables in a config file (next step), you'll be ready to run it and get Arvados deployed.
 
-If you already have a Saltstack environment you can skip this section.
+h2(#choose_configuration). Choose the desired configuration
 
-The simplest way to get Salt up and running on a node is to use the bootstrap script they provide:
+For documentation's sake, we will use the cluster name <i>arva2</i> and the domain <i>arv.local</i>. If you don't change them as required in the next steps, installation won't proceed.
 
+Arvados' single host installation can be done in two fashions:
+
+* Using a single hostname, asigning <i>a different port (other than 443) for each user-facing service</i>: This choice is easier to setup, but the user will need to know the port/s for the different services she wants to connect to.
+* Using multiple hostnames on the same IP: this setup involves a few extra steps but each service will have a meaningful hostname so it will make easier to access them later.
+
+Once you decide which of these choices you prefer, copy one the two example configuration files and directory, and edit them to suit your needs.
+
+h3(#single_host_single_hostnames). Single host / single hostname
 <notextile>
-<pre><code>curl -L https://bootstrap.saltstack.com -o /tmp/bootstrap_salt.sh
-sudo sh /tmp/bootstrap_salt.sh -XUdfP -x python3
+<pre><code>cp local.params.example.single_host_single_hostname local.params
+cp -r config_examples/single_host/single_hostname local_config_dir
 </code></pre>
 </notextile>
 
-For more information check "Saltstack's documentation":https://docs.saltstack.com/en/latest/topics/installation/index.html
+Edit the variables in the <i>local.params</i> file. Pay attention to the <b>*_PORT, *_TOKEN</b> and <b>*KEY</b> variables.
 
-h2(#single_host). Single host install using the provision.sh script
+h3(#single_host_multiple_hostnames). Single host / multiple hostnames (Alternative configuration)
+<notextile>
+<pre><code>cp local.params.example.single_host_multiple_hostnames local.params
+cp -r config_examples/single_host/multiple_hostnames local_config_dir
+</code></pre>
+</notextile>
 
-This is a package-based installation method. The Salt scripts are available from the "tools/salt-install":https://github.com/arvados/arvados/tree/master/tools/salt-install directory in the Arvados git repository.
+Edit the variables in the <i>local.params</i> file.
 
-Use the @provision.sh@ script to deploy Arvados, which is implemented with the @arvados-formula@ in a Saltstack master-less setup:
+## "Further customization of the installation (modifying the salt pillars and states)":#further_customization
 
-* edit the variables at the very beginning of the file,
-* run the script as root
-* wait for it to finish
+If you want or need further customization, you can edit the Saltstack pillars and states files. Pay particular attention to the <i>pillars/arvados.sls</i> one. Any extra <i>state</i> file you add under <i>local_config_dir/states</i> will be added to the salt run and applied to the host.
 
-This will install all the main Arvados components to get you up and running. The whole installation procedure takes somewhere between 15 to 60 minutes, depending on the host and your network bandwidth. On a virtual machine with 1 core and 1 GB RAM, it takes ~25 minutes to do the initial install.
+h2(#run_provision_script). Run the provision.sh script
 
-If everything goes OK, you'll get some final lines stating something like:
+When you finished customizing the configuration, you are ready to copy the files to the host (if needed) and run the @provision.sh@ script:
 
 <notextile>
-<pre><code>arvados: Succeeded: 109 (changed=9)
-arvados: Failed:      0
+<pre><code>scp -r provision.sh local* user@host:
+ssh user@host sudo provision.sh
 </code></pre>
 </notextile>
 
-h2(#final_steps). Final configuration steps
-
-h3(#dns_configuration). DNS configuration
-
-After the setup is done, you need to set up your DNS to be able to access the cluster.
+and wait for it to finish.
 
-The simplest way to do this is to edit your @/etc/hosts@ file (as root):
+If everything goes OK, you'll get some final lines stating something like:
 
 <notextile>
-<pre><code>export CLUSTER="arva2"
-export DOMAIN="arv.local"
-export HOST_IP="127.0.0.2"    # This is valid either if installing in your computer directly
-                              # or in a Vagrant VM. If you're installing it on a remote host
-                              # just change the IP to match that of the host.
-echo "${HOST_IP} api keep keep0 collections download ws workbench workbench2 ${CLUSTER}.${DOMAIN} api.${CLUSTER}.${DOMAIN} keep.${CLUSTER}.${DOMAIN} keep0.${CLUSTER}.${DOMAIN} collections.${CLUSTER}.${DOMAIN} download.${CLUSTER}.${DOMAIN} ws.${CLUSTER}.${DOMAIN} workbench.${CLUSTER}.${DOMAIN} workbench2.${CLUSTER}.${DOMAIN}" >> /etc/hosts
+<pre><code>arvados: Succeeded: 109 (changed=9)
+arvados: Failed:      0
 </code></pre>
 </notextile>
 
-h3(#ca_root_certificate). Install root certificate
+h2(#final_steps). Final configuration steps
+
+Once the deployment went OK, you'll need to perform a few extra steps in your local browser/host to access the cluster.
+
+h3(#ca_root_certificate). Install the CA root certificate (required in both alternatives)
 
 Arvados uses SSL to encrypt communications. Its UI uses AJAX which will silently fail if the certificate is not valid or signed by an unknown Certification Authority.
 
@@ -102,11 +121,25 @@ To access your Arvados instance using command line clients (such as arv-get and
 </code></pre>
 </notextile>
 
-h2(#initial_user). Initial user and login
+h3(#single_host_multiple_hostnames_dns_configuration). DNS configuration (single host / multiple hostnames)
+
+When using multiple hostnames, after the setup is done, you need to set up your DNS to be able to access the cluster.
+
+If you don't have access to the domain's DNS to add the required entries, the simplest way to do it is to edit your @/etc/hosts@ file (as root):
+
+<notextile>
+<pre><code>export CLUSTER="arva2"
+export DOMAIN="arv.local"
+export HOST_IP="127.0.0.2"    # This is valid either if installing in your computer directly
+                              # or in a Vagrant VM. If you're installing it on a remote host
+                              # just change the IP to match that of the host.
+echo "${HOST_IP} api keep keep0 collections download ws workbench workbench2 ${CLUSTER}.${DOMAIN} api.${CLUSTER}.${DOMAIN} keep.${CLUSTER}.${DOMAIN} keep0.${CLUSTER}.${DOMAIN} collections.${CLUSTER}.${DOMAIN} download.${CLUSTER}.${DOMAIN} ws.${CLUSTER}.${DOMAIN} workbench.${CLUSTER}.${DOMAIN} workbench2.${CLUSTER}.${DOMAIN}" >> /etc/hosts
+</code></pre>
+</notextile>
 
-At this point you should be able to log into the Arvados cluster.
+h2(#initial_user). Initial user and login 
 
-If you changed nothing in the @provision.sh@ script, the initial URL will be:
+At this point you should be able to log into the Arvados cluster. The initial URL will be:
 
 * https://workbench.arva2.arv.local
 
@@ -116,7 +149,7 @@ or, in general, the url format will be:
 
 By default, the provision script creates an initial user for testing purposes. This user is configured as administrator of the newly created cluster.
 
-Assuming you didn't change these values in the @provision.sh@ script, the initial credentials are:
+Assuming you didn't change these values in the @local.params@ file, the initial credentials are:
 
 * User: 'admin'
 * Password: 'password'
@@ -124,7 +157,7 @@ Assuming you didn't change these values in the @provision.sh@ script, the initia
 
 h2(#test_install). Test the installed cluster running a simple workflow
 
-The @provision.sh@ script saves a simple example test workflow in the @/tmp/cluster_tests@. If you want to run it, just change to that directory and run:
+The @provision.sh@ script saves a simple example test workflow in the @/tmp/cluster_tests@ directory in the node. If you want to run it, just ssh to the node, change to that directory and run:
 
 <notextile>
 <pre><code>cd /tmp/cluster_tests
@@ -132,7 +165,7 @@ The @provision.sh@ script saves a simple example test workflow in the @/tmp/clus
 </code></pre>
 </notextile>
 
-It will create a test user, upload a small workflow and run it. If everything goes OK, the output should similar to this (some output was shortened for clarity):
+It will create a test user (by default, the same one as the admin user), upload a small workflow and run it. If everything goes OK, the output should similar to this (some output was shortened for clarity):
 
 <notextile>
 <pre><code>Creating Arvados Standard Docker Images project
index 2b7aa660280717090750f1423aeb5ddb0a6c0c6c..a9ee08fb886d0747ff5ffda161f323996d664165 100644 (file)
@@ -10,20 +10,35 @@ SPDX-License-Identifier: CC-BY-SA-3.0
 {% endcomment %}
 
 # "Introduction":#introduction
-# "Choose an installation method":#installmethod
+# "Install Saltstack":#saltstack
+# "Choose an Arvados installation configuration":#installconfiguration
 
 h2(#introduction). Introduction
 
-To ease the installation of the various Arvados components, we have developed a "Saltstack":https://www.saltstack.com/ 's "arvados-formula":https://github.com/arvados/arvados-formula which can help you get an Arvados cluster up and running.
+To ease the installation of the various Arvados components, we have developed a "Saltstack":https://www.saltstack.com/ 's "arvados-formula":https://github.com/arvados/arvados-formula.git which can help you get an Arvados cluster up and running.
 
 Saltstack is a Python-based, open-source software for event-driven IT automation, remote task execution, and configuration management. It can be used in a master/minion setup or master-less.
 
-This is a package-based installation method. The Salt scripts are available from the "tools/salt-install":https://github.com/arvados/arvados/tree/master/tools/salt-install directory in the Arvados git repository.
+This is a package-based installation method. The Salt scripts to install and configure Arvados using this formula are available at the "tools/salt-install":https://github.com/arvados/arvados/tree/master/tools/salt-install directory in the Arvados git repository.
 
-h2(#installmethod). Choose an installation method
+h2(#saltstack). Install Saltstack
 
-The salt formulas can be used in different ways. Choose one of these three options to install Arvados:
+If you already have a Saltstack environment or you plan to use the @provision.sh@ script we provide, you can skip this section.
+
+The simplest way to get Salt up and running on a node is to use the bootstrap script they provide:
+
+<notextile>
+<pre><code>curl -L https://bootstrap.saltstack.com -o /tmp/bootstrap_salt.sh
+sudo sh /tmp/bootstrap_salt.sh -XUdfP -x python3
+</code></pre>
+</notextile>
+
+For more information check "Saltstack's documentation":https://docs.saltstack.com/en/latest/topics/installation/index.html
+
+h2(#installconfiguration). Choose an Arvados installation configuration
+
+The salt formula can be used in a few different ways. Choose one of these three options to install Arvados:
 
 * "Arvados on a single host":salt-single-host.html
-* "Use Vagrant to install Arvados in a virtual machine":salt-vagrant.html
 * "Arvados across multiple hosts":salt-multi-host.html
+* "Use Vagrant to install Arvados in a virtual machine":salt-vagrant.html
index 56b0a42e8b96578a14e5898031c746a10c173b22..71e712cad3c278d3ac5bbedc2d3b36bd2fe59993 100644 (file)
@@ -15,11 +15,11 @@ postgres:
     - ['local', 'all', 'all', 'peer']
     - ['host', 'all', 'all', '127.0.0.1/32', 'md5']
     - ['host', 'all', 'all', '::1/128', 'md5']
-    - ['host', 'arvados', 'arvados', '127.0.0.1/32']
+    - ['host', '__CLUSTER___arvados', '__CLUSTER___arvados', '127.0.0.1/32']
   users:
-    arvados:
+    __CLUSTER___arvados:
       ensure: present
-      password: changeme_arvados
+      password: __DATABASE_PASSWORD__
 
   # tablespaces:
   #   arvados_tablespace:
@@ -27,15 +27,15 @@ postgres:
   #     owner: arvados
 
   databases:
-    arvados:
-      owner: arvados
+    __CLUSTER___arvados:
+      owner: __CLUSTER___arvados
       template: template0
       lc_ctype: en_US.utf8
       lc_collate: en_US.utf8
       # tablespace: arvados_tablespace
       schemas:
         public:
-          owner: arvados
+          owner: __CLUSTER___arvados
       extensions:
         pg_trgm:
           if_not_exists: true
index 56b0a42e8b96578a14e5898031c746a10c173b22..71e712cad3c278d3ac5bbedc2d3b36bd2fe59993 100644 (file)
@@ -15,11 +15,11 @@ postgres:
     - ['local', 'all', 'all', 'peer']
     - ['host', 'all', 'all', '127.0.0.1/32', 'md5']
     - ['host', 'all', 'all', '::1/128', 'md5']
-    - ['host', 'arvados', 'arvados', '127.0.0.1/32']
+    - ['host', '__CLUSTER___arvados', '__CLUSTER___arvados', '127.0.0.1/32']
   users:
-    arvados:
+    __CLUSTER___arvados:
       ensure: present
-      password: changeme_arvados
+      password: __DATABASE_PASSWORD__
 
   # tablespaces:
   #   arvados_tablespace:
@@ -27,15 +27,15 @@ postgres:
   #     owner: arvados
 
   databases:
-    arvados:
-      owner: arvados
+    __CLUSTER___arvados:
+      owner: __CLUSTER___arvados
       template: template0
       lc_ctype: en_US.utf8
       lc_collate: en_US.utf8
       # tablespace: arvados_tablespace
       schemas:
         public:
-          owner: arvados
+          owner: __CLUSTER___arvados
       extensions:
         pg_trgm:
           if_not_exists: true
index 78c26af0efe827338b2a64a97b23864bec790651..8d5438e8f64ef9522999d436e0325d3cd76cee33 100644 (file)
@@ -45,19 +45,26 @@ MANAGEMENT_TOKEN=managementtokenmushaveatleast32characters
 SYSTEM_ROOT_TOKEN=systemroottokenmushaveatleast32characters
 ANONYMOUS_USER_TOKEN=anonymoususertokenmushaveatleast32characters
 WORKBENCH_SECRET_KEY=workbenchsecretkeymushaveatleast32characters
+DATABASE_PASSWORD=please_set_this_to_some_secure_value
+
+# SSL CERTIFICATES
+# Arvados REQUIRES valid SSL to work correctly. Otherwise, some components will fail
+# to communicate and can silently drop traffic. You can try to use the Letsencrypt
+# salt formula (https://github.com/saltstack-formulas/letsencrypt-formula) to try to
+# automatically obtain and install SSL certificates for your instances or set this
+# variable to "no", provide and upload your own certificates to the instances and
+# modify the 'nginx_*' salt pillars accordingly
+USE_LETSENCRYPT="no"
 
 # The directory to check for the config files (pillars, states) you want to use.
 # There are a few examples under 'config_examples'. If you don't change this
 # variable, the single_host, multiple_hostnames config will be used
 # CONFIG_DIR="config_examples/single_host/single_hostname"
-CONFIG_DIR="config_examples/single_host/multiple_hostnames"
+CONFIG_DIR="local_config_dir"
 # Extra states to apply. If you use your own subdir, change this value accordingly
 # This is the value for the single_host/multiple_hostnames example
 EXTRA_STATES_DIR="${F_DIR}/arvados-formula/test/salt/states/examples/single_host"
 
-# When using the single_host/single_hostname example, change to this one
-# EXTRA_STATES_DIR="${CONFIG_DIR}/states"
-
 # Which release of Arvados repo you want to use
 RELEASE="production"
 # Which version of Arvados you want to install. Defaults to 'latest'
@@ -74,7 +81,8 @@ BRANCH="master"
 
 # Formulas versions
 ARVADOS_TAG="v1.1.4"
-POSTGRES_TAG="v0.41.3"
-NGINX_TAG="v2.4.0"
+POSTGRES_TAG="v0.41.6"
+NGINX_TAG="v2.5.0"
 DOCKER_TAG="v1.0.0"
 LOCALE_TAG="v0.3.4"
+LETSENCRYPT_TAG="v2.1.0"
index 110d79429661796b5d7590adaf397aea0e02d56b..264f2a72e7ccf91fca7aa0bc559fcd494b2da0b3 100644 (file)
@@ -45,12 +45,22 @@ MANAGEMENT_TOKEN=managementtokenmushaveatleast32characters
 SYSTEM_ROOT_TOKEN=systemroottokenmushaveatleast32characters
 ANONYMOUS_USER_TOKEN=anonymoususertokenmushaveatleast32characters
 WORKBENCH_SECRET_KEY=workbenchsecretkeymushaveatleast32characters
+DATABASE_PASSWORD=please_set_this_to_some_secure_value
+
+# SSL CERTIFICATES
+# Arvados REQUIRES valid SSL to work correctly. Otherwise, some components will fail
+# to communicate and can silently drop traffic. You can try to use the Letsencrypt
+# salt formula (https://github.com/saltstack-formulas/letsencrypt-formula) to try to
+# automatically obtain and install SSL certificates for your instances or set this
+# variable to "no", provide and upload your own certificates to the instances and
+# modify the 'nginx_*' salt pillars accordingly
+USE_LETSENCRYPT="no"
 
 # The directory to check for the config files (pillars, states) you want to use.
 # There are a few examples under 'config_examples'. If you don't change this
 # variable, the single_host, multiple_hostnames config will be used
 # CONFIG_DIR="config_examples/single_host/single_hostname"
-CONFIG_DIR="config_examples/single_host/single_hostname"
+CONFIG_DIR="local_config_dir"
 # Extra states to apply. If you use your own subdir, change this value accordingly
 # This is the value for the single_host/multiple_hostnames example
 # EXTRA_STATES_DIR="${F_DIR}/arvados-formula/test/salt/states/examples/single_host"
@@ -74,7 +84,8 @@ VERSION="latest"
 
 # Formulas versions
 ARVADOS_TAG="v1.1.4"
-POSTGRES_TAG="v0.41.3"
-NGINX_TAG="v2.4.0"
+POSTGRES_TAG="v0.41.6"
+NGINX_TAG="v2.5.0"
 DOCKER_TAG="v1.0.0"
 LOCALE_TAG="v0.3.4"
+LETSENCRYPT_TAG="v2.1.0"
index 5174f2398cbea0259e1329a40490f9166382cec9..19ec6eccbecea8c1ec1ec4a2dcd34705bce56342 100755 (executable)
@@ -129,10 +129,11 @@ WORKBENCH2_EXT_SSL_PORT=3001
 RELEASE="production"
 VERSION="latest"
 ARVADOS_TAG="v1.1.4"
-POSTGRES_TAG="v0.41.3"
-NGINX_TAG="v2.4.0"
+POSTGRES_TAG="v0.41.6"
+NGINX_TAG="v2.5.0"
 DOCKER_TAG="v1.0.0"
 LOCALE_TAG="v0.3.4"
+LETSENCRYPT_TAG="v2.1.0"
 
 # Salt's dir
 ## states
@@ -192,11 +193,13 @@ mkdir -p ${S_DIR} ${F_DIR} ${P_DIR}
 
 # Get the formula and dependencies
 cd ${F_DIR} || exit 1
-git clone --branch "${ARVADOS_TAG}" https://github.com/arvados/arvados-formula.git
-git clone --branch "${DOCKER_TAG}" https://github.com/saltstack-formulas/docker-formula.git
-git clone --branch "${LOCALE_TAG}" https://github.com/saltstack-formulas/locale-formula.git
-git clone --branch "${NGINX_TAG}" https://github.com/saltstack-formulas/nginx-formula.git
-git clone --branch "${POSTGRES_TAG}" https://github.com/saltstack-formulas/postgres-formula.git
+git clone --branch "${ARVADOS_TAG}"     https://github.com/arvados/arvados-formula.git
+git clone --branch "${DOCKER_TAG}"      https://github.com/saltstack-formulas/docker-formula.git
+git clone --branch "${LOCALE_TAG}"      https://github.com/saltstack-formulas/locale-formula.git
+# git clone --branch "${NGINX_TAG}"       https://github.com/saltstack-formulas/nginx-formula.git
+git clone --branch "${NGINX_TAG}"       https://github.com/netmanagers/nginx-formula.git
+git clone --branch "${POSTGRES_TAG}"    https://github.com/saltstack-formulas/postgres-formula.git
+git clone --branch "${LETSENCRYPT_TAG}" https://github.com/saltstack-formulas/letsencrypt-formula.git
 
 # If we want to try a specific branch of the formula
 if [ "x${BRANCH}" != "x" ]; then
@@ -218,41 +221,54 @@ SOURCE_STATES_DIR="${EXTRA_STATES_DIR}"
 # Replace variables (cluster,  domain, etc) in the pillars, states and tests
 # to ease deployment for newcomers
 for f in "${SOURCE_PILLARS_DIR}"/*; do
-  sed "s/__ANONYMOUS_USER_TOKEN__/${ANONYMOUS_USER_TOKEN}/g;
-       s/__BLOB_SIGNING_KEY__/${BLOB_SIGNING_KEY}/g;
-       s/__CONTROLLER_EXT_SSL_PORT__/${CONTROLLER_EXT_SSL_PORT}/g;
-       s/__CLUSTER__/${CLUSTER}/g;
-       s/__DOMAIN__/${DOMAIN}/g;
-       s/__HOSTNAME_EXT__/${HOSTNAME_EXT}/g;
-       s/__HOSTNAME_INT__/${HOSTNAME_INT}/g;
-       s/__INITIAL_USER_EMAIL__/${INITIAL_USER_EMAIL}/g;
-       s/__INITIAL_USER_PASSWORD__/${INITIAL_USER_PASSWORD}/g;
-       s/__INITIAL_USER__/${INITIAL_USER}/g;
-       s/__KEEPWEB_EXT_SSL_PORT__/${KEEPWEB_EXT_SSL_PORT}/g;
-       s/__KEEP_EXT_SSL_PORT__/${KEEP_EXT_SSL_PORT}/g;
-       s/__MANAGEMENT_TOKEN__/${MANAGEMENT_TOKEN}/g;
-       s/__RELEASE__/${RELEASE}/g;
-       s/__SYSTEM_ROOT_TOKEN__/${SYSTEM_ROOT_TOKEN}/g;
-       s/__VERSION__/${VERSION}/g;
-       s/__WEBSHELL_EXT_SSL_PORT__/${WEBSHELL_EXT_SSL_PORT}/g;
-       s/__WEBSOCKET_EXT_SSL_PORT__/${WEBSOCKET_EXT_SSL_PORT}/g;
-       s/__WORKBENCH1_EXT_SSL_PORT__/${WORKBENCH1_EXT_SSL_PORT}/g;
-       s/__WORKBENCH2_EXT_SSL_PORT__/${WORKBENCH2_EXT_SSL_PORT}/g;
-       s/__WORKBENCH_SECRET_KEY__/${WORKBENCH_SECRET_KEY}/g" \
+  sed "s#__ANONYMOUS_USER_TOKEN__#${ANONYMOUS_USER_TOKEN}#g;
+       s#__BLOB_SIGNING_KEY__#${BLOB_SIGNING_KEY}#g;
+       s#__CONTROLLER_EXT_SSL_PORT__#${CONTROLLER_EXT_SSL_PORT}#g;
+       s#__CLUSTER__#${CLUSTER}#g;
+       s#__DOMAIN__#${DOMAIN}#g;
+       s#__HOSTNAME_EXT__#${HOSTNAME_EXT}#g;
+       s#__HOSTNAME_INT__#${HOSTNAME_INT}#g;
+       s#__INITIAL_USER_EMAIL__#${INITIAL_USER_EMAIL}#g;
+       s#__INITIAL_USER_PASSWORD__#${INITIAL_USER_PASSWORD}#g;
+       s#__INITIAL_USER__#${INITIAL_USER}#g;
+       s#__DATABASE_PASSWORD__#${DATABASE_PASSWORD}#g;
+       s#__KEEPWEB_EXT_SSL_PORT__#${KEEPWEB_EXT_SSL_PORT}#g;
+       s#__KEEP_EXT_SSL_PORT__#${KEEP_EXT_SSL_PORT}#g;
+       s#__MANAGEMENT_TOKEN__#${MANAGEMENT_TOKEN}#g;
+       s#__RELEASE__#${RELEASE}#g;
+       s#__SYSTEM_ROOT_TOKEN__#${SYSTEM_ROOT_TOKEN}#g;
+       s#__VERSION__#${VERSION}#g;
+       s#__WEBSHELL_EXT_SSL_PORT__#${WEBSHELL_EXT_SSL_PORT}#g;
+       s#__WEBSOCKET_EXT_SSL_PORT__#${WEBSOCKET_EXT_SSL_PORT}#g;
+       s#__WORKBENCH1_EXT_SSL_PORT__#${WORKBENCH1_EXT_SSL_PORT}#g;
+       s#__WORKBENCH2_EXT_SSL_PORT__#${WORKBENCH2_EXT_SSL_PORT}#g;
+       s#__CLUSTER_INT_CIDR__#${CLUSTER_INT_CIDR}#g;
+       s#__CONTROLLER_INT_IP__#${CONTROLLER_INT_IP}#g;
+       s#__WEBSOCKET_INT_IP__#${WEBSOCKET_INT_IP}#g;
+       s#__KEEP_INT_IP__#${KEEP_INT_IP}#g;
+       s#__KEEPSTORE0_INT_IP__#${KEEPSTORE0_INT_IP}#g;
+       s#__KEEPSTORE1_INT_IP__#${KEEPSTORE1_INT_IP}#g;
+       s#__KEEPWEB_INT_IP__#${KEEPWEB_INT_IP}#g;
+       s#__WEBSHELL_INT_IP__#${WEBSHELL_INT_IP}#g;
+       s#__WORKBENCH1_INT_IP__#${WORKBENCH1_INT_IP}#g;
+       s#__WORKBENCH2_INT_IP__#${WORKBENCH2_INT_IP}#g;
+       s#__DATABASE_INT_IP__#${DATABASE_INT_IP}#g;
+       s#__WORKBENCH_SECRET_KEY__#${WORKBENCH_SECRET_KEY}#g" \
   "${f}" > "${P_DIR}"/$(basename "${f}")
 done
 
 mkdir -p /tmp/cluster_tests
 # Replace cluster and domain name in the test files
 for f in "${SOURCE_TESTS_DIR}"/*; do
-  sed "s/__CLUSTER__/${CLUSTER}/g;
-       s/__CONTROLLER_EXT_SSL_PORT__/${CONTROLLER_EXT_SSL_PORT}/g;
-       s/__DOMAIN__/${DOMAIN}/g;
-       s/__HOSTNAME_INT__/${HOSTNAME_INT}/g;
-       s/__INITIAL_USER_EMAIL__/${INITIAL_USER_EMAIL}/g;
-       s/__INITIAL_USER_PASSWORD__/${INITIAL_USER_PASSWORD}/g
-       s/__INITIAL_USER__/${INITIAL_USER}/g;
-       s/__SYSTEM_ROOT_TOKEN__/${SYSTEM_ROOT_TOKEN}/g" \
+  sed "s#__CLUSTER__#${CLUSTER}#g;
+       s#__CONTROLLER_EXT_SSL_PORT__#${CONTROLLER_EXT_SSL_PORT}#g;
+       s#__DOMAIN__#${DOMAIN}#g;
+       s#__HOSTNAME_INT__#${HOSTNAME_INT}#g;
+       s#__INITIAL_USER_EMAIL__#${INITIAL_USER_EMAIL}#g;
+       s#__INITIAL_USER_PASSWORD__#${INITIAL_USER_PASSWORD}#g
+       s#__INITIAL_USER__#${INITIAL_USER}#g;
+       s#__DATABASE_PASSWORD__#${DATABASE_PASSWORD}#g;
+       s#__SYSTEM_ROOT_TOKEN__#${SYSTEM_ROOT_TOKEN}#g" \
   "${f}" > "/tmp/cluster_tests"/$(basename "${f}")
 done
 chmod 755 /tmp/cluster_tests/run-test.sh
@@ -262,27 +278,39 @@ if [ -d "${SOURCE_STATES_DIR}" ]; then
   mkdir -p "${F_DIR}"/extra/extra
 
   for f in "${SOURCE_STATES_DIR}"/*; do
-    sed "s/__ANONYMOUS_USER_TOKEN__/${ANONYMOUS_USER_TOKEN}/g;
-         s/__CLUSTER__/${CLUSTER}/g;
-         s/__BLOB_SIGNING_KEY__/${BLOB_SIGNING_KEY}/g;
-         s/__CONTROLLER_EXT_SSL_PORT__/${CONTROLLER_EXT_SSL_PORT}/g;
-         s/__DOMAIN__/${DOMAIN}/g;
-         s/__HOSTNAME_EXT__/${HOSTNAME_EXT}/g;
-         s/__HOSTNAME_INT__/${HOSTNAME_INT}/g;
-         s/__INITIAL_USER_EMAIL__/${INITIAL_USER_EMAIL}/g;
-         s/__INITIAL_USER_PASSWORD__/${INITIAL_USER_PASSWORD}/g;
-         s/__INITIAL_USER__/${INITIAL_USER}/g;
-         s/__KEEPWEB_EXT_SSL_PORT__/${KEEPWEB_EXT_SSL_PORT}/g;
-         s/__KEEP_EXT_SSL_PORT__/${KEEP_EXT_SSL_PORT}/g;
-         s/__MANAGEMENT_TOKEN__/${MANAGEMENT_TOKEN}/g;
-         s/__RELEASE__/${RELEASE}/g;
-         s/__SYSTEM_ROOT_TOKEN__/${SYSTEM_ROOT_TOKEN}/g;
-         s/__VERSION__/${VERSION}/g;
-         s/__WEBSHELL_EXT_SSL_PORT__/${WEBSHELL_EXT_SSL_PORT}/g;
-         s/__WEBSOCKET_EXT_SSL_PORT__/${WEBSOCKET_EXT_SSL_PORT}/g;
-         s/__WORKBENCH1_EXT_SSL_PORT__/${WORKBENCH1_EXT_SSL_PORT}/g;
-         s/__WORKBENCH2_EXT_SSL_PORT__/${WORKBENCH2_EXT_SSL_PORT}/g;
-         s/__WORKBENCH_SECRET_KEY__/${WORKBENCH_SECRET_KEY}/g" \
+    sed "s#__ANONYMOUS_USER_TOKEN__#${ANONYMOUS_USER_TOKEN}#g;
+         s#__CLUSTER__#${CLUSTER}#g;
+         s#__BLOB_SIGNING_KEY__#${BLOB_SIGNING_KEY}#g;
+         s#__CONTROLLER_EXT_SSL_PORT__#${CONTROLLER_EXT_SSL_PORT}#g;
+         s#__DOMAIN__#${DOMAIN}#g;
+         s#__HOSTNAME_EXT__#${HOSTNAME_EXT}#g;
+         s#__HOSTNAME_INT__#${HOSTNAME_INT}#g;
+         s#__INITIAL_USER_EMAIL__#${INITIAL_USER_EMAIL}#g;
+         s#__INITIAL_USER_PASSWORD__#${INITIAL_USER_PASSWORD}#g;
+         s#__INITIAL_USER__#${INITIAL_USER}#g;
+         s#__DATABASE_PASSWORD__#${DATABASE_PASSWORD}#g;
+         s#__KEEPWEB_EXT_SSL_PORT__#${KEEPWEB_EXT_SSL_PORT}#g;
+         s#__KEEP_EXT_SSL_PORT__#${KEEP_EXT_SSL_PORT}#g;
+         s#__MANAGEMENT_TOKEN__#${MANAGEMENT_TOKEN}#g;
+         s#__RELEASE__#${RELEASE}#g;
+         s#__SYSTEM_ROOT_TOKEN__#${SYSTEM_ROOT_TOKEN}#g;
+         s#__VERSION__#${VERSION}#g;
+         s#__CLUSTER_INT_CIDR__#${CLUSTER_INT_CIDR}#g;
+         s#__CONTROLLER_INT_IP__#${CONTROLLER_INT_IP}#g;
+         s#__WEBSOCKET_INT_IP__#${WEBSOCKET_INT_IP}#g;
+         s#__KEEP_INT_IP__#${KEEP_INT_IP}#g;
+         s#__KEEPSTORE0_INT_IP__#${KEEPSTORE0_INT_IP}#g;
+         s#__KEEPSTORE1_INT_IP__#${KEEPSTORE1_INT_IP}#g;
+         s#__KEEPWEB_INT_IP__#${KEEPWEB_INT_IP}#g;
+         s#__WEBSHELL_INT_IP__#${WEBSHELL_INT_IP}#g;
+         s#__WORKBENCH1_INT_IP__#${WORKBENCH1_INT_IP}#g;
+         s#__WORKBENCH2_INT_IP__#${WORKBENCH2_INT_IP}#g;
+         s#__DATABASE_INT_IP__#${DATABASE_INT_IP}#g;
+         s#__WEBSHELL_EXT_SSL_PORT__#${WEBSHELL_EXT_SSL_PORT}#g;
+         s#__WEBSOCKET_EXT_SSL_PORT__#${WEBSOCKET_EXT_SSL_PORT}#g;
+         s#__WORKBENCH1_EXT_SSL_PORT__#${WORKBENCH1_EXT_SSL_PORT}#g;
+         s#__WORKBENCH2_EXT_SSL_PORT__#${WORKBENCH2_EXT_SSL_PORT}#g;
+         s#__WORKBENCH_SECRET_KEY__#${WORKBENCH_SECRET_KEY}#g" \
     "${f}" > "${F_DIR}/extra/extra"/$(basename "${f}")
   done
 fi
@@ -318,6 +346,9 @@ fi
 if [ -z "${ROLES}" ]; then
   # States
   echo "    - nginx.passenger" >> ${S_DIR}/top.sls
+  if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
+    grep -q "letsencrypt" ${S_DIR}/top.sls || echo "    - letsencrypt" >> ${S_DIR}/top.sls
+  fi
   echo "    - postgres" >> ${S_DIR}/top.sls
   echo "    - docker" >> ${S_DIR}/top.sls
   echo "    - arvados" >> ${S_DIR}/top.sls
@@ -334,6 +365,9 @@ if [ -z "${ROLES}" ]; then
   echo "    - nginx_workbench2_configuration" >> ${P_DIR}/top.sls
   echo "    - nginx_workbench_configuration" >> ${P_DIR}/top.sls
   echo "    - postgresql" >> ${P_DIR}/top.sls
+  if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
+    grep -q "letsencrypt" ${P_DIR}/top.sls || echo "    - letsencrypt" >> ${P_DIR}/top.sls
+  fi
 else
   # If we add individual roles, make sure we add the repo first
   echo "    - arvados.repo" >> ${S_DIR}/top.sls
@@ -350,6 +384,11 @@ else
         # FIXME: https://dev.arvados.org/issues/17352
         grep -q "postgres.client" ${S_DIR}/top.sls || echo "    - postgres.client" >> ${S_DIR}/top.sls
         grep -q "nginx.passenger" ${S_DIR}/top.sls || echo "    - nginx.passenger" >> ${S_DIR}/top.sls
+        ### If we don't install and run LE before arvados-api-server, it fails and breaks everything
+        ### after it so we add this here, as we are, after all, sharing the host for api and controller
+        if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
+          grep -q "letsencrypt" ${S_DIR}/top.sls || echo "    - letsencrypt" >> ${S_DIR}/top.sls
+        fi
         grep -q "arvados.${R}" ${S_DIR}/top.sls    || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
         # Pillars
         grep -q "docker" ${P_DIR}/top.sls                   || echo "    - docker" >> ${P_DIR}/top.sls
@@ -360,10 +399,17 @@ else
       "controller" | "websocket" | "workbench" | "workbench2" | "keepweb" | "keepproxy")
         # States
         grep -q "nginx.passenger" ${S_DIR}/top.sls || echo "    - nginx.passenger" >> ${S_DIR}/top.sls
+        if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
+          grep -q "letsencrypt" ${S_DIR}/top.sls || echo "    - letsencrypt" >> ${S_DIR}/top.sls
+        fi
         grep -q "arvados.${R}" ${S_DIR}/top.sls    || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
         # Pillars
         grep -q "nginx_passenger" ${P_DIR}/top.sls          || echo "    - nginx_passenger" >> ${P_DIR}/top.sls
         grep -q "nginx_${R}_configuration" ${P_DIR}/top.sls || echo "    - nginx_${R}_configuration" >> ${P_DIR}/top.sls
+        if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
+          grep -q "letsencrypt" ${P_DIR}/top.sls || echo "    - letsencrypt" >> ${P_DIR}/top.sls
+          grep -q "letsencrypt_${R}_configuration" ${P_DIR}/top.sls || echo "    - letsencrypt_${R}_configuration" >> ${P_DIR}/top.sls
+        fi
       ;;
       "shell")
         # States