Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 14 additions & 29 deletions docs/guides/contexts.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,48 @@
---
title: "Contexts"
description: "The Windsor CLI enables a contextual workflow, dynamically reconfiguring your environment and toolchain for each specific deployment context."
description: "Understanding how contexts work in Windsor"
---
# Contexts

In a Windsor project, you work across different deployments or environments as "contexts". You could think of a context in terms of your software development lifecycle (SDLC) environments, such as `development`, `staging`, and `production`. You could also think of a context in terms of different pieces of your organizational infrastructure -- `admin`, `web`, or `observability`. Or, some combination of schemes. You may have a `web-staging` and `web-production` as well as `observability-staging` and `observability-production`.

Context assets are stored at `contexts/<context-name>/` and consist of the following :
Generally speaking, it is a good idea to stick to simple patterns. A context may represent a single role with your cloud provider and a single role with your cluster. You consider all the accounts and services associated with a context to share common administrative access. That is, you may be an administrative user of your production AWS account, and likewise have administrative access to a Kubernetes cluster running in a VPC in that same account. You consider all of this to be a part of a shared administrative context.

- Authentication details for a cloud service provider account. (_e.g._, AWS credentials)
- Authentication details for a Kubernetes cluster. (_e.g._, a kube config file)
- Encrypted secrets used to configure resources. (_e.g._, KMS-encrypted SOPS file)
- A [Blueprint](../reference/blueprint.md) resource and its associated Terraform and Kustomize configurations.

Generally speaking, it is a good idea to stick to simple patterns. A context may represent a single role with your cloud provider and a single role with your cluster. You consider all the accounts and services associated with a context to share common administrative access. That is, you may be an administrative user of your production AWS account, and likewise have adminstrative access to a Kubernetes cluster running in a VPC in that same account. You consider all of this to be a part of a shared administrative context.

## Creating contexts
## Creating Contexts

You create a Windsor project by running `windsor init`. When doing so, it automatically creates a `local` context. This step results in the following:

- Creates a new folder of assets in `contexts/local`
- Adds a new entry to your project's `windsor.yaml` file at `contexts.local`

**Note:** Not all context names are handled in the same manner. Contexts named `local` or that begin with `local-` assume that you will be running a local cloud virtualization, setting defaults accordingly. You can read more in the documentation on the [local workstation](../guides/local-workstation.md).
**Note:** Not all context names are handled in the same manner. Contexts named `local` or that begin with `local-` assume that you will be running a local cloud virtualization, setting defaults accordingly. You can read more in the documentation on the [local workstation](local-workstation.md).

To create another context, say one representing production, you run:

```
windsor init production
```bash
windsor init production --provider aws
```

This will create a folder, `contexts/production` with a basic `blueprint.yaml` file.
This will create a folder, `contexts/production` with a basic `blueprint.yaml` file and default `windsor.yaml` file.

## Switching contexts
## Switching Contexts

You can switch contexts by running:

```
```bash
windsor context set <context-name>
```

You can see the current context by running:

