Helm charts with Terraform Integration
Omnistrate supports integrating Terraform IaC steps as part of a Helm chart deployment to build a unified deployment workflow. A good example of such a use-case is when you need auxiliary services like Databases or Caches through managed services like AWS RDS, Elasticache, MongoDB Atlas, etc. to be deployed as part of your Helm chart deployment. Additionally, you may want to reference the output of the Terraform IaC steps in the Helm chart configuration (e.g. the database connection string, cache endpoint, etc.).
More details how to you can use Terraform stack to define your service can be found on Getting started / Terraform.
In this guide, we will show you how to deploy an Umbrella Helm chart that deploys a simple app that depends on a Postgres Helm chart with an S3 bucket and a DynamoDB table. You can define any number of such compositions and Omnistrate powers all of them through its idempotent, scalable workflow engine.
The following diagram lays out the composition and the end goal for this SaaS deployment:
At the end of this exercise, you will have an Nginx "app" deployment that is configured to talk to a Postgres database through a Kubernetes Service. The app also will have environment variables configured with the S3 bucket ARN and the DynamoDB Table ARN. To secure access to these services, we will leverage IRSA for federated access. We will leverage the power and versatility of System Parameters to inject the right context of the EKS cluster and OIDC configuration.
Variant: Fully Hosted Deployment¶
In this variant, we will deploy the entire composition for your tenants in your account. We will slice up your AWS account and EKS cluster into multiple tenant environments with isolation across the stack including dedicated IAM roles for each tenant deployment.
Build a new SaaS service plan / composition¶
The first step is to model the above composition as a specification on Omnistrate. Following the earlier examples of onboarding a SaaS service based on Helm charts, you can use the Omnistrate CLI to build the SaaS service plan. Make sure to replace the <AWS_ID>
with your AWS account and connect your AWS account to Omnistrate.
# yaml-language-server: $schema=https://api.omnistrate.cloud/2022-09-01-00/schema/service-spec-schema.json
name: Web App # Service Plan Name
deployment:
hostedDeployment:
AwsAccountId: "<AWS_ID>"
AwsBootstrapRoleAccountArn: arn:aws:iam::<AWS_ID>:role/omnistrate-bootstrap-role
services:
- name: Web App
dependsOn:
- dataInfraTerraform
compute:
instanceTypes:
- apiParam: instanceType
cloudProvider: aws
- apiParam: instanceType
cloudProvider: gcp
network:
ports:
- 80
helmChartConfiguration:
chartName: private-umbrella-chart
chartVersion: 0.1.4
chartRepoName: private-umbrella-repo
chartRepoURL: https://raw.githubusercontent.com/omnistrate-community/helm-private-example/main
authProvider:
username: <PAT>
password: <PAT>
chartValues:
serviceAccount:
name: "web-app-sa"
s3BucketARN: "{{ $dataInfraTerraform.out.s3_bucket_arn }}"
dynamoDBTableARN: "{{ $dataInfraTerraform.out.dynamodb_table_arn }}"
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: instanceType
description: Instance Type
name: Instance Type
type: String
modifiable: true
required: false
export: true
defaultValue: "t4g.small"
- name: dataInfraTerraform
internal: true
terraformConfigurations:
configurationPerCloudProvider:
aws:
terraformPath: /
gitConfiguration:
reference: refs/heads/demo
repositoryUrl: https://github.com/omnistrate-community/terraform-private-example.git
accessToken: <ACCESS_TOKEN>
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 'UmbrellaHelm' --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