Dictionary secrets store multiple key-value pairs in a single secret, making them ideal for grouping related configuration values. Each key can be accessed individually when injecting into workloads.
Use Cases
Database Configuration : Store host, port, username, and database name together
API Configuration : Group related API settings (endpoint, version, timeout)
Feature Flags : Store multiple feature toggles in one secret
Environment Variables : Bundle related environment variables
Application Settings : Group configuration that belongs together logically
Use dictionary secrets when you have multiple related values that you want to manage as a single unit but access individually in your workload.
Configuration Options
Dictionary secrets store key-value pairs where:
Component Description Key The identifier for each value (e.g., DB_HOST, DB_PORT) Value The secret value associated with the key
All values in a dictionary secret are stored as strings. If you need to store JSON or complex data, use an Opaque secret instead.
Create a Dictionary Secret
Console UI
CLI
Terraform
Pulumi
Navigate to Secrets
In the Console, navigate to Secrets and click New , or use the Create dropdown in the top-right corner and select Secret .
Enter basic information
Enter a Name and optional Description .
Select secret type
Select Dictionary as the secret type.
Configure key-value pairs
Click Data in the left pane. Click Add to add key-value pairs, or drag and drop a file / click to import.
Create the secret
Click Create .
cpln secret create-dictionary \
--name database-config \
--entry DB_HOST=db.example.com \
--entry DB_PORT= 5432 \
--entry DB_NAME=myapp_production \
--entry DB_SSL_MODE=require \
--org my-org
resource "cpln_secret" "database_config" {
name = "database-config"
description = "Database connection configuration"
dictionary = {
DB_HOST = "db.example.com"
DB_PORT = "5432"
DB_NAME = "myapp_production"
DB_SSL_MODE = "require"
}
}
Access individual keys using the dictionary_as_envs output: # Reference in workload environment variables
resource "cpln_workload" "my_app" {
# ... other config ...
container {
name = "main"
image = "my-app:latest"
env = {
DB_HOST = cpln_secret.database_config.dictionary_as_envs[ "DB_HOST" ]
DB_PORT = cpln_secret.database_config.dictionary_as_envs[ "DB_PORT" ]
}
}
}
import * as cpln from "@pulumiverse/cpln" ;
const databaseConfig = new cpln . Secret ( "database-config" , {
name: "database-config" ,
description: "Database connection configuration" ,
dictionary: {
DB_HOST: "db.example.com" ,
DB_PORT: "5432" ,
DB_NAME: "myapp_production" ,
DB_SSL_MODE: "require" ,
},
});
// Export for use in workloads
export const dbHostEnv = databaseConfig . dictionaryAsEnvs . apply (
envs => envs [ "DB_HOST" ]
);
import pulumiverse_cpln as cpln
database_config = cpln.Secret( "database-config" ,
name = "database-config" ,
description = "Database connection configuration" ,
dictionary = {
"DB_HOST" : "db.example.com" ,
"DB_PORT" : "5432" ,
"DB_NAME" : "myapp_production" ,
"DB_SSL_MODE" : "require" ,
})
# Export for use in workloads
pulumi.export( "db_host_env" , database_config.dictionary_as_envs[ "DB_HOST" ])
package main
import (
" github.com/pulumi/pulumi/sdk/v3/go/pulumi "
" github.com/pulumiverse/pulumi-cpln/sdk/go/cpln "
)
func main () {
pulumi . Run ( func ( ctx * pulumi . Context ) error {
databaseConfig , err := cpln . NewSecret ( ctx , "database-config" , & cpln . SecretArgs {
Name : pulumi . String ( "database-config" ),
Description : pulumi . String ( "Database connection configuration" ),
Dictionary : pulumi . StringMap {
"DB_HOST" : pulumi . String ( "db.example.com" ),
"DB_PORT" : pulumi . String ( "5432" ),
"DB_NAME" : pulumi . String ( "myapp_production" ),
"DB_SSL_MODE" : pulumi . String ( "require" ),
},
})
if err != nil {
return err
}
ctx . Export ( "secretLink" , databaseConfig . SecretLink )
return nil
})
}
using System . Collections . Generic ;
using Pulumi ;
using Pulumiverse . Cpln ;
using Pulumiverse . Cpln . Inputs ;
return await Deployment . RunAsync (() =>
{
var databaseConfig = new Secret ( "database-config" , new SecretArgs
{
Name = "database-config" ,
Description = "Database connection configuration" ,
Dictionary =
{
{ "DB_HOST" , "db.example.com" },
{ "DB_PORT" , "5432" },
{ "DB_NAME" , "myapp_production" },
{ "DB_SSL_MODE" , "require" },
},
});
return new Dictionary < string , object ?>
{
[ "secretLink" ] = databaseConfig . SecretLink ,
};
});
Injecting into Workloads
Individual Keys as Environment Variables
Reference specific keys from the dictionary:
env :
- name : DATABASE_HOST
value : "cpln://secret/database-config.DB_HOST"
- name : DATABASE_PORT
value : "cpln://secret/database-config.DB_PORT"
- name : DATABASE_NAME
value : "cpln://secret/database-config.DB_NAME"
Mount as Directory
When mounted as a volume, each key becomes a file:
volumes :
- uri : "cpln://secret/database-config"
path : /etc/config
This creates:
/etc/config/DB_HOST containing db.example.com
/etc/config/DB_PORT containing 5432
/etc/config/DB_NAME containing myapp_production
/etc/config/DB_SSL_MODE containing require
Common Patterns
Database Configuration
kind : secret
name : postgres-config
type : dictionary
data :
PGHOST : db.example.com
PGPORT : "5432"
PGDATABASE : myapp
PGUSER : app_user
PGSSLMODE : require
Redis Configuration
kind : secret
name : redis-config
type : dictionary
data :
REDIS_HOST : redis.example.com
REDIS_PORT : "6379"
REDIS_DB : "0"
REDIS_TLS : "true"
External API Settings
kind : secret
name : stripe-config
type : dictionary
data :
STRIPE_API_VERSION : "2023-10-16"
STRIPE_WEBHOOK_TOLERANCE : "300"
STRIPE_MAX_RETRIES : "3"
Next Steps
Using Secrets in Workloads Learn how to grant access and inject secrets
Opaque Secrets Store single values or complex data