Populate best practices from claude-foundations

Migrates 20 topic files from claude-foundations/best-practices/ to this
standalone repo. Adds BESTPRACTICES.md index, CLAUDE.md conventions, and
updated README.md. Container agents clone this repo to /best-practices.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul O'Reilly
2026-03-28 17:46:13 +13:00
parent 1ca7ecfe19
commit 3efe153ca1
23 changed files with 2236 additions and 1 deletions

View File

@@ -0,0 +1,221 @@
# Octopus Deploy Process Templates
Best practices for creating and managing Octopus Deploy process templates using OCL (Octopus Configuration Language) in Platform Hub.
## Key Concepts
- **Step templates** (action templates) are reusable individual steps, created via API or UI, stored in a space's library
- **Process templates** are reusable multi-step deployment processes, stored as OCL files in Platform Hub's Git repo
- **Project templates** compose process templates into full project configurations (feature coming soon)
- Process templates live in `.octopus/process-templates/<slug>.ocl` in the Platform Hub Git repo
- Projects consume process templates via `process_template` blocks in their `deployment_process.ocl`
## OCL File Structure
### Process Template File
```hcl
name = "Deploy to Kubernetes - Helm"
description = "Standard Helm-based Kubernetes deployment with pre-validation and smoke tests"
# Parameters — values supplied by consuming projects
parameter "target_tags" {
display_settings = {
Octopus.ControlType = "TargetTags"
}
help_text = "Kubernetes target tags"
label = "Target Tags"
}
parameter "cloud_target" {
display_settings = {
Octopus.ControlType = "SingleLineText"
}
help_text = "Cloud provider (gcp, aws, azure)"
label = "Cloud Target"
value "gcp" {} # default value
}
# Steps — ordered deployment steps
step "deploy-helm" {
name = "Deploy via Helm"
properties = {
Octopus.Action.TargetRoles = "#{target_tags}"
}
action {
action_type = "Octopus.Script"
properties = {
Octopus.Action.Script.ScriptSource = "Inline"
Octopus.Action.Script.Syntax = "PowerShell"
Octopus.Action.Script.ScriptBody = "Write-Host 'Deploying...'"
}
worker_pool_variable = ""
}
}
```
### How Projects Consume Process Templates
In a project's `deployment_process.ocl`:
```hcl
process_template "deploy-app" {
name = "Deploy Application"
process_template_slug = "deploy-to-kubernetes-helm"
version_mask = "1.X" # auto-update minor/patch
parameter "target_tags" {
value = "kubernetes,production"
}
parameter "cloud_target" {
value = "aws"
}
}
```
## OCL Syntax Rules
From the EBNF grammar (https://github.com/OctopusDeploy/Ocl):
- **Name, `=`, and value** must be on the same line
- **Block name, labels, and `{`** must be on the same line
- **Closing `}`** must be on its own line (except empty blocks like `value "default" {}`)
- **Strings** use double quotes, cannot contain unescaped `"`
- **Multi-line strings** use heredoc: `<<-EOF` / `EOF` (indented variant)
- **Arrays** use `["item1", "item2"]`
- **Dictionaries** use `{ key = value }` (one entry per line inside braces)
## Referencing Step Templates
Step templates are referenced by **ID and version** in the action's properties, NOT by name:
```hcl
step "run-tests" {
name = "Run Unit Tests"
action {
# Reference a step template instead of action_type
properties = {
Octopus.Action.Template.Id = "ActionTemplates-62"
Octopus.Action.Template.Version = "1"
# Step template parameter values
Language = "go"
CloudTarget = "gcp"
}
worker_pool_variable = ""
}
}
```
When NOT using a step template, define `action_type` directly:
```hcl
action {
action_type = "Octopus.Script"
properties = { ... }
}
```
## Channel Scoping
Scope steps to specific channels using the `channels` attribute on the action block. Uses **channel slugs** (auto-generated from names):
```hcl
action {
action_type = "Octopus.Script"
channels = ["non-prod"] # only runs in non-prod channel
properties = { ... }
}
```
## Package References
```hcl
# Container image for worker execution
container {
feed = "registered-dockerhub" # feed slug, not ID
image = "octopusdeploy/worker-tools:ubuntu.22.04"
}
# Package reference in a step
packages "MyPackage" {
acquisition_location = "NotAcquired" # Server | ExecutionTarget | NotAcquired
feed = "platformhub-non-prod" # feed slug
package_id = "paul-oreilly-octopus/nonprod/listing-service"
properties = {
SelectionMode = "immediate"
}
}
```
## Parameter Types
| Control Type | `Octopus.ControlType` Value | Can Have Default |
|---|---|---|
| Single-line text | `SingleLineText` | Yes |
| Multi-line text | `MultiLineText` | Yes |
| Sensitive/password | `Sensitive` | Yes (encrypted) |
| Checkbox | `Checkbox` | Yes |
| Dropdown | `Select` | Yes |
| AWS/Azure/GCP Account | `AWSAccount` etc. | Yes |
| Worker Pool | (worker pool) | No |
| Package | (package) | No |
| Target Tags | `TargetTags` | No |
| Environments | (environments) | No |
| Channels | (channels) | No |
## Step Properties Reference
| Property | Type | Values | Default |
|---|---|---|---|
| `step.condition` | enum | `Success`, `Failure`, `Always`, `Variable` | `Success` |
| `step.start_trigger` | enum | `StartAfterPrevious`, `StartWithPrevious` | `StartAfterPrevious` |
| `step.package_requirement` | enum | `LetOctopusDecide`, `BeforePackageAcquisition`, `AfterPackageAcquisition` | `LetOctopusDecide` |
| `action.channels` | string[] | channel slugs | all |
| `action.environments` | string[] | environment slugs | all |
| `action.excluded_environments` | string[] | environment slugs | none |
| `action.is_disabled` | bool | | `False` |
| `action.is_required` | bool | | `False` |
| `action.notes` | string | step description | |
| `action.worker_pool` | string | worker pool slug | |
| `action.worker_pool_variable` | string | variable name | |
## Versioning
- Process templates use **semantic versioning** (major.minor.patch)
- `version_mask = "1.X"` in consuming projects auto-updates on minor/patch changes
- **Major version bumps** require explicit upgrade by consuming projects
- Keep major bumps for breaking changes (parameter renames, step removals)
- Minor/patch for new optional parameters, script improvements, bug fixes
## Gotchas
1. **Step templates are space-scoped.** Process templates in Platform Hub cannot reference `ActionTemplates-*` IDs from other spaces. If you need reusable steps, use inline `action_type = "Octopus.Script"` in the process template OCL. Step templates are useful within a single space's projects, but not for cross-space process templates.
2. **Process template names** cannot contain parentheses, slashes, or ampersands — only letters, numbers, periods, commas, dashes, underscores, and hashes.
3. **Heredoc for multi-line scripts** — use `<<-EOT` / `EOT` for PowerShell scripts that contain double quotes. The `-` prefix allows indented closing tags.
4. **Every step needs a worker pool.** Process templates must have a `worker_pool` parameter (type `WorkerPool`), and every action must set `worker_pool_variable = "worker_pool"` referencing it. Without this, the template will fail to parse with "A step must specify a worker pool parameter".
5. **Publishing and sharing is UI-only.** Process template sharing (which spaces can see/use a template) is stored in the Octopus database, not in Git/OCL. You must publish and share each template through the UI. There is no API or CLI for this currently.
## Best Practices
1. **One template per deployment pattern**, not per cloud. Use parameters to vary cloud-specific behaviour.
2. **Use step templates for reusable individual steps**, process templates for reusable multi-step workflows.
3. **Parameters should have sensible defaults** where possible — reduces friction for consuming projects.
4. **Use `TargetTags` parameter type** for Kubernetes target selection rather than hardcoding roles.
5. **Name templates with the action, not the technology**: "Deploy to Kubernetes" not "Helm Chart Deployer".
6. **Keep descriptions updated** — they appear in the UI when browsing templates.
7. **Process templates cannot reference the project's own Git repo** for scripts — use inline scripts or external URLs.
8. **Test templates** by creating a test project that consumes them before sharing widely.
## References
- OCL Syntax: https://octopus.com/docs/projects/version-control/ocl-file-format
- Config as Code Reference: https://octopus.com/docs/projects/version-control/config-as-code-reference
- Process Templates: https://octopus.com/docs/platform-hub/templates/process-templates
- Template Parameters: https://octopus.com/docs/platform-hub/templates/parameters
- Publishing & Sharing: https://octopus.com/docs/platform-hub/templates/publishing-and-sharing
- Best Practices: https://octopus.com/docs/platform-hub/templates/process-templates/best-practices
- Troubleshooting: https://octopus.com/docs/platform-hub/templates/process-templates/troubleshooting
- OCL Grammar (EBNF): https://github.com/OctopusDeploy/Ocl