Skip to main content
AWS CloudFormation is a native AWS infrastructure-as-code tool that can be used with Tensor9. A CloudFormation origin stack is a standard CloudFormation template that Tensor9 compiles into customer-specific deployment stacks for each appliance.

What is a CloudFormation origin stack?

A CloudFormation origin stack is your existing CloudFormation template - the YAML or JSON file that defines your application’s AWS infrastructure. Tensor9 uses this as the blueprint to generate deployment stacks tailored to each customer’s appliance. When you publish a CloudFormation origin stack to Tensor9, you use the AWS CLI to:
  1. Create or update a CloudFormation stack in your control plane’s AWS account
  2. Store the template as the source for generating deployment stacks
  3. Use it as the blueprint for creating appliance-specific stacks
The key difference from standard CloudFormation usage: you maintain one origin stack that Tensor9 compiles into many deployment stacks - one per customer appliance.
Your origin stack should be your existing CloudFormation template. Tensor9 is designed to work with the infrastructure-as-code you already have - you don’t need to write a new template just for Tensor9. The goal is to maintain a single template that works for both your cloud deployment and private customer deployments.
CloudFormation origin stacks can only be deployed to AWS appliances. If you need to support multiple cloud providers, use Terraform or OpenTofu as your origin stack format.

How CloudFormation origin stacks work

Using CloudFormation with Tensor9 follows a straightforward workflow:
1

Publish your origin stack

You publish your CloudFormation template by using the AWS CLI to create or update a CloudFormation stack in your control plane’s AWS account. This stack serves as the origin stack that Tensor9 will use as the blueprint for all appliance deployments.
2

Create a release

When you want to deploy to an appliance, you create a release using tensor9 stack release create. During release creation, your control plane compiles your origin stack into a deployment stack tailored to that specific appliance, and automatically creates the CloudFormation stack in your control plane.The compilation process:
  • Injects the InstanceId parameter to ensure resource uniqueness
  • Instruments the stack for observability (logs, metrics, traces)
  • Rewrites artifact references to point to appliance-local locations
  • Updates resource names to include the instance ID
The result is a deployment stack - a new CloudFormation stack that is automatically created in your control plane.
3

Monitor deployment progress

Your control plane automatically deploys the compiled deployment stack by creating a CloudFormation stack in your control plane’s AWS account. You can monitor the deployment progress using:
The CloudFormation stack creates all the infrastructure resources in your control plane’s AWS account automatically.
You write and maintain one origin stack. Tensor9 compiles it into many deployment stacks (one per appliance), each customized for that appliance. The control plane automatically creates and manages these CloudFormation stacks in your control plane’s AWS account - you don’t need to manually download or deploy anything.

Prerequisites

Before using CloudFormation as an origin stack, ensure you have:
  • AWS CLI installed: Version 2.0+ recommended for publishing your origin stack and monitoring deployments
  • Valid CloudFormation template: Your template must pass CloudFormation validation
  • Tensor9 CLI installed: For publishing your origin stack and creating releases
  • Tensor9 API key configured: Set as T9_API_KEY environment variable
  • AWS credentials configured: For publishing your origin stack to your control plane’s AWS account

CloudFormation template structure

Your CloudFormation origin stack should follow standard CloudFormation conventions:

YAML template example

JSON template example

Publishing your CloudFormation origin stack

To make your CloudFormation template available to Tensor9, use the AWS CLI to create a CloudFormation stack in your control plane’s AWS account:
Or if updating an existing origin stack:

What gets published

When you create or update the CloudFormation stack:
  1. CloudFormation validates and stores your template in your control plane’s AWS account
  2. The stack name becomes the native stack ID you’ll use to bind the stack to your app
  3. Tensor9 uses this stack as the source template for generating deployment stacks
Example output:
The native stack ID for binding is simply the stack name: myapp-origin-stack

Publishing updates

When you make changes to your CloudFormation template, update the stack:
The updated template becomes available for creating new releases. Previously deployed appliances continue running their current version until you create and deploy a new release.

Binding your origin stack to an app

After publishing for the first time, bind your origin stack to your app using the CloudFormation stack name as the native stack ID:
The native stack ID is simply the CloudFormation stack name you used when creating the stack with aws cloudformation create-stack. Important: You only need to bind once. Future publishes of the same stack don’t require re-binding.

Parameterization

Parameterization is the process of making your origin stack capable of being deployed to multiple appliances without resource naming conflicts. This is the most critical requirement for a CloudFormation origin stack in Tensor9.

The InstanceId parameter

Tensor9 automatically provides an InstanceId parameter to every deployment to ensure resource uniqueness across appliances. Your origin stack should declare this parameter:
Tensor9 automatically provides this value during compilation - you never need to manually set it.

Using InstanceId for resource naming

Use !Ref InstanceId to make all resource names unique. This prevents conflicts when deploying to multiple customer appliances:

What to parameterize

Use InstanceId for:
  • Resource identifiers: S3 bucket names, RDS identifiers, Lambda function names
  • IAM resources: Role names, policy names
  • Networking: VPC names, subnet tags, security group names
  • Logging: CloudWatch log group names
  • Secret paths: Secrets Manager secret names
DNS names are managed automatically: Tensor9 automatically generates DNS names for your appliances using either your vendor vanity domain or the customer’s vanity domain (if they specified one). You don’t need to include InstanceId in DNS records. See Endpoints and DNS for details.
Without proper parameterization, attempting to deploy to multiple appliances will result in resource creation failures as CloudFormation tries to create duplicate resources.

Complete example origin stack

Here’s a complete CloudFormation origin stack for a typical application:

Parameters

Define parameters for values that vary per deployment:
When creating a release, Tensor9 automatically provides the InstanceId parameter. Other parameters like container images are detected and injected during compilation. Sensitive parameters like DbPassword can be stored in AWS Secrets Manager in the customer’s account and referenced via !Sub '{{resolve:secretsmanager:${InstanceId}/prod/db/password}}'.

Outputs

Define outputs to expose important values after deployment:
After deployment, view outputs using the AWS CLI:
Outputs are also visible in tensor9 report.

Best practices

Every AWS resource with a name or identifier should include InstanceId to prevent conflicts across customer appliances:
Apply the instance-id tag to every resource:
This enables:
  • IAM permission scoping
  • CloudWatch filtering
  • Cost tracking
  • Resource discovery
Never hardcode secrets. Use Secrets Manager with parameterized names:

Troubleshooting

Symptom: aws cloudformation create-stack fails with CloudFormation validation errors.Solutions:
  • Run aws cloudformation validate-template locally to identify syntax errors
  • Ensure all required parameters are declared
  • Check that all resource references are valid
  • Verify resource property names and types match CloudFormation specification
Symptom: Release creation shows CloudFormation stack creation failed with “AlreadyExists” errors in your control plane.Solutions:
  • Ensure all resource names include !Sub with ${InstanceId}
  • Verify the InstanceId parameter is being properly used in your origin stack
  • Check that no hardcoded resource names exist in your template
  • For S3 buckets, remember they must be globally unique - include both app name and InstanceId
  • Review CloudFormation stack events in your control plane’s account: aws cloudformation describe-stack-events --stack-name <stack-name>
Symptom: “InsufficientCapacity” or quota limit errors during deployment.Solutions:
  • Check AWS service quotas for your control plane’s account
  • Reduce initial resource counts and scale up after deployment
  • Deploy resources across multiple availability zones to increase capacity
  • Request quota increases from AWS if needed
Symptom: “Template too large” error when publishing or deploying.Solutions:
  • Use CloudFormation modules for reusable components
  • Store large template bodies in S3 and reference by URL
  • Consider using Terraform instead of CloudFormation for complex infrastructure

Limitations and considerations

CloudFormation origin stacks can only be deployed to AWS appliances. CloudFormation is an AWS-specific infrastructure-as-code tool that only works within AWS environments. If you need to support multiple cloud providers (Google Cloud, Azure, DigitalOcean) or private Kubernetes environments, use Terraform or OpenTofu as your origin stack format instead.
Tensor9 does not currently support CloudFormation nested stacks (stacks that reference other stacks using AWS::CloudFormation::Stack). If your infrastructure requires modularity, consider using CloudFormation modules, or migrating to Terraform which supports module composition.

Next steps

Now that you understand CloudFormation origin stacks, explore these topics: