Namespace Configuration

Configure different pruning policies per namespace for environment-specific retention needs.

TOC

Configuration Hierarchy

Settings flow: GlobalNamespaceResource Group

Set enforcedConfigLevel: namespace in global config to enable namespace-level overrides.

Validation Boundaries

WARNING

CRITICAL - System Boundaries: Create namespace-level ConfigMaps ONLY in user namespaces where PipelineRuns/TaskRuns run.

FORBIDDEN namespaces (validation will reject):

  • System: kube-*
  • Tekton controllers: tekton-pipelines, tekton-*

Required labels for all configs:

labels:
  app.kubernetes.io/part-of: tekton-pruner
  pruner.tekton.dev/config-type: <global|namespace>
WARNING

Namespace-level ConfigMaps are outside the TektonConfig lifecycle. If you need to back up or restore Tekton configuration later, save these ConfigMaps separately.

Method 1: Inline Namespace Specs (Centralized)

Define all namespace configs in the TektonConfig:

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pruner:
    disabled: true  # Must disable job-based pruner
  tektonpruner:
    disabled: false  # Enable event-based pruner
    global-config:
      enforcedConfigLevel: namespace
      ttlSecondsAfterFinished: 3600  # Global fallback
      namespaces:
        dev:
          ttlSecondsAfterFinished: 300
          successfulHistoryLimit: 3
        staging:
          ttlSecondsAfterFinished: 86400
          successfulHistoryLimit: 5
        prod:
          ttlSecondsAfterFinished: 604800
          successfulHistoryLimit: 10

Method 2: Per-Namespace ConfigMaps (Self-Service)

Recommended for namespace isolation and team autonomy.

Step 1: Enable namespace-level config in TektonConfig:

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pruner:
    disabled: true  # Must disable job-based pruner
  tektonpruner:
    disabled: false  # Enable event-based pruner
    global-config:
      enforcedConfigLevel: namespace
      ttlSecondsAfterFinished: 3600  # Fallback for namespaces without config

Step 2: Create namespace-specific ConfigMap (fixed name: tekton-pruner-namespace-spec):

apiVersion: v1
kind: ConfigMap
metadata:
  name: tekton-pruner-namespace-spec  # Fixed name
  namespace: my-app  # User namespace only
  labels:
    app.kubernetes.io/part-of: tekton-pruner
    pruner.tekton.dev/config-type: namespace
data:
  ns-config: |
    ttlSecondsAfterFinished: 300
    successfulHistoryLimit: 5
    failedHistoryLimit: 10

Benefits:

  • Self-service for namespace owners
  • Independent lifecycle management
  • Takes priority over global config

Validation Rules

Namespace configurations are validated against limits to prevent resource exhaustion.

1. Explicit Global Limits

When the global config defines a limit, namespace configs cannot exceed it.

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pruner:
    disabled: true  # Must disable job-based pruner
  tektonpruner:
    disabled: false  # Enable event-based pruner
    global-config:
      ttlSecondsAfterFinished: 3600
      successfulHistoryLimit: 10
      namespaces:
        development:
          ttlSecondsAfterFinished: 7200   # Invalid: exceeds global limit
          successfulHistoryLimit: 5       # Valid: within global limit

2. System Default Limits

When no global limit is defined, the system enforces these maximums:

Configuration FieldSystem Maximum
ttlSecondsAfterFinished2,592,000 seconds (30 days)
successfulHistoryLimit100
failedHistoryLimit100
historyLimit100

Example:

spec:
  tektonpruner:
    global-config:
      enforcedConfigLevel: namespace
      # No limits defined - system maximums apply
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: tekton-pruner-namespace-spec
  namespace: my-app
data:
  ns-config: |
    ttlSecondsAfterFinished: 2592001   # Invalid: exceeds system maximum
    successfulHistoryLimit: 150        # Invalid: exceeds system maximum

3. Override Defaults

Cluster admins can set stricter limits via global config. Global limits override system defaults but cannot exceed system maximums.

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pruner:
    disabled: true  # Must disable job-based pruner
  tektonpruner:
    disabled: false  # Enable event-based pruner
    global-config:
      ttlSecondsAfterFinished: 86400     # Admin limit: 1 day
      successfulHistoryLimit: 20         # Admin limit: 20 runs
      namespaces:
        development:
          ttlSecondsAfterFinished: 3600   # Valid: within global limit
        # ttlSecondsAfterFinished: 172800 # Invalid example: exceeds global limit

Configuration Inheritance

Unspecified settings inherit from higher levels:

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pruner:
    disabled: true  # Must disable job-based pruner
  tektonpruner:
    disabled: false  # Enable event-based pruner
    global-config:
      enforcedConfigLevel: namespace
      ttlSecondsAfterFinished: 3600     # Global default
      successfulHistoryLimit: 5          # Global default
      namespaces:
        dev:
          ttlSecondsAfterFinished: 300   # Override TTL
          # Inherits successfulHistoryLimit: 5 from global

Selector Support

IMPORTANT: Resource selectors (matchLabels, matchAnnotations) only work in namespace-level ConfigMaps (tekton-pruner-namespace-spec), NOT in global ConfigMap's inline namespace specs.

This works (namespace ConfigMap):

apiVersion: v1
kind: ConfigMap
metadata:
  name: tekton-pruner-namespace-spec
  namespace: my-app
  labels:
    app.kubernetes.io/part-of: tekton-pruner
    pruner.tekton.dev/config-type: namespace
data:
  ns-config: |
    pipelineRuns:
      - selector:
          matchLabels:
            critical: "true"
        ttlSecondsAfterFinished: 2592000

This is IGNORED (inline namespace in global ConfigMap):

spec:
  tektonpruner:
    global-config:
      namespaces:
        production:
          pipelineRuns:
            - selector:
                matchLabels:
                  critical: "true"

For selector-based resource groups, use separate namespace ConfigMaps (Method 2).

Common Patterns

Environment-based:

spec:
  tektonpruner:
    global-config:
      enforcedConfigLevel: namespace
      namespaces:
        dev:
          ttlSecondsAfterFinished: 300
          successfulHistoryLimit: 3
        staging:
          ttlSecondsAfterFinished: 86400
          successfulHistoryLimit: 5
        prod:

Best Practices

  1. Use clear namespace naming conventions
  2. Start with permissive limits in development
  3. Implement stricter retention in production
  4. Document namespace configuration decisions
  5. Regularly review and adjust settings
  6. Test configurations before deployment
  7. Use namespace ConfigMaps for selector-based groups

Next Steps