```
```bash
windsor context get
```

Additionally, the `WINDSOR_CONTEXT` enviroment variable is available to you.
Additionally, the `WINDSOR_CONTEXT` environment variable is available to you.

<div>
{{ footer('Quick Start', '../../quick-start/index.html', 'Environment Injection', '../environment-injection/index.html') }}
</div>
## Blueprint Templates

<script>
document.getElementById('previousButton').addEventListener('click', function() {
window.location.href = '../../quick-start/index.html';
});
document.getElementById('nextButton').addEventListener('click', function() {
window.location.href = '../environment-injection/index.html';
});
</script>
Contexts are generated from blueprint templates stored in `contexts/_template/`. These templates define reusable blueprint components, features, and schemas that are shared across all contexts. See the [Blueprint Templates](templates.md) guide for details on how templates work.

For detailed reference information about contexts, see the [Contexts Reference](../reference/contexts.md).
88 changes: 85 additions & 3 deletions docs/guides/kustomize.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,96 @@ You can import Kustomize resources from remote sources. To import a component fr
```yaml
...
kustomize:
- name: system-csi
path: system-csi
- name: csi
path: csi
source: core
components:
- longhorn
```

This would result in importing the `system-csi` resource from `core`, and specifically using the `longhorn` driver. By including the `source` field referencing `core`, this reference will be used when the Kustomization is generated on your cluster.
This would result in importing the `csi` resource from `core`, and specifically using the `longhorn` driver. By including the `source` field referencing `core`, this reference will be used when the Kustomization is generated on your cluster.

## Context-Specific Patches

Windsor automatically discovers and includes patches from your context directory. Patches placed in `contexts/<context>/patches/<kustomization-name>/` are automatically discovered and applied to the corresponding kustomization.

### Directory Structure

Place patch files in a directory named after the kustomization:

```plaintext
contexts/
└── local/
├── blueprint.yaml
└── patches/
└── my-app/
├── increase-replicas.yaml
└── add-annotations.yaml
```

### Patch Discovery

All `.yaml` and `.yml` files in `contexts/<context>/patches/<kustomization-name>/` are automatically discovered and added to the kustomization's patches. Windsor automatically detects the patch format:

- **Strategic merge patches**: Standard Kubernetes resource YAML that will be merged into the base resources. See the [Kubernetes documentation on strategic merge patches](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/#create-apply-and-delete) for details.
- **JSON 6902 patches**: Patches that use a Kubernetes resource structure with `apiVersion`, `kind`, and `metadata` fields, but include a `patches` field (instead of `spec`) containing an array of JSON 6902 operations. See [RFC 6902](https://www.rfc-editor.org/rfc/rfc6902) for the JSON Patch specification.

### Examples

For a kustomization named `my-app`, create patches in `contexts/local/patches/my-app/`:

**Strategic Merge Patch:**

```yaml
# contexts/local/patches/my-app/increase-replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 5
```

**Strategic Merge Patch with Annotations:**

```yaml
# contexts/local/patches/my-app/add-annotations.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
annotations:
environment: local
managed-by: windsor
```

**JSON 6902 Patch:**

Windsor also supports JSON 6902 patches using a Kubernetes resource structure with a `patches` field:

```yaml
# contexts/local/patches/my-app/json-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
patches:
- op: replace
path: /spec/replicas
value: 5
- op: add
path: /spec/template/metadata/annotations/environment
value: local
```

In this format, the `apiVersion`, `kind`, and `metadata` fields identify the target resource, while the `patches` field contains an array of JSON 6902 operations (`op`, `path`, `value`). Windsor automatically extracts the target selector from the resource metadata.

These patches are automatically discovered and applied when the blueprint is processed. Patches defined in features (via the blueprint's `features/` directory) are merged with context-specific patches, with all patches being applied in order.

For more information on patch formats, see:
- [Kubernetes Kustomize documentation](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/)
- [RFC 6902 - JSON Patch](https://www.rfc-editor.org/rfc/rfc6902)

<div>
{{ footer('Environment Injection', '../environment-injection/index.html', 'Local Workstation', '../local-workstation/index.html') }}
Expand Down
38 changes: 38 additions & 0 deletions docs/guides/local-workstation.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,44 @@ docker tag my-image:latest ${REGISTRY_URL}/my-image:latest
docker push ${REGISTRY_URL}/my-image:latest
```

## Build ID Management

Windsor provides a `build-id` command for managing build identifiers used for artifact tagging in local development environments. Build IDs are stored persistently in the `.windsor/.build-id` file and are available as the `BUILD_ID` environment variable and postBuild variable in Kustomizations.

### Usage

```bash
windsor build-id # Output current build ID
windsor build-id --new # Generate and output new build ID
```

### Build ID Format

Build IDs follow the format `YYMMDD.RANDOM.#` where:
- `YYMMDD` is the current date (year, month, day)
- `RANDOM` is a random three-digit number for collision prevention
- `#` is a sequential counter incremented for each build on the same day

### Examples

```bash
# Get the current build ID
windsor build-id

# Generate a new build ID and use it for Docker tagging
BUILD_ID=$(windsor build-id --new) && docker build -t myapp:$BUILD_ID .

# Use build ID with local registry
BUILD_ID=$(windsor build-id --new)
docker build -t ${REGISTRY_URL}/myapp:$BUILD_ID .
docker push ${REGISTRY_URL}/myapp:$BUILD_ID
```

The `BUILD_ID` is automatically included in:
- Environment variables available to all processes
- Post-build variables in Kustomizations for Flux variable substitution
- Cluster variables accessible in Kubernetes manifests

## Local GitOps
A local GitOps workflow is provided by [git-livereload](https://github.com/windsorcli/git-livereload). When you save your files locally, they are updated within this container, and reflected as a new commit via [http://git.test](http://git.test). This feature is utilized by the internal gitops tooling ([Flux](https://github.com/fluxcd/flux2)), allowing you to persistently reflect your local Kubernetes manifests on to your local cluster.

Expand Down
Loading
Loading