Table of Contents

Infrastructure Workflow - Deploy Kubernetes with Hub CLI

Agile Stacks Updated by Agile Stacks

In this tutorial, you are going to deploy a Kubernetes cluster on AWS using Spot instances and cluster autoscaling for cost optimization. The cluster will be integrated with DNS, TLS via Let's Encrypt, and SSO via Okta.

Hub CLI is a powerful and easy to use tool for infrastructure automation. It is also an interface to SuperHub (API). SuperHub is an infrastructure automation service to deploy and manage software stacks - in the cloud and on-prem. You can manage, configure, and implement change control for your infrastructure-as-code using the SuperHub.

Install Hub CLI

First, install Hub CLI binary:

On Mac

curl -O
mv hub.darwin_amd64 hub
chmod +x hub
sudo mv hub /usr/local/bin
hub extensions install

On Linux

curl -O
mv hub.linux_amd64 hub
chmod +x hub
sudo mv hub /usr/local/bin
hub extensions install

Login into SuperHub:

hub login -u your@email.tld
Password: ****

Export environment variable `HUB_TOKEN` in your shell, or add export HUB_TOKEN=... to your ~/.bash_profile file.

Onboard Your Cloud Account

SuperHub is linked to the AWS cloud account via credentials supplied by you. When Hub CLI works in the local mode it talks to the cloud directly - by using ~/.aws/credentials.

To use a named AWS profile for multiple Hub CLI commands, you can set the AWS_PROFILE and the HUB_TOKEN environment variables at the command line.

export AWS_PROFILE=profile1
export HUB_TOKEN=1896390...a009

When Hub CLI drives SuperHub via its API, it must setup several essential cloud resources in the account:

  1. An S3 bucket for Hub CLI and Terraform state, for backups;
  2. DNS zone that will be linked to under a subdomain of your choice;
  3. A cross-account IAM role that will be used by SuperHub to securely deploy resources in your cloud account. SuperHub do not store your AWS keys.

Choose a cloud account name. This will become the subdomain under which all of your Kubernetes services are hosted. The name will become a subdomain under

For the rest of this example, we will use Please replace it with your chosen name in the rest of the examples.

By default, your stack will be deployed in the DNS domain. This is to ensure that there is a valid DNS zone to host all of the Kubernetes clusters that are created. The domain name can be changed later, but for now, the fastest approach is to use

hub api cloudaccount onboard -w aws us-east-2

Consult hub api cloudaccount onboard --help for additional details.

You can list cloud accounts via the following command:

hub api cloudaccount get

Create an Environment

The environment is a SuperHub umbrella entity that organizes deployments, parameters, external facts, and Team's permissions. A good name for the environment is Dev, QA, etc.

Create environment:

hub api environment create Dev01

You can list environments via:

hub api environment get

A single cloud account can host multiple environments.

Create Your Template

SuperHub approach of repeatable infrastructure-as-code revolves around Templates - a collection of automation scripts to deploy interconnected software Components. A unit of deployment is a template; also, every component could be redeployed or undeployed individually.

Start by copy-pasting this json into your own template.json file. Feel free to name the template whatever you like, but remember it, because we'll use it in the next steps.


