Skip to content

Inject secrets and configuration into test pods

Inject credentials and configuration into Locust test pods without hardcoding them in test files. The operator provides four methods for injecting data.

Method 1: ConfigMap environment variables

Inject all keys from a ConfigMap as environment variables with an optional prefix.

Create a ConfigMap:

kubectl create configmap app-config \
  --from-literal=TARGET_HOST=https://api.example.com \
  --from-literal=LOG_LEVEL=INFO \
  --from-literal=TIMEOUT=30

Reference in LocustTest CR:

apiVersion: locust.io/v2
kind: LocustTest
metadata:
  name: configmap-test
spec:
  image: locustio/locust:2.43.3
  master:
    command: "--locustfile /lotest/src/test.py --host https://example.com"
  worker:
    command: "--locustfile /lotest/src/test.py"
    replicas: 3
  env:
    configMapRefs:
      - name: app-config          # ConfigMap name
        prefix: "APP_"            # Prefix for all keys (optional)

Result: ConfigMap keys become environment variables with the prefix: - TARGET_HOSTAPP_TARGET_HOST - LOG_LEVELAPP_LOG_LEVEL - TIMEOUTAPP_TIMEOUT

Access in your locustfile:

import os

target_host = os.getenv('APP_TARGET_HOST')
log_level = os.getenv('APP_LOG_LEVEL', 'INFO')
timeout = int(os.getenv('APP_TIMEOUT', '30'))

Method 2: Secret environment variables

Inject all keys from a Secret as environment variables with an optional prefix.

Create a Secret:

kubectl create secret generic api-credentials \
  --from-literal=API_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... \
  --from-literal=API_KEY=sk_live_51H8... \
  --from-literal=DB_PASSWORD=secure-password-here

Reference in LocustTest CR:

apiVersion: locust.io/v2
kind: LocustTest
metadata:
  name: secret-test
spec:
  image: locustio/locust:2.43.3
  master:
    command: "--locustfile /lotest/src/test.py --host https://api.example.com"
  worker:
    command: "--locustfile /lotest/src/test.py"
    replicas: 5
  env:
    secretRefs:
      - name: api-credentials     # Secret name
        # No prefix specified -- keys are used as-is

Result: Secret keys become environment variables: - API_TOKENAPI_TOKEN - API_KEYAPI_KEY - DB_PASSWORDDB_PASSWORD

Access in your locustfile:

import os

api_token = os.getenv('API_TOKEN')
api_key = os.getenv('API_KEY')
db_password = os.getenv('DB_PASSWORD')

Secret values in pod specs

Kubernetes injects Secret values as environment variables. They're visible in pod specs. Use RBAC to restrict access to pod definitions.

Method 3: Individual variables

Define individual environment variables with literal values or references to ConfigMap/Secret keys. This gives you fine-grained control over which keys to inject.

Create sources:

kubectl create configmap app-settings --from-literal=api-url=https://api.example.com
kubectl create secret generic auth --from-literal=token=secret-token-here

Reference in LocustTest CR:

apiVersion: locust.io/v2
kind: LocustTest
metadata:
  name: individual-vars-test
spec:
  image: locustio/locust:2.43.3
  master:
    command: "--locustfile /lotest/src/test.py --host https://example.com"
  worker:
    command: "--locustfile /lotest/src/test.py"
    replicas: 3
  env:
    variables:
      # Literal value
      - name: ENVIRONMENT
        value: "staging"

      # Reference to Secret key
      - name: API_TOKEN
        valueFrom:
          secretKeyRef:
            name: auth                    # Secret name
            key: token                    # Key within Secret

      # Reference to ConfigMap key
      - name: API_URL
        valueFrom:
          configMapKeyRef:
            name: app-settings            # ConfigMap name
            key: api-url                  # Key within ConfigMap

Result: Three environment variables are injected: - ENVIRONMENT=staging (literal value) - API_TOKEN=secret-token-here (from Secret) - API_URL=https://api.example.com (from ConfigMap)

Use cases: - Mix literal values with secrets/configs - Select specific keys from ConfigMaps/Secrets - Set defaults with fallback to secrets for sensitive values

Method 4: Secret file mounts

Mount secrets as files in the container filesystem. This is useful for: - TLS certificates - Credential files (JSON key files, kubeconfig, etc.) - Configuration files that must be read from disk

Create a Secret from files:

kubectl create secret generic tls-certs \
  --from-file=ca.crt=path/to/ca.crt \
  --from-file=client.crt=path/to/client.crt \
  --from-file=client.key=path/to/client.key

Reference in LocustTest CR:

apiVersion: locust.io/v2
kind: LocustTest
metadata:
  name: file-mount-test
