> ## Documentation Index
> Fetch the complete documentation index at: https://docs.controlplane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dictionary

> Create a dictionary secret to store multiple key-value pairs in a single secret, ideal for grouping related configuration values.

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

<Tip>
  Use dictionary secrets when you have multiple related values that you want to manage as a single unit but access individually in your workload.
</Tip>

## 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                   |

<Note>
  All values in a dictionary secret are stored as strings. If you need to store JSON or complex data, use an [Opaque secret](/guides/create-secret/opaque) instead.
</Note>

***

## Create a Dictionary Secret

<Tabs>
  <Tab title="Console UI">
    <Steps>
      <Step title="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**.
      </Step>

      <Step title="Enter basic information">
        Enter a **Name** and optional **Description**.
      </Step>

      <Step title="Select secret type">
        Select **Dictionary** as the secret type.
      </Step>

      <Step title="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.
      </Step>

      <Step title="Create the secret">
        Click **Create**.
      </Step>
    </Steps>
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    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
    ```
  </Tab>

  <Tab title="Terraform">
    ```hcl theme={null}
    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:

    ```hcl theme={null}
    # 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"]
        }
      }
    }
    ```
  </Tab>

  <Tab title="Pulumi">
    <Tabs>
      <Tab title="TypeScript">
        ```typescript theme={null}
        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"]
        );
        ```
      </Tab>

      <Tab title="Python">
        ```python theme={null}
        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"])
        ```
      </Tab>

      <Tab title="Go">
        ```go theme={null}
        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
            })
        }
        ```
      </Tab>

      <Tab title="C#">
        ```csharp theme={null}
        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,
            };
        });
        ```
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

***

## Injecting into Workloads

### Individual Keys as Environment Variables

Reference specific keys from the dictionary:

```yaml theme={null}
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:

```yaml theme={null}
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

```yaml theme={null}
kind: secret
name: postgres-config
type: dictionary
data:
  PGHOST: db.example.com
  PGPORT: "5432"
  PGDATABASE: myapp
  PGUSER: app_user
  PGSSLMODE: require
```

### Redis Configuration

```yaml theme={null}
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

```yaml theme={null}
kind: secret
name: stripe-config
type: dictionary
data:
  STRIPE_API_VERSION: "2023-10-16"
  STRIPE_WEBHOOK_TOLERANCE: "300"
  STRIPE_MAX_RETRIES: "3"
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Using Secrets in Workloads" icon="cube" href="/guides/create-secret/overview#using-secrets-in-workloads">
    Learn how to grant access and inject secrets
  </Card>

  <Card title="Opaque Secrets" icon="file-lines" href="/guides/create-secret/opaque">
    Store single values or complex data
  </Card>
</CardGroup>
