Facades
The facade concept
To provide vendors with a SaaS-like development experience, we introduced the concept of a facade.
A facade is a lightweight cloud resource living in the vendor’s cloud that reflects a real cloud resource living in the customer’s appliance. The vendor can deploy, update, configure, observe and delete a facade in their own cloud as if it was a real resource. Behind the scenes, Tensor9 does the work of reflecting cause and effect inside the customer’s appliance.
Tensor9 also mirrors the operational state (e.g. CPU utilization) of the real resource back to the facade. The facade mechanism provides vendors with a lever to influence, and a window to observe, a customer’s appliance without direct access. The end result is that vendor engineers can build and operate their software in a way that feels like the familiar SaaS experience they are used to.
Container facades
The simplest type of facade is a (Docker) container facade. A container facade running in the vendor’s cloud corresponds to a real container running in the customer’s appliance. A vendor engineer builds a container facade by running an existing container through the tensor9
CLI like this:
tensor9 -action BuildContainerFacade -img my-node-service:ded9f4b -applianceId 844385dc6fa8d4fc
This creates a container facade that embeds the vendor’s containerized software (my-node-service
above) and will deploy that software to a customer appliance (identified by 844385dc6fa8d4fc
above).
The vendor engineer can then deploy that container facade however they like (e.g. AWS CDK) and wherever they like (e.g. AWS Fargate). Doing so will deploy their container embedded in the facade to the customer’s appliance. This means that, to the vendor engineer, software deployments continue to work the same way:
Machine facades
A machine facade is a minimally-sized virtual machine running in the vendor’s cloud. Its existence implies the existence of a corresponding real virtual machine running in the customer’s appliance. A vendor engineer builds a machine facade matching their hardware specifications (i.e. operating, CPU, memory, GPU) using the tensor9
CLI like this:
tensor9 -action BuildMachineFacade -spec my-machine-spec.json -applianceId 844385dc6fa8d4fc -cloud Aws
This creates a machine facade in the form of a cloud-native virtual machine image (AWS AMI above, Google Cloud and Azure supported too) that will provision a corresponding virtual machine inside the customer’s appliance (identified by “844385dc6fa8d4fc” above). The virtual machine provisioned inside the customer’s appliance will match the hardware/software requirements and configuration specified in the provided machine specification (“my-machine-spec.json” above). Here is an example machine specification:
{
"spec": {
"cloud": "Gcp",
"os": "Ubuntu20",
"arch": "X86",
"cores": 2,
"mem": 17179869184,
"gpu": "T4"
},
"startupScript": "sudo apt-get update\nsudo apt-get -y install supervisor\nsudo systemctl enable supervisor\nsudo systemctl start supervisor\nAPPLIANCE_HTTPS_PROXY=$(t9dev -action GetHttpsProxy)\ncurl -x $APPLIANCE_HTTPS_PROXY -o inference-server.tar.gz https://packages.my-app.com/inference-server.tar.gz?accessToken=89ajfd8943hf\ntar -xvzf inference-server.tar.gz\ncd inference-server\nchmod +x install-and-run.sh\n./install-and-run.sh",
"ssh": {
"user": "my-user",
"port": 2222,
"authorizedKeys": [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC7XlpYeWjDSZV564fsL4afZuijPnIKFxp8ze5b3ybh7OprByqrY1Jt2STr1b528WziYEN3GXKmqhpttH8EsEYAJryTxsOumvnPQXnHPLKwoviOMNFBbxCijDVvf/mi7okJkHN0BrzqU6uFrE9ISGQex7OOJ8lN0xkmVK4XVhlwj1DBREJikX1laPe8drKH1fvA7hcNrnJi9WqwVCoFj01OgPTtFzn2NUJHu/xcV2yLt72TgR70nASX9eotr035P7TLIOpp4jUzyJi8QsaCdMmE7ZcHViN1lYt2BN65GmLLPovQwhPydsJXLjkjlz9iytah5h4xPNsJWX0mYUL/3KHEu0CKDTMsD7ZkQzD+vqfc1VD8LnauDyV1ZuZMj27ybV83iCQdcqMnkM6MFpsZeFkLlZgfBolvfwDRjt1c6qlHaWzwfj7pue5TLdbG5D9l6gD8O1/NY9zL0BCjClCBXXKv5cbEhTxig3iRVSYun9RHhfI84Z3nGOvg9k0/Xr+qwxCMC7LRHrSnC312BHTYK7X9+2vsy1mrCMeCkzC5bG6J8XT+nfCuhh+XUZd6izZxVn7YNt4jUGiwFgErBYRYAvDkbTv0iUYrZWXu5RughDmGiMvAHVESHnRr80qEpWOE85ZsVLFH4V5RvGGk45Cht/rfuuY+E42hx1VF2TPG4j7XBw== user@machine.local"
]
}
}
Notice that, in addition to a startup script, the vendor engineer is also able to specify authorized SSH keys. A machine facade allows vendor engineers to issue SSH commands to the corresponding real virtual machine running in the customer’s appliance. To do so, a vendor engineer simply issues SSH commands to the machine facade running in their own cloud. The machine facade handles tunneling the command through the customer’s appliance to the real virtual machine. The appliance will only allow SSH commands pre-approved by the customer; and all output data will be appended to the appliance’s audit log. Remote commands and secure copy protocol (SCP) commands work, but interactive SSH sessions are no allowed. The end result is that vendor engineers can administer virtual machines running inside of a customer appliance using many of their existing tools. For example, they can use Ansible playbooks to configure and administer facade inventory.
Infrastructure facades
An infrastructure facade is an AWS CloudFormation Custom Resource living in the vendor’s cloud (support for vendors primarily using Google Cloud and Azure coming soon) that affects and reflects the deployment state of an infrastructure resource running in the customer’s appliance. Infrastructure facades enable a vendor engineer to deploy arbitrary cloud infrastructure into the their customer’s appliances, including: queues, storage buckets, caches, and databases. Here is how a vendor engineer can deploy a Redis instance to a customer’s appliance using AWS CDK:
import * as constructs from "constructs";
import {CfnOutput, CustomResource, CustomResourceProps, Reference} from 'aws-cdk-lib';
import {Cloud, TemplateFormat} from "./tensor9-aws-cdk";
import {OnPremCfg} from "./on-prem-stack";
export class RedisOnPrem extends CustomResource {
public readonly hostRef: Reference;
public readonly portRef: Reference;
constructor(scope: constructs.Construct, id: string, onPremCfg: OnPremCfg) {
super(scope, id, <CustomResourceProps>{
serviceToken: onPremCfg.tensor9Cfg.infraTopic,
properties: {
"t9-appliance-id": onPremCfg.tensor9Cfg.applianceId,
"t9-infra-template-fmt": TemplateFormat.Terraform,
"t9-infra-template": mkTemplate(onPremCfg)
}
})
this.hostRef = this.getAtt('redis_on_prem_host')
this.portRef = this.getAtt('redis_on_prem_port')
new CfnOutput(this, 'Host', {
description: 'The host address of the on-premises Redis instance',
value: this.hostRef.toString()
})
new CfnOutput(this, 'Port', {
description: 'The port of the on-premises Redis instance',
value: this.portRef.toString()
})
}
}
function mkTemplate(onPremCfg: OnPremCfg): string {
switch (onPremCfg.tensor9Cfg.premises.cloud) {
case Cloud.Gcp:
let name = onPremCfg.tensor9Cfg.namespace + "-redis"
return `
resource "google_redis_instance" "redis_on_prem" {
name = "${name}"
tier = "STANDARD_HA"
memory_size_gb = 4
authorized_network = "${onPremCfg.tensor9Cfg.network}"
redis_configs = {
maxmemory-policy = "volatile-lru"
}
}
output "redis_on_prem_host" {
value = google_redis_instance.redis_on_prem.host
}
output "redis_on_prem_port" {
value = google_redis_instance.redis_on_prem.port
}
`
case Cloud.Aws:
// Omitted for brevity
case Cloud.Azure:
// Omitted for brevity
default:
throw Error(`Premises not supported: ${onPremCfg.tensor9Cfg.premises}`)
}
}
When this RedisOnPrem custom resource, which is an infrastructure facade, is deployed via CDK+CloudFormation, Tensor9 will in-turn deploy the specified Terraform-defined infrastructure into the customer’s appliance. The customer’s appliance will fill in the appropriate security context to deploy inside the customer’s account (Google Cloud in the example above). Similarly, updating the infrastructure facade in the vendor’s cloud (e.g. to change the memory size from 4GB to 16GB), or deleting the infrastructure facade, will affect the real Redis instance in the customer’s appliance as expected. Tensor9 handles serializing and rehydrating the Terraform state between vendor initiated mutation events.
The end result is that a vendor sees infrastructure facades in their own cloud as if they were real infrastructure: