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

# Release Targets

> The combination of a Deployment, Environment, and Resource

A **Release Target** is the combination of a Deployment, Environment, and Resource. It represents a specific place where a deployment version can be released.

## Understanding Release Targets

The core formula:

```
Deployment × Environment × Resource = Release Target
```

### Example

Given:

* **Deployment**: API Service
* **Environment**: Production (matches 2 resources)
  * Resource 1: prod-cluster-us-east
  * Resource 2: prod-cluster-us-west

**Release Targets Created**:

1. API Service → Production → prod-cluster-us-east
2. API Service → Production → prod-cluster-us-west

Each release target can independently receive deployment versions.

## How Release Targets are Created

Release targets are created automatically based on selectors:

### 1. Environment Selector Matches Resources

Environment defines a resource selector:

```yaml theme={null}
type: Environment
name: Production
resourceSelector: resource.metadata["environment"] == "production"
```

This matches all resources with `metadata.environment = "production"`.

### 2. Deployment Selector Further Filters (Optional)

Deployment can have an additional resource selector:

```yaml theme={null}
type: Deployment
name: API Service
resourceSelector: resource.kind == "KubernetesCluster"
```

This limits the deployment to only Kubernetes clusters.

### 3. Intersection Creates Release Targets

The final set of resources is the intersection of:

* Resources matched by environment selector
* Resources matched by deployment selector (if present)

**Example Calculation**:

```
Environment "Production" matches:
  - prod-k8s-cluster-1 (kind: kubernetes-cluster, env: production)
  - prod-k8s-cluster-2 (kind: kubernetes-cluster, env: production)
  - prod-vm-server-1 (kind: vm, env: production)

Deployment "API Service" selector (kind: kubernetes-cluster):
  - prod-k8s-cluster-1 ✓
  - prod-k8s-cluster-2 ✓
  - prod-vm-server-1 ✗ (not a kubernetes-cluster)

Release Targets Created:
  1. API Service → Production → prod-k8s-cluster-1
  2. API Service → Production → prod-k8s-cluster-2
```

## Release Target Properties

```yaml theme={null}
id: rt_abc123
deploymentId: dep_api
environmentId: env_prod
resourceId: res_cluster1
key: dep_api:env_prod:res_cluster1
createdAt: "2024-01-15T10:00:00Z"
```

### key

Unique identifier combining deployment, environment, and resource IDs.

Format: `{deploymentId}:{environmentId}:{resourceId}`

This key is used to track which version is currently deployed to each target.

## Release Target Lifecycle

### Creation

Release targets are created when:

* A new deployment is created (targets created for all matching environments and resources)
* A new environment is created (targets created for all deployments and matching resources)
* A new resource is created that matches existing environment selectors (targets created for all deployments)

### Deletion

Release targets are deleted when:

* The deployment is deleted
* The environment is deleted
* The resource is deleted or no longer matches the selectors

### Dynamic Updates

As resources are added, updated, or removed:

* Resource metadata changes → Release targets re-evaluated
* Resource matches environment selector → New release targets created
* Resource stops matching → Release targets removed

## Viewing Release Targets

### Via Web UI

1. Navigate to your deployment
2. Click "Release Targets" tab
3. See all targets with current deployed versions

### Via CLI

```bash theme={null}
# List release targets for a deployment
ctrlc api get release-targets --deployment {deploymentId}
```

**Response**:

```yaml theme={null}
releaseTargets:
  - id: rt_abc123
    deployment:
      id: dep_api
      name: API Service
    environment:
      id: env_prod
      name: Production
    resource:
      id: res_cluster1
      name: Production US East Cluster
      identifier: k8s-prod-use1
    currentRelease:
      versionTag: v1.2.3
      status: completed
```

## Release Target Matrix

Think of release targets as a 3D matrix:

