Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Managing Stacks

Stacks are the fundamental organizational unit in Brokkr, representing collections of related Kubernetes resources that belong together. This guide covers creating stacks, configuring them with labels and annotations for targeting, managing their lifecycle, and understanding how they connect to agents and deployment objects.

Understanding Stacks

A stack serves as a container for deployment objects—the versioned snapshots of Kubernetes resources you want to deploy. When you create a stack, you establish a logical boundary for a set of resources, whether that’s an application, a service, or any collection of related Kubernetes manifests. Agents are then assigned to stacks through targeting relationships, enabling you to control which clusters receive which resources.

Each stack maintains a history of deployment objects, providing an immutable audit trail of every configuration change. This history enables rollback capabilities and satisfies compliance requirements for tracking what was deployed and when.

Creating Stacks

Basic Stack Creation

To create a stack, send a POST request to the stacks endpoint with a name and optional description:

curl -X POST http://localhost:3000/api/v1/stacks \
  -H "Authorization: Bearer $ADMIN_PAK" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "payment-service",
    "description": "Payment processing microservice and dependencies"
  }'

The response includes the stack’s UUID which you’ll use for all subsequent operations:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "payment-service",
  "description": "Payment processing microservice and dependencies",
  "created_at": "2025-01-02T10:00:00Z",
  "updated_at": "2025-01-02T10:00:00Z",
  "generator_id": "00000000-0000-0000-0000-000000000000"
}

Stack Naming Conventions

Stack names must be non-empty strings up to 255 characters. While Brokkr doesn’t enforce naming conventions, consistent patterns make your infrastructure easier to navigate. Consider including:

  • The application or service name
  • The environment (if not using labels)
  • A version or variant indicator for parallel deployments

Examples: frontend-app, database-cluster, monitoring-stack, api-gateway-v2

Configuring Labels and Annotations

Labels and annotations provide metadata for stacks that enables dynamic targeting and integration with external systems. Labels are simple string values used for categorization and selection. Annotations are key-value pairs for richer metadata.

Adding Labels

Labels enable pattern-based targeting where agents with matching labels automatically receive stacks. Add a label with a POST request:

curl -X POST http://localhost:3000/api/v1/stacks/$STACK_ID/labels \
  -H "Authorization: Bearer $ADMIN_PAK" \
  -H "Content-Type: application/json" \
  -d '"production"'

Labels must be non-empty strings up to 64 characters with no whitespace. Common labeling patterns include:

PurposeExample Labels
Environmentproduction, staging, development
Regionus-east, eu-west, apac
Tierfrontend, backend, data
Criticalitycritical, standard

Listing Labels

View all labels for a stack:

curl http://localhost:3000/api/v1/stacks/$STACK_ID/labels \
  -H "Authorization: Bearer $ADMIN_PAK"

Removing Labels

Remove a label by its value:

curl -X DELETE http://localhost:3000/api/v1/stacks/$STACK_ID/labels/production \
  -H "Authorization: Bearer $ADMIN_PAK"

Adding Annotations

Annotations carry key-value metadata for integration with external systems or configuration hints:

curl -X POST http://localhost:3000/api/v1/stacks/$STACK_ID/annotations \
  -H "Authorization: Bearer $ADMIN_PAK" \
  -H "Content-Type: application/json" \
  -d '{
    "stack_id": "550e8400-e29b-41d4-a716-446655440000",
    "key": "cost-center",
    "value": "engineering-team-a"
  }'

Both keys and values must be non-empty strings up to 64 characters with no whitespace. Annotations are useful for:

PurposeExample
Cost allocationcost-center=team-alpha
Owner trackingowner=platform-team
SLA classificationsla-tier=gold
External referencesjira-project=PLAT

Listing Annotations

View all annotations for a stack:

curl http://localhost:3000/api/v1/stacks/$STACK_ID/annotations \
  -H "Authorization: Bearer $ADMIN_PAK"

Removing Annotations

Remove an annotation by its key:

curl -X DELETE http://localhost:3000/api/v1/stacks/$STACK_ID/annotations/cost-center \
  -H "Authorization: Bearer $ADMIN_PAK"

Targeting Stacks to Agents

Targeting establishes the relationship between stacks and the agents that should manage them. Without targeting, an agent won’t receive deployment objects from a stack regardless of other configuration.

Direct Assignment

Create a targeting relationship by associating an agent with a specific stack:

curl -X POST http://localhost:3000/api/v1/agents/$AGENT_ID/targets \
  -H "Authorization: Bearer $ADMIN_PAK" \
  -H "Content-Type: application/json" \
  -d "{
    \"agent_id\": \"$AGENT_ID\",
    \"stack_id\": \"$STACK_ID\"
  }"