"name": "kubernetes-1",
"description": "Kubernetes with Let's Encrypt",
"tags": [
"stack": "k8s:1",
"componentsEnabled": [
"verbs": [
"parameters": [
{"name": "component.kubernetes.etcd.count", "value": 1},
{"name": "component.kubernetes.etcd.size", "value": "t3.micro"},
{"name": "component.kubernetes.etcd.spotPrice", "value": 0.20},
{"name": "component.kubernetes.master.size", "value": "t3.medium"},
{"name": "component.kubernetes.master.count", "value": 1},
{"name": "component.kubernetes.master.spotPrice", "value": 0.20},
{"name": "component.kubernetes.worker.size", "value": "m5.large"},
{"name": "component.kubernetes.worker.count", "value": 2},
{"name": "component.kubernetes.worker.spotPrice", "value": 0.20},
{"name": "component.kubernetes-dashboard.rbac.kind", "value": "admin"},
{"name": "component.ingress.urlPrefix", "value": "app"},
{"name": "component.ingress.ssoUrlPrefix", "value": "apps"}

Create the template in the SuperHub service using the template file you just created.

$ hub api template create < template.json

Here is a template named kubernetes-1 which provides several software components:

  • Traefik as ingress controller
  • Dex for SSO with Okta
  • Kubernetes Cluster Autoscaler
  • Cert-manager for TLS with Let's Encrypt
  • Kubernetes Dashboard v2

The template we created is based on k8s:1 Super Template that provides boilerplate and default configuration.

Kubernetes will be deployed on three AWS spot instances: one Etcd node on t3.micro , one Master node on t3.medium, and one Worker node on m5.large . Kubernetes Dashboard is given admin permissions. Ingress subdomain for the the cluster deployed from this template is appapps for SSO protected ingresses.

Initialize the template:

hub api template init kubernetes-1

This command creates a Git repository to host the template source code and populates it with automation scripts, components, and parameters. The repository is accessible via https URL, and you can clone a local copy on your computer using standard Git tools.

To list available templates:

hub api template get kubernetes-1

Deploy Your Stack Instance

This step creates the Kubernetes cluster in your AWS account, and populates it with the components specified in the template.

We call it a "Stack Instance" because it is an instantiation of a Stack Template. You can create 1 or 1,000 instances of the same template. They can also be upgraded as their constituent components are upgraded.

Create stack instance with defaults from the template:

$ hub api instance create <<EOF
"name": "cluster-01",
"environment": "Dev01",
"template": "kubernetes-1"

The stack instance is created in initial state.

Note the name of the instance. This, along with the name of the cloud account, becomes the root DNS domain of the Kubernetes cluster:
<stack instance name>.<cloud account name>

Finally, deploy!

hub api instance deploy -w
Remember to substitute my-domain-01 with the name of cloud account you specified in Onboard your Cloud Account step.

The command will show the deployment log and will exit after the automation task is completed on SuperHub side.

2020/02/18 20:28:38 Completed deploy on kubernetes-1 with components stack-k8s-aws, tiller, automation-tasks-namespace, cert-manager, traefik, dex, cluster-autoscaler, kube-dashboard2
2020/02/18 20:28:38 Wrote state `hub.yaml.state`
2020/02/18 20:28:38 Wrote state `s3://`
2020/02/18 20:28:38 Syncing Stack Instance state to SuperHub
===> 12:28:38 cluster-01 [2103] stackInstance update success
2020/02/18 20:28:38 All warnings combined:
Error query parameter `component.kubernetes.bastionHost` in environment `342`, stack instance `2103`:
Unable to retrieve parameter `component.kubernetes.bastionHost`: `value` not set
Error query parameter `component.kubernetes.bastionHost|stack-k8s-aws` in environment `342`, stack instance `2103`:
Unable to retrieve parameter `component.kubernetes.bastionHost`: `value` not set
Error query parameter `component.kubernetes.master.elb` in environment `342`, stack instance `2103`:
Unable to retrieve parameter `component.kubernetes.master.elb`: `value` not set
Error query parameter `component.kubernetes.master.elb|stack-k8s-aws` in environment `342`, stack instance `2103`:
Unable to retrieve parameter `component.kubernetes.master.elb`: `value` not set
===> 12:28:43 cluster-01 [2103] stackInstance update success
===> 12:28:46 cluster-01 [2103] stackInstance deploy success

Inspect the instance:

hub api instance get

Visit Kubernetes Dashboard at

Also, you can view the Traefik Dashboard at which will show you the services that are hosted in your K8s cluster.

From here you can explore SuperHub via hub api commands. Or check out the hub CLI documentation

Alternatively, go to to view infrastructure resources in the UI. Navigate to the stack instance using Stacks > Clusters > List menu. You can learn more about the Control Plane here

Cleanup the Cloud Resources

In the previous step you have deployed several resources in AWS, including ec2 instances, s3 buckets, load balancers, and security groups. Upon completion of this tutorial you may want to delete these resources to save cloud costs.

hub api instance undeploy -w
hub api instance delete
hub api template delete kubernetes-1
hub api environment delete Dev01
hub api cloudaccount delete -w

The stack instance is undeployed, and all related AWS resources are automatically cleaned up. You can save the stack template kubernetes-1 in your environment so you can easily redeploy it later.

Note that deleting the stack instance does not remove any other resources from your cloud account that you may have created with other stack templates.


Congratulations! You have completed the tutorial and learned how to create a Kubernetes cluster with Hub CLI. The cluster you created provides several add-ons that are essential for any application deployment: dashboard, ingress, DNS, load balancer, SSL certificate manager, SSO authentication, and cluster auto-scaler.

In the next tutorial (coming soon), you can learn about how to use SuperHub to deploy additional components as overlay stacks.

How did we do?

Infrastructure Workflow - Creating Stack Templates