You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by dm...@apache.org on 2020/04/14 07:32:24 UTC

[incubator-dlab] branch odahu-integration updated: [odahu-integration] Added scripts for odahu deployment on aws

This is an automated email from the ASF dual-hosted git repository.

dmysakovets pushed a commit to branch odahu-integration
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git


The following commit(s) were added to refs/heads/odahu-integration by this push:
     new ef74e4f  [odahu-integration] Added scripts for odahu deployment on aws
ef74e4f is described below

commit ef74e4ff03bfc409cf61694c233a785ef02742e7
Author: Demyan Mysakovets <de...@gmail.com>
AuthorDate: Tue Apr 14 10:32:06 2020 +0300

    [odahu-integration] Added scripts for odahu deployment on aws
---
 .../src/general/conf/dlab.ini                      |   4 +
 .../src/general/files/aws/odahu_Dockerfile         |  85 ++++++
 .../src/general/lib/aws/actions_lib.py             |   3 +
 .../src/general/scripts/aws/odahu_deploy.py        | 308 +++++++++++++++++++++
 .../src/general/scripts/aws/odahu_prepare.py       | 155 +++++++++++
 .../src/general/scripts/aws/odahu_resume.py        | 289 +++++++++++++++++++
 .../src/general/scripts/aws/odahu_suspend.py       | 287 +++++++++++++++++++
 .../src/general/scripts/aws/odahu_terminate.py     | 307 ++++++++++++++++++++
 .../src/ssn/scripts/configure_docker.py            |  29 +-
 9 files changed, 1457 insertions(+), 10 deletions(-)

diff --git a/infrastructure-provisioning/src/general/conf/dlab.ini b/infrastructure-provisioning/src/general/conf/dlab.ini
index 77966ad..c542259 100644
--- a/infrastructure-provisioning/src/general/conf/dlab.ini
+++ b/infrastructure-provisioning/src/general/conf/dlab.ini
@@ -370,6 +370,10 @@ jupyterlab_version = 1.1.0
 ###
 packager_version = 1.1.0
 ###
+private_subnet_cidrs = 172.10.2.0/24,172.10.4.0/24
+###
+public_subnet_cidrs = 172.10.1.0/24,172.10.3.0/24
+###
 oauth_mesh_enabled = true
 ###
 node_version = 1.13.12-gke.2