spec:
  image: locustio/locust:2.43.3
  master:
    command: "--locustfile /lotest/src/test.py --host https://api.example.com"
  worker:
    command: "--locustfile /lotest/src/test.py"
    replicas: 3
  env:
    secretMounts:
      - name: tls-certs                   # Secret name
        mountPath: /etc/locust/certs      # Mount path in container
        readOnly: true                    # Mount as read-only (recommended)

Result: Secret keys become files at mount path: - /etc/locust/certs/ca.crt - /etc/locust/certs/client.crt - /etc/locust/certs/client.key

Access in your locustfile:

import ssl

# Create SSL context with mounted certificates
ssl_context = ssl.create_default_context(cafile='/etc/locust/certs/ca.crt')
ssl_context.load_cert_chain(
    certfile='/etc/locust/certs/client.crt',
    keyfile='/etc/locust/certs/client.key'
)

# Use in HTTP client
# (implementation depends on your HTTP library)

Reserved paths

The following paths are reserved and cannot be used for secret mounts:

PathPurposeCustomizable via
/lotest/src/Test script mount pointtestFiles.srcMountPath
/opt/locust/libLibrary mount pointtestFiles.libMountPath

When testFiles is configured, only the paths actually in use are reserved. When not configured, both default paths are reserved.

If you customize srcMountPath or libMountPath, those custom paths become reserved instead.

Combined example

Use multiple injection methods together:

apiVersion: locust.io/v2
kind: LocustTest
metadata:
  name: combined-injection
spec:
  image: locustio/locust:2.43.3
  master:
    command: "--locustfile /lotest/src/test.py --host https://api.example.com"
  worker:
    command: "--locustfile /lotest/src/test.py"
    replicas: 5
  env:
    # Method 1: ConfigMap environment variables
    configMapRefs:
      - name: app-config
        prefix: "APP_"

    # Method 2: Secret environment variables
    secretRefs:
      - name: api-credentials
        # No prefix specified -- keys are used as-is

    # Method 3: Individual variables
    variables:
      - name: ENVIRONMENT
        value: "production"
      - name: REGION
        value: "us-west-2"
      - name: SPECIAL_TOKEN
        valueFrom:
          secretKeyRef:
            name: special-auth
            key: token

    # Method 4: Secret file mounts
    secretMounts:
      - name: tls-certs
        mountPath: /etc/locust/certs
        readOnly: true
      - name: service-account-key
        mountPath: /etc/locust/keys
        readOnly: true

Result: - All keys from app-config ConfigMap with APP_ prefix - All keys from api-credentials Secret (no prefix) - Literal values: ENVIRONMENT, REGION - Individual secret reference: SPECIAL_TOKEN - Files mounted at /etc/locust/certs/ and /etc/locust/keys/

Verification

Check environment variables

Verify that environment variables were injected into test pods:

# Get a pod name
POD=$(kubectl get pods -l performance-test-name=combined-injection -o jsonpath='{.items[0].metadata.name}')

# Check all environment variables
kubectl exec $POD -- printenv | sort

# Check specific prefix
kubectl exec $POD -- printenv | grep "APP_"

# Check specific variable
kubectl exec $POD -- printenv API_TOKEN

Check file mounts

Verify that secret files were mounted:

# List files in mount path
kubectl exec $POD -- ls -la /etc/locust/certs/

# Read file content (use with caution for sensitive data)
kubectl exec $POD -- cat /etc/locust/certs/ca.crt

Troubleshooting

ProblemSymptomSolution
Pod stuck in ContainerCreating or shows CreateContainerConfigErrorConfigurationError conditionVerify ConfigMap/Secret exists: kubectl get configmap,secret
Environment variable missingVariable not in printenv outputCheck spelling of ConfigMap/Secret name and key
File mount emptyDirectory exists but no filesVerify Secret exists and has data: kubectl get secret <name> -o yaml
Permission denied reading filecat fails with permission errorCheck readOnly: true and Secret file permissions

Check PodsHealthy condition:

kubectl get locusttest combined-injection -o jsonpath='{.status.conditions[?(@.type=="PodsHealthy")]}'

If status=False with reason ConfigurationError, the error message shows which ConfigMap or Secret is missing.

Security best practices

  1. Use Secrets for sensitive data: Never use ConfigMaps for passwords, tokens, or keys.

  2. Use RBAC to restrict Secret access: Limit who can read Secrets in your namespace. Users should not have direct Secret access -- only the operator's service account needs it.

  3. Rotate secrets regularly: See Security Best Practices - Secret Rotation for the rotation process.

  4. Use External Secrets Operator: For production, sync secrets from external vaults (AWS Secrets Manager, HashiCorp Vault, etc.). See Security Best Practices - External Secrets.

  5. Prefer file mounts for certificates: Mount TLS certificates as files instead of environment variables (harder to accidentally log).

  6. Use read-only mounts: Always set readOnly: true for secret mounts to prevent accidental modification.