# Step Templates & Script Modules

Source: https://www.jawsdeploy.net/features/step-templates-script-modules

Step templates give a repeated deployment pattern a form, validation, and defaults. Script modules share helper functions across every script you write. Together, they are the DRY layer your CI scripts never had.

## Two different abstractions, often confused

Jaws Deploy gives you two ways to share deployment logic. They look related, but they solve different problems and you will use both.

**A reusable step with a UI**

Encapsulate a deployment *action* - extract a package, configure a service, restart IIS - with structured inputs and validation. Used by selecting it in a project's deployment process.

**Shared PowerShell functions**

Pure code reuse. A library of functions that any deployment script can `import-module` and call. No UI, no inputs - just functions you don't want to redefine.

## Step templates: structured, reusable, validated

A step template is a parameterized step you can drop into any project's deployment process. It has:

## Beyond "a script in a file"

- **Typed inputs** - strings, multi-line text, secrets, references to packages, choices from a dropdown.
- **Per-input validation** - required vs. optional, default values, help text, even sensitive-data marking.
- **Versioning** - bump the template version when you change behavior; projects opt in to the new version.
- **Permissions** - team members can use the template without seeing or editing its body.
- **Discoverability** - templates show up in the step picker with their description. New team members find them.

> **// The cost of skipping this - Twelve copies of the same script, slowly diverging.**
> 
> Teams that don't use step templates end up with the same script pasted into a dozen projects, each one slightly modified for a project-specific quirk. When a bug surfaces, the fix has to be replayed across all of them - and there is always one nobody knows about. A template makes that scenario impossible by construction.

## What you author once, what every project gets

The template defines inputs and a body. Projects pick the template, fill in the inputs, and get a validated step.

```
# Template: Deploy-WindowsService
#
# Inputs:
#   ServiceName       (string, required)
#   PackageName       (package reference, required)
#   StopTimeoutSec    (number, default 30)
#   RunAsUser         (string, optional, sensitive: true)
#
# Body (PowerShell):
param($ServiceName, $PackagePath, $StopTimeoutSec, $RunAsUser)

Stop-Service $ServiceName -Force -Timeout $StopTimeoutSec
Expand-Archive -Path $PackagePath -DestinationPath "C:\Services\$ServiceName" -Force
if ($RunAsUser) {
    sc.exe config $ServiceName obj= $RunAsUser
}
Start-Service $ServiceName
```

## Script modules: shared PowerShell functions

A script module is a regular PowerShell module the platform manages. You write functions, you publish the module, and any deployment step in any project can `Import-Module` it and call the functions.

The rule of thumb: if you have written the same five-line helper in three scripts, it belongs in a module.

## Things that live well in a script module

- **Auth helpers**: Functions that wrap acquiring tokens, signing requests, or rotating credentials so individual steps stay short.
- **Database helpers**: `Invoke-Migration`, `Wait-DatabaseReady`, `Backup-BeforeChange` - the small functions every team rewrites.
- **Notification utilities**: Post to Slack, send an email, page someone. One function. Called from many scripts.
- **Feature flags**: Read a flag from a config store and return a typed value. Done once, used everywhere.

> **// When to template vs. when to module - If it has a UI form, it's a template. If it's pure code, it's a module.**
> 
> A useful test: does the next person to use this need to fill out fields, or just call a function? If they need to think about inputs, give them a template with structured inputs. If they are writing a script and want to *not* rewrite a function, ship them a module.

## Versioning, ownership, and the politics of shared code

The usual trap with shared deployment code is the same as with any internal library: one team owns it, another team needs a feature, the owners are busy, the consumers fork it. A few practical decisions help.

## Lessons from teams that did this and lived

- **Pick owners.** Templates and modules need a maintainer. "Everyone" means "no-one".
- **Version on change.** Bump the template version whenever behavior changes. Don't silently mutate.
- **Deprecate, don't delete.** Keep old versions usable while consumers migrate.
- **Document inputs.** The help text on each template input is what the consumer sees. Treat it like API docs.
- **Treat shared code like product code.** It deserves PR review, tests, and a changelog.

## The pay-off, six months in

A team that has invested in a small set of well-named step templates and one or two reliable script modules ends up with deployment processes that read like sentences. The deployment process for a new service is mostly "select template, fill three fields, select template, fill two fields." The interesting custom code lives in modules where it is reused.

That is the long-term shape Jaws Deploy is built for - and it is the part that pays back the hours you spend setting it up in the first place.