Direct assignment is appropriate when you have explicit control over which agents manage which stacks and the relationship is stable.

Label-Based Targeting

When both agents and stacks carry matching labels, you can configure agents to automatically target all stacks with those labels. This enables patterns like “all production agents receive all production stacks” without maintaining explicit per-pair associations.

To set up label-based targeting:

  1. Add labels to your stacks that represent their characteristics
  2. Add corresponding labels to agents that should manage those stacks
  3. Configure the targeting policy (see agent configuration)

The agent polls for stacks matching its label configuration and creates targeting relationships automatically.

Multi-Cluster Deployments

A single stack can be targeted by multiple agents, enabling multi-cluster deployment scenarios. Each agent independently polls for the stack’s deployment objects and applies them to its cluster. This is useful for:

  • High availability across regions
  • Disaster recovery setups
  • Consistent infrastructure across environments

Working with Deployment Objects

Once a stack exists and is targeted to agents, you populate it with deployment objects containing Kubernetes resources.

Creating Deployment Objects

Submit Kubernetes YAML as a deployment object:

curl -X POST "http://localhost:3000/api/v1/stacks/$STACK_ID/deployment-objects" \
  -H "Authorization: Bearer $ADMIN_PAK" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --arg yaml "$(cat resources.yaml)" '{yaml_content: $yaml, is_deletion_marker: false}')"

Each deployment object receives a sequence ID that guarantees ordering. Agents process deployment objects in sequence order, ensuring resources are applied in the intended order.

Listing Deployment Objects

View all deployment objects in a stack:

curl "http://localhost:3000/api/v1/stacks/$STACK_ID/deployment-objects" \
  -H "Authorization: Bearer $ADMIN_PAK"

Using Templates

For standardized deployments, instantiate a template into a deployment object:

curl -X POST "http://localhost:3000/api/v1/stacks/$STACK_ID/deployment-objects/from-template" \
  -H "Authorization: Bearer $ADMIN_PAK" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "template-uuid-here",
    "parameters": {
      "replicas": 3,
      "image_tag": "v1.2.3"
    }
  }'

The template’s parameters are validated against its JSON Schema before rendering. If the template has labels, they must match the stack’s labels for instantiation to succeed.

Stack Lifecycle

Updating Stacks

Modify a stack’s name or description:

curl -X PUT http://localhost:3000/api/v1/stacks/$STACK_ID \
  -H "Authorization: Bearer $ADMIN_PAK" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "payment-service-v2",
    "description": "Updated payment service with new features"
  }'

Deleting Stacks

Brokkr uses soft deletion for stacks. When you delete a stack, it’s marked with a deleted_at timestamp rather than being removed from the database:

curl -X DELETE http://localhost:3000/api/v1/stacks/$STACK_ID \
  -H "Authorization: Bearer $ADMIN_PAK"

Soft deletion marks the stack with a deleted_at timestamp:

  • The stack stops appearing in list queries
  • The underlying data remains intact for audit purposes and potential recovery

Note that soft-deleting a stack does not automatically cascade to its deployment objects or create deletion markers. To ensure agents remove resources from clusters, create a deletion marker deployment object before deleting the stack.

Understanding Deletion Markers

To clean up cluster resources, create a deployment object with is_deletion_marker: true for the stack before deleting it. Agents receiving this marker understand they should delete the stack’s resources rather than apply them. This ensures resources are cleaned up from clusters.

Generator Integration

Generators are external systems like CI/CD pipelines that create stacks programmatically. When a generator creates a stack, that stack’s generator_id links it to the creating generator, establishing ownership and access control.

Generators can only access stacks they created. This scoping ensures pipelines can’t accidentally modify resources belonging to other systems. See the Generators Guide for details on integrating CI/CD systems.

Best Practices

Organize by responsibility: Group resources into stacks based on what changes together. A stack should contain resources that are deployed, updated, and scaled as a unit.

Use labels for targeting: Rather than creating explicit targeting relationships for each stack-agent pair, use labels to establish patterns. This reduces configuration overhead as your infrastructure grows.

Keep stacks focused: While you can put any resources in a stack, keeping stacks focused on specific applications or services makes management clearer and reduces blast radius for changes.

Document with annotations: Use annotations to record metadata that helps teams understand the stack’s purpose, ownership, and relationship to business systems.

Plan for deletion: Remember that deleting a stack triggers resource deletion on targeted clusters. Ensure you understand which clusters are affected before deleting.