Helm charts topology
In the Getting Started guide, we designed a SaaS service that deploys Redis Clusters using a Helm chart. However, in that example, we only deployed a single component as part of the overall SaaS deployment.
Omnistrate supports deploying multiple Helm charts as part of a single deployment. Your SaaS service may require multiple components to be deployed, and each component may have its own Helm chart. For eg: a Redis Cluster Helm chart and a Postgres Helm chart.
In this guide, we will show you how to deploy multiple Helm charts as part of a single deployment. We will use the example of deploying a Redis Cluster and a Postgres database as part of a single deployment.
Add the Helm Chart Configuration¶
First, we need to update the Service Plan specification to include the Helm chart configurations for the Postgres Database. We will use the Bitnami chart to do so. We will also hide this component from your customers from a provisioning point of view and make it an internal component. We will also add some customization parameters that will be exposed to your customers.
- name: Postgres Database
internal: false
compute:
instanceTypes:
- apiParam: postgresInstanceType
cloudProvider: aws
- apiParam: postgresInstanceType
cloudProvider: gcp
network:
ports:
- 5432
helmChartConfiguration:
chartName: postgresql
chartVersion: 15.5.36
chartRepoName: bitnami
chartRepoURL: https://charts.bitnami.com/bitnami
chartValues:
auth:
database: $var.postgresDatabase
username: $var.postgresUsername
password: $var.postgresPassword
primary:
persistence:
enabled: false
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 1000m
memory: 1024Mi
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: omnistrate.com/managed-by
operator: In
values:
- omnistrate
- key: topology.kubernetes.io/region
operator: In
values:
- $sys.deploymentCell.region
- key: node.kubernetes.io/instance-type
operator: In
values:
- $sys.compute.node.instanceType
- key: omnistrate.com/resource
operator: In
values:
- $sys.deployment.resourceID
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: omnistrate.com/schedule-mode
operator: In
values:
- exclusive
namespaceSelector: {}
topologyKey: kubernetes.io/hostname
readReplicas:
replicaCount: 0
apiParameters:
- key: postgresUsername
description: Postgres Username
name: Postgres Username
type: String
modifiable: true
required: true
export: true
- key: postgresPassword
description: Postgres Password
name: Postgres Password
type: String
modifiable: true
required: true
export: true
- key: postgresDatabase
description: Postgres Database
name: Postgres Database
type: String
modifiable: true
required: true
export: true
- key: postgresInstanceType
description: Postgres Instance Type
name: Postgres Instance Type
type: String
modifiable: true
required: true
export: true
We will then set the Postgres component as a dependency on the Redis component. This will ensure that the Postgres component is deployed before the Redis component.
services:
- name: Redis Cluster
dependsOn:
- Postgres Database
apiParameters:
...
- key: postgresUsername
description: Postgres Username
name: Postgres Username
type: String
modifiable: false
required: false
export: true
defaultValue: "postgres"
parameterDependencyMap:
Postgres Database: postgresUsername
- key: postgresPassword
description: Postgres Password
name: Postgres Password
type: Password
modifiable: false
required: true
export: true
parameterDependencyMap:
Postgres Database: postgresPassword
- key: postgresDatabase
description: Postgres Database
name: Postgres Database
type: String
modifiable: false
required: false
export: true
defaultValue: "postgres"
parameterDependencyMap:
Postgres Database: postgresDatabase
- key: postgresInstanceType
description: Postgres Instance Type
name: Postgres Instance Type
type: String
modifiable: true
required: false
export: true
defaultValue: "t4g.small"
parameterDependencyMap:
Postgres Database: postgresInstanceType
parameterDependencyMap
field in the API parameters and mapping them to the dependent component and the relevant API parameter defined on the dependent component.
Final specification¶
name: Redis Server # Service Plan Name
deployment:
hostedDeployment:
AwsAccountId: "<AWS_ID>"
AwsBootstrapRoleAccountArn: arn:aws:iam::<AWS_ID>:role/omnistrate-bootstrap-role
services:
- name: Redis Cluster
dependsOn:
- Postgres Database
compute:
instanceTypes:
- apiParam: instanceType
cloudProvider: aws
- apiParam: instanceType
cloudProvider: gcp
network:
ports:
- 6379
helmChartConfiguration:
chartName: redis
chartVersion: 19.6.2
chartRepoName: bitnami
chartRepoURL: https://charts.bitnami.com/bitnami
chartValues:
master:
podLabels:
omnistrate.com/schedule-mode: exclusive
persistence:
enabled: false
service:
type: LoadBalancer
annotations:
external-dns.alpha.kubernetes.io/hostname: $sys.network.externalClusterEndpoint
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 150m
memory: 256Mi
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: omnistrate.com/managed-by
operator: In
values:
- omnistrate
- key: topology.kubernetes.io/region
operator: In
values:
- $sys.deploymentCell.region
- key: node.kubernetes.io/instance-type
operator: In
values:
- $sys.compute.node.instanceType
- key: omnistrate.com/resource
operator: In
values:
- $sys.deployment.resourceID
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: omnistrate.com/schedule-mode
operator: In
values:
- exclusive
namespaceSelector: {}
topologyKey: kubernetes.io/hostname
replica:
podLabels:
omnistrate.com/schedule-mode: exclusive
persistence:
enabled: false
replicaCount: $var.replicas
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 150m
memory: 256Mi
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: omnistrate.com/managed-by
operator: In
values:
- omnistrate
- key: topology.kubernetes.io/region
operator: In
values:
- $sys.deploymentCell.region
- key: node.kubernetes.io/instance-type
operator: In
values:
- $sys.compute.node.instanceType
- key: omnistrate.com/resource
operator: In
values:
- $sys.deployment.resourceID
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: omnistrate.com/schedule-mode
operator: In
values:
- exclusive
namespaceSelector: {}
topologyKey: kubernetes.io/hostname
apiParameters:
- key: replicas
description: Number of Replicas
name: Replica Count
type: Float64
modifiable: true
required: false
export: true
defaultValue: "1"
- key: instanceType
description: Instance Type
name: Instance Type
type: String
modifiable: true
required: false
export: true
defaultValue: "t4g.small"
- key: postgresUsername
description: Postgres Username
name: Postgres Username
type: String
modifiable: false
required: false
export: true
defaultValue: "postgres"
parameterDependencyMap:
Postgres Database: postgresUsername
- key: postgresPassword
description: Postgres Password
name: Postgres Password
type: Password
modifiable: false
required: true
export: true
parameterDependencyMap:
Postgres Database: postgresPassword
- key: postgresDatabase
description: Postgres Database
name: Postgres Database
type: String
modifiable: false
required: false
export: true
defaultValue: "postgres"
parameterDependencyMap:
Postgres Database: postgresDatabase
- key: postgresInstanceType
description: Postgres Instance Type
name: Postgres Instance Type
type: String
modifiable: true
required: false
export: true
defaultValue: "t4g.small"
parameterDependencyMap:
Postgres Database: postgresInstanceType
- name: Postgres Database
internal: false
compute:
instanceTypes:
- apiParam: postgresInstanceType
cloudProvider: aws
- apiParam: postgresInstanceType
cloudProvider: gcp
network:
ports:
- 5432
helmChartConfiguration:
chartName: postgresql
chartVersion: 15.5.36
chartRepoName: bitnami
chartRepoURL: https://charts.bitnami.com/bitnami
chartValues:
auth:
database: $var.postgresDatabase
username: $var.postgresUsername
password: $var.postgresPassword
primary:
persistence:
enabled: false
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 1000m
memory: 1024Mi
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: omnistrate.com/managed-by
operator: In
values:
- omnistrate
- key: topology.kubernetes.io/region
operator: In
values:
- $sys.deploymentCell.region
- key: node.kubernetes.io/instance-type
operator: In
values:
- $sys.compute.node.instanceType
- key: omnistrate.com/resource
operator: In
values:
- $sys.deployment.resourceID
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: omnistrate.com/schedule-mode
operator: In
values:
- exclusive
namespaceSelector: {}
topologyKey: kubernetes.io/hostname
readReplicas:
replicaCount: 0
apiParameters:
- key: postgresUsername
description: Postgres Username
name: Postgres Username
type: String
modifiable: true
required: true
export: true
- key: postgresPassword
description: Postgres Password
name: Postgres Password
type: String
modifiable: true
required: true
export: true
- key: postgresDatabase
description: Postgres Database
name: Postgres Database
type: String
modifiable: true
required: true
export: true
- key: postgresInstanceType
description: Postgres Instance Type
name: Postgres Instance Type
type: String
modifiable: true
required: true
export: true
Apply changes to the service¶
For this we will run the same command that was used to setup the service the first time.
omnistrate-ctl build -f spec.yaml --name 'RedisHelm' --release-as-preferred --spec-type ServicePlanSpec
# Example output shown below
✓ Successfully built service
Check the service plan result at: https://omnistrate.cloud/product-tier?serviceId=s-dEhutaDa2X&environmentId=se-92smpU2YAm
Access your SaaS offer at: https://saasportal.instance-w6vidhd14.hc-pelsk80ph.us-east-2.aws.f2e0a955bb84.cloud/service-plans?serviceId=s-dEhutaDa2X&environmentId=se-92smpU2YAm
Deploying a Redis Cluster through your dedicated Customer Portal¶
Now, your customers can deploy Redis Clusters alongwith the Postgres Helm chart with the desired instance type and number of replicas through the dedicated customer portal. The portal will use the REST API parameters to customize the deployment based on the customer's requirements.
The deployed cluster details
The Kubernetes Dashboard view