Skip to main content
Microsoft Azure is a fully supported deployment platform for Tensor9 BYOC appliances. Deploying to Azure customer environments provides access to Microsoft’s global cloud infrastructure, its security and compliance controls, and integration with customers’ existing Azure resources.

Overview

When you deploy an application to Azure customer environments using Tensor9 BYOC:
  • Customer appliances run entirely within the customer’s Azure subscription
  • Your control plane orchestrates deployments from your dedicated Tensor9 BYOC AWS account
  • Managed identities and RBAC enable your control plane to manage customer appliances with customer-approved permissions
  • Service equivalents compile your origin stack into Azure-native resources
Azure appliances use Azure services for compute, storage, networking, and observability, so they fit into the Azure environments your customers already run.

Prerequisites

Before deploying appliances to Azure customer environments, ensure:

Your control plane

  • Dedicated AWS account for your Tensor9 BYOC control plane
  • Control plane installed - See Installing Tensor9 BYOC
  • Origin stack published - Your application infrastructure defined and uploaded

Customer Azure subscription

Your customers must provide:
  • Azure subscription where the appliance will be deployed
  • Managed identities configured for the four-phase permissions model (Install, Steady-state, Deploy, Operate)
  • Virtual network and networking configured according to their requirements
  • Sufficient subscription quotas for your application’s resource needs
  • Azure region where they want the appliance deployed

Your development environment

  • Azure CLI installed and configured
  • kubectl for Kubernetes operations
  • Terraform or OpenTofu (if using Terraform origin stacks)
  • Docker (if deploying container-based applications)

How Azure appliances work

Azure appliances are deployed using Azure-native services orchestrated by your Tensor9 BYOC control plane.
1

Customer provisions managed identities

Your customer creates four managed identities in their Azure subscription, each corresponding to a permission phase: Install, Steady-state, Deploy, and Operate. These identities define what the Tensor9 BYOC controller can do within their environment.The customer configures RBAC role assignments that allow your control plane to impersonate these managed identities with appropriate conditions (time windows, approval tags, etc.).
2

You create a release for the customer appliance

You create a release targeting the customer’s appliance:
Your control plane compiles your origin stack into a deployment stack tailored for Azure, compiling any non-Azure resources to their Azure service equivalents. The deployment stack downloads to your local environment.
3

Customer grants deploy access

The customer approves the deployment by granting temporary deploy access. This can be manual (updating RBAC role assignments) or automated (scheduled maintenance windows).Once approved, the Tensor9 BYOC controller in the appliance can use the Deploy managed identity in the customer’s subscription.
4

You deploy the release

You run the deployment locally against the downloaded deployment stack:
The deployment stack is configured to route resource creation through the Tensor9 BYOC controller inside the customer’s appliance. The controller uses the Deploy managed identity and creates all infrastructure resources in the customer’s Azure subscription:
  • Virtual networks, subnets, network security groups
  • AKS clusters, Container Instances, Azure Functions
  • Azure Database for PostgreSQL/MySQL, Azure Blob Storage, Azure Cache for Redis
  • Azure Monitor workspaces, Log Analytics, managed identities, Azure DNS zones
  • Any other Azure resources defined in your origin stack
5

Steady-state observability begins

After deployment, your control plane uses the Steady-state managed identity to continuously collect observability data (logs, metrics, traces) from the customer’s appliance without requiring additional approvals.This data flows to your observability sink, giving you visibility into appliance health and performance.

Service adapters

When you deploy an origin stack to Azure customer environments, Tensor9 BYOC automatically compiles resources from other cloud providers to their Azure equivalents.

How service equivalents work

When compiling a deployment stack for Azure:
  1. AWS resources are compiled - AWS resources are converted to their Azure equivalents
  2. Generic resources are adapted - Cloud-agnostic resources (like Kubernetes manifests) are adapted for Azure
  3. Configuration is adjusted - Resource configurations are modified to match Azure conventions and best practices

Common service equivalents

Which AWS services reach Azure, what each becomes, and the tier it lands at are maintained in one place rather than repeated per form factor: see service adapters and the generated Service Catalog.
EC2, DynamoDB, and EFS are all offered. Some services are not adapted yet, including Step Functions, API Gateway, Cognito, AppSync, and Redshift. See Service Catalog.

