Secret ownership models
Tensor9 distinguishes between two core models for managing secrets, based on who owns the external service or resource:
Vendors and customers must agree on the ownership of all external services and their associated secrets.
Vendor Recommendation: While Tensor9 supports customer-supplied secrets at
the infrastructure (Terraform) level, we strongly encourage migrating to
a runtime secret model where the vendor’s application exposes an admin setting
page for the customer to provide optional secrets after initial setup. This
avoids requiring a new deployment for every secret change and makes secrets
easier to manage as optional.
Terraform secret patterns
Tensor9 supports the following common industry patterns for integrating secrets into your Terraform configuration:1. Runtime fetching via data source (recommended for external secrets)
This is the most common and recommended pattern for external services. Secrets are stored in an external secret store and retrieved during Terraform execution using a data block.Important constraints:
- Do not use ARNs: Tensor9 does not support referencing secrets by Amazon Resource Name (ARN). Use name-based identifiers instead, as ARNs are absolute and may not be accessible from the customer side of the appliance.
- Parameterization for Shared Secrets: For shared secrets (vendor-supplied), you must “parameterize” the secret path by including the
instance_idvariable in the path (e.g.,${var.instance_id}/prod/sentry/token). Tensor9 automatically injects theinstance_idvariable into every deployment - it uniquely identifies each appliance instance. Using it in your secret paths ensures each customer appliance references an isolated copy of the secret, preventing conflicts when the same origin stack is deployed to multiple customers.
2. Variable injection
Secrets are passed into the Terraform configuration as variables, typically injected via a CI/CD pipeline or.tfvars file.
Important Constraint: Tensor9 requires that injected variables contain the actual secret value, not a reference (like a Secrets Manager secret ID). If you need to pass a reference, use the Runtime Fetching (Data Source) pattern instead.
3. Platform/infrastructure generated passwords (no Tensor9 support needed)
This pattern is for secrets that are automatically generated and managed by the cloud provider or Terraform itself (e.g., a database master password created by AWS RDS). Since the secret is fully encapsulated within the IaC, no special Tensor9 annotation or transfer logic is required.Secret annotation and configuration
For the Runtime Fetching and Variable Injection patterns, you must explicitly tell Tensor9 which variables and data sources represent secrets and who owns them using a configuration file (via the tuning document or a separate JSON file). Without this annotation, Tensor9 defaults all secret-holding data sources/variables to be Vendor-owned (Shared).Secret lifecycle and rotation
Before deployment, Tensor9 performs a pre-flight check to validate that all configured secrets meet the requirements.
Secret rotation
The process for rotating secrets depends on how the secret is referenced in your Terraform:- If passing by Value: If the secret value is directly embedded in a resource definition (e.g.,
password = var.db_password), an update to the secret will be detected by Terraform, and a normal build and apply (deployment) will update the resource. - If passing by Reference: If the infrastructure retrieves the secret by reference (e.g., a data source fetching from Secrets Manager), the infrastructure itself will not detect a change to the secret value.
- Vendor Action Required: The vendor must trigger a refresh or a new deployment.
- Application Logic Required: The application consuming the secret must have refresh logic built-in to periodically check for updated values.
Secrets by origin stack type
The approach to managing secrets varies by origin stack type. All approaches share the same principle: store secrets in AWS Secrets Manager or SSM Parameter Store, then pass them to your application as environment variables.Terraform origin stacks
Define secrets in AWS Secrets Manager or SSM Parameter Store, then inject them into your compute resources as environment variables. Defining the secret:CloudFormation origin stacks
Use CloudFormation dynamic references to fetch secrets from Secrets Manager during stack deployment, then pass them to your resources.Docker Compose origin stacks
Define secrets in the tuning document, then reference them as environment variables in your compose file. docker-compose.yml:Docker Container origin stacks
Similar to Docker Compose, define secrets in the tuning document: tuning.json:Kubernetes origin stacks
Define secrets in AWS Secrets Manager within your Terraform/CloudFormation wrapper, then reference them in Kubernetes Deployment environment variables:Application code (all origin stack types)
Regardless of origin stack type, your application code reads secrets from environment variables:Do not use runtime SDK calls: If your application dynamically fetches secrets using AWS SDK calls (e.g.,
boto3.client('secretsmanager').get_secret_value()), those calls will NOT be automatically mapped by Tensor9 across different cloud environments. Always pass secrets as environment variables for consistent behavior across all deployment targets (AWS, Google Cloud, DigitalOcean).