diff --git a/docs/en_US/cloud_aws_rds.rst b/docs/en_US/cloud_aws_rds.rst
new file mode 100644
index 000000000..3c32022ef
--- /dev/null
+++ b/docs/en_US/cloud_aws_rds.rst
@@ -0,0 +1,93 @@
+.. _cloud_aws_rds:
+
+******************************************
+`Amazon AWS RDS Cloud Deployment`:index:
+******************************************
+
+To deploy a PostgreSQL server on the Amazon AWS cloud, follow the below steps.
+
+.. image:: images/cloud_aws_provider.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+Once you launch the tool, select the Amazon RDS option.
+Click on the *Next* button to proceed further.
+
+.. image:: images/cloud_aws_credentials.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+In the Credentials dialog, provide the region in which you want to deploy the
+instance along with the *AWS access key* and *AWS secret access key*.
+Provide *AWS session token* only if your AWS session is temporary.
+
+To proceed further, click on the next button. Before going further, pgAdmin
+will validate your credentials.
+
+.. image:: images/cloud_aws_instance.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+Use the fields from the Instance Specification tab to specify the Instance
+details.
+
+* Use the *Instance name* field to add an instance name for the PostgreSQL
+  server; the name specified will be displayed in the *Browser* tree control
+  too.
+
+* Use the *Public IP* field to specify the IP Address range for permitting the
+  inbound traffic.
+
+* Use the *Database version* field to specify the PostgreSQL version to deploy.
+
+* Use the *Instance class* field to allocate the computational, network, and
+  memory capacity required by planned workload of this DB instance.
+
+* Use the *Instance type* field to select the instance type.
+
+* Use the *Storage type* field to select the instance storage type. Three
+  options are available. General Purpose (SSD) storage, Provisioned IOPS (SSD)
+  and Magnetic storage.
+
+* Use the *Allocated storage* field to specify the storage capacity in GiB.
+
+* Use the *Provisioned IOPS* in case of  Provisioned IOPS (SSD) storage type.
+
+.. image:: images/cloud_aws_database.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+Use the fields from the Database Details tab to specify the Instance details.
+
+* Use the drop-down list box in the *Server group* field to select the parent
+  node for the server; the server will be displayed in the *Browser* tree
+  control within the specified group.
+
+* Use the *Database name* field to add the database name for the PostgreSQL
+  server.
+
+* Use the *Username* field to specify the name of a role that will be used when
+  authenticating with the server.
+
+* Use the *Password* field to provide a password that will be supplied when
+  authenticating with the server.
+
+* Use the *Confirm password* field to repeat the password.
+
+* Enter the listener port number of the server host in the *Port* field.
+
+.. image:: images/cloud_aws_review.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+At the end, review the Instance details that you provided. Click on Finish
+button to deploy the instance on Amazon RDS.
+
+.. image:: images/cloud_deployment_tree.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+Once you click on the finish, one background process will start which will
+deploy the instance in the cloud and monitor the progress of the deployment.
+The Server will be added to the tree with the cloud deployment icon. Once the
+deployment is done, the server details will be updated.
diff --git a/docs/en_US/cloud_deployment.rst b/docs/en_US/cloud_deployment.rst
index 002cb0c33..5bc2e1085 100644
--- a/docs/en_US/cloud_deployment.rst
+++ b/docs/en_US/cloud_deployment.rst
@@ -4,96 +4,15 @@
 `Cloud Deployment`:index:
 ******************************
 
-A PostgreSQL server can be deployed on the Amazon AWS cloud using this module.
-Currently only RDS is available, but in the future more cloud options will be
-available.
+A PostgreSQL server can be deployed on the Amazon AWS and EDB BigAnimal
+cloud using this module. In future more cloud options will be available.
 
 To launch the *Cloud Deployment...* tool, right click on the *Server Group* or
 *Server* of the tree control, and select *Deploy a Cloud Instance* from the
 *Register* menu.
 
-.. image:: images/cloud_deployment_provider.png
-    :alt: Cloud Deployment Provider
-    :align: center
+.. toctree::
+   :maxdepth: 2
 
-Once you launch the tool, the Amazon RDS is already selected as this is the
-only option currently available. Click on the *Next* button to proceed further.
-
-.. image:: images/cloud_deployment_credentials.png
-    :alt: Cloud Deployment Provider
-    :align: center
-
-In the Credentials dialog, provide the region in which you want to deploy the
-instance along with the *AWS access key* and *AWS secret access key*.
-Provide *AWS session token* only if your AWS session is temporary.
-
-To proceed further, click on the next button. Before going further, pgAdmin
-will validate your credentials.
-
-.. image:: images/cloud_deployment_instance.png
-    :alt: Cloud Deployment Provider
-    :align: center
-
-Use the fields from the Instance Specification tab to specify the Instance
-details.
-
-* Use the *Instance name* field to add an instance name for the PostgreSQL
-  server; the name specified will be displayed in the *Browser* tree control
-  too.
-
-* Use the *Public IP* field to specify the IP Address range for permitting the
-  inbound traffic.
-
-* Use the *Database version* field to specify the PostgreSQL version to deploy.
-
-* Use the *Instance class* field to allocate the computational, network, and
-  memory capacity required by planned workload of this DB instance.
-
-* Use the *Instance type* field to select the instance type.
-
-* Use the *Storage type* field to select the instance storage type. Three
-  options are available. General Purpose (SSD) storage, Provisioned IOPS (SSD)
-  and Magnetic storage.
-
-* Use the *Allocated storage* field to specify the storage capacity in GiB.
-
-* Use the *Provisioned IOPS* in case of  Provisioned IOPS (SSD) storage type.
-
-.. image:: images/cloud_deployment_database.png
-    :alt: Cloud Deployment Provider
-    :align: center
-
-Use the fields from the Database Details tab to specify the Instance details.
-
-* Use the drop-down list box in the *Server group* field to select the parent
-  node for the server; the server will be displayed in the *Browser* tree
-  control within the specified group.
-
-* Use the *Database name* field to add the database name for the PostgreSQL
-  server.
-
-* Use the *Username* field to specify the name of a role that will be used when
-  authenticating with the server.
-
-* Use the *Password* field to provide a password that will be supplied when
-  authenticating with the server.
-
-* Use the *Confirm password* field to repeat the password.
-
-* Enter the listener port number of the server host in the *Port* field.
-
-.. image:: images/cloud_deployment_review.png
-    :alt: Cloud Deployment Provider
-    :align: center
-
-At the end, review the Instance details that you provided. Click on Finish
-button to deploy the instance on Amazon RDS.
-
-.. image:: images/cloud_deployment_tree.png
-    :alt: Cloud Deployment Provider
-    :align: center
-
-Once you click on the finish, one background process will start which will
-deploy the instance in the cloud and monitor the progress of the deployment.
-The Server will be added to the tree with the cloud deployment icon. Once the
-deployment is done, the server details will be updated.
+   cloud_aws_rds
+   cloud_edb_biganimal
\ No newline at end of file
diff --git a/docs/en_US/cloud_edb_biganimal.rst b/docs/en_US/cloud_edb_biganimal.rst
new file mode 100644
index 000000000..7103d4e61
--- /dev/null
+++ b/docs/en_US/cloud_edb_biganimal.rst
@@ -0,0 +1,91 @@
+.. _cloud_edb_biganimal:
+
+******************************************
+`EDB BigAnimal Cloud Deployment`:index:
+******************************************
+
+To deploy a PostgreSQL server on the EDB BigAnimal cloud, follow the below steps.
+
+.. image:: images/cloud_biganimal_provider.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+Once you launch the tool, select the EDB BigAnimal option.
+Click on the *Next* button to proceed further.
+
+.. image:: images/cloud_biganimal_credentials.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+The next steps is to authenticate the user to EDB BigAninal.
+Click the given button to authenticate, by clicking the button, the user
+will be redirected to the new tab for the verification.
+Once you confirm the one time code, the pgAdmin will automatically detect it
+and the next button will be enabled. To proceed further, click on the next button.
+
+.. image:: images/cloud_biganimal_instance.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+Use the fields from the Instance Specification tab to specify the Instance
+details.
+
+* Use the *Cluster name* field to add a cluster name for the PostgreSQL
+  server; the name specified will be displayed in the *Browser* tree control
+  too.
+
+* Use the *Region* field to select the region.
+
+* Use the *Database version* field to specify the PostgreSQL version to deploy.
+
+* Use the *Instance type* field to select the instance type.
+
+* Use the *Instance series* field to select the instance series.
+
+* Use the *Instance size* field to allocate the computational, network, and
+  memory capacity required by planned workload of this DB instance.
+
+* Use the *Volume type* field to select the instance storage type.
+
+* Use the *Volume properties* field to specify the storage capacity.
+
+* Use the *Cloud type* field to specify the private or public network.
+
+* Use the *Public IP range* field to specify the IP Address range for permitting the
+  inbound traffic. Leave it blank for 0.0.0.0/0
+
+.. image:: images/cloud_biganimal_database.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+Use the fields from the Database Details tab to specify the Instance details.
+
+* Use the drop-down list box in the *Server group* field to select the parent
+  node for the server; the server will be displayed in the *Browser* tree
+  control within the specified group.
+
+* Use the *Database type* field to specify the PostgreSQL
+  type, EnterpriseDB PostgreSQL Advanced Server or PostgreSQL.
+
+* Use the *PostgreSQL version* field to select the database version.
+
+* Use the *Database Password* field to provide a password that will be supplied when
+  authenticating with the server.
+
+* Use the *Confirm password* field to repeat the password.
+
+.. image:: images/cloud_biganimal_review.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+At the end, review the Cluster details that you provided. Click on Finish
+button to deploy the instance on EDB BigAnimal.
+
+.. image:: images/cloud_deployment_tree.png
+    :alt: Cloud Deployment Provider
+    :align: center
+
+Once you click on the finish, one background process will start which will
+deploy the instance in the cloud and monitor the progress of the deployment.
+The Server will be added to the tree with the cloud deployment icon. Once the
+deployment is done, the server details will be updated.
diff --git a/docs/en_US/images/cloud_deployment_credentials.png b/docs/en_US/images/cloud_aws_credentials.png
similarity index 100%
rename from docs/en_US/images/cloud_deployment_credentials.png
rename to docs/en_US/images/cloud_aws_credentials.png
diff --git a/docs/en_US/images/cloud_deployment_database.png b/docs/en_US/images/cloud_aws_database.png
similarity index 100%
rename from docs/en_US/images/cloud_deployment_database.png
rename to docs/en_US/images/cloud_aws_database.png
diff --git a/docs/en_US/images/cloud_deployment_instance.png b/docs/en_US/images/cloud_aws_instance.png
similarity index 100%
rename from docs/en_US/images/cloud_deployment_instance.png
rename to docs/en_US/images/cloud_aws_instance.png
diff --git a/docs/en_US/images/cloud_aws_provider.png b/docs/en_US/images/cloud_aws_provider.png
new file mode 100644
index 0000000000000000000000000000000000000000..e35fd2a361c5cc8b3fc93b5f5944dc9009302af6
GIT binary patch
diff --git a/docs/en_US/images/cloud_deployment_review.png b/docs/en_US/images/cloud_aws_review.png
similarity index 100%
rename from docs/en_US/images/cloud_deployment_review.png
rename to docs/en_US/images/cloud_aws_review.png
diff --git a/docs/en_US/images/cloud_biganimal_credentials.png b/docs/en_US/images/cloud_biganimal_credentials.png
new file mode 100644
index 0000000000000000000000000000000000000000..9e64e3fef2a4fbe257bc58a411af5c597d590f66
GIT binary patch
diff --git a/docs/en_US/images/cloud_biganimal_database.png b/docs/en_US/images/cloud_biganimal_database.png
new file mode 100644
index 0000000000000000000000000000000000000000..df13c561e228b0d9919f2c7d691aaf0f6f4e1540
GIT binary patch
diff --git a/docs/en_US/images/cloud_biganimal_instance.png b/docs/en_US/images/cloud_biganimal_instance.png
new file mode 100644
index 0000000000000000000000000000000000000000..6e0cbcccc08b819c01c9d89371aff7a30035ce5d
GIT binary patch
diff --git a/docs/en_US/images/cloud_biganimal_provider.png b/docs/en_US/images/cloud_biganimal_provider.png
new file mode 100644
index 0000000000000000000000000000000000000000..feec225b7c970c2ea96bce39a9e0b18d2b6f881f
GIT binary patch
diff --git a/docs/en_US/images/cloud_biganimal_review.png b/docs/en_US/images/cloud_biganimal_review.png
new file mode 100644
index 0000000000000000000000000000000000000000..0065f3181588412e47766e382ea3ad705c2d8da8
GIT binary patch
diff --git a/docs/en_US/images/cloud_deployment_provider.png b/docs/en_US/images/cloud_deployment_provider.png
deleted file mode 100644
index 6f8f1044bf0e8cb8fa66f2ae7b4ed16dca475d63..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/web/pgacloud/pgacloud.py b/web/pgacloud/pgacloud.py
index a0a1c32ba..2c5f964a4 100755
--- a/web/pgacloud/pgacloud.py
+++ b/web/pgacloud/pgacloud.py
@@ -40,8 +40,6 @@ def get_args(providers):
     """ Creates the parsers and returns the args """
     # Create the top-level parser
     parser = argparse.ArgumentParser(prog='pgacloud.py')
-    parser.add_argument('--debug', action=argparse.BooleanOptionalAction,
-                        default=True, help='send debug messages to stderr')
 
     # Create the provider sub-parser
     parsers = parser.add_subparsers(help='provider help', dest='provider')
diff --git a/web/pgacloud/providers/biganimal.py b/web/pgacloud/providers/biganimal.py
new file mode 100644
index 000000000..53b0789f2
--- /dev/null
+++ b/web/pgacloud/providers/biganimal.py
@@ -0,0 +1,181 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2022, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+""" EDB BigAnimal PostgreSQL provider """
+
+import os
+import time
+import requests
+import json
+
+from providers._abstract import AbsProvider
+from utils.io import debug, error, output
+
+
+class BigAnimalProvider(AbsProvider):
+    BASE_URL = 'https://portal.biganimal.com/api/v1'
+
+    def __init__(self):
+        self._clients = {}
+        self._access_key = None
+        self._database_pass = None
+        self._cluster_info = None
+
+        # Get the credentials
+        if 'BIGANIMAL_ACCESS_KEY' in os.environ:
+            self._access_key = os.environ['BIGANIMAL_ACCESS_KEY']
+        if 'BIGANIMAL_DATABASE_PASSWORD' in os.environ:
+            self._database_pass = os.environ['BIGANIMAL_DATABASE_PASSWORD']
+
+    def init_args(self, parsers):
+        """ Create the command line parser for this provider """
+        self.parser = parsers.add_parser('biganimal',
+                                         help='Amazon AWS RDS PostgreSQL',
+                                         epilog='...')
+
+        # Create the command sub-parser
+        parsers = self.parser.add_subparsers(help='BigAnimal commands',
+                                             dest='command')
+
+        # Create the create instance command parser
+        parser_create_instance = parsers.add_parser('create-instance',
+                                                    help='create a new '
+                                                         'instance')
+        parser_create_instance.add_argument('--region', required=True,
+                                            help='name of the region')
+        parser_create_instance.add_argument('--name', required=True,
+                                            help='name of the cluster')
+        parser_create_instance.add_argument('--db-type', required=True,
+                                            help='database type (PostgreSQL'
+                                                 ' or EPAS)')
+        parser_create_instance.add_argument('--db-version', required=True,
+                                            help='database version')
+        parser_create_instance.add_argument('--instance-type', required=True,
+                                            help='machine type for the '
+                                                 'instance nodes')
+        parser_create_instance.add_argument('--volume-type', required=True,
+                                            help='storage type for the data '
+                                                 'database')
+        parser_create_instance.add_argument('--volume-properties',
+                                            required=True,
+                                            help='storage properties')
+        parser_create_instance.add_argument('--private-network', required=True,
+                                            help='Private or Public Network')
+        parser_create_instance.add_argument('--public-ip', default='',
+                                            help='Public IP '
+                                                 '(default: 127.0.0.1)')
+
+    def cmd_create_instance(self, args):
+        """ Create a biganimal cluster """
+
+        try:
+            private_network = True if args.private_network == '1' else False
+            ip = args.public_ip if args.public_ip else '0.0.0.0/0'
+            IpRanges = []
+
+            ip = ip.split(',')
+            for i in ip:
+                IpRanges.append([i, 'pgcloud client {}'.format(i)])
+
+            debug('Creating BigAnimal cluster: {}...'.format(args.name))
+
+            _url = "{0}/{1}".format(self.BASE_URL, 'clusters')
+            _headers = {"content-type": "application/json",
+                        "accept": "application/json",
+                        'authorization': 'Bearer {0}'.format(self._access_key)}
+
+            _data = {
+                'clusterName': args.name,
+                'instanceTypeId': args.instance_type,
+                'password': self._database_pass,
+                'postgresTypeId': args.db_type,
+                'postgresVersion': args.db_version,
+                'privateNetworking': private_network,
+                'providerId': 'azure',
+                'regionId': args.region,
+                'replicas': 3,
+                'volumePropertiesId': args.volume_properties,
+                'volumeTypeId': args.volume_type,
+                'zoneRedundantHa': False,
+                'pgConfigMap': [],
+            }
+
+            if not private_network:
+                _data['allowIpRangeMap'] = IpRanges
+
+            cluster_resp = requests.post(_url,
+                                         headers=_headers,
+                                         data=json.dumps(_data))
+
+            if cluster_resp.status_code == 202 and cluster_resp.content:
+                cluster_info = json.loads(cluster_resp.content)
+                instance_id = cluster_info['pgId']
+                instance = self.get_instance_status(instance_id)
+                data = {'instance': {
+                    'ImageName': instance['imageName'],
+                    'Database Type': instance['pgType']['name'],
+                    'Hostname': instance['clusterConnectionInfo'][
+                        'serviceName'],
+                    'Port': instance['clusterConnectionInfo']['port'],
+                    'Database': instance['clusterConnectionInfo'][
+                        'databaseName'],
+                    'Username': instance['clusterConnectionInfo'][
+                        'username']
+                }}
+
+                output(data)
+            else:
+                error(str(cluster_resp.text))
+
+        except Exception as e:
+            debug(str(e))
+
+    def get_instance_status(self, instance_id):
+        """ Get the biganimal cluster status """
+
+        running = True
+        status = None
+        while running:
+            _url = "{0}/{1}/{2}".format(self.BASE_URL, 'clusters', instance_id)
+            _headers = {"accept": "application/json",
+                        'authorization': 'Bearer {0}'.format(self._access_key)}
+
+            cluster_resp = requests.get(_url,
+                                        headers=_headers)
+
+            if cluster_resp.status_code == 200 and cluster_resp.content:
+                cluster_info = json.loads(cluster_resp.content)
+
+                self._cluster_info = cluster_info[0]
+
+                if self._cluster_info['instance'] != 0 and\
+                    self._cluster_info['phase'] not in [
+                    'Cluster creation request received',
+                    'Setting up primary',
+                    'Creating CNP cluster'
+                ]:
+                    running = False
+
+                if status != self._cluster_info['phase']:
+                    status = self._cluster_info['phase']
+                    debug('BigAnimal cluster status: {}...'.format(
+                        status))
+            else:
+                running = False
+                error(str(cluster_resp.text))
+
+            if running:
+                time.sleep(5)
+
+        return self._cluster_info
+
+
+def load():
+    """ Loads the current provider """
+    return BigAnimalProvider()
diff --git a/web/pgacloud/providers/rds.py b/web/pgacloud/providers/rds.py
index 86dd4977b..7381917cc 100644
--- a/web/pgacloud/providers/rds.py
+++ b/web/pgacloud/providers/rds.py
@@ -144,7 +144,7 @@ class RdsProvider(AbsProvider):
             name = 'pgacloud_{}_{}_{}'.format(args.name,
                                               ip[0].replace('.', '-'),
                                               get_random_id())
-            debug(args, 'Creating security group: {}...'.format(name))
+            debug('Creating security group: {}...'.format(name))
             output({'Creating': 'Creating security group: {}...'.format(name)})
             response = ec2.create_security_group(
                 Description='Inbound access for {} to RDS instance {}'.format(
@@ -152,7 +152,7 @@ class RdsProvider(AbsProvider):
                 GroupName=name
             )
         except Exception as e:
-            error(args, str(e))
+            error(str(e))
 
         return response['GroupId']
 
@@ -172,8 +172,7 @@ class RdsProvider(AbsProvider):
             })
         try:
             output({'Adding': 'Adding ingress rule for: {}...'.format(ip)})
-            debug(args,
-                  'Adding ingress rule for: {}...'.format(ip))
+            debug('Adding ingress rule for: {}...'.format(ip))
             ec2.authorize_security_group_ingress(
                 GroupId=security_group,
                 IpPermissions=[
@@ -186,7 +185,7 @@ class RdsProvider(AbsProvider):
                 ]
             )
         except Exception as e:
-            error(args, e)
+            error(e)
 
     def _create_rds_instance(self, args, security_group):
         """ Create an RDS instance """
@@ -197,7 +196,7 @@ class RdsProvider(AbsProvider):
             else args.db_password
 
         try:
-            debug(args, 'Creating RDS instance: {}...'.format(args.name))
+            debug('Creating RDS instance: {}...'.format(args.name))
             rds.create_db_instance(DBInstanceIdentifier=args.name,
                                    AllocatedStorage=args.storage_size,
                                    DBName=args.db_name,
@@ -218,18 +217,18 @@ class RdsProvider(AbsProvider):
 
         except rds.exceptions.DBInstanceAlreadyExistsFault as e:
             try:
-                debug(args, DEL_SEC_GROUP_MSG.format(security_group))
+                debug(DEL_SEC_GROUP_MSG.format(security_group))
                 ec2.delete_security_group(GroupId=security_group)
             except Exception:
                 pass
-            error(args, 'RDS instance {} already exists.'.format(args.name))
+            error('RDS instance {} already exists.'.format(args.name))
         except Exception as e:
             try:
-                debug(args, DEL_SEC_GROUP_MSG.format(security_group))
+                debug(DEL_SEC_GROUP_MSG.format(security_group))
                 ec2.delete_security_group(GroupId=security_group)
             except Exception:
                 pass
-            error(args, str(e))
+            error(str(e))
 
         # Wait for completion
         running = True
@@ -252,7 +251,7 @@ class RdsProvider(AbsProvider):
         """ Delete an RDS instance """
         rds = self._get_aws_client('rds', args)
 
-        debug(args, 'Deleting RDS instance: {}...'.format(name))
+        debug('Deleting RDS instance: {}...'.format(name))
         try:
             rds.delete_db_instance(
                 DBInstanceIdentifier=name,
@@ -260,7 +259,7 @@ class RdsProvider(AbsProvider):
                 DeleteAutomatedBackups=True
             )
         except Exception as e:
-            error(args, str(e))
+            error(str(e))
 
         # Wait for completion
         while True:
@@ -269,7 +268,7 @@ class RdsProvider(AbsProvider):
             except rds.exceptions.DBInstanceNotFoundFault:
                 return
             except Exception as e:
-                error(args, str(e))
+                error(str(e))
 
             time.sleep(5)
 
@@ -277,13 +276,13 @@ class RdsProvider(AbsProvider):
         """ Delete a security group """
         ec2 = self._get_aws_client('ec2', args)
 
-        debug(args, 'Deleting security group: {}...'.format(id))
+        debug('Deleting security group: {}...'.format(id))
         try:
             ec2.delete_security_group(
                 GroupId=id
             )
         except Exception as e:
-            error(args, str(e))
+            error(str(e))
 
     ##########################################################################
     # User commands
diff --git a/web/pgacloud/utils/io.py b/web/pgacloud/utils/io.py
index e55834702..f3ba0db6d 100644
--- a/web/pgacloud/utils/io.py
+++ b/web/pgacloud/utils/io.py
@@ -13,20 +13,17 @@ import sys
 import time
 
 
-def debug(args, message):
+def debug(message):
     """ Print a debug message """
-    if not args.debug:
-        return
-
     now = datetime.datetime.now()
 
     print('[{}]: {}'.format(now.strftime("%H:%M:%S"), message),
-          file=sys.stderr, flush=True)
+          file=sys.stderr)
 
 
-def error(args, message):
+def error(message):
     """ Print an error message and exit """
-    debug(args, message)
+    debug(message)
 
     output({'error': message})
 
@@ -35,4 +32,4 @@ def error(args, message):
 
 def output(data):
     """ Dump JSON output from a dict """
-    print(json.dumps(data), flush=True)
+    print(json.dumps(data))
diff --git a/web/pgadmin/misc/bgprocess/process_executor.py b/web/pgadmin/misc/bgprocess/process_executor.py
index bdeffe34d..fe9adfa06 100755
--- a/web/pgadmin/misc/bgprocess/process_executor.py
+++ b/web/pgadmin/misc/bgprocess/process_executor.py
@@ -170,7 +170,8 @@ class ProcessLogger(Thread):
         Thread.__init__(self)
         self.process = None
         self.stream = None
-        self.logger = open(os.path.join(_out_dir, stream_type), 'wb')
+        self.logger = open(os.path.join(_out_dir, stream_type), 'wb',
+                           buffering=0)
 
     def attach_process_stream(self, process, stream):
         """
diff --git a/web/pgadmin/misc/cloud/__init__.py b/web/pgadmin/misc/cloud/__init__.py
index c03502813..7dcbe9561 100644
--- a/web/pgadmin/misc/cloud/__init__.py
+++ b/web/pgadmin/misc/cloud/__init__.py
@@ -9,6 +9,7 @@
 
 """Implements Cloud Deployment"""
 
+import pickle
 import simplejson as json
 from flask import Response, url_for, session
 from flask import render_template, request, current_app
@@ -26,6 +27,7 @@ from pgadmin.misc.cloud.utils.rds import RDS, verify_aws_credentials,\
     get_aws_db_instances, get_aws_db_versions, clear_aws_session,\
     get_aws_regions
 from pgadmin.misc.cloud.utils import get_my_ip
+from pgadmin.misc.cloud.utils.biganimal import BigAnimalProvider
 
 from config import root
 
@@ -83,7 +85,15 @@ class CloudModule(PgAdminModule):
                 'cloud.update_cloud_server',
                 'cloud.update_cloud_process',
                 'cloud.get_aws_regions',
-                'cloud.get_host_ip']
+                'cloud.get_host_ip',
+                'cloud.biganimal_verification',
+                'cloud.biganimal_verification_ack',
+                'cloud.biganimal_regions',
+                'cloud.biganimal_db_types',
+                'cloud.biganimal_db_versions',
+                'cloud.biganimal_instance_types',
+                'cloud.biganimal_volume_types',
+                'cloud.biganimal_volume_properties']
 
 
 # Create blueprint for CloudModule class
@@ -119,6 +129,31 @@ def get_host_ip():
     return make_json_response(data=ip)
 
 
+@blueprint.route('/biganimal_verification_ack/',
+                 methods=['GET'], endpoint='biganimal_verification_ack')
+@login_required
+def biganimal_verification_ack():
+    """Verify Credentials."""
+    biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
+    status, error = biganimal_obj.polling_for_token()
+    session['biganimal']['provider_obj'] = pickle.dumps(biganimal_obj, -1)
+    return make_json_response(success=status,
+                              errormsg=error)
+
+
+@blueprint.route('/biganimal_verification/',
+                 methods=['GET'], endpoint='biganimal_verification')
+@login_required
+def biganimal_verification():
+    """Verify Credentials."""
+    biganimal = BigAnimalProvider()
+    verification_uri = biganimal.get_device_code()
+    session['biganimal'] = {}
+    session['biganimal']['provider_obj'] = pickle.dumps(biganimal, -1)
+
+    return make_json_response(data=verification_uri)
+
+
 @blueprint.route('/verify_credentials/',
                  methods=['POST'], endpoint='verify_credentials')
 @login_required
@@ -192,81 +227,158 @@ def deploy_on_cloud():
     """Deploy on Cloud"""
 
     data = json.loads(request.data, encoding='utf-8')
-    from subprocess import Popen, PIPE
+
     _cmd = 'python'
     _cmd_script = '{0}/pgacloud/pgacloud.py'.format(root)
-
-    args = [_cmd_script,
-            '--debug',
-            data['cloud'],
-            '--region',
-            str(data['secret']['aws_region']),
-            'create-instance',
-            '--name',
-            data['instance_details']['aws_name'],
-            '--db-name',
-            data['db_details']['aws_db_name'],
-            '--db-username',
-            data['db_details']['aws_db_username'],
-            '--db-port',
-            str(data['db_details']['aws_db_port']),
-            '--db-version',
-            str(data['instance_details']['aws_db_version']),
-            '--instance-type',
-            data['instance_details']['aws_instance_type'],
-            '--storage-type',
-            data['instance_details']['aws_storage_type'],
-            '--storage-size',
-            str(data['instance_details']['aws_storage_size']),
-            '--public-ip',
-            str(data['instance_details']['aws_public_ip']),
-            ]
-
-    if data['instance_details']['aws_storage_type'] == 'io1':
-        args.append('--storage-iops')
-        args.append(str(data['instance_details']['aws_storage_IOPS']))
-
-    _cmd_msg = '{0} {1} {2}'.format(_cmd, _cmd_script, ' '.join(args))
-    try:
-        sid = _create_server({
-            'gid': data['db_details']['gid'],
-            'name': data['instance_details']['aws_name'],
-            'db': data['db_details']['aws_db_name'],
-            'username': data['db_details']['aws_db_username'],
-            'port': data['db_details']['aws_db_port'],
-            'cloud_status': -1
-        })
-
-        p = BatchProcess(
-            desc=CloudProcessDesc(sid, _cmd_msg, data['cloud'],
-                                  data['instance_details']['aws_name']),
-            cmd=_cmd,
-            args=args
-        )
-
-        env = dict()
-        env['AWS_ACCESS_KEY_ID'] = data['secret']['aws_access_key']
-        env['AWS_SECRET_ACCESS_KEY'] = data['secret']['aws_secret_access_key']
-
-        if 'aws_session_token' in data['secret'] and\
-                data['secret']['aws_session_token'] is not None:
-            env['AWS_SESSION_TOKEN'] = data['secret']['aws_session_token']
-
-        if 'aws_db_password' in data['db_details']:
-            env['AWS_DATABASE_PASSWORD'] = data[
-                'db_details']['aws_db_password']
-
-        p.set_env_variables(None, env=env)
-        p.update_server_id(p.id, sid)
-        p.start()
-
-    except Exception as e:
-        current_app.logger.exception(e)
-        return make_json_response(
-            status=410,
-            success=0,
-            errormsg=str(e)
-        )
+    _label = None
+
+    if data['cloud'] == 'biganimal':
+        _label = data['instance_details']['cluster_name']
+
+        _private_network = '0'
+        if str(data['instance_details']['cloud_type']) == 'private':
+            _private_network = '1'
+
+        args = [_cmd_script,
+                data['cloud'],
+                'create-instance',
+                '--name',
+                data['instance_details']['cluster_name'],
+                '--region',
+                str(data['instance_details']['region']),
+                '--db-type',
+                str(data['db_details']['database_type']),
+                '--db-version',
+                str(data['db_details']['postgres_version']),
+                '--volume-type',
+                str(data['instance_details']['volume_type']),
+                '--volume-properties',
+                str(data['instance_details']['volume_properties']),
+                '--instance-type',
+                str(data['instance_details']['instance_size']),
+                '--private-network',
+                _private_network
+                ]
+
+        if 'biganimal_public_ip' in data['instance_details']:
+            args.append('--public-ip')
+            args.append(str(data['instance_details']['biganimal_public_ip']))
+
+        _cmd_msg = '{0} {1} {2}'.format(_cmd, _cmd_script, ' '.join(args))
+        try:
+            sid = _create_server({
+                'gid': data['db_details']['gid'],
+                'name': data['instance_details']['cluster_name'],
+                'db': 'edb_admin',
+                'username': 'edb_admin',
+                'port': 5432,
+                'cloud_status': -1
+            })
+
+            p = BatchProcess(
+                desc=CloudProcessDesc(sid, _cmd_msg,
+                                      data['cloud'],
+                                      data['instance_details']['cluster_name']
+                                      ),
+                cmd=_cmd,
+                args=args
+            )
+
+            env = dict()
+            biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
+            env['BIGANIMAL_ACCESS_KEY'] = biganimal_obj.access_token
+
+            if 'password' in data['db_details']:
+                env['BIGANIMAL_DATABASE_PASSWORD'] = data[
+                    'db_details']['password']
+
+            p.set_env_variables(None, env=env)
+            p.update_server_id(p.id, sid)
+            p.start()
+
+        except Exception as e:
+            current_app.logger.exception(e)
+            return make_json_response(
+                status=410,
+                success=0,
+                errormsg=str(e)
+            )
+
+    elif data['cloud'] == 'rds':
+        from subprocess import Popen, PIPE
+        _label = data['instance_details']['aws_name']
+
+        args = [_cmd_script,
+                data['cloud'],
+                '--region',
+                str(data['secret']['aws_region']),
+                'create-instance',
+                '--name',
+                data['instance_details']['aws_name'],
+                '--db-name',
+                data['db_details']['aws_db_name'],
+                '--db-username',
+                data['db_details']['aws_db_username'],
+                '--db-port',
+                str(data['db_details']['aws_db_port']),
+                '--db-version',
+                str(data['instance_details']['aws_db_version']),
+                '--instance-type',
+                data['instance_details']['aws_instance_type'],
+                '--storage-type',
+                data['instance_details']['aws_storage_type'],
+                '--storage-size',
+                str(data['instance_details']['aws_storage_size']),
+                '--public-ip',
+                str(data['instance_details']['aws_public_ip']),
+                ]
+
+        if data['instance_details']['aws_storage_type'] == 'io1':
+            args.append('--storage-iops')
+            args.append(str(data['instance_details']['aws_storage_IOPS']))
+
+        _cmd_msg = '{0} {1} {2}'.format(_cmd, _cmd_script, ' '.join(args))
+        try:
+            sid = _create_server({
+                'gid': data['db_details']['gid'],
+                'name': data['instance_details']['aws_name'],
+                'db': data['db_details']['aws_db_name'],
+                'username': data['db_details']['aws_db_username'],
+                'port': data['db_details']['aws_db_port'],
+                'cloud_status': -1
+            })
+
+            p = BatchProcess(
+                desc=CloudProcessDesc(sid, _cmd_msg, data['cloud'],
+                                      data['instance_details']['aws_name']),
+                cmd=_cmd,
+                args=args
+            )
+
+            env = dict()
+            env['AWS_ACCESS_KEY_ID'] = data['secret']['aws_access_key']
+            env['AWS_SECRET_ACCESS_KEY'] = data['secret'][
+                'aws_secret_access_key']
+
+            if 'aws_session_token' in data['secret'] and\
+                    data['secret']['aws_session_token'] is not None:
+                env['AWS_SESSION_TOKEN'] = data['secret']['aws_session_token']
+
+            if 'aws_db_password' in data['db_details']:
+                env['AWS_DATABASE_PASSWORD'] = data[
+                    'db_details']['aws_db_password']
+
+            p.set_env_variables(None, env=env)
+            p.update_server_id(p.id, sid)
+            p.start()
+
+        except Exception as e:
+            current_app.logger.exception(e)
+            return make_json_response(
+                status=410,
+                success=0,
+                errormsg=str(e)
+            )
 
     # Return response
     return make_json_response(
@@ -279,7 +391,7 @@ def deploy_on_cloud():
             'icon': 'icon-server-cloud-deploy',
             'id': 'server_{}'.format(sid),
             'inode': True,
-            'label': data['instance_details']['aws_name'],
+            'label': _label,
             'server_type': 'pg',
             'module': 'pgadmin.node.server',
             'cloud_status': -1
@@ -420,3 +532,71 @@ class CloudProcessDesc(IProcessDesc):
     @property
     def type_desc(self):
         return "Cloud Deployment"
+
+
+@blueprint.route('/biganimal_regions/',
+                 methods=['GET'], endpoint='biganimal_regions')
+@login_required
+def biganimal_regions():
+    """BigAnimal Regions."""
+    biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
+    regions = biganimal_obj.get_regions()
+    return make_json_response(data=regions)
+
+
+@blueprint.route('/biganimal_db_types/',
+                 methods=['GET'], endpoint='biganimal_db_types')
+@login_required
+def biganimal_db_types():
+    """BigAnimal Database Types."""
+    biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
+    pg_types = biganimal_obj.get_postgres_types()
+    return make_json_response(data=pg_types)
+
+
+@blueprint.route('/biganimal_db_versions/',
+                 methods=['GET'], endpoint='biganimal_db_versions')
+@login_required
+def biganimal_db_versions():
+    """BigAnimal Database Version."""
+    biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
+    pg_versions = biganimal_obj.get_postgres_versions()
+    return make_json_response(data=pg_versions)
+
+
+@blueprint.route('/biganimal_instance_types/<region_id>',
+                 methods=['GET'], endpoint='biganimal_instance_types')
+@login_required
+def biganimal_instance_types(region_id):
+    """BigAnimal Instance Types."""
+    if not region_id:
+        return make_json_response(data=[])
+    biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
+    biganimal_instances = biganimal_obj.get_instance_types(region_id)
+    return make_json_response(data=biganimal_instances)
+
+
+@blueprint.route('/biganimal_volume_types/<region_id>',
+                 methods=['GET'], endpoint='biganimal_volume_types')
+@login_required
+def biganimal_volume_types(region_id):
+    """VigAnimal Volume Types."""
+    if not region_id:
+        return make_json_response(data=[])
+    biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
+    biganimal_volumes = biganimal_obj.get_volume_types(region_id)
+    return make_json_response(data=biganimal_volumes)
+
+
+@blueprint.route('/biganimal_volume_properties/<region_id>/<volume_type>',
+                 methods=['GET'], endpoint='biganimal_volume_properties')
+@login_required
+def biganimal_volume_properties(region_id, volume_type):
+    """BigAnimal Volume Properties."""
+    if not region_id:
+        return make_json_response(data=[])
+    biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
+    biganimal_volume_properties = biganimal_obj.get_volume_properties(
+        region_id,
+        volume_type)
+    return make_json_response(data=biganimal_volume_properties)
diff --git a/web/pgadmin/misc/cloud/static/js/CloudWizard.jsx b/web/pgadmin/misc/cloud/static/js/CloudWizard.jsx
index d176ba1aa..5bb0340fe 100644
--- a/web/pgadmin/misc/cloud/static/js/CloudWizard.jsx
+++ b/web/pgadmin/misc/cloud/static/js/CloudWizard.jsx
@@ -14,17 +14,19 @@ import { Box, Table, TableBody, TableCell, TableHead, TableRow, Paper } from '@m
 import { makeStyles } from '@material-ui/core/styles';
 import Wizard from '../../../../static/js/helpers/wizard/Wizard';
 import WizardStep from '../../../../static/js/helpers/wizard/WizardStep';
-import {FormFooterMessage, MESSAGE_TYPE, InputToggle } from '../../../../static/js/components/FormComponents';
+import {FormFooterMessage, MESSAGE_TYPE } from '../../../../static/js/components/FormComponents';
 import getApiInstance from '../../../../static/js/api_instance';
-import SchemaView from '../../../../static/js/SchemaView';
 import Alertify from 'pgadmin.alertifyjs';
 import PropTypes from 'prop-types';
-import {CloudInstanceDetailsSchema, CloudDBCredSchema, DatabaseSchema} from './cloud_db_details_schema.ui';
-import { isEmptyString } from 'sources/validators';
 import pgAdmin from 'sources/pgadmin';
-import { getNodeAjaxOptions, getNodeListById } from 'pgbrowser/node_ajax';
 import { commonTableStyles } from '../../../../static/js/Theme';
 import clsx from 'clsx';
+import ToggleButtons from './cloud_components';
+import { PrimaryButton } from '../../../../static/js/components/Buttons';
+import {AwsCredentials, AwsInstanceDetails, AwsDatabaseDetails, validateCloudStep1,
+  validateCloudStep2, validateCloudStep3, getAWSSummary} from './aws';
+import {BigAnimalInstance, BigAnimalDatabase, validateBigAnimal, getBigAnimalSummary,
+  validateBigAnimalStep2, validateBigAnimalStep3} from './biganimal';
 
 const useStyles = makeStyles(() =>
   ({
@@ -33,7 +35,12 @@ const useStyles = makeStyles(() =>
       display: 'flex',
     },
     messagePadding: {
-      flex: 2.5
+      paddingTop: '10px',
+      flex: 2.5,
+    },
+    buttonMarginEDB: {
+      position: 'relative',
+      top: '20%',
     },
     toggleButton: {
       height: '100px',
@@ -49,7 +56,15 @@ const useStyles = makeStyles(() =>
     tableCell: {
       padding: '9px',
       paddingLeft: '11px',
-    }
+    },
+    summaryContainer: {
+      flexGrow: 1,
+      minHeight: 0,
+      overflow: 'auto',
+    },
+    boxText: {
+      paddingBottom: '5px'
+    },
   }),
 );
 
@@ -61,17 +76,24 @@ export default function CloudWizard({ nodeInfo, nodeData }) {
   const [currentStep, setCurrentStep] = React.useState('');
   const [selectionVal, setCloudSelection] = React.useState('');
   const [errMsg, setErrMsg] = React.useState('');
-  const [cloudInstanceDetailsInstance, setCloudInstanceDetailsInstance] = React.useState();
-  const [cloudDBCredInstance, setCloudDBCredInstance] = React.useState();
-  const [cloudDBInstance, setCloudDBInstance] = React.useState();
   const [cloudInstanceDetails, setCloudInstanceDetails] = React.useState({});
   const [cloudDBCred, setCloudDBCred] = React.useState({});
   const [cloudDBDetails, setCloudDBDetails] = React.useState({});
   const [callRDSAPI, setCallRDSAPI] = React.useState({});
   const [hostIP, setHostIP] = React.useState('127.0.0.1/32');
+  const [cloudProvider, setCloudProvider] = React.useState('');
+  const [verificationIntiated, setVerificationIntiated] = React.useState(false);
+  const [bigAnimalInstanceData, setBigAnimalInstanceData] = React.useState({});
+  const [bigAnimalDatabaseData, setBigAnimalDatabaseData] = React.useState({});
+  const [summary, setFinalSummary] = React.useState([]);
+
   const axiosApi = getApiInstance();
 
+  const [verificationURI, setVerificationURI] = React.useState('');
+  const [verificationCode, setVerificationCode] = React.useState('');
+
   React.useEffect(() => {
+    if (cloudProvider != 'rds') return;
     let _url = url_for('cloud.get_host_ip') ;
     axiosApi.get(_url)
       .then((res) => {
@@ -82,139 +104,33 @@ export default function CloudWizard({ nodeInfo, nodeData }) {
       .catch((error) => {
         Alertify.error(gettext(`Error while getting the host ip: ${error.response.data.errormsg}`));
       });
-  }, []);
-
-  React.useEffect(() => {
-    if (callRDSAPI == 2) {
-      const cloudDBInstanceSchema = new CloudInstanceDetailsSchema({
-        version: ()=>getNodeAjaxOptions('get_aws_db_versions', pgAdmin.Browser.Nodes['server'], nodeInfo, nodeData, {
-          useCache:false,
-          cacheNode: 'server',
-          customGenerateUrl: ()=>{
-            return url_for('cloud.get_aws_db_versions');
-          }
-        }),
-        getInstances: (engine, reload, options) =>
-        {
-          return new Promise((resolve, reject)=>{
-            const api = getApiInstance();
-            var _url = url_for('cloud.get_aws_db_instances') ;
-
-            if (engine) _url += '?eng_version=' + engine;
-            if (reload || options === undefined || options.length == 0) {
-              api.get(_url)
-                .then(res=>{
-                  let data = res.data.data;
-                  resolve(data);
-                })
-                .catch((err)=>{
-                  reject(err);
-                });
-            } else {
-              resolve(options);
-            }
-          });
-        },
-        instance_type: ()=>getNodeAjaxOptions('get_aws_db_instances', pgAdmin.Browser.Nodes['server'], nodeInfo, nodeData, {
-          useCache:false,
-          cacheNode: 'server',
-          customGenerateUrl: ()=>{
-            return url_for('cloud.get_aws_db_instances');
-          }
-        }),
-        server_groups: ()=>getNodeListById(pgAdmin.Browser.Nodes['server_group'], nodeInfo, nodeData),
-      }, {
-        gid: nodeInfo['server_group']._id,
-        hostIP: hostIP,
-      });
-      setCloudInstanceDetailsInstance(cloudDBInstanceSchema);
-    }
-  }, [callRDSAPI]);
-
-  React.useEffect(() => {
-    const cloudDBCredSchema = new CloudDBCredSchema({
-      regions: ()=>getNodeAjaxOptions('get_aws_regions', pgAdmin.Browser.Nodes['server'], nodeInfo, nodeData, {
-        useCache:false,
-        cacheNode: 'server',
-        customGenerateUrl: ()=>{
-          return url_for('cloud.get_aws_regions');
-        }
-      }),
-    });
-    setCloudDBCredInstance(cloudDBCredSchema);
-
-    const cloudDBSchema = new DatabaseSchema({
-      server_groups: ()=>getNodeListById(pgAdmin.Browser.Nodes['server_group'], nodeInfo, nodeData),
-    },
-    {
-      gid: nodeInfo['server_group']._id,
-    }
-    );
-    setCloudDBInstance(cloudDBSchema);
-
-  }, []);
+  }, [cloudProvider]);
 
   const wizardStepChange = (data) => {
     setCurrentStep(data.currentStep);
   };
 
-  const validateCloudStep1 = (cloudDBCred) => {
-    let isError = false;
-    if (isEmptyString(cloudDBCred.aws_access_key) || isEmptyString(cloudDBCred.aws_secret_access_key)) {
-      isError = true;
-    }
-    return isError;
-  };
-
-  const validateCloudStep2 = (cloudInstanceDetails, host_ip) => {
-    let isError = false;
-    if (isEmptyString(cloudInstanceDetails.aws_name) ||
-    isEmptyString(cloudInstanceDetails.aws_db_version) || isEmptyString(cloudInstanceDetails.aws_instance_type) ||
-    isEmptyString(cloudInstanceDetails.aws_storage_type)|| isEmptyString(cloudInstanceDetails.aws_storage_size)) {
-      isError = true;
-    }
-
-    if(cloudInstanceDetails.aws_storage_type == 'io1' && isEmptyString(cloudInstanceDetails.aws_storage_IOPS)) {
-      isError = true;
-    }
-    if (isEmptyString(cloudInstanceDetails.aws_public_ip)) cloudInstanceDetails.aws_public_ip = host_ip;
-    return isError;
-  };
-
-  const validateCloudStep3 = (cloudDBDetails) => {
-    let isError = false;
-    if (isEmptyString(cloudDBDetails.aws_db_name) ||
-    isEmptyString(cloudDBDetails.aws_db_username) || isEmptyString(cloudDBDetails.aws_db_password)) {
-      isError = true;
-    }
-    if (isEmptyString(cloudDBDetails.aws_db_port)) cloudDBDetails.aws_db_port = 5432;
-    if (isEmptyString(cloudDBDetails.gid)) cloudDBDetails.gid = nodeInfo['server_group']._id;
-    return isError;
-  };
-
-  const getStorageType = (cloudInstanceDetails) => {
-    let _storage_type = 'General Purpose SSD (gp2)',
-      _io1 = undefined;
-
-    if(cloudInstanceDetails.aws_storage_type == 'gp2') _storage_type = 'General Purpose SSD (gp2)';
-    else if(cloudInstanceDetails.aws_storage_type == 'io1') {
-      _storage_type = 'Provisioned IOPS SSD (io1)';
-      _io1 = cloudInstanceDetails.aws_storage_IOPS;
+  const onSave = () => {
+    var _url = url_for('cloud.deploy_on_cloud'),
+      post_data = {};
+
+    if (cloudProvider == 'rds') {
+      post_data = {
+        gid: nodeInfo.server_group._id,
+        cloud: cloudProvider,
+        secret: cloudDBCred,
+        instance_details:cloudInstanceDetails,
+        db_details: cloudDBDetails
+      };
+    } else {
+      post_data = {
+        gid: nodeInfo.server_group._id,
+        cloud: cloudProvider,
+        instance_details:bigAnimalInstanceData,
+        db_details: bigAnimalDatabaseData
+      };
     }
-    else if(cloudInstanceDetails.aws_storage_type == 'magnetic') _storage_type = 'Magnetic';
-
-    return [_io1, _storage_type];
-  };
 
-  const onSave = () => {
-    var _url = url_for('cloud.deploy_on_cloud');
-    const post_data = {
-      gid: nodeInfo.server_group._id,
-      cloud: selectionVal,
-      secret: cloudDBCred,
-      instance_details:cloudInstanceDetails,
-      db_details: cloudDBDetails
-    };
     axiosApi.post(_url, post_data)
       .then((res) => {
         pgAdmin.Browser.Events.trigger('pgadmin:browser:tree:add', res.data.data.node, {'server_group': nodeInfo['server_group']});
@@ -228,21 +144,49 @@ export default function CloudWizard({ nodeInfo, nodeData }) {
 
   const disableNextCheck = () => {
     setCallRDSAPI(currentStep);
-    let isError = false;
-    switch (currentStep) {
-    case 0:
-      setCloudSelection('rds');
-      break;
-    case 1:
-      isError = validateCloudStep1(cloudDBCred);
-      break;
-    case 2:
-      isError = validateCloudStep2(cloudInstanceDetails, hostIP);
-      break;
-    case 3:
-      isError = validateCloudStep3(cloudDBDetails);
+    let isError = (cloudProvider == '');
+    switch(cloudProvider) {
+    case 'rds':
+      switch (currentStep) {
+      case 0:
+        setCloudSelection('rds');
+        break;
+      case 1:
+        isError = validateCloudStep1(cloudDBCred);
+        break;
+      case 2:
+        isError = validateCloudStep2(cloudInstanceDetails, hostIP);
+        break;
+      case 3:
+        isError = validateCloudStep3(cloudDBDetails, nodeInfo);
+        break;
+      case 4:
+        setFinalSummary(getAWSSummary(cloudProvider, cloudInstanceDetails, cloudDBDetails));
+        break;
+      default:
+        break;
+      }
       break;
-    default:
+    case 'biganimal':
+      switch (currentStep) {
+      case 0:
+        setCloudSelection('biganimal');
+        break;
+      case 1:
+        isError = !verificationIntiated;
+        break;
+      case 2:
+        isError = validateBigAnimalStep2(bigAnimalInstanceData);
+        break;
+      case 3:
+        isError = validateBigAnimalStep3(bigAnimalDatabaseData, nodeInfo);
+        break;
+      case 4:
+        setFinalSummary(getBigAnimalSummary(cloudProvider, bigAnimalInstanceData, bigAnimalDatabaseData));
+        break;
+      default:
+        break;
+      }
       break;
     }
     return isError;
@@ -250,7 +194,7 @@ export default function CloudWizard({ nodeInfo, nodeData }) {
 
   const onBeforeNext = (activeStep) => {
     return new Promise((resolve, reject)=>{
-      if(activeStep == 1) {
+      if(activeStep == 1 && cloudProvider == 'rds') {
         setErrMsg([MESSAGE_TYPE.INFO, 'Validating credentials...']);
         var _url = url_for('cloud.verify_credentials');
         const post_data = {
@@ -271,61 +215,59 @@ export default function CloudWizard({ nodeInfo, nodeData }) {
             setErrMsg([MESSAGE_TYPE.ERROR, 'Error while checking cloud credentials']);
             reject();
           });
-      } else {
+      } else if(activeStep == 0 && cloudProvider == 'biganimal') {
+        setErrMsg([MESSAGE_TYPE.INFO, 'Getting EDB BigAnimal verification URL...']);
+        validateBigAnimal()
+          .then((res) => {
+            setVerificationURI(res);
+            setVerificationCode(res.substring(res.indexOf('=')+1));
+            setErrMsg(['', '']);
+            resolve();
+          })
+          .catch((error) => {
+            setErrMsg([MESSAGE_TYPE.ERROR, gettext(error)]);
+            reject();
+          });
+      }
+      else {
         resolve();
       }
     });
   };
 
-  const onDialogHelp = () => {
-    window.open(url_for('help.static', { 'filename': 'cloud_deployment.html' }), 'pgadmin_help');
-  };
-
-  function createData(name, value) {
-    return { name, value };
-  }
-
-  let cloud = '';
-
-  switch (selectionVal) {
-  case 'rds':
-    cloud = 'Amazon RDS';
-    break;
-  case 'azure':
-    cloud = 'Azure PostgreSQL';
-    break;
-  case 'biganimal':
-    cloud = 'EDB Big Animal';
-    break;
-  }
-
-  const rows1 = [
-    createData('Cloud', cloud),
-    createData('Instance name', cloudInstanceDetails.aws_name),
-    createData('Public IP', cloudInstanceDetails.aws_public_ip),
-  ];
+  const authenticateBigAnimal = () => {
+    var loading_icon_url = url_for(
+      'static', { 'filename': 'img/loading.gif'}
+    );
 
-  const rows2 = [
-    createData('PostgreSQL version', cloudInstanceDetails.aws_db_version),
-    createData('Instance type', cloudInstanceDetails.aws_instance_type),
-  ];
+    setErrMsg([MESSAGE_TYPE.INFO, 'EDB BigAnimal authentication process is in progress...<img src="' + loading_icon_url + '" alt="' + gettext('Loading...') + '">']);
+    window.open(verificationURI, 'edb_bibanimal_authentication');
+    let _url = url_for('cloud.biganimal_verification_ack') ;
+    const myInterval = setInterval(() => {
+      axiosApi.get(_url)
+        .then((res) => {
+          if (res.data && res.data.success == 1 ) {
+            setErrMsg([MESSAGE_TYPE.SUCCESS, 'Authentication completed successfully. Click the Next button to proceed.']);
+            setVerificationIntiated(true);
+            clearInterval(myInterval);
+          }
+          else if (res.data && res.data.success == 0 &&  res.data.errormsg == 'access_denied') {
+            setErrMsg([MESSAGE_TYPE.INFO, 'Verification failed. Access Denied...']);
+            setVerificationIntiated(false);
+            clearInterval(myInterval);
+          }
+        })
+        .catch((error) => {
+          setErrMsg([MESSAGE_TYPE.ERROR, gettext(`Error while verification EDB BigAnimal: ${error.response.data.errormsg}`)]);
+        });
+    }, 1000);
 
-  let _storage_type = getStorageType(cloudInstanceDetails);
+  };
 
-  const rows3 = [
-    createData('Storage type', _storage_type[1]),
-    createData('Allocated storage', cloudInstanceDetails.aws_storage_size + ' GiB'),
-  ];
-  if (_storage_type[0] !== undefined) {
-    rows3.push(createData('Provisioned IOPS', _storage_type[0]));
-  }
 
-  const rows4 = [
-    createData('Database name', cloudDBDetails.aws_db_name),
-    createData('Username', cloudDBDetails.aws_db_username),
-    createData('Password', 'xxxxxxx'),
-    createData('Port',  cloudDBDetails.aws_db_port),
-  ];
+  const onDialogHelp = () => {
+    window.open(url_for('help.static', { 'filename': 'cloud_deployment.html' }), 'pgadmin_help');
+  };
 
   const onErrClose = React.useCallback(()=>{
     setErrMsg([]);
@@ -341,6 +283,22 @@ export default function CloudWizard({ nodeInfo, nodeData }) {
     ));
   };
 
+  const summaryHeader = ['Cloud Details', 'Version and Instance Details', 'Storage Details', 'Database Details'];
+  const tableRows = summary.map((item, index) => {
+    return (
+      <Table key={index} className={clsx(tableClasses.table)}>
+        <TableHead>
+          <TableRow>
+            <TableCell colSpan={2}>{gettext(summaryHeader[index])}</TableCell>
+          </TableRow>
+        </TableHead>
+        <TableBody>
+          {displayTableRows(item)}
+        </TableBody>
+      </Table>
+    );
+  });
+
   return (
     <>
       <Wizard
@@ -353,107 +311,70 @@ export default function CloudWizard({ nodeInfo, nodeData }) {
         beforeNext={onBeforeNext}>
         <WizardStep stepId={0}>
           <Box className={classes.messageBox}>
-            <Box className={classes.messagePadding}>{gettext('Deploy on Amazon RDS cloud.')}</Box>
+            <Box className={classes.messagePadding}>{gettext('Select any option to deploy on cloud.')}</Box>
           </Box>
           <Box className={classes.messageBox}>
-            <InputToggle
-              value='rds'
-              options={[{'label': gettext('Amazon RDS'), value: 'rds'}]}
-              className={classes.toggleButton}
-              onChange={(value) => {
-                setCloudSelection(value);}
-              }
-            >
-            </InputToggle>
+            <ToggleButtons cloudProvider={cloudProvider} setCloudProvider={setCloudProvider}
+              options={[{'label': 'Amazon RDS', value: 'rds'}, {'label': 'EDB BigAnimal', value: 'biganimal'}]}
+            ></ToggleButtons>
           </Box>
           <Box className={classes.messageBox}>
             <Box className={classes.messagePadding}>{gettext('More cloud providers are coming soon...')}</Box>
           </Box>
+          <FormFooterMessage type={errMsg[0]} message={errMsg[1]} onClose={onErrClose} />
         </WizardStep>
         <WizardStep stepId={1} >
-          {cloudDBCredInstance &&
-            <SchemaView
-              formType={'dialog'}
-              getInitData={() => { /*This is intentional (SonarQube)*/ }}
-              viewHelperProps={{ mode: 'create' }}
-              schema={cloudDBCredInstance}
-              showFooter={false}
-              isTabView={false}
-              onDataChange={(isChanged, changedData) => {
-                setCloudDBCred(changedData);
-              }}
-            />
-          }
+          <Box className={classes.buttonMarginEDB}>
+            {cloudProvider == 'biganimal' && <Box className={classes.messageBox}>
+              <Box>{gettext('The verification code to authenticate the pgAdmin to EDB BigAnimal is: ')} <strong>{verificationCode}</strong>
+                <br/>{gettext('By clicking the below button, you will be redirected to the EDB BigAnimal authentication page in a new tab.')}
+              </Box>
+            </Box>}
+            {cloudProvider == 'biganimal' && <PrimaryButton onClick={authenticateBigAnimal}>
+              {gettext('Click here to authenticate yourself to EDB BigAnimal')}
+            </PrimaryButton>}
+            {cloudProvider == 'biganimal' && <Box className={classes.messageBox}>
+              <Box ></Box>
+            </Box>}
+          </Box>
+          {cloudProvider == 'rds' && <AwsCredentials cloudProvider={cloudProvider} nodeInfo={nodeInfo} nodeData={nodeData} setCloudDBCred={setCloudDBCred}/>}
           <FormFooterMessage type={errMsg[0]} message={errMsg[1]} onClose={onErrClose} />
         </WizardStep>
         <WizardStep stepId={2} >
-          {cloudInstanceDetailsInstance &&
-            <SchemaView
-              formType={'dialog'}
-              getInitData={() => { /*This is intentional (SonarQube)*/ }}
-              viewHelperProps={{ mode: 'create' }}
-              schema={cloudInstanceDetailsInstance}
-              showFooter={false}
-              isTabView={false}
-              onDataChange={(isChanged, changedData) => {
-                setCloudInstanceDetails(changedData);
-              }}
-            />
-          }
+          {cloudProvider == 'rds' && callRDSAPI == 2 && <AwsInstanceDetails
+            cloudProvider={cloudProvider}
+            nodeInfo={nodeInfo}
+            nodeData={nodeData}
+            setCloudInstanceDetails={setCloudInstanceDetails}
+            hostIP={hostIP} /> }
+          {cloudProvider == 'biganimal' && callRDSAPI == 2 && <BigAnimalInstance
+            cloudProvider={cloudProvider}
+            nodeInfo={nodeInfo}
+            nodeData={nodeData}
+            setBigAnimalInstanceData={setBigAnimalInstanceData}
+            hostIP={hostIP}
+          /> }
         </WizardStep>
         <WizardStep stepId={3} >
-          {cloudDBInstance &&
-            <SchemaView
-              formType={'dialog'}
-              getInitData={() => { /*This is intentional (SonarQube)*/ }}
-              viewHelperProps={{ mode: 'create' }}
-              schema={cloudDBInstance}
-              showFooter={false}
-              isTabView={false}
-              onDataChange={(isChanged, changedData) => {
-                setCloudDBDetails(changedData);
-              }}
-            />
+          {cloudProvider == 'rds' && <AwsDatabaseDetails
+            cloudProvider={cloudProvider}
+            nodeInfo={nodeInfo}
+            nodeData={nodeData}
+            setCloudDBDetails={setCloudDBDetails}
+          />
+          }
+          {cloudProvider == 'biganimal' && callRDSAPI == 3 && <BigAnimalDatabase
+            cloudProvider={cloudProvider}
+            nodeInfo={nodeInfo}
+            nodeData={nodeData}
+            setBigAnimalDatabaseData={setBigAnimalDatabaseData}
+          />
           }
         </WizardStep>
         <WizardStep stepId={4} >
           <Box className={classes.boxText}>{gettext('Please review the details before creating the cloud instance.')}</Box>
           <Paper variant="outlined" elevation={0} className={classes.summaryContainer}>
-            <Table aria-label="simple table" className={clsx(tableClasses.table)}>
-              <TableBody>
-                {displayTableRows(rows1)}
-              </TableBody>
-            </Table>
-            <Table aria-label="simple table" className={clsx(tableClasses.table)}>
-              <TableHead>
-                <TableRow>
-                  <TableCell colSpan={2}>{gettext('Version and Instance Details')}</TableCell>
-                </TableRow>
-              </TableHead>
-              <TableBody>
-                {displayTableRows(rows2)}
-              </TableBody>
-            </Table>
-            <Table aria-label="simple table" className={clsx(tableClasses.table)}>
-              <TableHead>
-                <TableRow>
-                  <TableCell colSpan={2}>{gettext('Storage Details')}</TableCell>
-                </TableRow>
-              </TableHead>
-              <TableBody>
-                {displayTableRows(rows3)}
-              </TableBody>
-            </Table>
-            <Table aria-label="simple table" className={clsx(tableClasses.table)}>
-              <TableHead>
-                <TableRow>
-                  <TableCell colSpan={2}>{gettext('Database Details')}</TableCell>
-                </TableRow>
-              </TableHead>
-              <TableBody>
-                {displayTableRows(rows4)}
-              </TableBody>
-            </Table>
+            {tableRows}
           </Paper>
         </WizardStep>
       </Wizard>
diff --git a/web/pgadmin/misc/cloud/static/js/aws.js b/web/pgadmin/misc/cloud/static/js/aws.js
new file mode 100644
index 000000000..844b42db1
--- /dev/null
+++ b/web/pgadmin/misc/cloud/static/js/aws.js
@@ -0,0 +1,243 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import React from 'react';
+import pgAdmin from 'sources/pgadmin';
+import { getNodeAjaxOptions, getNodeListById } from 'pgbrowser/node_ajax';
+import {CloudInstanceDetailsSchema, CloudDBCredSchema, DatabaseSchema} from './cloud_db_details_schema.ui';
+import SchemaView from '../../../../static/js/SchemaView';
+import url_for from 'sources/url_for';
+import getApiInstance from '../../../../static/js/api_instance';
+import { isEmptyString } from 'sources/validators';
+import PropTypes from 'prop-types';
+
+// AWS credentials
+export function AwsCredentials(props) {
+  const [cloudDBCredInstance, setCloudDBCredInstance] = React.useState();
+
+  React.useMemo(() => {
+    const cloudDBCredSchema = new CloudDBCredSchema({
+      regions: ()=>getNodeAjaxOptions('get_aws_regions', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, {
+        useCache:false,
+        cacheNode: 'server',
+        customGenerateUrl: ()=>{
+          return url_for('cloud.get_aws_regions');
+        }
+      }),
+    });
+    setCloudDBCredInstance(cloudDBCredSchema);
+  }, [props.cloudProvider]);
+
+  return  <SchemaView
+    formType={'dialog'}
+    getInitData={() => { /*This is intentional (SonarQube)*/ }}
+    viewHelperProps={{ mode: 'create' }}
+    schema={cloudDBCredInstance}
+    showFooter={false}
+    isTabView={false}
+    onDataChange={(isChanged, changedData) => {
+      props.setCloudDBCred(changedData);
+    }}
+  />;
+}
+AwsCredentials.propTypes = {
+  nodeInfo: PropTypes.object,
+  nodeData: PropTypes.object,
+  cloudProvider: PropTypes.string,
+  setCloudDBCred: PropTypes.func,
+};
+
+// AWS Instance Details
+export function AwsInstanceDetails(props) {
+  const [cloudInstanceDetailsInstance, setCloudInstanceDetailsInstance] = React.useState();
+
+  React.useMemo(() => {
+    const cloudDBInstanceSchema = new CloudInstanceDetailsSchema({
+      version: ()=>getNodeAjaxOptions('get_aws_db_versions', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, {
+        useCache:false,
+        cacheNode: 'server',
+        customGenerateUrl: ()=>{
+          return url_for('cloud.get_aws_db_versions');
+        }
+      }),
+      getInstances: (engine, reload, options) =>
+      {
+        return new Promise((resolve, reject)=>{
+          const api = getApiInstance();
+          var _url = url_for('cloud.get_aws_db_instances') ;
+
+          if (engine) _url += '?eng_version=' + engine;
+          if (reload || options === undefined || options.length == 0) {
+            api.get(_url)
+              .then(res=>{
+                let data = res.data.data;
+                resolve(data);
+              })
+              .catch((err)=>{
+                reject(err);
+              });
+          } else {
+            resolve(options);
+          }
+        });
+      },
+      instance_type: ()=>getNodeAjaxOptions('get_aws_db_instances', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, {
+        useCache:false,
+        cacheNode: 'server',
+        customGenerateUrl: ()=>{
+          return url_for('cloud.get_aws_db_instances');
+        }
+      }),
+      server_groups: ()=>getNodeListById(pgAdmin.Browser.Nodes['server_group'], props.nodeInfo, props.nodeData),
+    }, {
+      gid: props.nodeInfo['server_group']._id,
+      hostIP: props.hostIP,
+    });
+    setCloudInstanceDetailsInstance(cloudDBInstanceSchema);
+  }, [props.cloudProvider]);
+
+
+  return  <SchemaView
+    formType={'dialog'}
+    getInitData={() => { /*This is intentional (SonarQube)*/ }}
+    viewHelperProps={{ mode: 'create' }}
+    schema={cloudInstanceDetailsInstance}
+    showFooter={false}
+    isTabView={false}
+    onDataChange={(isChanged, changedData) => {
+      props.setCloudInstanceDetails(changedData);
+    }}
+  />;
+}
+AwsInstanceDetails.propTypes = {
+  nodeInfo: PropTypes.object,
+  nodeData: PropTypes.object,
+  cloudProvider: PropTypes.string,
+  hostIP: PropTypes.string,
+  setCloudInstanceDetails: PropTypes.func,
+};
+
+// AWS Database Details
+export function AwsDatabaseDetails(props) {
+  const [cloudDBInstance, setCloudDBInstance] = React.useState();
+
+  React.useMemo(() => {
+    const cloudDBSchema = new DatabaseSchema({
+      server_groups: ()=>getNodeListById(pgAdmin.Browser.Nodes['server_group'], props.nodeInfo, props.nodeData),
+    },
+    {
+      gid: props.nodeInfo['server_group']._id,
+    }
+    );
+    setCloudDBInstance(cloudDBSchema);
+
+  }, [props.cloudProvider]);
+
+  return <SchemaView
+    formType={'dialog'}
+    getInitData={() => { /*This is intentional (SonarQube)*/ }}
+    viewHelperProps={{ mode: 'create' }}
+    schema={cloudDBInstance}
+    showFooter={false}
+    isTabView={false}
+    onDataChange={(isChanged, changedData) => {
+      props.setCloudDBDetails(changedData);
+    }}
+  />;
+}
+AwsDatabaseDetails.propTypes = {
+  nodeInfo: PropTypes.object,
+  nodeData: PropTypes.object,
+  cloudProvider: PropTypes.string,
+  setCloudDBDetails: PropTypes.func,
+};
+
+export function validateCloudStep1(cloudDBCred) {
+  let isError = false;
+  if (isEmptyString(cloudDBCred.aws_access_key) || isEmptyString(cloudDBCred.aws_secret_access_key)) {
+    isError = true;
+  }
+  return isError;
+}
+
+export function validateCloudStep2(cloudInstanceDetails, host_ip) {
+  let isError = false;
+  if (isEmptyString(cloudInstanceDetails.aws_name) ||
+  isEmptyString(cloudInstanceDetails.aws_db_version) || isEmptyString(cloudInstanceDetails.aws_instance_type) ||
+  isEmptyString(cloudInstanceDetails.aws_storage_type)|| isEmptyString(cloudInstanceDetails.aws_storage_size)) {
+    isError = true;
+  }
+
+  if(cloudInstanceDetails.aws_storage_type == 'io1' && isEmptyString(cloudInstanceDetails.aws_storage_IOPS)) {
+    isError = true;
+  }
+  if (isEmptyString(cloudInstanceDetails.aws_public_ip)) cloudInstanceDetails.aws_public_ip = host_ip;
+  return isError;
+}
+
+export function validateCloudStep3(cloudDBDetails, nodeInfo) {
+  let isError = false;
+  if (isEmptyString(cloudDBDetails.aws_db_name) ||
+  isEmptyString(cloudDBDetails.aws_db_username) || isEmptyString(cloudDBDetails.aws_db_password)) {
+    isError = true;
+  }
+  if (isEmptyString(cloudDBDetails.aws_db_port)) cloudDBDetails.aws_db_port = 5432;
+  if (isEmptyString(cloudDBDetails.gid)) cloudDBDetails.gid = nodeInfo['server_group']._id;
+  return isError;
+}
+
+function createData(name, value) {
+  return { name, value };
+}
+
+export function getAWSSummary(cloud, cloudInstanceDetails, cloudDBDetails) {
+  const rows1 = [
+    createData('Cloud', cloud),
+    createData('Instance name', cloudInstanceDetails.aws_name),
+    createData('Public IP', cloudInstanceDetails.aws_public_ip),
+  ];
+
+  const rows2 = [
+    createData('PostgreSQL version', cloudInstanceDetails.aws_db_version),
+    createData('Instance type', cloudInstanceDetails.aws_instance_type),
+  ];
+
+  let _storage_type = getStorageType(cloudInstanceDetails);
+
+  const rows3 = [
+    createData('Storage type', _storage_type[1]),
+    createData('Allocated storage', cloudInstanceDetails.aws_storage_size + ' GiB'),
+  ];
+  if (_storage_type[0] !== undefined) {
+    rows3.push(createData('Provisioned IOPS', _storage_type[0]));
+  }
+
+  const rows4 = [
+    createData('Database name', cloudDBDetails.aws_db_name),
+    createData('Username', cloudDBDetails.aws_db_username),
+    createData('Password', 'xxxxxxx'),
+    createData('Port',  cloudDBDetails.aws_db_port),
+  ];
+
+  return [rows1, rows2, rows3, rows4];
+}
+
+const getStorageType = (cloudInstanceDetails) => {
+  let _storage_type = 'General Purpose SSD (gp2)',
+    _io1 = undefined;
+
+  if(cloudInstanceDetails.aws_storage_type == 'gp2') _storage_type = 'General Purpose SSD (gp2)';
+  else if(cloudInstanceDetails.aws_storage_type == 'io1') {
+    _storage_type = 'Provisioned IOPS SSD (io1)';
+    _io1 = cloudInstanceDetails.aws_storage_IOPS;
+  }
+  else if(cloudInstanceDetails.aws_storage_type == 'magnetic') _storage_type = 'Magnetic';
+
+  return [_io1, _storage_type];
+};
diff --git a/web/pgadmin/misc/cloud/static/js/biganimal.js b/web/pgadmin/misc/cloud/static/js/biganimal.js
new file mode 100644
index 000000000..389396b89
--- /dev/null
+++ b/web/pgadmin/misc/cloud/static/js/biganimal.js
@@ -0,0 +1,204 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import React from 'react';
+import pgAdmin from 'sources/pgadmin';
+import { getNodeAjaxOptions, getNodeListById } from 'pgbrowser/node_ajax';
+import {BigAnimalClusterSchema, BigAnimalDatabaseSchema} from './cloud_db_details_schema.ui';
+import SchemaView from '../../../../static/js/SchemaView';
+import url_for from 'sources/url_for';
+import getApiInstance from '../../../../static/js/api_instance';
+import { isEmptyString } from 'sources/validators';
+import PropTypes from 'prop-types';
+
+
+const axiosApi = getApiInstance();
+
+// BigAnimal Instance
+export function BigAnimalInstance(props) {
+  const [bigAnimalInstance, setBigAnimalInstance] = React.useState();
+
+  React.useMemo(() => {
+    const bigAnimalSchema = new BigAnimalClusterSchema({
+      regions: ()=>getNodeAjaxOptions('biganimal_regions', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, {
+        useCache:false,
+        cacheNode: 'server',
+        customGenerateUrl: ()=>{
+          return url_for('cloud.biganimal_regions');
+        }
+      }),
+      instance_types: (region_id)=>getNodeAjaxOptions('biganimal_instance_types', pgAdmin.Browser.Nodes['server'],
+        props.nodeInfo, props.nodeData, {
+          useCache:false,
+          cacheNode: 'server',
+          customGenerateUrl: ()=>{
+            return url_for('cloud.biganimal_instance_types', {'region_id': region_id || 0});
+          }
+        }),
+      volume_types: (region_id)=>getNodeAjaxOptions('biganimal_volume_types', pgAdmin.Browser.Nodes['server'],
+        props.nodeInfo, props.nodeData, {
+          useCache:false,
+          cacheNode: 'server',
+          customGenerateUrl: ()=>{
+            return url_for('cloud.biganimal_volume_types', {'region_id': region_id || 0});
+          }
+        }),
+      volume_properties: (region_id, volume_type)=>getNodeAjaxOptions('biganimal_volume_properties', pgAdmin.Browser.Nodes['server'],
+        props.nodeInfo, props.nodeData, {
+          useCache:false,
+          cacheNode: 'server',
+          customGenerateUrl: ()=>{
+            return url_for('cloud.biganimal_volume_properties', {'region_id': region_id || 0, 'volume_type': volume_type || ''});
+          }
+        }),
+    }, {
+      nodeInfo: props.nodeInfo,
+      nodeData: props.nodeData,
+      hostIP: props.hostIP,
+    });
+    setBigAnimalInstance(bigAnimalSchema);
+  }, [props.cloudProvider]);
+
+  return  <SchemaView
+    formType={'dialog'}
+    getInitData={() => { /*This is intentional (SonarQube)*/ }}
+    viewHelperProps={{ mode: 'create' }}
+    schema={bigAnimalInstance}
+    showFooter={false}
+    isTabView={false}
+    onDataChange={(isChanged, changedData) => {
+      props.setBigAnimalInstanceData(changedData);
+    }}
+  />;
+}
+BigAnimalInstance.propTypes = {
+  nodeInfo: PropTypes.object,
+  nodeData: PropTypes.object,
+  cloudProvider: PropTypes.string,
+  setBigAnimalInstanceData: PropTypes.func,
+  hostIP: PropTypes.string,
+};
+
+
+// BigAnimal Instance
+export function BigAnimalDatabase(props) {
+  const [bigAnimalDatabase, setBigAnimalDatabase] = React.useState();
+
+  React.useMemo(() => {
+    const bigAnimalDBSchema = new BigAnimalDatabaseSchema({
+      db_types: ()=>getNodeAjaxOptions('biganimal_db_types', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, {
+        useCache:false,
+        cacheNode: 'server',
+        customGenerateUrl: ()=>{
+          return url_for('cloud.biganimal_db_types');
+        }
+      }),
+      db_versions: ()=>getNodeAjaxOptions('biganimal_db_versions', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, {
+        useCache:false,
+        cacheNode: 'server',
+        customGenerateUrl: ()=>{
+          return url_for('cloud.biganimal_db_versions');
+        }
+      }),
+      server_groups: ()=>getNodeListById(pgAdmin.Browser.Nodes['server_group'], props.nodeInfo, props.nodeData),
+    }, {gid: props.nodeInfo['server_group']._id});
+    setBigAnimalDatabase(bigAnimalDBSchema);
+  }, [props.cloudProvider]);
+
+  return  <SchemaView
+    formType={'dialog'}
+    getInitData={() => { /*This is intentional (SonarQube)*/ }}
+    viewHelperProps={{ mode: 'create' }}
+    schema={bigAnimalDatabase}
+    showFooter={false}
+    isTabView={false}
+    onDataChange={(isChanged, changedData) => {
+      props.setBigAnimalDatabaseData(changedData);
+    }}
+  />;
+}
+BigAnimalDatabase.propTypes = {
+  nodeInfo: PropTypes.object,
+  nodeData: PropTypes.object,
+  cloudProvider: PropTypes.string,
+  setBigAnimalDatabaseData: PropTypes.func,
+};
+
+
+export function validateBigAnimal() {
+  return new Promise((resolve, reject)=>{
+    let _url = url_for('cloud.biganimal_verification') ;
+    axiosApi.get(_url)
+      .then((res) => {
+        if (res.data.data) {
+          resolve(res.data.data);
+        }
+      })
+      .catch((error) => {
+        reject(`Error while fetchng EDB BigAnimal verification uri: ${error.response.data.errormsg}`);
+      });
+  });
+}
+
+
+function createData(name, value) {
+  return { name, value };
+}
+
+export function getBigAnimalSummary(cloud, bigAnimalInstanceData, bigAnimalDatabaseData) {
+  const rows1 = [
+    createData('Cloud', cloud),
+    createData('Instance name', bigAnimalInstanceData.cluster_name),
+    createData('Region', bigAnimalInstanceData.region),
+    createData('Cluster type', bigAnimalInstanceData.cloud_type),
+    createData('Public IPs', bigAnimalInstanceData.biganimal_public_ip),
+  ];
+
+  const rows2 = [
+    createData('Instance type', bigAnimalInstanceData.instance_type),
+    createData('Instance series', bigAnimalInstanceData.instance_series),
+    createData('Instance size', bigAnimalInstanceData.instance_size),
+  ];
+
+  const rows3 = [
+    createData('Volume type', bigAnimalInstanceData.volume_type),
+    createData('Volume properties', bigAnimalInstanceData.volume_properties),
+  ];
+
+  const rows4 = [
+    createData('Password', 'xxxxxxx'),
+    createData('Database Type',  bigAnimalDatabaseData.database_type),
+    createData('Database Version',  bigAnimalDatabaseData.postgres_version),
+  ];
+
+  return [rows1, rows2, rows3, rows4];
+}
+
+export function validateBigAnimalStep2(cloudInstanceDetails) {
+  let isError = false;
+  if (isEmptyString(cloudInstanceDetails.cluster_name) ||
+  isEmptyString(cloudInstanceDetails.region) || isEmptyString(cloudInstanceDetails.instance_type) ||
+  isEmptyString(cloudInstanceDetails.instance_series)|| isEmptyString(cloudInstanceDetails.instance_size) ||
+  isEmptyString(cloudInstanceDetails.volume_type)|| isEmptyString(cloudInstanceDetails.volume_properties) ||
+  isEmptyString(cloudInstanceDetails.cloud_type)) {
+    isError = true;
+  }
+
+  return isError;
+}
+
+export function validateBigAnimalStep3(cloudDBDetails, nodeInfo) {
+  let isError = false;
+  if (isEmptyString(cloudDBDetails.password) ||
+  isEmptyString(cloudDBDetails.database_type) || isEmptyString(cloudDBDetails.postgres_version)) {
+    isError = true;
+  }
+  if (isEmptyString(cloudDBDetails.gid)) cloudDBDetails.gid = nodeInfo['server_group']._id;
+  return isError;
+}
diff --git a/web/pgadmin/misc/cloud/static/js/cloud_components.jsx b/web/pgadmin/misc/cloud/static/js/cloud_components.jsx
new file mode 100644
index 000000000..d96d26ad7
--- /dev/null
+++ b/web/pgadmin/misc/cloud/static/js/cloud_components.jsx
@@ -0,0 +1,56 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import React from 'react';
+import { ToggleButton, ToggleButtonGroup } from '@material-ui/lab';
+import CheckRoundedIcon from '@material-ui/icons/CheckRounded';
+import { DefaultButton, PrimaryButton } from '../../../../static/js/components/Buttons';
+import { makeStyles } from '@material-ui/core/styles';
+import { AWSIcon } from '../../../../static/js/components/ExternalIcon';
+import PropTypes from 'prop-types';
+
+const useStyles = makeStyles(() =>
+  ({
+    toggleButton: {
+      height: '100px',
+    },
+  }),
+);
+
+
+export default function ToggleButtons(props) {
+  const classes = useStyles();
+
+  const handleCloudProvider = (event, provider) => {
+    if (provider) props.setCloudProvider(provider);
+  };
+
+  return (
+    <ToggleButtonGroup
+      color="primary"
+      value={props.cloudProvider}
+      onChange={handleCloudProvider}
+      className={classes.toggleButton}
+      exclusive>
+      {
+        (props.options||[]).map((option)=>{
+          return (<ToggleButton value={option.value} key={option.label} aria-label={option.label} component={props.cloudProvider == option.value ? PrimaryButton : DefaultButton}>
+            <CheckRoundedIcon style={{visibility: props.cloudProvider == option.value  ? 'visible': 'hidden'}}/>&nbsp;
+            {option.value == 'rds' ? <AWSIcon className={classes.icon} /> : ''}&nbsp;&nbsp;{option.label}
+          </ToggleButton>);
+        })
+      }
+    </ToggleButtonGroup>
+  );
+}
+ToggleButtons.propTypes = {
+  setCloudProvider: PropTypes.func,
+  cloudProvider: PropTypes.string,
+  options: PropTypes.array,
+};
diff --git a/web/pgadmin/misc/cloud/static/js/cloud_db_details_schema.ui.js b/web/pgadmin/misc/cloud/static/js/cloud_db_details_schema.ui.js
index f26a6c199..4f343d662 100644
--- a/web/pgadmin/misc/cloud/static/js/cloud_db_details_schema.ui.js
+++ b/web/pgadmin/misc/cloud/static/js/cloud_db_details_schema.ui.js
@@ -173,6 +173,7 @@ class DatabaseSchema extends BaseUISchema {
   }
 }
 
+
 export class InstanceSchema extends BaseUISchema {
   constructor(versionOpts, instanceOpts, getInstances) {
     super({
@@ -301,8 +302,329 @@ export class StorageSchema extends BaseUISchema {
   }
 }
 
+
+class BigAnimalInstanceSchema extends BaseUISchema {
+  constructor(fieldOptions = {}, initValues={}) {
+    super({
+      oid: undefined,
+      instance_type: '',
+      instance_series: '',
+      instance_size: '',
+      ...initValues
+    });
+
+    this.fieldOptions = {
+      ...fieldOptions,
+    };
+
+    this.initValues = initValues;
+  }
+
+  get idAttribute() {
+    return 'oid';
+  }
+
+  get baseFields() {
+    return [
+      {
+        id: 'instance_type', label: gettext('Instance type'),
+        mode: ['create'],
+        deps: [['region']],
+        type: (state) => {
+          return {
+            type: 'select',
+            options: ()=>this.fieldOptions.instance_types(state.region),
+            optionsReloadBasis: state.region,
+            optionsLoaded: (options) => { state.instanceData = options; },
+            controlProps: {
+              allowClear: false,
+              filter: (options) => {
+                if (options.length == 0) return;
+                let _types = _.uniq(_.map(options, 'category')),
+                  _options = [];
+                _.forEach(_types, function(value) {
+                  _options.push({
+                    'label': value,
+                    'value': value
+                  });
+                });
+                return _options;
+              },
+            }
+          };
+        },
+        noEmpty: true,
+      },{
+        id: 'instance_series', label: gettext('Instance series'),
+        mode: ['create'], deps: ['instance_type'],
+        type: (state) => {
+          return {
+            type: 'select',
+            options: state.instanceData,
+            optionsReloadBasis: state.instance_type,
+            controlProps: {
+              allowClear: false,
+              filter: (options) => {
+                if (options.length == 0) return;
+                let _types = _.filter(options, {'category': state.instance_type}),
+                  _options = [];
+                _types = _.uniq(_.map(_types, 'familyName'));
+                _.forEach(_types, function(value) {
+                  _options.push({
+                    'label': value,
+                    'value': value
+                  });
+                });
+                return _options;
+              },
+            }
+          };
+        },
+        noEmpty: true,
+      },{
+        id: 'instance_size', label: gettext('Instance size'),
+        mode: ['create'], deps: ['instance_series'],
+        type: (state) => {
+          return {
+            type: 'select',
+            options: state.instanceData,
+            optionsReloadBasis: state.instance_series,
+            controlProps: {
+              allowClear: false,
+              filter: (options) => {
+                if (options.length == 0) return;
+                let _types = _.filter(options, {'familyName': state.instance_series}),
+                  _options = [];
+                _.forEach(_types, function(value) {
+                  _options.push({
+                    'label': value.instanceType + ' (' + value.cpu + 'vCPU, ' + value.ram + 'GB RAM)',
+                    'value': value.id,
+                  });
+                });
+                return _options;
+              },
+            }
+          };
+        }, noEmpty: true,
+      },
+    ];
+  }
+}
+
+
+class BigAnimalVolumeSchema extends BaseUISchema {
+  constructor(fieldOptions = {}, initValues = {}) {
+    super({
+      oid: undefined,
+      volume_type: '',
+      volume_properties: '',
+      ...initValues
+    });
+
+    this.fieldOptions = {
+      ...fieldOptions,
+    };
+    this.initValues = initValues;
+  }
+
+  get idAttribute() {
+    return 'oid';
+  }
+
+  get baseFields() {
+    return [
+      {
+        id: 'volume_type', label: gettext('Volume type'),
+        mode: ['create'], deps: [['region']],
+        type: (state) => {
+          return {
+            type: 'select',
+            options: ()=>this.fieldOptions.volume_types(state.region),
+            optionsReloadBasis: state.region,
+          };
+        }, noEmpty: true,
+      },{
+        id: 'volume_properties', label: gettext('Volume properties'),
+        mode: ['create'], deps: ['volume_type'],
+        type: (state) => {
+          return {
+            type: 'select',
+            options: ()=>this.fieldOptions.volume_properties(state.region, state.volume_type),
+            optionsReloadBasis: state.volume_type,
+          };
+        }, noEmpty: true,
+      },
+    ];
+  }
+}
+
+
+class BigAnimalNetworkSchema extends BaseUISchema {
+  constructor(fieldOptions = {}, initValues = {}) {
+    super({
+      oid: undefined,
+      cloud_type: '',
+      biganimal_public_ip: initValues.hostIP,
+      ...initValues
+    });
+
+    this.fieldOptions = {
+      ...fieldOptions,
+    };
+    this.initValues = initValues;
+  }
+
+  get idAttribute() {
+    return 'oid';
+  }
+
+  get baseFields() {
+    return [
+      {
+        id: 'cloud_type', label: gettext('Cloud type'), type: 'toggle',
+        mode: ['create'],
+        options: [
+          {'label': gettext('Private'), 'value': 'private'},
+          {'label': gettext('Public'), 'value': 'public'},
+        ], noEmpty: true,
+      },{
+        id: 'biganimal_public_ip', label: gettext('Public IP range'), type: 'text',
+        mode: ['create'], deps: ['cloud_type'],
+        disabled: (state) => {
+          if (state.cloud_type == 'public') return false;
+          return true;
+        },
+        helpMessage: gettext('IP Address range for permitting the inbound traffic. Ex: 127.0.0.1/32, add multiple ip addresses/ranges by comma separated. Leave it blank for 0.0.0.0/0'),
+      },
+    ];
+  }
+}
+class BigAnimalDatabaseSchema extends BaseUISchema {
+  constructor(fieldOptions = {}, initValues = {}) {
+    super({
+      oid: undefined,
+      password: '',
+      confirm_password: '',
+      database_type: '',
+      postgres_version: '',
+      ...initValues
+    });
+
+    this.fieldOptions = {
+      ...fieldOptions,
+    };
+    this.initValues = initValues;
+  }
+
+
+  validate(data, setErrMsg) {
+    if(!isEmptyString(data.password) && !isEmptyString(data.confirm_password)
+    && data.password != data.confirm_password) {
+      setErrMsg('confirm_password', gettext('Passwords do not match.'));
+      return true;
+    }
+    if (!isEmptyString(data.confirm_password) && data.confirm_password.length < 12) {
+      setErrMsg('confirm_password', gettext('Password must be 12 characters or more.'));
+      return true;
+    }
+
+    return false;
+  }
+
+  get idAttribute() {
+    return 'oid';
+  }
+
+  get baseFields() {
+    return [
+      {
+        id: 'gid', label: gettext('Server group'), type: 'select',
+        options: this.fieldOptions.server_groups,
+        mode: ['create'],
+        controlProps: { allowClear: false },
+        noEmpty: true,
+      }, {
+        id: 'database_type', label: gettext('Database type'), mode: ['create'],
+        type: 'select',
+        options: this.fieldOptions.db_types,
+        noEmpty: true, orientation: 'vertical',
+      },{
+        id: 'postgres_version', label: gettext('PostgreSQL version'), type: 'select',
+        mode: ['create'], noEmpty: true,
+        options: this.fieldOptions.db_versions,
+      },{
+        id: 'password', label: gettext('Database password'), type: 'password',
+        mode: ['create'], noEmpty: true,
+      },{
+        id: 'confirm_password', label: gettext('Confirm password'), type: 'password',
+        mode: ['create'], noEmpty: true,
+      },
+    ];
+  }
+}
+
+class BigAnimalClusterSchema extends BaseUISchema {
+  constructor(fieldOptions = {}, initValues = {}) {
+    super({
+      oid: undefined,
+      cluster_name: '',
+      region: '',
+      public_ip: initValues.hostIP,
+      ...initValues
+    });
+
+    this.fieldOptions = {
+      ...fieldOptions,
+    };
+    this.initValues = initValues;
+
+    this.instance_types = new BigAnimalInstanceSchema({
+      instance_types: this.fieldOptions.instance_types,
+    });
+    this.volume_types = new BigAnimalVolumeSchema({
+      volume_types: this.fieldOptions.volume_types,
+      volume_properties: this.fieldOptions.volume_properties
+    });
+  }
+
+  get idAttribute() {
+    return 'oid';
+  }
+
+  get baseFields() {
+    return [
+      {
+        id: 'cluster_name', label: gettext('Cluster name'), type: 'text',
+        mode: ['create'], noEmpty: true,
+      },{
+        id: 'region', label: gettext('Region'), type: 'select',
+        options: this.fieldOptions.regions,
+        controlProps: { allowClear: false },
+        noEmpty: true,
+        mode: ['create'],
+      },{
+        type: 'nested-fieldset', label: gettext('Instance Type'),
+        mode: ['create'], deps: ['region'],
+        schema: this.instance_types,
+      },{
+        type: 'nested-fieldset', label: gettext('Storage'),
+        mode: ['create'], deps: ['region'],
+        schema: this.volume_types,
+      }, {
+        type: 'nested-fieldset', label: gettext('Network Connectivity'),
+        mode: ['create'],
+        schema: new BigAnimalNetworkSchema({}, this.initValues),
+      }
+    ];
+  }
+}
+
+
 export {
   CloudInstanceDetailsSchema,
   CloudDBCredSchema,
   DatabaseSchema,
+  BigAnimalClusterSchema,
+  BigAnimalDatabaseSchema
 };
+
diff --git a/web/pgadmin/misc/cloud/utils/__init__.py b/web/pgadmin/misc/cloud/utils/__init__.py
index 4cded810f..206d79fb3 100644
--- a/web/pgadmin/misc/cloud/utils/__init__.py
+++ b/web/pgadmin/misc/cloud/utils/__init__.py
@@ -15,10 +15,10 @@ def get_my_ip():
     """ Return the public IP of this host """
     http = urllib3.PoolManager()
     try:
-        external_ip = http.request('GET', 'https://ident.me').data
+        external_ip = http.request('GET', 'http://ident.me').data
     except Exception:
         try:
-            external_ip = http.request('GET', 'https://ifconfig.me/ip').data
+            external_ip = http.request('GET', 'http://ifconfig.me/ip').data
         except Exception:
             external_ip = '127.0.0.1'
 
diff --git a/web/pgadmin/misc/cloud/utils/biganimal.py b/web/pgadmin/misc/cloud/utils/biganimal.py
new file mode 100644
index 000000000..e04f30c38
--- /dev/null
+++ b/web/pgadmin/misc/cloud/utils/biganimal.py
@@ -0,0 +1,210 @@
+# ##########################################################################
+# #
+# # pgAdmin 4 - PostgreSQL Tools
+# #
+# # Copyright (C) 2013 - 2022, The pgAdmin Development Team
+# # This software is released under the PostgreSQL Licence
+# #
+# ##########################################################################
+
+# EDB BigAnimal
+
+import requests
+import json
+from werkzeug.datastructures import Headers
+
+
+class BigAnimalProvider():
+    BASE_URL = 'https://portal.biganimal.com/api/v1'
+
+    def __init__(self):
+        self.provider = {}
+        self.device_code = {}
+        self.token = {}
+        self.raw_access_token = None
+        self.access_token = None
+        self.token_error = {}
+        self.token_status = -1
+        self.get_auth_provider()
+
+    def get_auth_provider(self):
+        # 1. Get Authentication Provider Relevant Information
+        provider_resp = requests.get("{0}/{1}".format(self.BASE_URL,
+                                                      'auth/provider'))
+        if provider_resp.status_code == 200 and provider_resp.content:
+            self.provider = json.loads(provider_resp.content)
+            print(self.provider)
+
+    def get_device_code(self):
+        _url = "{0}/{1}".format(self.provider['issuerUri'],
+                                'oauth/device/code')
+        _headers = {"content-type": "application/x-www-form-urlencoded"}
+        _data = {
+            'client_id': self.provider['clientId'],
+            'audience': self.provider['audience'],
+            'scope': self.provider['scope']
+        }
+        device_resp = requests.post(_url,
+                                    headers=_headers,
+                                    data=_data)
+
+        if device_resp.status_code == 200 and device_resp.content:
+            self.device_code = json.loads(device_resp.content)
+            return self.device_code['verification_uri_complete']
+
+    def polling_for_token(self):
+        # Polling for the Token
+        _url = "{0}/{1}".format(self.provider['issuerUri'], 'oauth/token')
+        _headers = {"content-type": "application/x-www-form-urlencoded"}
+        _data = {
+            'grant_type': 'urn:ietf:params:oauth:grant-type:device_code',
+            'device_code': self.device_code['device_code'],
+            'client_id': self.provider['clientId']
+        }
+        token_resp = requests.post(_url,
+                                   headers=_headers,
+                                   data=_data)
+        if token_resp.status_code == 200:
+            self.token = json.loads(token_resp.content)
+            self.raw_access_token = self.token['access_token']
+            self.token_error['error'] = None
+            self.token_status = 1
+            return self.exchange_token()
+        elif token_resp.status_code == 403:
+            self.token_error = json.loads(token_resp.content)
+            if self.token_error['error'] == 'authorization_pending' or\
+                    self.token_error['error'] == 'access_denied':
+                self.token_status = 0
+                return False, self.token_error['error']
+        return False, None
+
+    def exchange_token(self):
+        _url = "{0}/{1}".format(self.BASE_URL, 'auth/token')
+        _headers = {"content-type": "application/json"}
+        _data = {'token': self.raw_access_token}
+        token_resp = requests.post(_url,
+                                   headers=_headers,
+                                   data=json.dumps(_data))
+
+        final_token = json.loads(token_resp.content)
+        if token_resp.status_code == 200:
+            self.access_token = final_token['token']
+            print("Access Token: {}".format(self.access_token))
+            return True, None
+        else:
+            return False, self.token_error['error']
+
+    def get_regions(self):
+        _url = "{0}/{1}".format(
+            self.BASE_URL,
+            'cloud-providers/azure/regions')
+        headers = Headers()
+        headers.add('Authorization', 'Bearer {0}'.format(self.access_token))
+        headers.add('content-type', 'application/json')
+        _headers = {
+            'content-type': 'application/json',
+            'Authorization': 'Bearer {0}'.format(self.access_token)
+        }
+        regions = []
+        resp = requests.get(_url, headers=headers)
+        if resp.status_code == 200 and resp.content:
+            regions_resp = json.loads(resp.content)
+            for value in regions_resp['regionsList']:
+                regions.append({
+                    'label': value['regionName'],
+                    'value': value['regionId']
+                })
+
+        return regions
+
+    def get_postgres_types(self):
+        _url = "{0}/{1}".format(
+            self.BASE_URL,
+            'postgres-types')
+        _headers = {
+            'content-type': 'application/json',
+            'authorization': 'Bearer {0}'.format(self.access_token)
+        }
+        pg_types = []
+        resp = requests.get(_url, headers=_headers)
+        if resp.status_code == 200 and resp.content:
+            pg_types_resp = json.loads(resp.content)
+            for value in pg_types_resp['pgTypesList']:
+                pg_types.append({
+                    'label': value['name'],
+                    'value': value['id']
+                })
+        return pg_types
+
+    def get_postgres_versions(self):
+        _url = "{0}/{1}".format(
+            self.BASE_URL,
+            'postgres-versions')
+        _headers = {
+            'content-type': 'application/json',
+            'authorization': 'Bearer {0}'.format(self.access_token)
+        }
+        pg_versions = []
+        resp = requests.get(_url, headers=_headers)
+        if resp.status_code == 200 and resp.content:
+            pg_versions_resp = json.loads(resp.content)
+            for value in pg_versions_resp['pgVersionsList']:
+                pg_versions.append({
+                    'label': value['versionName'],
+                    'value': value['versionId']
+                })
+        return pg_versions
+
+    def get_instance_types(self, region_id):
+        _url = "{0}/{1}".format(
+            self.BASE_URL,
+            'cloud-providers/azure/regions/'
+            '{0}/instance-types'.format(region_id))
+        _headers = {
+            'content-type': 'application/json',
+            'authorization': 'Bearer {0}'.format(self.access_token)
+        }
+        resp = requests.get(_url, headers=_headers)
+        if resp.status_code == 200 and resp.content:
+            pg_types = json.loads(resp.content)
+            return pg_types['instanceTypesList']
+        return []
+
+    def get_volume_types(self, region_id):
+        _url = "{0}/{1}".format(
+            self.BASE_URL,
+            'cloud-providers/azure/regions/{0}/volume-types'.format(region_id))
+        _headers = {
+            'content-type': 'application/json',
+            'authorization': 'Bearer {0}'.format(self.access_token)
+        }
+        volume_types = []
+        resp = requests.get(_url, headers=_headers)
+        if resp.status_code == 200 and resp.content:
+            volume_resp = json.loads(resp.content)
+            for value in volume_resp['volumeTypesList']:
+                volume_types.append({
+                    'label': value['displayName'],
+                    'value': value['id']
+                })
+        return volume_types
+
+    def get_volume_properties(self, region_id, volume_type):
+        _url = "{0}/{1}".format(
+            self.BASE_URL,
+            'cloud-providers/azure/regions/{0}/volume-types'
+            '/{1}/volume-properties'.format(region_id, volume_type))
+        _headers = {
+            'content-type': 'application/json',
+            'authorization': 'Bearer {0}'.format(self.access_token)
+        }
+        volume_properties = []
+        resp = requests.get(_url, headers=_headers)
+        if resp.status_code == 200 and resp.content:
+            volume_prop = json.loads(resp.content)
+            for value in volume_prop['volumePropertiesList']:
+                volume_properties.append({
+                    'label': value['value'],
+                    'value': value['id']
+                })
+        return volume_properties
diff --git a/web/pgadmin/misc/cloud/utils/rds.py b/web/pgadmin/misc/cloud/utils/rds.py
index 9c32cbbf1..5975c8f3c 100644
--- a/web/pgadmin/misc/cloud/utils/rds.py
+++ b/web/pgadmin/misc/cloud/utils/rds.py
@@ -51,7 +51,7 @@ class RDS():
         return rds.describe_db_engine_versions(Engine=engine)
 
     def get_available_db_instance_class(self, engine='postgres',
-                                        engine_version='9.6'):
+                                        engine_version='10'):
         rds = self._get_aws_client('rds')
         _instances = rds.describe_orderable_db_instance_options(
             Engine=engine,
diff --git a/web/pgadmin/static/img/aws.svg b/web/pgadmin/static/img/aws.svg
new file mode 100644
index 000000000..3dec8e73f
--- /dev/null
+++ b/web/pgadmin/static/img/aws.svg
@@ -0,0 +1 @@
+<svg height="1465" viewBox="-.1 1.1 304.9 179.8" width="2500" xmlns="http://www.w3.org/2000/svg"><path d="m86.4 66.4c0 3.7.4 6.7 1.1 8.9.8 2.2 1.8 4.6 3.2 7.2.5.8.7 1.6.7 2.3 0 1-.6 2-1.9 3l-6.3 4.2c-.9.6-1.8.9-2.6.9-1 0-2-.5-3-1.4-1.4-1.5-2.6-3.1-3.6-4.7-1-1.7-2-3.6-3.1-5.9-7.8 9.2-17.6 13.8-29.4 13.8-8.4 0-15.1-2.4-20-7.2s-7.4-11.2-7.4-19.2c0-8.5 3-15.4 9.1-20.6s14.2-7.8 24.5-7.8c3.4 0 6.9.3 10.6.8s7.5 1.3 11.5 2.2v-7.3c0-7.6-1.6-12.9-4.7-16-3.2-3.1-8.6-4.6-16.3-4.6-3.5 0-7.1.4-10.8 1.3s-7.3 2-10.8 3.4c-1.6.7-2.8 1.1-3.5 1.3s-1.2.3-1.6.3c-1.4 0-2.1-1-2.1-3.1v-4.9c0-1.6.2-2.8.7-3.5s1.4-1.4 2.8-2.1c3.5-1.8 7.7-3.3 12.6-4.5 4.9-1.3 10.1-1.9 15.6-1.9 11.9 0 20.6 2.7 26.2 8.1 5.5 5.4 8.3 13.6 8.3 24.6v32.4zm-40.6 15.2c3.3 0 6.7-.6 10.3-1.8s6.8-3.4 9.5-6.4c1.6-1.9 2.8-4 3.4-6.4s1-5.3 1-8.7v-4.2c-2.9-.7-6-1.3-9.2-1.7s-6.3-.6-9.4-.6c-6.7 0-11.6 1.3-14.9 4s-4.9 6.5-4.9 11.5c0 4.7 1.2 8.2 3.7 10.6 2.4 2.5 5.9 3.7 10.5 3.7zm80.3 10.8c-1.8 0-3-.3-3.8-1-.8-.6-1.5-2-2.1-3.9l-23.5-77.3c-.6-2-.9-3.3-.9-4 0-1.6.8-2.5 2.4-2.5h9.8c1.9 0 3.2.3 3.9 1 .8.6 1.4 2 2 3.9l16.8 66.2 15.6-66.2c.5-2 1.1-3.3 1.9-3.9s2.2-1 4-1h8c1.9 0 3.2.3 4 1 .8.6 1.5 2 1.9 3.9l15.8 67 17.3-67c.6-2 1.3-3.3 2-3.9.8-.6 2.1-1 3.9-1h9.3c1.6 0 2.5.8 2.5 2.5 0 .5-.1 1-.2 1.6s-.3 1.4-.7 2.5l-24.1 77.3c-.6 2-1.3 3.3-2.1 3.9s-2.1 1-3.8 1h-8.6c-1.9 0-3.2-.3-4-1s-1.5-2-1.9-4l-15.5-64.5-15.4 64.4c-.5 2-1.1 3.3-1.9 4s-2.2 1-4 1zm128.5 2.7c-5.2 0-10.4-.6-15.4-1.8s-8.9-2.5-11.5-4c-1.6-.9-2.7-1.9-3.1-2.8s-.6-1.9-.6-2.8v-5.1c0-2.1.8-3.1 2.3-3.1.6 0 1.2.1 1.8.3s1.5.6 2.5 1c3.4 1.5 7.1 2.7 11 3.5 4 .8 7.9 1.2 11.9 1.2 6.3 0 11.2-1.1 14.6-3.3s5.2-5.4 5.2-9.5c0-2.8-.9-5.1-2.7-7s-5.2-3.6-10.1-5.2l-14.5-4.5c-7.3-2.3-12.7-5.7-16-10.2-3.3-4.4-5-9.3-5-14.5 0-4.2.9-7.9 2.7-11.1s4.2-6 7.2-8.2c3-2.3 6.4-4 10.4-5.2s8.2-1.7 12.6-1.7c2.2 0 4.5.1 6.7.4 2.3.3 4.4.7 6.5 1.1 2 .5 3.9 1 5.7 1.6s3.2 1.2 4.2 1.8c1.4.8 2.4 1.6 3 2.5.6.8.9 1.9.9 3.3v4.7c0 2.1-.8 3.2-2.3 3.2-.8 0-2.1-.4-3.8-1.2-5.7-2.6-12.1-3.9-19.2-3.9-5.7 0-10.2.9-13.3 2.8s-4.7 4.8-4.7 8.9c0 2.8 1 5.2 3 7.1s5.7 3.8 11 5.5l14.2 4.5c7.2 2.3 12.4 5.5 15.5 9.6s4.6 8.8 4.6 14c0 4.3-.9 8.2-2.6 11.6-1.8 3.4-4.2 6.4-7.3 8.8-3.1 2.5-6.8 4.3-11.1 5.6-4.5 1.4-9.2 2.1-14.3 2.1z" fill="#252f3e"/><g clip-rule="evenodd" fill="#f90" fill-rule="evenodd"><path d="m273.5 143.7c-32.9 24.3-80.7 37.2-121.8 37.2-57.6 0-109.5-21.3-148.7-56.7-3.1-2.8-.3-6.6 3.4-4.4 42.4 24.6 94.7 39.5 148.8 39.5 36.5 0 76.6-7.6 113.5-23.2 5.5-2.5 10.2 3.6 4.8 7.6z"/><path d="m287.2 128.1c-4.2-5.4-27.8-2.6-38.5-1.3-3.2.4-3.7-2.4-.8-4.5 18.8-13.2 49.7-9.4 53.3-5 3.6 4.5-1 35.4-18.6 50.2-2.7 2.3-5.3 1.1-4.1-1.9 4-9.9 12.9-32.2 8.7-37.5z"/></g></svg>
\ No newline at end of file
diff --git a/web/pgadmin/static/js/components/ExternalIcon.jsx b/web/pgadmin/static/js/components/ExternalIcon.jsx
index 3fa91b895..234ac3a83 100644
--- a/web/pgadmin/static/js/components/ExternalIcon.jsx
+++ b/web/pgadmin/static/js/components/ExternalIcon.jsx
@@ -13,6 +13,7 @@ import FormatCaseSvg from '../../img/fonticon/format_case.svg?svgr';
 import PropTypes from 'prop-types';
 import Expand from '../../img/fonticon/open_in_full.svg?svgr';
 import Collapse from '../../img/fonticon/close_fullscreen.svg?svgr';
+import AWS from '../../img/aws.svg?svgr';
 
 export default function ExternalIcon({Icon, ...props}) {
   return <Icon className={'MuiSvgIcon-root'} {...props} />;
@@ -35,3 +36,4 @@ export const RegexIcon = ()=><ExternalIcon Icon={RegexSvg} />;
 export const FormatCaseIcon = ()=><ExternalIcon Icon={FormatCaseSvg} />;
 export const ExpandDialogIcon = ()=><ExternalIcon Icon={Expand} style={{height: '1.2rem'}}  />;
 export const MinimizeDialogIcon = ()=><ExternalIcon Icon={Collapse} style={{height: '1.4rem'}} />;
+export const AWSIcon = ()=><ExternalIcon Icon={AWS} style={{height: '1.4rem'}} />;
diff --git a/web/pgadmin/static/js/components/FormComponents.jsx b/web/pgadmin/static/js/components/FormComponents.jsx
index cec2ae439..cd3eb2380 100644
--- a/web/pgadmin/static/js/components/FormComponents.jsx
+++ b/web/pgadmin/static/js/components/FormComponents.jsx
@@ -588,7 +588,6 @@ InputRadio.propTypes = {
   labelPlacement: PropTypes.string
 };
 
-
 export const InputToggle = forwardRef(({ cid, value, onChange, options, disabled, readonly, ...props }, ref) => {
   return (
     <ToggleButtonGroup
@@ -1264,7 +1263,7 @@ export function NotifierMessage({ type = MESSAGE_TYPE.SUCCESS, message, closable
   return (
     <Box className={clsx(classes.container, classes[`container${type}`])}>
       <FormIcon type={type} className={classes[`icon${type}`]} />
-      <Box className={classes.message}>{message}</Box>
+      <Box className={classes.message}>{HTMLReactParse(message || '')}</Box>
       {closable && <IconButton className={clsx(classes.closeButton, classes[`icon${type}`])} onClick={onClose}>
         <FormIcon close={true} />
       </IconButton>}
diff --git a/web/yarn.lock b/web/yarn.lock
index 3868618e6..3dcce15be 100644
--- a/web/yarn.lock
+++ b/web/yarn.lock
@@ -9754,7 +9754,7 @@ source-map-js@^0.6.2:
   resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
   integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
 
-source-map-support@^0.5.5, source-map-support@~0.5.20:
+source-map-support@^0.5.5:
   version "0.5.20"
   resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9"
   integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==
@@ -9762,6 +9762,14 @@ source-map-support@^0.5.5, source-map-support@~0.5.20:
     buffer-from "^1.0.0"
     source-map "^0.6.0"
 
+source-map-support@~0.5.20:
+  version "0.5.21"
+  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
+  integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
+  dependencies:
+    buffer-from "^1.0.0"
+    source-map "^0.6.0"
+
 source-map@^0.5.0, source-map@^0.5.7, source-map@~0.5.3:
   version "0.5.7"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