Example: Compiling an AWS origin stack

If your origin stack defines a Lambda function:
Tensor9 BYOC compiles it to an Azure Function:

Permissions model

Azure appliances use a four-phase managed identity permissions model that balances operational capability with customer control.

The four permission phases

Managed identity structure

Each managed identity is created in the customer’s Azure subscription with RBAC role assignments that allow your control plane to use it. Example: Deploy managed identity with conditional access
Your control plane can only use the Deploy managed identity when:
  • The customer has granted the Managed Identity Operator role
  • Resources being created are tagged with Tensor9 BYOC’s t9-appliance-id
  • The time window hasn’t expired (enforced via conditional access policies)
Customers control when and how long deploy access is granted. Example: Steady-state managed identity (read-only observability)
The Steady-state managed identity:
  • Can read observability data from resources tagged with the appliance’s t9-appliance-id
  • Cannot modify, delete, or terminate any resources
  • Cannot change RBAC role assignments

Deployment workflow with managed identities

1

Customer grants deploy access

Customer approves a deployment by granting the Managed Identity Operator role and setting up conditional access policies. This can be done manually or through automated approval workflows.
2

You execute deployment locally

You run the deployment locally against the downloaded deployment stack:
The deployment stack is configured to route resource creation through the Tensor9 BYOC controller in the appliance.
3

Controller uses Deploy identity and creates resources

For each resource Terraform attempts to create, the Tensor9 BYOC controller inside the appliance uses the Deploy managed identity and creates the resource in the customer’s subscription.All infrastructure changes occur within the customer’s subscription using their Deploy managed identity permissions.
4

Deploy access expires

After the time window expires or the role assignment is removed, the Deploy identity can no longer be used. Your control plane automatically reverts to using only the Steady-state identity for observability.
See Permissions Model for detailed information on all four phases.

Networking

Azure appliances use an isolated networking architecture with a Tensor9 BYOC controller that manages communication with your control plane.

Tensor9 BYOC controller VNet

When an appliance is deployed, Tensor9 BYOC creates an isolated VNet containing the Tensor9 BYOC controller. This VNet is configured with:
  • Azure NAT Gateway: Provides outbound internet connectivity
  • Route to control plane: Establishes a secure channel to your Tensor9 BYOC control plane
  • No inbound NSG rules: The controller VNet does not accept inbound connections - all communication is outbound-only
The Tensor9 BYOC controller uses this secure channel to:
  • Receive deployments: Deployment stacks are pushed from your control plane to the appliance
  • Configure observability pipeline: Set up log, metric, and trace forwarding to your observability sink
  • Receive operational commands: Execute remote operations initiated from your control plane

Outbound-only security model

The Tensor9 BYOC controller in your customer’s appliance is designed to only make outbound connections and not require ingress ports to be opened in your customer’s network perimeter:
This architecture ensures that the customer’s appliance cannot be compromised via inbound network attacks on the controller.

Application VNet topology

Your application resources run in their own VNet(s), completely separate from the Tensor9 BYOC controller VNet. The application VNet topology is defined entirely by your origin stack - whatever VPC resources you define in your origin stack will be compiled to Azure VNet resources in the appliance. Example: Application VNet with internet-facing load balancer If your origin stack defines an AWS VPC with public subnets and a load balancer, that topology will compile to Azure VNet resources in the customer’s appliance:
This application VPC topology is deployed alongside the Tensor9 BYOC controller VNet, but they remain completely separate. The controller VNet manages the control plane connection, while the application VNet handles your application’s traffic and resources.

Resource naming and tagging

All Azure resources should incorporate the @namespace annotated variable to ensure uniqueness across multiple customer appliances.

Parameterization pattern

This page uses max_size=16 because storage account names cap at 24 characters and allow only lowercase letters and digits, so they take the namespace with its hyphens stripped.

Tags applied by Tensor9 BYOC