```
                    Resources
                 ┌─────┬─────┬─────┐
                 │ R1  │ R2  │ R3  │
    ┌────────────┼─────┼─────┼─────┤
    │ Dev        │ RT  │ RT  │ RT  │ Environments
    │ Staging    │ RT  │ RT  │ RT  │
    │ Production │ RT  │ RT  │ RT  │
    └────────────┴─────┴─────┴─────┘
                    ↑
               Deployment
```

Each cell "RT" is a release target.

For multiple deployments, this becomes a 3D cube:

```
          Deployments (layers)
               ↓
        [API] [Frontend] [Worker]
         ↓       ↓          ↓
    Environment × Resource matrices
```

## Release Target States

While release targets don't have an explicit "status" field, their state is determined by their current release:

### No Release

Target exists but no version has been deployed yet.

### Active Release

A version is currently being deployed (job in progress).

### Completed Release

A version is successfully deployed (job completed).

### Failed Release

Latest deployment attempt failed.

### Pending Release

A release exists but is waiting for approval/policies.

## Deployment Targeting Strategies

### Strategy 1: Broad Matching

Environment matches many resources, deployment doesn't filter:

```yaml theme={null}
# Environment matches all production resources
type: Environment
name: Production
resourceSelector: resource.metadata["environment"] == "production"
```

```yaml theme={null}
# Deployment (no selector)
# → Deploys to ALL production resources
type: Deployment
name: Monitoring Agent
# resourceSelector: not specified
```

**Result**: Deployment goes to every production resource.

**Use Case**: Services that should run everywhere (monitoring agents, logging).

### Strategy 2: Deployment-Level Filtering

Deployment limits which resources it can target:

```yaml theme={null}
# Environment
type: Environment
name: Production
resourceSelector: resource.metadata["environment"] == "production"
```

```yaml theme={null}
# Deployment filters to Kubernetes only
type: Deployment
name: API Service
resourceSelector: resource.kind == "KubernetesCluster"
```

**Result**: Deployment only goes to production Kubernetes clusters.

**Use Case**: Platform-specific deployments (containers vs. VMs).

### Strategy 3: Fine-Grained Environments

Create specific environments for precise targeting:

```yaml theme={null}
# Environment: Production Kubernetes US East
type: Environment
name: Production Kubernetes US East
resourceSelector: >-
  resource.metadata["environment"] == "production" &&
  resource.metadata["region"] == "us-east-1" &&
  resource.kind == "KubernetesCluster"
```

**Result**: Very specific set of release targets.

**Use Case**: Region-specific deployments, gradual rollouts.

## Release Target Locking

Release targets can be locked to prevent new deployments:

```bash theme={null}
ctrlc api lock release-target {releaseTargetId} --reason "Maintenance window"
```

To unlock:

```bash theme={null}
ctrlc api unlock release-target {releaseTargetId}
```

**Use Cases**:

* Maintenance windows
* Incident response (freeze deployments)
* Testing/debugging (keep specific version)

Locked targets won't receive new deployments until unlocked.

## Querying Release Targets

### By Deployment

```bash theme={null}
ctrlc api get release-targets --deployment {deploymentId}
```

Shows all targets for a specific deployment.

### By Environment

```bash theme={null}
ctrlc api get release-targets --environment {environmentId}
```

Shows all targets in a specific environment.

### By Resource

```bash theme={null}
ctrlc api get release-targets --resource {resourceId}
```

Shows all targets for a specific resource (all deployments).

### With Filters

```bash theme={null}
ctrlc api get release-targets \
  --deployment dep_api \
  --environment env_prod \
  --status completed
```

## Release Target Count Estimates

Before creating a deployment, estimate how many release targets will be created:

```bash theme={null}
ctrlc api estimate-targets \
  --system sys_abc \
  --selector 'resource.kind == "KubernetesCluster"'
```

**Response**:

```yaml theme={null}
environments:
  - name: Development
    matchingResources: 1
    releaseTargets: 1
  - name: Production
    matchingResources: 3
    releaseTargets: 3
totalReleaseTargets: 4
```

## Common Patterns

### Pattern 1: Environment-Per-Region

```yaml theme={null}
# regional-setup.yaml
---
type: Deployment
name: API Service
slug: api-service
jobAgent:
  ref: kubernetes-agent
---
type: Environment
name: Production US East
resourceSelector: >-
  resource.metadata["environment"] == "production" &&
  resource.metadata["region"] == "us-east-1"
---
type: Environment
name: Production US West
resourceSelector: >-
  resource.metadata["environment"] == "production" &&
  resource.metadata["region"] == "us-west-2"
```

```bash theme={null}
ctrlc apply -f regional-setup.yaml
```

**Release Targets**: API Service gets separate targets per region.

**Benefit**: Independent regional deployments, gradual rollout by region.

### Pattern 2: Tiered Resources

```yaml theme={null}
# tiered-setup.yaml
---
type: Deployment
name: Critical Service
slug: critical-service
resourceSelector: resource.metadata["tier"] == "critical"
jobAgent:
  ref: kubernetes-agent
---
type: Deployment
name: Standard Service
slug: standard-service
resourceSelector: resource.metadata["tier"] == "standard"
jobAgent:
  ref: kubernetes-agent
---
type: Environment
name: Production
resourceSelector: resource.metadata["environment"] == "production"
```

```bash theme={null}
ctrlc apply -f tiered-setup.yaml
```

**Release Targets**: Services only deploy to appropriate tier resources.

**Benefit**: Resource isolation, cost optimization.

### Pattern 3: Canary Deployments

```yaml theme={null}
# canary-setup.yaml
---
type: Deployment
name: API Service
slug: api-service
jobAgent:
  ref: kubernetes-agent
---
type: Environment
name: Production Canary
resourceSelector: >-
  resource.metadata["environment"] == "production" &&
  resource.metadata["canary"] == "true"
---
type: Environment
name: Production Stable
resourceSelector: >-
  resource.metadata["environment"] == "production" &&
  resource.metadata["canary"] != "true"
```

```bash theme={null}
ctrlc apply -f canary-setup.yaml
```

**Release Targets**: Separate targets for canary vs. stable.

**Benefit**: Test new versions on canary before rolling out to stable.

## Best Practices

### Resource Metadata Design

Design resource metadata with targeting in mind:

```yaml theme={null}
# Good resource metadata
metadata:
  environment: production
  region: us-east-1
  zone: us-east-1a
  tier: critical
  team: platform
  canary: "false"
```

This allows flexible targeting across multiple dimensions.

### Selector Simplicity

**Prefer Simple Selectors**:

```yaml theme={null}
resourceSelector: resource.metadata["environment"] == "production"
```

**Over Complex Ones**:

```yaml theme={null}
resourceSelector: >-
  (resource.metadata["environment"] == "production" ||
   resource.metadata["environment"] == "prod") &&
  resource.metadata["tier"] != "deprecated" && ...
```

Complex selectors are harder to understand and maintain.

### Validate Target Count

Before deploying:

1. Check estimated release target count
2. Verify targets match expectations
3. Test in lower environment first

### Monitor Release Targets

* Track release target creation/deletion events
* Alert on unexpected target count changes
* Review targets when resources are added/updated

## Troubleshooting

### Too many release targets created

* Review environment resource selectors
* Check if deployment needs a resource selector to filter
* Verify resource metadata is correct

### Expected targets not created

* Check environment selector matches resources
* Verify deployment selector (if present) isn't too restrictive
* Ensure deployment and environment are in same system
* Check resources exist and aren't deleted

### Targets created for wrong resources

* Review selector logic (AND vs. OR)
* Check resource metadata matches expectations
* Test selectors with query API before applying

### Release target disappeared

* Check if resource was deleted
* Verify resource still matches environment selector
* Check if resource metadata changed

## Next Steps

* [Releases and Jobs](./releases-and-jobs) - How versions deploy to targets
* [Selectors](./selectors) - Master the selector syntax
* [Environments](./environments) - Create and configure environments
* [Policies](../policies/overview) - Control which targets receive deployments