diff --git a/infrastructure-provisioning/src/general/files/aws/odahu_Dockerfile b/infrastructure-provisioning/src/general/files/aws/odahu_Dockerfile
new file mode 100644
index 0000000..d41a94a
--- /dev/null
+++ b/infrastructure-provisioning/src/general/files/aws/odahu_Dockerfile
@@ -0,0 +1,85 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+FROM ODAHU_IMAGE
+ARG OS
+ARG SRC_PATH
+
+ENV PROFILE=/profile.json
+
+# Install any .deb dependecies
+RUN	apt-get update && \
+    apt-get -y upgrade && \
+    apt-get -y install python-pip python-dev build-essential python3 python3-dev && \
+    apt-get -y install groff vim less git wget nano libssl-dev libffi-dev libffi6 && \
+    apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+# Install any python dependencies
+RUN pip install -UI pip==9.0.3 && \
+    pip install boto3 backoff fabric==1.14.0 fabvenv awscli argparse requests ujson jupyter pycrypto
+
+# Configuring ssh for user
+RUN mkdir -p /root/.ssh; echo "Host *" > /root/.ssh/config; \
+    echo "StrictHostKeyChecking no" >>  /root/.ssh/config; \
+    echo "UserKnownHostsFile=/dev/null" >> /root/.ssh/config; \
+    echo "GlobalKnownHostsFile=/dev/null" >> /root/.ssh/config; \
+    echo "ConnectTimeout=30" >> /root/.ssh/config
+
+# Configuring log directories
+RUN mkdir -p /response; chmod a+rwx /response && \
+    mkdir -p /logs/ssn; chmod a+rwx /logs/ssn && \
+    mkdir -p /logs/project; chmod a+rwx /logs/project && \
+    mkdir -p /logs/edge; chmod a+rwx /logs/edge && \
+    mkdir -p /logs/notebook; chmod a+rwx /logs/notebook && \
+    mkdir -p /logs/dataengine; chmod a+rwx /logs/dataengine && \
+    mkdir -p /logs/dataengine-service; chmod a+rwx /logs/dataengine-service
+
+# Copying all base scripts to docker
+ENV PROVISION_CONFIG_DIR /root/conf/
+ENV KEYFILE_DIR /root/keys/
+ENV AWS_DIR /root/.aws
+
+RUN mkdir -p /root/conf && \
+    mkdir -p /root/scripts && \
+    mkdir -p /root/templates && \
+    mkdir -p /root/files && \
+    mkdir -p /usr/lib/python2.7/dlab && \
+    mkdir -p /root/keys/.ssh
+
+COPY ${SRC_PATH}base/ /root
+COPY ${SRC_PATH}odahu/ /root
+COPY ${SRC_PATH}general/conf/* /root/conf/
+COPY ${SRC_PATH}general/api/*.py /bin/
+COPY ${SRC_PATH}general/scripts/aws/common_* /root/scripts/
+COPY ${SRC_PATH}general/scripts/aws/odahu_* /root/scripts/
+COPY ${SRC_PATH}general/lib/aws/* /usr/lib/python2.7/dlab/
+COPY ${SRC_PATH}general/lib/os/${OS}/common_lib.py /usr/lib/python2.7/dlab/common_lib.py
+COPY ${SRC_PATH}general/lib/os/fab.py /usr/lib/python2.7/dlab/fab.py
+COPY ${SRC_PATH}general/files/os/${OS}/sources.list /root/files/
+COPY ${SRC_PATH}general/files/os/ivysettings.xml /root/templates/
+COPY ${SRC_PATH}general/files/os/local_endpoint.json /root/files/
+COPY ${SRC_PATH}project/templates/locations/ /root/locations/
+
+RUN chmod a+x /root/*.py && \
+    chmod a+x /root/scripts/* && \
+    chmod a+x /bin/*.py
+
+ENTRYPOINT ["/root/entrypoint.py"]
diff --git a/infrastructure-provisioning/src/general/lib/aws/actions_lib.py b/infrastructure-provisioning/src/general/lib/aws/actions_lib.py
index adb2661..cb0a7ad 100644
--- a/infrastructure-provisioning/src/general/lib/aws/actions_lib.py
+++ b/infrastructure-provisioning/src/general/lib/aws/actions_lib.py
@@ -1028,6 +1028,9 @@ def remove_s3(bucket_type='all', scientist=''):
         elif bucket_type == 'edge':
             bucket_name = (os.environ['conf_service_base_name'] + '-' + "{}".format(scientist) + '-' +
                            os.environ['endpoint_name'] + '-bucket').lower().replace('_', '-')
+        elif bucket_type == 'odahu':
+            bucket_name = "{}-{}-tfstate".format((os.environ['conf_service_base_name']).lower().replace('_', '-'),
+                                                 (os.environ['odahu_cluster_name']).lower().replace('_', '-'))
         else:
             bucket_name = (os.environ['conf_service_base_name']).lower().replace('_', '-')
         for item in client.list_buckets().get('Buckets'):
diff --git a/infrastructure-provisioning/src/general/scripts/aws/odahu_deploy.py b/infrastructure-provisioning/src/general/scripts/aws/odahu_deploy.py
new file mode 100644
index 0000000..e7e0363
--- /dev/null
+++ b/infrastructure-provisioning/src/general/scripts/aws/odahu_deploy.py
@@ -0,0 +1,308 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+import logging
+import json
+import sys
+from dlab.fab import *
+from dlab.meta_lib import *
+from dlab.actions_lib import *
+import os
+import base64
+
+if __name__ == "__main__":
+    local_log_filename = "{}_{}_{}.log".format(os.environ['conf_resource'], os.environ['project_name'],
+                                               os.environ['request_id'])
+    local_log_filepath = "/logs/project/" + local_log_filename
+    logging.basicConfig(format='%(levelname)-8s [%(asctime)s]  %(message)s',
+                        level=logging.DEBUG,
+                        filename=local_log_filepath)
+
+    print('Generating infrastructure names and tags')
+    odahu_conf = dict()
+    odahu_conf['allowed_cidr'] = os.environ['odahu_allowed_cidr'].split(',')
+    odahu_conf['project_id'] = (os.environ['gcp_project_id'])
+    odahu_conf['region'] = (os.environ['aws_region'])
+    odahu_conf['zone'] = (os.environ['aws_zone'])
+    odahu_conf['edge_user_name'] = os.environ['edge_user_name']
+    if os.environ['aws_region'] == 'us-east':
+        odahu_conf['az_list'] = ["us-east-1", "us-east-2"]
+    elif os.environ['aws_region'] == 'ap-south':
+        odahu_conf['az_list'] = ["ap-south-1"]
+    elif os.environ['aws_region'] == 'us-west':
+        odahu_conf['az_list'] = ["us-west-1", "us-west-2"]
+    elif os.environ['aws_region'] == 'eu-west':
+        odahu_conf['az_list'] = ["eu-west-1", "eu-west-2", "eu-west-3"]
+    elif os.environ['aws_region'] == 'ca-central':
+        odahu_conf['az_list'] = ["ca-central-1"]
+    odahu_conf['az_list'] = GCPMeta().get_available_zones()
+    odahu_conf['dns_zone_name'] = os.environ['odahu_dns_zone_name']
+    odahu_conf['docker_repo'] = os.environ['odahu_docker_repo']
+    odahu_conf['cidr'] = os.environ['odahu_cidr']
+    odahu_conf['service_base_name'] = (os.environ['conf_service_base_name']).lower().replace('_', '-')
+    odahu_conf['project_name'] = (os.environ['project_name']).lower().replace('_', '-')
+    odahu_conf['cluster_name'] = "{}-{}".format((os.environ['conf_service_base_name']).lower().replace('_', '-'),
+                                                (os.environ['odahu_cluster_name']).lower().replace('_', '-'))
+    odahu_conf['bucket_name'] = "{}-tfstate".format(odahu_conf['cluster_name'])
+    odahu_conf['static_address_name'] = "{}-nat-gw".format(odahu_conf['cluster_name'])
+    try:
+        if os.environ['gcp_vpc_name'] == '':
+            raise KeyError
+        else:
+            odahu_conf['vpc_name'] = os.environ['gcp_vpc_name']
+    except KeyError:
+        odahu_conf['vpc_name'] = odahu_conf['service_base_name'] + '-ssn-vpc'
+    odahu_conf['vpc_cidr'] = os.environ['conf_vpc_cidr']
+    odahu_conf['private_subnet_name'] = '{0}-{1}-subnet'.format(odahu_conf['service_base_name'],
+                                                                odahu_conf['project_name'])
+    odahu_conf['grafana_admin'] = os.environ['odahu_grafana_admin']
+    odahu_conf['grafana_pass'] = id_generator()
+    odahu_conf['docker_password'] = base64.b64decode(os.environ['odahu_docker_password'] + "==")
+    odahu_conf['initial_node_count'] = os.environ['odahu_initial_node_count']
+    odahu_conf['istio_helm_repo'] = os.environ['odahu_istio_helm_repo']
+    odahu_conf['helm_repo'] = os.environ['odahu_helm_repo']
+    odahu_conf['k8s_version'] = os.environ['odahu_k8s_version']
+    odahu_conf['oauth_oidc_issuer_url'] = "{}/realms/{}".format(os.environ['keycloak_auth_server_url'],
+                                                                os.environ['keycloak_realm_name'])
+    odahu_conf['oauth_oidc_host'] = os.environ['keycloak_auth_server_url'].replace('https://', '').replace('/auth', '')
+    odahu_conf['oauth_client_id'] = os.environ['keycloak_client_name']
+    odahu_conf['oauth_client_secret'] = os.environ['keycloak_client_secret']
+    odahu_conf['oauth_cookie_secret'] = base64.b64encode(id_generator(16))
+    odahu_conf['oauth_local_jwks'] = os.environ['odahu_oauth_local_jwks']
+    odahu_conf['infra_version'] = os.environ['odahu_infra_version']
+    odahu_conf['odahuflow_version'] = os.environ['odahu_odahuflow_version']
+    odahu_conf['mlflow_toolchain_version'] = os.environ['odahu_mlflow_toolchain_version']
+    odahu_conf['jupyterlab_version'] = os.environ['odahu_jupyterlab_version']
+    odahu_conf['packager_version'] = os.environ['odahu_packager_version']
+    odahu_conf['private_subnet_cidrs'] = os.environ['odahu_private_subnet_cidrs'].split(',')
+    odahu_conf['public_subnet_cidrs'] = os.environ['odahu_public_subnet_cidrs'].split(',')
+    odahu_conf['infra_cidr'] = os.environ['odahu_pods_cidr']
+    odahu_conf['root_domain'] = os.environ['odahu_root_domain']
+    odahu_conf['service_cidr'] = os.environ['odahu_service_cidr']
+    odahu_conf['tls_crt'] = base64.b64decode(os.environ['odahu_tls_crt'] + "==")
+    odahu_conf['tls_key'] = base64.b64decode(os.environ['odahu_tls_key'] + "==")
+    odahu_conf['ssh_key'] = os.environ['ssh_key']
+    odahu_conf['dns_project_id'] = os.environ['odahu_dns_project_id']
+    odahu_conf['decrypt_token'] = id_generator()
+    odahu_conf['infra_vpc_peering'] = os.environ['odahu_infra_vpc_peering']
+    odahu_conf['automation_version'] = os.environ['odahu_automation_version']
+    odahu_conf['ui_version'] = os.environ['odahu_ui_version']
+    odahu_conf['examples_version'] = os.environ['odahu_examples_version']
+    odahu_conf['jupyterhub_enabled'] = os.environ['odahu_jupyterhub_enabled']
+    odahu_conf['oauth_mesh_enabled'] = os.environ['odahu_oauth_mesh_enabled']
+    odahu_conf['keysecret'] = os.environ['odahu_keysecret']
+    odahu_conf['airflow_secret'] = os.environ['odahu_airflow_secret']
+    odahu_conf['operator_secret'] =os.environ['odahu_operator_secret']
+    odahu_conf['resource-uploader_secret'] = os.environ['odahu_resource_uploader_secret']
+    odahu_conf['tester_secret'] = os.environ['odahu_tester_secret']
+    odahu_conf['tester-data-scientist_secret'] = os.environ['odahu_tester_data_scientist_secret']
+
+    print('Preparing parameters file')
+    try:
+        local("cp /root/templates/profile.json /tmp/")
+        with open("/tmp/profile.json", 'w') as profile:
+            prof ={
+                    "allowed_ips": odahu_conf['allowed_cidr'],
+                    "authorization_enabled": "true",
+                    "authz_dry_run": "false",
+                    "cloud": {
+                        "aws": {
+                            "az_list": odahu_conf['az_list'],
+                            "zone": "{}".format(odahu_conf['zone']),
+                        },
+                        "region": "{}".format(odahu_conf['region']),
+                        "type": "aws"
+                    },
+                    "cluster_name": "{}".format(odahu_conf['cluster_name']),
+                    "cluster_type": "aws/eks",
+                    "data_bucket": "{}-data-bucket".format(odahu_conf['cluster_name']),
+                    "dns": {
+                        "domain": "odahu.{}.{}".format(odahu_conf['cluster_name'], odahu_conf['root_domain']),
+                        "gcp_credentials": "{}",
+                        "gcp_project_id": "{}".format(odahu_conf['project_id']),
+                        "provider": "gcp",
+                        "zone_name": "{}".format(odahu_conf['dns_zone_name']),
+                    },
+                    "docker_password": "{}".format(odahu_conf['docker_password']),
+                    "docker_repo": "{}".format(odahu_conf['docker_repo']),
+                    "docker_username": "_json_key",
+                    "infra_cidr": "{}".format(odahu_conf['infra_cidr']),
+                    "examples_version": "{}".format(odahu_conf['examples_version']),
+                    "grafana_pass": "{}".format(odahu_conf['grafana_pass']),
+                    "helm_repo": "{}".format(odahu_conf['helm_repo']),
+                    "jupyterhub_enabled": odahu_conf['jupyterhub_enabled'],
+                    "jupyterlab_version": "{}".format(odahu_conf['jupyterlab_version']),
+                    "k8s_version": "{}".format(odahu_conf['k8s_version']),
+                    "mlflow_toolchain_version": "{}".format(odahu_conf['mlflow_toolchain_version']),
+                    "nat_subnet_cidr": "{}".format(odahu_conf['cidr']),
+                    "node_pools": {
+                        "main": {
+                            "init_node_count": 1,
+                            "max_node_count": 7,
+                            "min_node_count": 1
+                        },
+                        "model_deployment": {
+                            "labels": {
+                                "mode": "odahu-flow-deployment"
+                            },
+                            "max_node_count": 3,
+                            "taints": [
+                                {
+                                    "effect": "NO_SCHEDULE",
+                                    "key": "dedicated",
+                                    "value": "deployment"
+                                }
+                            ]
+                        },
+                        "packaging": {
+                            "disk_size_gb": 100,
+                            "labels": {
+                                "mode": "odahu-flow-packaging"
+                            },
+                            "max_node_count": 3,
+                            "taints": [
+                                {
+                                    "effect": "NO_SCHEDULE",
+                                    "key": "dedicated",
+                                    "value": "packaging"
+                                }
+                            ]
+                        },
+                        "training": {
+                            "disk_size_gb": 50,
+                            "labels": {
+                                "mode": "odahu-flow-training"
+                            },
+                            "machine_type": "c5.2xlarge",
+                            "taints": [
+                                {
+                                    "effect": "NO_SCHEDULE",
+                                    "key": "dedicated",
+                                    "value": "training"
+                                }
+                            ]
+                        }
+                    },
+                    "oauth_client_id": "{}".format(odahu_conf['oauth_client_id']),
+                    "oauth_client_secret": "{}".format(odahu_conf['oauth_client_secret']),
+                    "oauth_cookie_secret": "{}".format(odahu_conf['oauth_cookie_secret']),
+                    "oauth_local_jwks": "{}".format(odahu_conf['oauth_local_jwks']),
+                    "oauth_mesh_enabled": odahu_conf['oauth_mesh_enabled'],
+                    "oauth_oidc_audience": "legion",
+                    "oauth_oidc_host": "{}".format(odahu_conf['oauth_oidc_host']),
+                    "oauth_oidc_issuer_url": "{}".format(odahu_conf['oauth_oidc_issuer_url']),
+                    "oauth_oidc_jwks_url": "{}/protocol/openid-connect/certs".format(odahu_conf['oauth_oidc_issuer_url']),
+                    "oauth_oidc_port": 443,
+                    "oauth_oidc_scope": "openid profile email offline_access groups",
+                    "oauth_oidc_token_endpoint": "{}/protocol/openid-connect/token".format(odahu_conf['oauth_oidc_issuer_url']),
+                    "odahu_automation_version": "{}".format(odahu_conf['automation_version']),
+                    "odahu_infra_version": "{}".format(odahu_conf['infra_version']),
+                    "odahu_ui_version": "{}".format(odahu_conf['ui_version']),
+                    "odahuflow_connection_decrypt_token": "{}".format(odahu_conf['decrypt_token']),
+                    "odahuflow_connections": [
+                        {
+                            "id": "odahu-flow-examples",
+                            "spec": {
+                                "description": "Git repository with the Odahu-Flow examples",
+                                "keySecret": "{}".format(odahu_conf['keysecret']),
+                                "reference": "{}".format(odahu_conf['examples_version']),
+                                "type": "git",
+                                "uri": "git@github.com:odahu/odahu-examples.git",
+                                "webUILink": "https://github.com/odahu/odahu-examples"
+                            }
+                        }
+                    ],
+                    "odahuflow_version": "{}".format(odahu_conf['odahuflow_version']),
+                    "opa_policies": {},
+                    "packager_version": "{}".format(odahu_conf['packager_version']),
+                    "private_subnet_cidrs": odahu_conf['private_subnet_cidrs'],
+                    "public_subnet_cidrs": odahu_conf['public_subnet_cidrs'],
+                    "service_accounts": {
+                        "airflow": {
+                            "client_id": "sa-airflow",
+                            "client_secret": "{}".format(odahu_conf['airflow_secret'])
+                        },
+                        "operator": {
+                            "client_id": "sa-operator",
+                            "client_secret": "{}".format(odahu_conf['operator_secret'])
+                        },
+                        "resource_uploader": {
+                            "client_id": "sa-resource-uploader",
+                            "client_secret": "{}".format(odahu_conf['resource-uploader_secret'])
+                        },
+                        "test": {
+                            "client_id": "sa-tester",
+                            "client_secret": "{}".format(odahu_conf['tester_secret'])
+                        },
+                        "test_data_scientist": {
+                            "client_id": "sa-tester-data-scientist",
+                            "client_secret": "{}".format(odahu_conf['tester-data-scientist_secret'])
+                        }
+                    },
+                    "service_cidr": "{}".format(odahu_conf['service_cidr']),
+                    "ssh_key": "{}".format(odahu_conf['ssh_key'].replace('\n', '')),
+                    "subnet_name": "{}".format(odahu_conf['private_subnet_name']),
+                    "tfstate_bucket": "{}-tfstate".format(odahu_conf['cluster_name']),
+                    "tls_crt": "{}".format(odahu_conf['tls_crt']),
+                    "tls_key": "{}".format(odahu_conf['tls_key']),
+                    "vpc_name": "{}".format(odahu_conf['vpc_name']),
+                    "vault": {
+                        "enabled": "true"
+                    }
+                    }
+            profile.write(json.dumps(prof))
+        local('cat /tmp/profile.json')
+        local('cp /tmp/profile.json /')
+    except Exception as err:
+        traceback.print_exc()
+        append_result("Failed to configure parameter file.", str(err))
+        GCPActions().remove_bucket(odahu_conf['bucket_name'])
+        GCPActions().remove_static_address(odahu_conf['static_address_name'], odahu_conf['region'])
+        sys.exit(1)
+
+    try:
+        local('tf_runner create -o /tmp/result.json')
+        local("sed -i 's|name|description|g' /tmp/result.json")
+    except Exception as err:
+        traceback.print_exc()
+        append_result("Failed to deploy Odahu cluster.", str(err))
+        GCPActions().remove_bucket(odahu_conf['bucket_name'])
+        GCPActions().remove_static_address(odahu_conf['static_address_name'], odahu_conf['region'])
+        sys.exit(1)
+
+    # generating output information
+    print('[SUMMARY]')
+    logging.info('[SUMMARY]')
+    print('Cluster name: {}'.format(odahu_conf['cluster_name']))
+    with open('/tmp/result.json', 'r') as f:
+        output = json.load(f)
+        odahu_urls = json.dumps(output['odahu_urls']['value'], sort_keys=True, indent=4)
+    print('Odahu urls: {}'.format(odahu_urls))
+    res = dict()
+    res['odahu_urls'] = output['odahu_urls']['value']
+    res['oauth_cookie_secret'] = odahu_conf['oauth_cookie_secret']
+    res['odahuflow_connection_decrypt_token'] = odahu_conf['decrypt_token']
+    res['grafana_pass'] = odahu_conf['grafana_pass']
+    res['grafana_admin'] = odahu_conf['grafana_admin']
+    with open("/root/result.json", 'w') as result:
+        result.write(json.dumps(res))
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/scripts/aws/odahu_prepare.py b/infrastructure-provisioning/src/general/scripts/aws/odahu_prepare.py
new file mode 100644
index 0000000..d4168ed
--- /dev/null
+++ b/infrastructure-provisioning/src/general/scripts/aws/odahu_prepare.py
@@ -0,0 +1,155 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+import logging
+import json
+import sys
+import requests
+from dlab.fab import *
+from dlab.meta_lib import *
+from dlab.actions_lib import *
+import os
+
+if __name__ == "__main__":
+    local_log_filename = "{}_{}_{}.log".format(os.environ['conf_resource'], os.environ['project_name'],
+                                               os.environ['request_id'])
+    local_log_filepath = "/logs/project/" + local_log_filename
+    logging.basicConfig(format='%(levelname)-8s [%(asctime)s]  %(message)s',
+                        level=logging.DEBUG,
+                        filename=local_log_filepath)
+
+    print('Generating infrastructure names and tags')
+    odahu_conf = dict()
+    odahu_conf['service_base_name'] = (os.environ['conf_service_base_name']).lower().replace('_', '-')
+    odahu_conf['project_name'] = (os.environ['project_name']).lower().replace('_', '-')
+    odahu_conf['endpoint_name'] = (os.environ['endpoint_name']).lower().replace('_', '-')
+    odahu_conf['cluster_name'] = "{}-{}".format((os.environ['conf_service_base_name']).lower().replace('_', '-'),
+                                                (os.environ['odahu_cluster_name']).lower().replace('_', '-'))
+    odahu_conf['tag_name'] = '{}-tag'.format(odahu_conf['service_base_name'])
+    odahu_conf['endpoint_tag'] = (os.environ['endpoint_name']).lower().replace('_', '-')
+    odahu_conf['project_tag'] = (os.environ['project_name']).lower().replace('_', '-')
+    odahu_conf['region'] = os.environ['gcp_region']
+    odahu_conf['bucket_name'] = "{}-tfstate".format(odahu_conf['cluster_name'])
+    odahu_conf['static_address_name'] = "{}-nat-gw".format(odahu_conf['cluster_name'])
+    odahu_conf['keycloak_auth_server_url'] = os.environ['keycloak_auth_server_url']
+    odahu_conf['keycloak_realm_name'] = os.environ['keycloak_realm_name']
+    odahu_conf['keycloak_client_name'] = os.environ['keycloak_client_name']
+    odahu_conf['keycloak_user'] = os.environ['keycloak_user']
+    odahu_conf['keycloak_user_password'] = os.environ['keycloak_user_password']
+    odahu_conf['root_domain'] = os.environ['odahu_root_domain']
+    if 'conf_additional_tags' in os.environ:
+        odahu_conf['bucket_additional_tags'] = ';' + os.environ['conf_additional_tags']
+        os.environ['conf_additional_tags'] = os.environ['conf_additional_tags'] + \
+                                             ';project_tag:{0};endpoint_tag:{1};'.format(
+                                                 odahu_conf['project_tag'], odahu_conf['endpoint_tag'])
+    else:
+        odahu_conf['bucket_additional_tags'] = ''
+        os.environ['conf_additional_tags'] = 'project_tag:{0};endpoint_tag:{1}'.format(odahu_conf['project_tag'],
+                                                                                       odahu_conf['endpoint_tag'])
+    print('Additional tags will be added: {}'.format(os.environ['conf_additional_tags']))
+
+
+    try:
+        logging.info('[CREATE STATE BUCKETS]')
+        print('[CREATE STATE BUCKETS]')
+
+        odahu_conf['bucket_tags'] = 'endpoint_tag:{0};{1}:{2};project_tag:{3};{4}:{5}{6}'\
+            .format(odahu_conf['endpoint_tag'], os.environ['conf_billing_tag_key'], os.environ['conf_billing_tag_value'],
+                    odahu_conf['project_tag'], odahu_conf['tag_name'], odahu_conf['bucket_name'],
+                    odahu_conf['bucket_additional_tags']).replace(';', ',')
+
+        params = "--bucket_name {0} --bucket_tags {1} --region {2} --bucket_name_tag {0}". \
+            format(odahu_conf['bucket_name'], odahu_conf['bucket_tags'], odahu_conf['region'])
+        try:
+            local("~/scripts/{}.py {}".format('common_create_bucket', params))
+        except:
+            traceback.print_exc()
+            raise Exception
+    except Exception as err:
+        print('Error: {0}'.format(err))
+        append_result("Unable to create bucket.", str(err))
+        sys.exit(1)
+
+    try:
+        logging.info('[CREATE NAT GATEWAY]')
+        print('[CREATE NAT GATEWAY]')
+        print("Allocating Elastic IP")
+        allocation_id = allocate_elastic_ip()
+        tag = {"Key": odahu_conf['tag_name'], "Value": odahu_conf['static_address_name']}
+        tag_name = {"Key": "Name", "Value": odahu_conf['static_address_name']}
+        create_tag(allocation_id, tag)
+        create_tag(allocation_id, tag_name)
+    except Exception as err:
+        print('Error: {0}'.format(err))
+        append_result("Unable to reserve static ip.", str(err))
+        remove_s3(bucket_type='odahu')
+        sys.exit(1)
+
+    try:
+        print('[CONFIGURE REDIRECT URI]')
+        logging.info('[CONFIGURE REDIRECT URI]')
+        keycloak_auth_server_url = '{}/realms/master/protocol/openid-connect/token'.format(
+            odahu_conf['keycloak_auth_server_url'])
+        keycloak_auth_data = {
+            "username": odahu_conf['keycloak_user'],
+            "password": odahu_conf['keycloak_user_password'],
+            "grant_type": "password",
+            "client_id": "admin-cli",
+        }
+        keycloak_client_create_url = '{0}/admin/realms/{1}/clients'.format(odahu_conf['keycloak_auth_server_url'],
+                                                                           odahu_conf['keycloak_realm_name'])
+        odahu_redirectUris = 'https://odahu.{0}.{1}/*,http://odahu.{0}.{1}/*'.format(odahu_conf['cluster_name'],
+                                                                                        odahu_conf['root_domain']).split(',')
+
+
+        try:
+            keycloak_token = requests.post(keycloak_auth_server_url, data=keycloak_auth_data, verify=False).json()
+            keycloak_get_Uris = requests.get(keycloak_client_create_url,
+                                            headers={"Authorization": "Bearer " + keycloak_token.get("access_token"),
+                                                     "Content-Type": "application/json"}, verify=False).json()
+            for dict in keycloak_get_Uris:
+                if dict["clientId"] == odahu_conf['keycloak_client_name']:
+                    ui_redirectUris = dict["redirectUris"]
+                    keycloak_client_id = dict["id"]
+            keycloak_redirectUris = odahu_redirectUris + ui_redirectUris
+            updated_client_data = {
+                "clientId": odahu_conf['keycloak_client_name'],
+                "id": keycloak_client_id,
+                "enabled": "true",
+                "redirectUris": keycloak_redirectUris,
+                "publicClient": "false",
+                "protocol": "openid-connect",
+            }
+            client_url = "{}/{}".format(keycloak_client_create_url, keycloak_client_id)
+            keycloak_update_Uris = requests.put(client_url, json=updated_client_data,
+                                            headers={"Authorization": "Bearer " + keycloak_token.get("access_token"),
+                                                     "Content-Type": "application/json"}, verify=False)
+        except Exception as err:
+            append_result("Failed to configure keycloak.")
+            sys.exit(1)
+    except Exception as err:
+        print('Error: {0}'.format(err))
+        append_result("Failed to configure keycloak.", str(err))
+        remove_s3(bucket_type='odahu')
+        release_elastic_ip(allocation_id)
+        sys.exit(1)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/scripts/aws/odahu_resume.py b/infrastructure-provisioning/src/general/scripts/aws/odahu_resume.py
new file mode 100644
index 0000000..245336a
--- /dev/null
+++ b/infrastructure-provisioning/src/general/scripts/aws/odahu_resume.py
@@ -0,0 +1,289 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+import logging
+import json
+import sys
+from dlab.fab import *
+from dlab.meta_lib import *
+from dlab.actions_lib import *
+import os
+import string
+import random
+import base64
+
+if __name__ == "__main__":
+    local_log_filename = "{}_{}_{}.log".format(os.environ['conf_resource'], os.environ['project_name'],
+                                               os.environ['request_id'])
+    local_log_filepath = "/logs/project/" + local_log_filename
+    logging.basicConfig(format='%(levelname)-8s [%(asctime)s]  %(message)s',
+                        level=logging.DEBUG,
+                        filename=local_log_filepath)
+
+    print('Generating infrastructure names and tags')
+    odahu_conf = dict()
+    odahu_conf['allowed_cidr'] = os.environ['odahu_allowed_cidr'].split(',')
+    odahu_conf['project_id'] = (os.environ['gcp_project_id'])
+    odahu_conf['region'] = (os.environ['aws_region'])
+    odahu_conf['zone'] = (os.environ['aws_zone'])
+    odahu_conf['edge_user_name'] = os.environ['edge_user_name']
+    if os.environ['aws_region'] == 'us-east':
+        odahu_conf['az_list'] = ["us-east-1", "us-east-2"]
+    elif os.environ['aws_region'] == 'ap-south':
+        odahu_conf['az_list'] = ["ap-south-1"]
+    elif os.environ['aws_region'] == 'us-west':
+        odahu_conf['az_list'] = ["us-west-1", "us-west-2"]
+    elif os.environ['aws_region'] == 'eu-west':
+        odahu_conf['az_list'] = ["eu-west-1", "eu-west-2", "eu-west-3"]
+    elif os.environ['aws_region'] == 'ca-central':
+        odahu_conf['az_list'] = ["ca-central-1"]
+    odahu_conf['az_list'] = GCPMeta().get_available_zones()
+    odahu_conf['dns_zone_name'] = os.environ['odahu_dns_zone_name']
+    odahu_conf['docker_repo'] = os.environ['odahu_docker_repo']
+    odahu_conf['cidr'] = os.environ['odahu_cidr']
+    odahu_conf['service_base_name'] = (os.environ['conf_service_base_name']).lower().replace('_', '-')
+    odahu_conf['project_name'] = (os.environ['project_name']).lower().replace('_', '-')
+    odahu_conf['cluster_name'] = "{}-{}".format((os.environ['conf_service_base_name']).lower().replace('_', '-'),
+                                                (os.environ['odahu_cluster_name']).lower().replace('_', '-'))
+    odahu_conf['bucket_name'] = "{}-tfstate".format(odahu_conf['cluster_name'])
+    odahu_conf['static_address_name'] = "{}-nat-gw".format(odahu_conf['cluster_name'])
+    try:
+        if os.environ['gcp_vpc_name'] == '':
+            raise KeyError
+        else:
+            odahu_conf['vpc_name'] = os.environ['gcp_vpc_name']
+    except KeyError:
+        odahu_conf['vpc_name'] = odahu_conf['service_base_name'] + '-ssn-vpc'
+    odahu_conf['vpc_cidr'] = os.environ['conf_vpc_cidr']
+    odahu_conf['private_subnet_name'] = '{0}-{1}-subnet'.format(odahu_conf['service_base_name'],
+                                                                odahu_conf['project_name'])
+    odahu_conf['grafana_admin'] = os.environ['grafana_admin']
+    odahu_conf['grafana_pass'] = os.environ['grafana_pass']
+    odahu_conf['docker_password'] = base64.b64decode(os.environ['odahu_docker_password'] + "==")
+    odahu_conf['initial_node_count'] = os.environ['odahu_initial_node_count']
+    odahu_conf['istio_helm_repo'] = os.environ['odahu_istio_helm_repo']
+    odahu_conf['helm_repo'] = os.environ['odahu_helm_repo']
+    odahu_conf['k8s_version'] = os.environ['odahu_k8s_version']
+    odahu_conf['oauth_oidc_issuer_url'] = "{}/realms/{}".format(os.environ['keycloak_auth_server_url'],
+                                                                os.environ['keycloak_realm_name'])
+    odahu_conf['oauth_oidc_host'] = os.environ['keycloak_auth_server_url'].replace('https://', '').replace('/auth', '')
+    odahu_conf['oauth_client_id'] = os.environ['keycloak_client_name']
+    odahu_conf['oauth_client_secret'] = os.environ['keycloak_client_secret']
+    odahu_conf['oauth_cookie_secret'] = os.environ['oauth_cookie_secret']
+    odahu_conf['oauth_local_jwks'] = os.environ['odahu_oauth_local_jwks']
+    odahu_conf['infra_version'] = os.environ['odahu_infra_version']
+    odahu_conf['odahuflow_version'] = os.environ['odahu_odahuflow_version']
+    odahu_conf['mlflow_toolchain_version'] = os.environ['odahu_mlflow_toolchain_version']
+    odahu_conf['jupyterlab_version'] = os.environ['odahu_jupyterlab_version']
+    odahu_conf['packager_version'] = os.environ['odahu_packager_version']
+    odahu_conf['private_subnet_cidrs'] = os.environ['odahu_private_subnet_cidrs'].split(',')
+    odahu_conf['public_subnet_cidrs'] = os.environ['odahu_public_subnet_cidrs'].split(',')
+    odahu_conf['infra_cidr'] = os.environ['odahu_pods_cidr']
+    odahu_conf['root_domain'] = os.environ['odahu_root_domain']
+    odahu_conf['service_cidr'] = os.environ['odahu_service_cidr']
+    odahu_conf['tls_crt'] = base64.b64decode(os.environ['odahu_tls_crt'] + "==")
+    odahu_conf['tls_key'] = base64.b64decode(os.environ['odahu_tls_key'] + "==")
+    odahu_conf['ssh_key'] = os.environ['ssh_key']
+    odahu_conf['dns_project_id'] = os.environ['odahu_dns_project_id']
+    odahu_conf['decrypt_token'] = os.environ['decrypt_token']
+    odahu_conf['infra_vpc_peering'] = os.environ['odahu_infra_vpc_peering']
+    odahu_conf['automation_version'] = os.environ['odahu_automation_version']
+    odahu_conf['ui_version'] = os.environ['odahu_ui_version']
+    odahu_conf['examples_version'] = os.environ['odahu_examples_version']
+    odahu_conf['jupyterhub_enabled'] = os.environ['odahu_jupyterhub_enabled']
+    odahu_conf['oauth_mesh_enabled'] = os.environ['odahu_oauth_mesh_enabled']
+    odahu_conf['keysecret'] = os.environ['odahu_keysecret']
+    odahu_conf['airflow_secret'] = os.environ['odahu_airflow_secret']
+    odahu_conf['operator_secret'] = os.environ['odahu_operator_secret']
+    odahu_conf['resource-uploader_secret'] = os.environ['odahu_resource_uploader_secret']
+    odahu_conf['tester_secret'] = os.environ['odahu_tester_secret']
+    odahu_conf['tester-data-scientist_secret'] = os.environ['odahu_tester_data_scientist_secret']
+
+    print('Preparing parameters file')
+    try:
+        local("cp /root/templates/profile.json /tmp/")
+        with open("/tmp/profile.json", 'w') as profile:
+            prof = {
+                "allowed_ips": odahu_conf['allowed_cidr'],
+                "authorization_enabled": "true",
+                "authz_dry_run": "false",
+                "cloud": {
+                    "aws": {
+                        "az_list": odahu_conf['az_list'],
+                        "zone": "{}".format(odahu_conf['zone']),
+                    },
+                    "region": "{}".format(odahu_conf['region']),
+                    "type": "aws"
+                },
+                "cluster_name": "{}".format(odahu_conf['cluster_name']),
+                "cluster_type": "aws/eks",
+                "data_bucket": "{}-data-bucket".format(odahu_conf['cluster_name']),
+                "dns": {
+                    "domain": "odahu.{}.{}".format(odahu_conf['cluster_name'], odahu_conf['root_domain']),
+                    "gcp_credentials": "{}",
+                    "gcp_project_id": "{}".format(odahu_conf['project_id']),
+                    "provider": "gcp",
+                    "zone_name": "{}".format(odahu_conf['dns_zone_name']),
+                },
+                "docker_password": "{}".format(odahu_conf['docker_password']),
+                "docker_repo": "{}".format(odahu_conf['docker_repo']),
+                "docker_username": "_json_key",
+                "infra_cidr": "{}".format(odahu_conf['infra_cidr']),
+                "examples_version": "{}".format(odahu_conf['examples_version']),
+                "grafana_pass": "{}".format(odahu_conf['grafana_pass']),
+                "helm_repo": "{}".format(odahu_conf['helm_repo']),
+                "jupyterhub_enabled": odahu_conf['jupyterhub_enabled'],
+                "jupyterlab_version": "{}".format(odahu_conf['jupyterlab_version']),
+                "k8s_version": "{}".format(odahu_conf['k8s_version']),
+                "mlflow_toolchain_version": "{}".format(odahu_conf['mlflow_toolchain_version']),
+                "nat_subnet_cidr": "{}".format(odahu_conf['cidr']),
+                "node_pools": {
+                    "main": {
+                        "init_node_count": 1,
+                        "max_node_count": 7,
+                        "min_node_count": 1
+                    },
+                    "model_deployment": {
+                        "labels": {
+                            "mode": "odahu-flow-deployment"
+                        },
+                        "max_node_count": 3,
+                        "taints": [
+                            {
+                                "effect": "NO_SCHEDULE",
+                                "key": "dedicated",
+                                "value": "deployment"
+                            }
+                        ]
+                    },
+                    "packaging": {
+                        "disk_size_gb": 100,
+                        "labels": {
+                            "mode": "odahu-flow-packaging"
+                        },
+                        "max_node_count": 3,
+                        "taints": [
+                            {
+                                "effect": "NO_SCHEDULE",
+                                "key": "dedicated",
+                                "value": "packaging"
+                            }
+                        ]
+                    },
+                    "training": {
+                        "disk_size_gb": 50,
+                        "labels": {
+                            "mode": "odahu-flow-training"
+                        },
+                        "machine_type": "c5.2xlarge",
+                        "taints": [
+                            {
+                                "effect": "NO_SCHEDULE",
+                                "key": "dedicated",
+                                "value": "training"
+                            }
+                        ]
+                    }
+                },
+                "oauth_client_id": "{}".format(odahu_conf['oauth_client_id']),
+                "oauth_client_secret": "{}".format(odahu_conf['oauth_client_secret']),
+                "oauth_cookie_secret": "{}".format(odahu_conf['oauth_cookie_secret']),
+                "oauth_local_jwks": "{}".format(odahu_conf['oauth_local_jwks']),
+                "oauth_mesh_enabled": odahu_conf['oauth_mesh_enabled'],
+                "oauth_oidc_audience": "legion",
+                "oauth_oidc_host": "{}".format(odahu_conf['oauth_oidc_host']),
+                "oauth_oidc_issuer_url": "{}".format(odahu_conf['oauth_oidc_issuer_url']),
+                "oauth_oidc_jwks_url": "{}/protocol/openid-connect/certs".format(odahu_conf['oauth_oidc_issuer_url']),
+                "oauth_oidc_port": 443,
+                "oauth_oidc_scope": "openid profile email offline_access groups",
+                "oauth_oidc_token_endpoint": "{}/protocol/openid-connect/token".format(
+                    odahu_conf['oauth_oidc_issuer_url']),
+                "odahu_automation_version": "{}".format(odahu_conf['automation_version']),
+                "odahu_infra_version": "{}".format(odahu_conf['infra_version']),
+                "odahu_ui_version": "{}".format(odahu_conf['ui_version']),
+                "odahuflow_connection_decrypt_token": "{}".format(odahu_conf['decrypt_token']),
+                "odahuflow_connections": [
+                    {
+                        "id": "odahu-flow-examples",
+                        "spec": {
+                            "description": "Git repository with the Odahu-Flow examples",
+                            "keySecret": "{}".format(odahu_conf['keysecret']),
+                            "reference": "{}".format(odahu_conf['examples_version']),
+                            "type": "git",
+                            "uri": "git@github.com:odahu/odahu-examples.git",
+                            "webUILink": "https://github.com/odahu/odahu-examples"
+                        }
+                    }
+                ],
+                "odahuflow_version": "{}".format(odahu_conf['odahuflow_version']),
+                "opa_policies": {},
+                "packager_version": "{}".format(odahu_conf['packager_version']),
+                "private_subnet_cidrs": odahu_conf['private_subnet_cidrs'],
+                "public_subnet_cidrs": odahu_conf['public_subnet_cidrs'],
+                "service_accounts": {
+                    "airflow": {
+                        "client_id": "sa-airflow",
+                        "client_secret": "{}".format(odahu_conf['airflow_secret'])
+                    },
+                    "operator": {
+                        "client_id": "sa-operator",
+                        "client_secret": "{}".format(odahu_conf['operator_secret'])
+                    },
+                    "resource_uploader": {
+                        "client_id": "sa-resource-uploader",
+                        "client_secret": "{}".format(odahu_conf['resource-uploader_secret'])
+                    },
+                    "test": {
+                        "client_id": "sa-tester",
+                        "client_secret": "{}".format(odahu_conf['tester_secret'])
+                    },
+                    "test_data_scientist": {
+                        "client_id": "sa-tester-data-scientist",
+                        "client_secret": "{}".format(odahu_conf['tester-data-scientist_secret'])
+                    }
+                },
+                "service_cidr": "{}".format(odahu_conf['service_cidr']),
+                "ssh_key": "{}".format(odahu_conf['ssh_key'].replace('\n', '')),
+                "subnet_name": "{}".format(odahu_conf['private_subnet_name']),
+                "tfstate_bucket": "{}-tfstate".format(odahu_conf['cluster_name']),
+                "tls_crt": "{}".format(odahu_conf['tls_crt']),
+                "tls_key": "{}".format(odahu_conf['tls_key']),
+                "vpc_name": "{}".format(odahu_conf['vpc_name']),
+                "vault": {
+                    "enabled": "true"
+                }
+            }
+            profile.write(json.dumps(prof))
+        local('cat /tmp/profile.json')
+        local('cp /tmp/profile.json /')
+    except Exception as err:
+        traceback.print_exc()
+        append_result("Failed to configure parameter file.", str(err))
+        sys.exit(1)
+
+    try:
+        local('tf_runner resume -v')
+    except Exception as err:
+        traceback.print_exc()
+        append_result("Failed to deploy Odahu cluster.", str(err))
+        sys.exit(1)
diff --git a/infrastructure-provisioning/src/general/scripts/aws/odahu_suspend.py b/infrastructure-provisioning/src/general/scripts/aws/odahu_suspend.py
new file mode 100644
index 0000000..7a1faa8
--- /dev/null
+++ b/infrastructure-provisioning/src/general/scripts/aws/odahu_suspend.py
@@ -0,0 +1,287 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+import logging
+import json
+import sys
+from dlab.fab import *
+from dlab.meta_lib import *
+from dlab.actions_lib import *
+import os
+import base64
+
+if __name__ == "__main__":
+    local_log_filename = "{}_{}_{}.log".format(os.environ['conf_resource'], os.environ['project_name'],
+                                               os.environ['request_id'])
+    local_log_filepath = "/logs/project/" + local_log_filename
+    logging.basicConfig(format='%(levelname)-8s [%(asctime)s]  %(message)s',
+                        level=logging.DEBUG,
+                        filename=local_log_filepath)
+
+    print('Generating infrastructure names and tags')
+    odahu_conf = dict()
+    odahu_conf['allowed_cidr'] = os.environ['odahu_allowed_cidr'].split(',')
+    odahu_conf['project_id'] = (os.environ['gcp_project_id'])
+    odahu_conf['region'] = (os.environ['aws_region'])
+    odahu_conf['zone'] = (os.environ['aws_zone'])
+    odahu_conf['edge_user_name'] = os.environ['edge_user_name']
+    if os.environ['aws_region'] == 'us-east':
+        odahu_conf['az_list'] = ["us-east-1", "us-east-2"]
+    elif os.environ['aws_region'] == 'ap-south':
+        odahu_conf['az_list'] = ["ap-south-1"]
+    elif os.environ['aws_region'] == 'us-west':
+        odahu_conf['az_list'] = ["us-west-1", "us-west-2"]
+    elif os.environ['aws_region'] == 'eu-west':
+        odahu_conf['az_list'] = ["eu-west-1", "eu-west-2", "eu-west-3"]
+    elif os.environ['aws_region'] == 'ca-central':
+        odahu_conf['az_list'] = ["ca-central-1"]
+    odahu_conf['az_list'] = GCPMeta().get_available_zones()
+    odahu_conf['dns_zone_name'] = os.environ['odahu_dns_zone_name']
+    odahu_conf['docker_repo'] = os.environ['odahu_docker_repo']
+    odahu_conf['cidr'] = os.environ['odahu_cidr']
+    odahu_conf['service_base_name'] = (os.environ['conf_service_base_name']).lower().replace('_', '-')
+    odahu_conf['project_name'] = (os.environ['project_name']).lower().replace('_', '-')
+    odahu_conf['cluster_name'] = "{}-{}".format((os.environ['conf_service_base_name']).lower().replace('_', '-'),
+                                                (os.environ['odahu_cluster_name']).lower().replace('_', '-'))
+    odahu_conf['bucket_name'] = "{}-tfstate".format(odahu_conf['cluster_name'])
+    odahu_conf['static_address_name'] = "{}-nat-gw".format(odahu_conf['cluster_name'])
+    try:
+        if os.environ['gcp_vpc_name'] == '':
+            raise KeyError
+        else:
+            odahu_conf['vpc_name'] = os.environ['gcp_vpc_name']
+    except KeyError:
+        odahu_conf['vpc_name'] = odahu_conf['service_base_name'] + '-ssn-vpc'
+    odahu_conf['vpc_cidr'] = os.environ['conf_vpc_cidr']
+    odahu_conf['private_subnet_name'] = '{0}-{1}-subnet'.format(odahu_conf['service_base_name'],
+                                                                odahu_conf['project_name'])
+    odahu_conf['grafana_admin'] = os.environ['grafana_admin']
+    odahu_conf['grafana_pass'] = os.environ['grafana_pass']
+    odahu_conf['docker_password'] = base64.b64decode(os.environ['odahu_docker_password'] + "==")
+    odahu_conf['initial_node_count'] = os.environ['odahu_initial_node_count']
+    odahu_conf['istio_helm_repo'] = os.environ['odahu_istio_helm_repo']
+    odahu_conf['helm_repo'] = os.environ['odahu_helm_repo']
+    odahu_conf['k8s_version'] = os.environ['odahu_k8s_version']
+    odahu_conf['oauth_oidc_issuer_url'] = "{}/realms/{}".format(os.environ['keycloak_auth_server_url'],
+                                                                os.environ['keycloak_realm_name'])
+    odahu_conf['oauth_oidc_host'] = os.environ['keycloak_auth_server_url'].replace('https://', '').replace('/auth', '')
+    odahu_conf['oauth_client_id'] = os.environ['keycloak_client_name']
+    odahu_conf['oauth_client_secret'] = os.environ['keycloak_client_secret']
+    odahu_conf['oauth_cookie_secret'] = os.environ['oauth_cookie_secret']
+    odahu_conf['oauth_local_jwks'] = os.environ['odahu_oauth_local_jwks']
+    odahu_conf['infra_version'] = os.environ['odahu_infra_version']
+    odahu_conf['odahuflow_version'] = os.environ['odahu_odahuflow_version']
+    odahu_conf['mlflow_toolchain_version'] = os.environ['odahu_mlflow_toolchain_version']
+    odahu_conf['jupyterlab_version'] = os.environ['odahu_jupyterlab_version']
+    odahu_conf['packager_version'] = os.environ['odahu_packager_version']
+    odahu_conf['private_subnet_cidrs'] = os.environ['odahu_private_subnet_cidrs'].split(',')
+    odahu_conf['public_subnet_cidrs'] = os.environ['odahu_public_subnet_cidrs'].split(',')
+    odahu_conf['infra_cidr'] = os.environ['odahu_pods_cidr']
+    odahu_conf['root_domain'] = os.environ['odahu_root_domain']
+    odahu_conf['service_cidr'] = os.environ['odahu_service_cidr']
+    odahu_conf['tls_crt'] = base64.b64decode(os.environ['odahu_tls_crt'] + "==")
+    odahu_conf['tls_key'] = base64.b64decode(os.environ['odahu_tls_key'] + "==")
+    odahu_conf['ssh_key'] = os.environ['ssh_key']
+    odahu_conf['dns_project_id'] = os.environ['odahu_dns_project_id']
+    odahu_conf['decrypt_token'] = os.environ['decrypt_token']
+    odahu_conf['infra_vpc_peering'] = os.environ['odahu_infra_vpc_peering']
+    odahu_conf['automation_version'] = os.environ['odahu_automation_version']
+    odahu_conf['ui_version'] = os.environ['odahu_ui_version']
+    odahu_conf['examples_version'] = os.environ['odahu_examples_version']
+    odahu_conf['jupyterhub_enabled'] = os.environ['odahu_jupyterhub_enabled']
+    odahu_conf['oauth_mesh_enabled'] = os.environ['odahu_oauth_mesh_enabled']
+    odahu_conf['keysecret'] = os.environ['odahu_keysecret']
+    odahu_conf['airflow_secret'] = os.environ['odahu_airflow_secret']
+    odahu_conf['operator_secret'] = os.environ['odahu_operator_secret']
+    odahu_conf['resource-uploader_secret'] = os.environ['odahu_resource_uploader_secret']
+    odahu_conf['tester_secret'] = os.environ['odahu_tester_secret']
+    odahu_conf['tester-data-scientist_secret'] = os.environ['odahu_tester_data_scientist_secret']
+
+    print('Preparing parameters file')
+    try:
+        local("cp /root/templates/profile.json /tmp/")
+        with open("/tmp/profile.json", 'w') as profile:
+            prof = {
+                "allowed_ips": odahu_conf['allowed_cidr'],
+                "authorization_enabled": "true",
+                "authz_dry_run": "false",
+                "cloud": {
+                    "aws": {
+                        "az_list": odahu_conf['az_list'],
+                        "zone": "{}".format(odahu_conf['zone']),
+                    },
+                    "region": "{}".format(odahu_conf['region']),
+                    "type": "aws"
+                },
+                "cluster_name": "{}".format(odahu_conf['cluster_name']),
+                "cluster_type": "aws/eks",
+                "data_bucket": "{}-data-bucket".format(odahu_conf['cluster_name']),
+                "dns": {
+                    "domain": "odahu.{}.{}".format(odahu_conf['cluster_name'], odahu_conf['root_domain']),
+                    "gcp_credentials": "{}",
+                    "gcp_project_id": "{}".format(odahu_conf['project_id']),
+                    "provider": "gcp",
+                    "zone_name": "{}".format(odahu_conf['dns_zone_name']),
+                },
+                "docker_password": "{}".format(odahu_conf['docker_password']),
+                "docker_repo": "{}".format(odahu_conf['docker_repo']),
+                "docker_username": "_json_key",
+                "infra_cidr": "{}".format(odahu_conf['infra_cidr']),
+                "examples_version": "{}".format(odahu_conf['examples_version']),
+                "grafana_pass": "{}".format(odahu_conf['grafana_pass']),
+                "helm_repo": "{}".format(odahu_conf['helm_repo']),
+                "jupyterhub_enabled": odahu_conf['jupyterhub_enabled'],
+                "jupyterlab_version": "{}".format(odahu_conf['jupyterlab_version']),
+                "k8s_version": "{}".format(odahu_conf['k8s_version']),
+                "mlflow_toolchain_version": "{}".format(odahu_conf['mlflow_toolchain_version']),
+                "nat_subnet_cidr": "{}".format(odahu_conf['cidr']),
+                "node_pools": {
+                    "main": {
+                        "init_node_count": 1,
+                        "max_node_count": 7,
+                        "min_node_count": 1
+                    },
+                    "model_deployment": {
+                        "labels": {
+                            "mode": "odahu-flow-deployment"
+                        },
+                        "max_node_count": 3,
+                        "taints": [
+                            {
+                                "effect": "NO_SCHEDULE",
+                                "key": "dedicated",
+                                "value": "deployment"
+                            }
+                        ]
+                    },
+                    "packaging": {
+                        "disk_size_gb": 100,
+                        "labels": {
+                            "mode": "odahu-flow-packaging"
+                        },
+                        "max_node_count": 3,
+                        "taints": [
+                            {
+                                "effect": "NO_SCHEDULE",
+                                "key": "dedicated",
+                                "value": "packaging"
+                            }
+                        ]
+                    },
+                    "training": {
+                        "disk_size_gb": 50,
+                        "labels": {
+                            "mode": "odahu-flow-training"
+                        },
+                        "machine_type": "c5.2xlarge",
+                        "taints": [
+                            {
+                                "effect": "NO_SCHEDULE",
+                                "key": "dedicated",
+                                "value": "training"
+                            }
+                        ]
+                    }
+                },
+                "oauth_client_id": "{}".format(odahu_conf['oauth_client_id']),
+                "oauth_client_secret": "{}".format(odahu_conf['oauth_client_secret']),
+                "oauth_cookie_secret": "{}".format(odahu_conf['oauth_cookie_secret']),
+                "oauth_local_jwks": "{}".format(odahu_conf['oauth_local_jwks']),
+                "oauth_mesh_enabled": odahu_conf['oauth_mesh_enabled'],
+                "oauth_oidc_audience": "legion",
+                "oauth_oidc_host": "{}".format(odahu_conf['oauth_oidc_host']),
+                "oauth_oidc_issuer_url": "{}".format(odahu_conf['oauth_oidc_issuer_url']),
+                "oauth_oidc_jwks_url": "{}/protocol/openid-connect/certs".format(odahu_conf['oauth_oidc_issuer_url']),
+                "oauth_oidc_port": 443,
+                "oauth_oidc_scope": "openid profile email offline_access groups",
+                "oauth_oidc_token_endpoint": "{}/protocol/openid-connect/token".format(
+                    odahu_conf['oauth_oidc_issuer_url']),
+                "odahu_automation_version": "{}".format(odahu_conf['automation_version']),
+                "odahu_infra_version": "{}".format(odahu_conf['infra_version']),
+                "odahu_ui_version": "{}".format(odahu_conf['ui_version']),
+                "odahuflow_connection_decrypt_token": "{}".format(odahu_conf['decrypt_token']),
+                "odahuflow_connections": [
+                    {
+                        "id": "odahu-flow-examples",
+                        "spec": {
+                            "description": "Git repository with the Odahu-Flow examples",
+                            "keySecret": "{}".format(odahu_conf['keysecret']),
+                            "reference": "{}".format(odahu_conf['examples_version']),
+                            "type": "git",
+                            "uri": "git@github.com:odahu/odahu-examples.git",
+                            "webUILink": "https://github.com/odahu/odahu-examples"
+                        }
+                    }
+                ],
+                "odahuflow_version": "{}".format(odahu_conf['odahuflow_version']),
+                "opa_policies": {},
+                "packager_version": "{}".format(odahu_conf['packager_version']),
+                "private_subnet_cidrs": odahu_conf['private_subnet_cidrs'],
+                "public_subnet_cidrs": odahu_conf['public_subnet_cidrs'],
+                "service_accounts": {
+                    "airflow": {
+                        "client_id": "sa-airflow",
+                        "client_secret": "{}".format(odahu_conf['airflow_secret'])
+                    },
+                    "operator": {
+                        "client_id": "sa-operator",
+                        "client_secret": "{}".format(odahu_conf['operator_secret'])
+                    },
+                    "resource_uploader": {
+                        "client_id": "sa-resource-uploader",
+                        "client_secret": "{}".format(odahu_conf['resource-uploader_secret'])
+                    },
+                    "test": {
+                        "client_id": "sa-tester",
+                        "client_secret": "{}".format(odahu_conf['tester_secret'])
+                    },
+                    "test_data_scientist": {
+                        "client_id": "sa-tester-data-scientist",
+                        "client_secret": "{}".format(odahu_conf['tester-data-scientist_secret'])
+                    }
+                },
+                "service_cidr": "{}".format(odahu_conf['service_cidr']),
+                "ssh_key": "{}".format(odahu_conf['ssh_key'].replace('\n', '')),
+                "subnet_name": "{}".format(odahu_conf['private_subnet_name']),
+                "tfstate_bucket": "{}-tfstate".format(odahu_conf['cluster_name']),
+                "tls_crt": "{}".format(odahu_conf['tls_crt']),
+                "tls_key": "{}".format(odahu_conf['tls_key']),
+                "vpc_name": "{}".format(odahu_conf['vpc_name']),
+                "vault": {
+                    "enabled": "true"
+                }
+            }
+            profile.write(json.dumps(prof))
+        local('cat /tmp/profile.json')
+        local('cp /tmp/profile.json /')
+    except Exception as err:
+        traceback.print_exc()
+        append_result("Failed to configure parameter file.", str(err))
+        sys.exit(1)
+
+    try:
+        local('tf_runner suspend -v')
+    except Exception as err:
+        traceback.print_exc()
+        append_result("Failed to suspend Odahu cluster.", str(err))
+        sys.exit(1)
diff --git a/infrastructure-provisioning/src/general/scripts/aws/odahu_terminate.py b/infrastructure-provisioning/src/general/scripts/aws/odahu_terminate.py
new file mode 100644
index 0000000..20f5468
--- /dev/null
+++ b/infrastructure-provisioning/src/general/scripts/aws/odahu_terminate.py
@@ -0,0 +1,307 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+import logging
+import json
+import sys
+from dlab.fab import *
+from dlab.meta_lib import *
+from dlab.actions_lib import *
+import os
+import base64
+
+
+if __name__ == "__main__":
+    local_log_filename = "{}_{}_{}.log".format(os.environ['conf_resource'], os.environ['project_name'],
+                                               os.environ['request_id'])
+    local_log_filepath = "/logs/project/" + local_log_filename
+    logging.basicConfig(format='%(levelname)-8s [%(asctime)s]  %(message)s',
+                        level=logging.DEBUG,
+                        filename=local_log_filepath)
+
+    print('Generating infrastructure names and tags')
+    odahu_conf = dict()
+    odahu_conf['allowed_cidr'] = os.environ['odahu_allowed_cidr'].split(',')
+    odahu_conf['project_id'] = (os.environ['gcp_project_id'])
+    odahu_conf['region'] = (os.environ['aws_region'])
+    odahu_conf['zone'] = (os.environ['aws_zone'])
+    odahu_conf['edge_user_name'] = os.environ['edge_user_name']
+    if os.environ['aws_region'] == 'us-east':
+        odahu_conf['az_list'] = ["us-east-1", "us-east-2"]
+    elif os.environ['aws_region'] == 'ap-south':
+        odahu_conf['az_list'] = ["ap-south-1"]
+    elif os.environ['aws_region'] == 'us-west':
+        odahu_conf['az_list'] = ["us-west-1", "us-west-2"]
+    elif os.environ['aws_region'] == 'eu-west':
+        odahu_conf['az_list'] = ["eu-west-1", "eu-west-2", "eu-west-3"]
+    elif os.environ['aws_region'] == 'ca-central':
+        odahu_conf['az_list'] = ["ca-central-1"]
+    odahu_conf['az_list'] = GCPMeta().get_available_zones()
+    odahu_conf['dns_zone_name'] = os.environ['odahu_dns_zone_name']
+    odahu_conf['docker_repo'] = os.environ['odahu_docker_repo']
+    odahu_conf['cidr'] = os.environ['odahu_cidr']
+    odahu_conf['service_base_name'] = (os.environ['conf_service_base_name']).lower().replace('_', '-')
+    odahu_conf['project_name'] = (os.environ['project_name']).lower().replace('_', '-')
+    odahu_conf['cluster_name'] = "{}-{}".format((os.environ['conf_service_base_name']).lower().replace('_', '-'),
+                                                (os.environ['odahu_cluster_name']).lower().replace('_', '-'))
+    odahu_conf['bucket_name'] = "{}-tfstate".format(odahu_conf['cluster_name'])
+    odahu_conf['static_address_name'] = "{}-nat-gw".format(odahu_conf['cluster_name'])
+    try:
+        if os.environ['gcp_vpc_name'] == '':
+            raise KeyError
+        else:
+            odahu_conf['vpc_name'] = os.environ['gcp_vpc_name']
+    except KeyError:
+        odahu_conf['vpc_name'] = odahu_conf['service_base_name'] + '-ssn-vpc'
+    odahu_conf['vpc_cidr'] = os.environ['conf_vpc_cidr']
+    odahu_conf['private_subnet_name'] = '{0}-{1}-subnet'.format(odahu_conf['service_base_name'],
+                                                                odahu_conf['project_name'])
+    odahu_conf['grafana_admin'] = os.environ['grafana_admin']
+    odahu_conf['grafana_pass'] = os.environ['grafana_pass']
+    odahu_conf['docker_password'] = base64.b64decode(os.environ['odahu_docker_password'] + "==")
+    odahu_conf['initial_node_count'] = os.environ['odahu_initial_node_count']
+    odahu_conf['istio_helm_repo'] = os.environ['odahu_istio_helm_repo']
+    odahu_conf['helm_repo'] = os.environ['odahu_helm_repo']
+    odahu_conf['k8s_version'] = os.environ['odahu_k8s_version']
+    odahu_conf['oauth_oidc_issuer_url'] = "{}/realms/{}".format(os.environ['keycloak_auth_server_url'],
+                                                                os.environ['keycloak_realm_name'])
+    odahu_conf['oauth_oidc_host'] = os.environ['keycloak_auth_server_url'].replace('https://', '').replace('/auth', '')
+    odahu_conf['oauth_client_id'] = os.environ['keycloak_client_name']
+    odahu_conf['oauth_client_secret'] = os.environ['keycloak_client_secret']
+    odahu_conf['oauth_cookie_secret'] = os.environ['oauth_cookie_secret']
+    odahu_conf['oauth_local_jwks'] = os.environ['odahu_oauth_local_jwks']
+    odahu_conf['infra_version'] = os.environ['odahu_infra_version']
+    odahu_conf['odahuflow_version'] = os.environ['odahu_odahuflow_version']
+    odahu_conf['mlflow_toolchain_version'] = os.environ['odahu_mlflow_toolchain_version']
+    odahu_conf['jupyterlab_version'] = os.environ['odahu_jupyterlab_version']
+    odahu_conf['packager_version'] = os.environ['odahu_packager_version']
+    odahu_conf['private_subnet_cidrs'] = os.environ['odahu_private_subnet_cidrs'].split(',')
+    odahu_conf['public_subnet_cidrs'] = os.environ['odahu_public_subnet_cidrs'].split(',')
+    odahu_conf['infra_cidr'] = os.environ['odahu_pods_cidr']
+    odahu_conf['root_domain'] = os.environ['odahu_root_domain']
+    odahu_conf['service_cidr'] = os.environ['odahu_service_cidr']
+    odahu_conf['tls_crt'] = base64.b64decode(os.environ['odahu_tls_crt'] + "==")
+    odahu_conf['tls_key'] = base64.b64decode(os.environ['odahu_tls_key'] + "==")
+    odahu_conf['ssh_key'] = os.environ['ssh_key']
+    odahu_conf['dns_project_id'] = os.environ['odahu_dns_project_id']
+    odahu_conf['decrypt_token'] = os.environ['decrypt_token']
+    odahu_conf['infra_vpc_peering'] = os.environ['odahu_infra_vpc_peering']
+    odahu_conf['automation_version'] = os.environ['odahu_automation_version']
+    odahu_conf['ui_version'] = os.environ['odahu_ui_version']
+    odahu_conf['examples_version'] = os.environ['odahu_examples_version']
+    odahu_conf['jupyterhub_enabled'] = os.environ['odahu_jupyterhub_enabled']
+    odahu_conf['oauth_mesh_enabled'] = os.environ['odahu_oauth_mesh_enabled']
+    odahu_conf['keysecret'] = os.environ['odahu_keysecret']
+    odahu_conf['airflow_secret'] = os.environ['odahu_airflow_secret']
+    odahu_conf['operator_secret'] = os.environ['odahu_operator_secret']
+    odahu_conf['resource-uploader_secret'] = os.environ['odahu_resource_uploader_secret']
+    odahu_conf['tester_secret'] = os.environ['odahu_tester_secret']
+    odahu_conf['tester-data-scientist_secret'] = os.environ['odahu_tester_data_scientist_secret']
+
+    print('Preparing parameters file')
+    try:
+        local("cp /root/templates/profile.json /tmp/")
+        with open("/tmp/profile.json", 'w') as profile:
+            prof = {
+                "allowed_ips": odahu_conf['allowed_cidr'],
+                "authorization_enabled": "true",
+                "authz_dry_run": "false",
+                "cloud": {
+                    "aws": {
+                        "az_list": odahu_conf['az_list'],
+                        "zone": "{}".format(odahu_conf['zone']),
+                    },
+                    "region": "{}".format(odahu_conf['region']),
+                    "type": "aws"
+                },
+                "cluster_name": "{}".format(odahu_conf['cluster_name']),
+                "cluster_type": "aws/eks",
+                "data_bucket": "{}-data-bucket".format(odahu_conf['cluster_name']),
+                "dns": {
+                    "domain": "odahu.{}.{}".format(odahu_conf['cluster_name'], odahu_conf['root_domain']),
+                    "gcp_credentials": "{}",
+                    "gcp_project_id": "{}".format(odahu_conf['project_id']),
+                    "provider": "gcp",
+                    "zone_name": "{}".format(odahu_conf['dns_zone_name']),
+                },
+                "docker_password": "{}".format(odahu_conf['docker_password']),
+                "docker_repo": "{}".format(odahu_conf['docker_repo']),
+                "docker_username": "_json_key",
+                "infra_cidr": "{}".format(odahu_conf['infra_cidr']),
+                "examples_version": "{}".format(odahu_conf['examples_version']),
+                "grafana_pass": "{}".format(odahu_conf['grafana_pass']),
+                "helm_repo": "{}".format(odahu_conf['helm_repo']),
+                "jupyterhub_enabled": odahu_conf['jupyterhub_enabled'],
+                "jupyterlab_version": "{}".format(odahu_conf['jupyterlab_version']),
+                "k8s_version": "{}".format(odahu_conf['k8s_version']),
+                "mlflow_toolchain_version": "{}".format(odahu_conf['mlflow_toolchain_version']),
+                "nat_subnet_cidr": "{}".format(odahu_conf['cidr']),
+                "node_pools": {
+                    "main": {
+                        "init_node_count": 1,
+                        "max_node_count": 7,
+                        "min_node_count": 1
+                    },
+                    "model_deployment": {
+                        "labels": {
+                            "mode": "odahu-flow-deployment"
+                        },
+                        "max_node_count": 3,
+                        "taints": [
+                            {
+                                "effect": "NO_SCHEDULE",
+                                "key": "dedicated",
+                                "value": "deployment"
+                            }
+                        ]
+                    },
+                    "packaging": {
+                        "disk_size_gb": 100,
+                        "labels": {
+                            "mode": "odahu-flow-packaging"
+                        },
+                        "max_node_count": 3,
+                        "taints": [
+                            {
+                                "effect": "NO_SCHEDULE",
+                                "key": "dedicated",
+                                "value": "packaging"
+                            }
+                        ]
+                    },
+                    "training": {
+                        "disk_size_gb": 50,
+                        "labels": {
+                            "mode": "odahu-flow-training"
+                        },
+                        "machine_type": "c5.2xlarge",
+                        "taints": [
+                            {
+                                "effect": "NO_SCHEDULE",
+                                "key": "dedicated",
+                                "value": "training"
+                            }
+                        ]
+                    }
+                },
+                "oauth_client_id": "{}".format(odahu_conf['oauth_client_id']),
+                "oauth_client_secret": "{}".format(odahu_conf['oauth_client_secret']),
+                "oauth_cookie_secret": "{}".format(odahu_conf['oauth_cookie_secret']),
+                "oauth_local_jwks": "{}".format(odahu_conf['oauth_local_jwks']),
+                "oauth_mesh_enabled": odahu_conf['oauth_mesh_enabled'],
+                "oauth_oidc_audience": "legion",
+                "oauth_oidc_host": "{}".format(odahu_conf['oauth_oidc_host']),
+                "oauth_oidc_issuer_url": "{}".format(odahu_conf['oauth_oidc_issuer_url']),
+                "oauth_oidc_jwks_url": "{}/protocol/openid-connect/certs".format(odahu_conf['oauth_oidc_issuer_url']),
+                "oauth_oidc_port": 443,
+                "oauth_oidc_scope": "openid profile email offline_access groups",
+                "oauth_oidc_token_endpoint": "{}/protocol/openid-connect/token".format(
+                    odahu_conf['oauth_oidc_issuer_url']),
+                "odahu_automation_version": "{}".format(odahu_conf['automation_version']),
+                "odahu_infra_version": "{}".format(odahu_conf['infra_version']),
+                "odahu_ui_version": "{}".format(odahu_conf['ui_version']),
+                "odahuflow_connection_decrypt_token": "{}".format(odahu_conf['decrypt_token']),
+                "odahuflow_connections": [
+                    {
+                        "id": "odahu-flow-examples",
+                        "spec": {
+                            "description": "Git repository with the Odahu-Flow examples",
+                            "keySecret": "{}".format(odahu_conf['keysecret']),
+                            "reference": "{}".format(odahu_conf['examples_version']),
+                            "type": "git",
+                            "uri": "git@github.com:odahu/odahu-examples.git",
+                            "webUILink": "https://github.com/odahu/odahu-examples"
+                        }
+                    }
+                ],
+                "odahuflow_version": "{}".format(odahu_conf['odahuflow_version']),
+                "opa_policies": {},
+                "packager_version": "{}".format(odahu_conf['packager_version']),
+                "private_subnet_cidrs": odahu_conf['private_subnet_cidrs'],
+                "public_subnet_cidrs": odahu_conf['public_subnet_cidrs'],
+                "service_accounts": {
+                    "airflow": {
+                        "client_id": "sa-airflow",
+                        "client_secret": "{}".format(odahu_conf['airflow_secret'])
+                    },
+                    "operator": {
+                        "client_id": "sa-operator",
+                        "client_secret": "{}".format(odahu_conf['operator_secret'])
+                    },
+                    "resource_uploader": {
+                        "client_id": "sa-resource-uploader",
+                        "client_secret": "{}".format(odahu_conf['resource-uploader_secret'])
+                    },
+                    "test": {
+                        "client_id": "sa-tester",
+                        "client_secret": "{}".format(odahu_conf['tester_secret'])
+                    },
+                    "test_data_scientist": {
+                        "client_id": "sa-tester-data-scientist",
+                        "client_secret": "{}".format(odahu_conf['tester-data-scientist_secret'])
+                    }
+                },
+                "service_cidr": "{}".format(odahu_conf['service_cidr']),
+                "ssh_key": "{}".format(odahu_conf['ssh_key'].replace('\n', '')),
+                "subnet_name": "{}".format(odahu_conf['private_subnet_name']),
+                "tfstate_bucket": "{}-tfstate".format(odahu_conf['cluster_name']),
+                "tls_crt": "{}".format(odahu_conf['tls_crt']),
+                "tls_key": "{}".format(odahu_conf['tls_key']),
+                "vpc_name": "{}".format(odahu_conf['vpc_name']),
+                "vault": {
+                    "enabled": "true"
+                }
+            }
+            profile.write(json.dumps(prof))
+        local('cat /tmp/profile.json')
+        local('cp /tmp/profile.json /')
+    except Exception as err:
+        traceback.print_exc()
+        append_result("Failed to configure parameter file.", str(err))
+        sys.exit(1)
+
+    print('Removing Odahu cluster')
+    try:
+        local('tf_runner destroy')
+    except Exception as err:
+        traceback.print_exc()
+        append_result("Failed to terminate Odahu cluster.", str(err))
+        sys.exit(1)
+
+    try:
+        buckets = GCPMeta().get_list_buckets(odahu_conf['cluster_name'])
+        if 'items' in buckets:
+            for i in buckets['items']:
+                GCPActions().remove_bucket(i['name'])
+    except Exception as err:
+        print('Error: {0}'.format(err))
+        sys.exit(1)
+
+    try:
+        static_addresses = GCPMeta().get_list_static_addresses(odahu_conf['region'], odahu_conf['cluster_name'])
+        if 'items' in static_addresses:
+            for i in static_addresses['items']:
+                GCPActions().remove_static_address(i['name'], odahu_conf['region'])
+    except Exception as err:
+        print('Error: {0}'.format(err))
+        sys.exit(1)
diff --git a/infrastructure-provisioning/src/ssn/scripts/configure_docker.py b/infrastructure-provisioning/src/ssn/scripts/configure_docker.py
index ad4ef73..abae744 100644
--- a/infrastructure-provisioning/src/ssn/scripts/configure_docker.py
+++ b/infrastructure-provisioning/src/ssn/scripts/configure_docker.py
@@ -82,20 +82,29 @@ def add_china_repository(dlab_path):
         sudo('sed -i "22i COPY general/files/os/debian/sources.list /etc/apt/sources.list" Dockerfile')
 
 def login_in_gcr(gcr_creds, odahu_image, dlab_path):
-    if os.environ['conf_cloud_provider'] == 'gcp':
+    if os.environ['conf_cloud_provider'] != 'gcp':
         try:
-            with open('/tmp/dlab-gcr-ro-sa', 'w') as f:
-                f.write(gcr_creds)
-            local('scp -i {} /tmp/dlab-gcr-ro-sa {}:/tmp/dlab-gcr-ro-sa'.format(args.keyfile, env.host_string))
-            sudo('cat /tmp/dlab-gcr-ro-sa | base64 --decode > /tmp/dlab-gcr-ro-sa.json')
-            sudo('cat /tmp/dlab-gcr-ro-sa.json | docker login -u _json_key --password-stdin https://gcr.io')
-            sudo('sed -i "s|ODAHU_IMAGE|{}|" '
-                 '{}sources/infrastructure-provisioning/src/general/files/gcp/odahu_Dockerfile'.format(odahu_image,
-                                                                                                       dlab_path))
+            local('echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt '
+                  'cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list')
+            local('sudo apt-get -y install apt-transport-https ca-certificates gnupg')
+            local('sudo apt-get update && sudo apt-get -y install google-cloud-sdk')
         except Exception as err:
             traceback.print_exc()
-            print('Failed to prepare odahu image: ', str(err))
+            print('Failed to install gcloud: ', str(err))
             sys.exit(1)
+    try:
+        with open('/tmp/dlab-gcr-ro-sa', 'w') as f:
+            f.write(gcr_creds)
+        local('scp -i {} /tmp/dlab-gcr-ro-sa {}:/tmp/dlab-gcr-ro-sa'.format(args.keyfile, env.host_string))
+        sudo('cat /tmp/dlab-gcr-ro-sa | base64 --decode > /tmp/dlab-gcr-ro-sa.json')
+        sudo('cat /tmp/dlab-gcr-ro-sa.json | docker login -u _json_key --password-stdin https://gcr.io')
+        sudo('sed -i "s|ODAHU_IMAGE|{}|" '
+             '{}sources/infrastructure-provisioning/src/general/files/gcp/odahu_Dockerfile'.format(odahu_image,
+                                                                                                   dlab_path))
+    except Exception as err:
+        traceback.print_exc()
+        print('Failed to prepare odahu image: ', str(err))
+        sys.exit(1)
 
 def build_docker_images(image_list, region, dlab_path):
     try:


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org