You don’t need to tag resources to identify the appliance. When Tensor9 BYOC compiles your origin stack it stamps t9-app-name, t9-app-id, t9-buyer-name, t9-appliance-id, t9-projection-id, t9-release-id, and t9-release-version onto every resource whose provider schema supports tags, merging them with any tags you set yourself:
The t9-appliance-id tag:
  • Enables RBAC condition expressions to scope permissions to specific appliances
  • Allows Azure Monitor filters to isolate telemetry by appliance
  • Helps customers track costs per appliance
  • Facilitates resource discovery by Tensor9 BYOC controllers

Observability

Azure appliances provide observability through Azure Monitor, Log Analytics, and Application Insights.

Azure Monitor Logs

Application and infrastructure logs flow to Log Analytics workspaces:
Your control plane uses the Steady-state managed identity to continuously fetch logs:
Logs are forwarded to your observability sink for centralized monitoring.

Azure Monitor Metrics

Infrastructure metrics are automatically collected:
  • Virtual Machines: CPU percentage, network in/out, disk operations
  • Azure Database for PostgreSQL: Database connections, CPU percent, storage used
  • Azure Functions: Execution count, execution units, errors
  • AKS: Node CPU/memory, pod counts, API server metrics
  • Azure Load Balancer: Data path availability, health probe status, packet count

Application Insights

Enable distributed tracing for Azure Functions and containerized applications:
Application Insights traces are accessible through the Steady-state identity and forwarded to your observability sink.

Azure Activity Log

All API calls within the customer’s Azure subscription are logged to Activity Log, providing a complete audit trail of what your control plane does:
  • Managed identity usage
  • Resource creation, modification, deletion
  • Permission denials
  • Role assignment changes
Customers have full visibility into your control plane’s actions through their Activity Log.

Artifacts

Azure appliances automatically provision private artifact repositories to store container images and application files deployed by your deployment stacks.

Container images (Azure Container Registry)

When you deploy an appliance, Tensor9 BYOC automatically provisions a private Azure Container Registry in the customer’s Azure subscription to store your container images. Example: Origin stack with container service Your AWS origin stack references container images from your vendor’s Amazon ECR:
Container copy during deployment When you deploy the deployment stack, Tensor9 BYOC automatically:
  1. Detects the container image reference in your ECS task definition
  2. Provisions a private Azure Container Registry in the appliance (e.g., myappacr000000007e.azurecr.io)
  3. Copies the container image from your vendor ECR registry to the appliance’s private ACR
  4. Rewrites the deployment stack to reference the appliance-local registry
The compiled deployment stack will contain an Azure Container Instances or AKS deployment with the rewritten image reference:
This ensures the container image is stored locally in the customer’s subscription and the application doesn’t depend on cross-subscription access to your vendor registry. Artifact lifecycle Container artifacts are tied to the deployment stack lifecycle:
  • Deploy (tofu apply): Tensor9 BYOC copies the container image from your vendor registry to the appliance’s private registry
  • Destroy (tofu destroy): Deleting the deployment stack also deletes the copied container artifact from the appliance’s private registry
This ensures that artifacts are cleaned up when deployments are removed, preventing orphaned resources.

Function source code

For Lambda functions in your AWS origin stack, Tensor9 BYOC automatically handles copying function source code to the customer’s Azure environment:
During deployment, Tensor9 BYOC:
  1. Provisions a private Azure Storage Account in the appliance for function sources
  2. Copies the Lambda source archive from your vendor S3 bucket to the appliance’s Storage Account
  3. Compiles the Lambda function to a Container Apps service with the appliance-local source reference
Like container images, destroying the deployment stack (tofu destroy) removes the copied function source archives. See Artifacts for documentation on artifact management, including immutability requirements and supported artifact types.

Secrets management

Store secrets in AWS Secrets Manager or AWS Systems Manager Parameter Store in your AWS origin stack, then pass them to your application as environment variables.

Secret naming and injection

Always use parameterized secret names and inject them as environment variables:
Your application reads secrets from environment variables:
Your application can keep using AWS Secrets Manager SDK calls on Azure through the configured Secrets Manager service adapter. The adapter serves supported requests and maintains secret values and versions. Review the target-specific limits before deployment; environment variables remain an option for values needed at startup.
See Secrets for detailed secret management patterns.

Operations

Perform remote operations on Azure appliances using the Operate managed identity.

kubectl on AKS

Execute kubectl commands against AKS clusters:
Output:

Azure CLI operations

Execute Azure CLI commands:

Database queries

Execute SQL queries against Azure Database for PostgreSQL:

Operations endpoints

Create temporary operations endpoints for interactive access:
See Operations for the full operations documentation.

Example: Complete Azure appliance

Here’s a complete example of a deployment stack for an Azure appliance, compiled from an AWS origin stack:

main.tf

variables.tf

outputs.tf

Best practices

Every Azure resource with a name should be prefixed with ${var.namespace} to prevent conflicts across customer appliances. Don’t skip resource-group-scoped names: two installs commonly share one resource group:
Note: Storage account names must be globally unique and can only contain lowercase letters and numbers (no hyphens).
You don’t need to add appliance-identifying tags yourself. Tensor9 BYOC stamps t9-appliance-id, t9-buyer-name, t9-app-name, and related tags onto every resource whose provider schema supports tags, merging them with your own:
This enables:
  • RBAC condition expressions for permission scoping
  • Azure Monitor filtering
  • Cost tracking
  • Resource discovery
Configure diagnostics for AKS, Azure Functions, databases, and other services:
This ensures observability data flows to your control plane.
Never hardcode secrets. Use AWS Secrets Manager or SSM Parameter Store with parameterized names in your AWS origin stack:
Environment variables supply values at application startup. For runtime AWS Secrets Manager reads, use the configured Secrets Manager service adapter and check the operations your application needs.

Troubleshooting

Symptom: Terraform apply fails with “AuthorizationFailed” or “Forbidden” errors.Solutions:
  • Verify the Tensor9 BYOC controller has successfully authenticated with the Deploy managed identity
  • Check the Deploy identity’s role assignments include necessary permissions for the resources being created
  • Ensure the RBAC conditional access policies allow the operation
  • Verify resources are tagged with Tensor9 BYOC’s t9-appliance-id
  • Review Azure Activity Log in the customer subscription to see which specific API call was denied
Symptom: “ResourceExists” or “NameNotAvailable” errors during deployment.Solutions:
  • Ensure all resource names are prefixed with ${var.namespace}
  • Verify the @namespace annotated variable is being passed correctly
  • Check that no hardcoded resource names exist in your origin stack
  • For storage accounts, remember names must be globally unique and only contain lowercase letters and numbers
  • For storage accounts, ensure the name is between 3-24 characters
Symptom: Azure Monitor logs and metrics aren’t appearing in your observability sink.Solutions:
  • Verify the Steady-state identity has Monitoring Reader and Log Analytics Reader permissions
  • Check that all resources are tagged with Tensor9 BYOC’s t9-appliance-id
  • Ensure diagnostic settings are configured for all resources
  • Verify Log Analytics workspace retention is set appropriately
  • Check that the control plane is successfully using the Steady-state identity
Symptom: “QuotaExceeded” or “OperationNotAllowed” errors when creating resources.Solutions:
  • Ask the customer to request quota increases from Azure Portal
  • Consider deploying appliances in separate Azure regions
  • Review and clean up unused resources in the customer’s subscription
  • For virtual machine quotas, consider using different VM sizes
Symptom: Kubernetes cluster creation times out or fails.Solutions:
  • Verify the region supports AKS
  • Check that the Kubernetes version is supported in the region
  • Ensure the VM SKU is available in the region
  • Verify VNet and subnet configuration is correct
  • Check that service principal or managed identity has necessary permissions
  • Review Azure Service Health for service incidents
Symptom: “StorageAccountNameInvalid” errors.Solutions:
  • Ensure storage account names only contain lowercase letters and numbers (no hyphens)
  • Verify the name is between 3-24 characters
  • Check that ${var.namespace} doesn’t contain characters the target namespace rejects
  • Consider shortening the app name prefix if the full name is too long
If you’re experiencing issues not covered here or need additional assistance with Azure deployments, we’re here to help:
  • Slack: Join our community Slack workspace for real-time support
  • Email: Contact us at [email protected]
Our team can help with deployment troubleshooting, managed identity configuration, service equivalents, and best practices for Azure environments.

Next steps

Now that you understand deploying to Azure customer environments, explore these related topics: