Derived Developer Identity
A developer deployment names its instance from the Terraform workspace, chosen from an override, the CI branch, or the local username — never from a per-developer file.
- Kind
- Convention
- Domain
- Infrastructure & Runtime
- Applies at
workspaces/- Status
- Stable
- Source
scripts/deploy.sh
01 Defines
How a single committed workspace root yields one isolated instance per developer or branch: the deployer selects a Terraform workspace from standard context, and the root derives every name from terraform.workspace.
02 Applies when
- Several people or branches deploy their own copy of the same system from one root.
- Instances need separate state, resources, and hostnames without separate configuration.
- The same command runs both on a laptop and in CI.
03 Boundaries
- Applies to
workspaces/roots only; canonical roots underenv/own their state directly and take no identity from context. - Derived identity names the instance; it does not change what the instance is built from.
- Credentials are not derived this way; roots still use their committed provider profiles.
Expected behaviour
- 01The workspace name is the first of
DEPLOY_WORKSPACE,GITHUB_REF_NAME, andid -unthat is set. - 02The deployer runs
terraform workspace select -or-create, so a first deploy needs no setup step. - 03The root uses
terraform.workspacefor every name that has to be unique, such as the hostname and tags. - 04One committed backend key serves every instance; the S3 backend stores each workspace under
env:/<workspace>/<key>. - 05An instance is removed completely with
make deploy.destroy.
Behaviour#
Every developer needs their own copy, but nobody wants a directory per
developer. The convention resolves this by deriving identity from context that
already exists. Locally that is your username; in CI it is the branch name; when
you want more than one copy, it is whatever you set DEPLOY_WORKSPACE to.
The deployer turns that name into a Terraform workspace, and the root reads it
back as terraform.workspace. From there, one value flows into the state path,
the hostname, and the resource tags, so two instances can never collide.
- 01
Override
DEPLOY_WORKSPACEif set — for a second copy of your own - 02
Branch
Otherwise
GITHUB_REF_NAME, the branch name in CI - 03
User
Otherwise
id -un, your local username - 04
Select
terraform workspace select -or-create <name>inworkspaces/site - 05
Derive
State at
env:/<name>/<key>, hostnamesampletest-<name>.dev.prosyon.caWorkspaces
Why derive rather than configure#
Derived from convention
- One root, reviewed once, used by everyone
- A new developer deploys with no setup
- Branch instances appear without extra files
Per-developer configuration
- A directory or
.tfvarsfile per person - Copies drift and pick up private changes
- Local variable files tempt secrets into the tree
Canonical environments take the opposite position: nothing about them comes from context. See Parameterless Deployment .
Examples#
Only the workspace root selects a workspace; canonical roots skip this step:
# workspaces/site deploys one instance per developer or branch, each with its own
# state and hostname. The canonical environments own their state directly.
if [ "$root" = workspaces/site ]; then
terraform -chdir="$root" workspace select -or-create \
"${DEPLOY_WORKSPACE:-${GITHUB_REF_NAME:-$(id -un)}}"
fi
One backend key is enough, because the S3 backend separates workspaces itself:
# One backend, one state object per Terraform workspace: the S3 backend stores
# non-default workspaces under env:/<workspace>/<key>.
terraform {
backend "s3" {
bucket = "org-terraform-state-220087710539"
region = "us-west-2"
key = "static-website/workspaces/site/terraform.tfstate"
encrypt = true
use_lockfile = true
}
}
make deploy # instance named after you
DEPLOY_WORKSPACE=experiment make deploy # a second, separate instance
Connections