Chapter 19Lesson 03~155 minutes

Environments, Deployments, Environment Tiers, URLs, Deployment History, and Operational Traceability: Configuration, Design Choices, and Tradeoffs

Choose environment naming, tiers, actions, URL semantics, environment-scoped variables, artifact promotion, retention, and rollback strategy from operational evidence requirements.

Design tradeoffsEnvironment scopeActionsPromotionRollback

Learning objectives

  • Choose static versus dynamic environment naming and one-environment-per-tier versus service-specific environments.
  • Treat GitLab environment URL/history as metadata and prove real target health independently.
  • Choose build-once artifact promotion over rebuild-at-deploy when byte identity and rollback reproducibility matter.
  • Use environment-scoped variables narrowly while avoiding them as pipeline-compilation inputs in rules/includes.
  • Choose start/prepare/verify/access/stop actions and auto-stop behavior according to deployment-record and lifecycle intent.

1. Design starts with the target identity and evidence contract

Once a team can create an environment, the hard questions are architectural: should production be one environment or one per service? Should feature branches create dynamic environments? Should a verification job create deployment history? Where should an artifact live so rollback does not rebuild it? Which variables should be scoped to which environment?

The answer should follow the operational object you need to control and audit, not a preference for shorter YAML.

2. Static versus dynamic environments

Choice Strengths Risks / evidence cost Typical fit
Static: staging, production Stable history, predictable scoping, simple URLs Can be too coarse for multiple independent services Long-lived shared targets
Dynamic: review/$CI_COMMIT_REF_SLUG Per-change isolation, reviewability Cardinality, cleanup, URL/slug collisions, cost Ephemeral review/test stacks

Chapter 20 is dedicated to dynamic review environments. Chapter 19 keeps the mandatory path static so environment history is easy to reason about.

3. One environment per tier versus per service

Environment granularity should match rollback and authorization granularity. If five services deploy independently, one production environment can blur which service changed and complicate protected-environment permissions. Names such as production/payments and production/catalog can preserve separate history while both use deployment_tier: production.

Question Single tier environment Service-specific environment
Deployment history All changes mixed Per-service history
Rollback target Potentially ambiguous Clearer per service
Environment-scoped variables Coarser scope Narrower scope
Operational dashboard Simple count More objects to govern

4. Name and deployment tier solve different problems

The name is the environment identity; the tier classifies its operational role. GitLab can guess tiers from common names, but explicit deployment_tier is safer for unconventional names.

deploy:portal:
  environment:
    name: customer-portal
    deployment_tier: production
    url: https://portal.example.com

Current GitLab supports CI/CD variables in deployment_tier starting with GitLab 18.5, but use a small, validated set of tier values; do not turn tier classification into arbitrary user input.

5. Use actions to preserve semantic deployment history

Intent Action Creates deployment? Auto-stop effect to consider
Apply a new version start Yes Deploying can reset lifetime when configured.
Prepare target prepare No ordinary deployment Can reset scheduled stop based on latest successful deployment.
Read/verify health verify No ordinary deployment Does not reset scheduled stop in the same way as access/prepare.
Access target context access No ordinary deployment Can reset scheduled stop.
Teardown stop Stops environment No auto_stop_in on stop action.

Using start for a health check pollutes history with “deployments” that did not deploy anything. Using verify preserves the meaning of the deployment timeline.

6. auto_stop_in is lifecycle scheduling, not deletion proof

auto_stop_in accepts natural-language durations such as 1 day or never. GitLab’s background worker detects expired environments periodically, so the stop is not an exact real-time SLA.

A stop action can run teardown logic, but the environment becoming stopped still does not prove that a cloud resource, DNS record, namespace, or database was deleted. Chapter 20 will require explicit cleanup proof for ephemeral stacks.

7. GitLab URL/record versus actual service health

Choose URL semantics that help humans navigate, but define a separate health contract: expected artifact/image digest, version endpoint, provider resource ID, minimum dependency health, or another read-back appropriate to the target.

Signal What it proves What it does not prove
Deployment job success Script exited successfully Target serves intended version
GitLab deployment success GitLab recorded a successful deployable Provider accepted/settled all external changes
Environment URL Navigation destination Reachability or version identity
Target health/read-back Observed external state How GitLab configuration was compiled
Artifact digest match Byte identity Runtime dependency health

8. Rebuild versus artifact promotion

For high-assurance delivery, treat build output as a versioned input to deployment. Rebuilding in each environment breaks the chain from test evidence to production bytes.

Preferred lineage:
source SHA -> build job -> artifact/image digest -> test evidence -> staging deployment -> production deployment -> rollback reference

Risky lineage:
source SHA -> test build A -> rebuild for staging B -> rebuild for production C

When artifact retention in job storage is too short for release/rollback requirements, promote the artifact into an appropriate package/container registry with an immutable version/digest policy. Do not misuse cache as deployment evidence.

9. Environment-scoped variables narrow exposure, but are not rule inputs

Project variables can be scoped to a specific environment or wildcard. This is useful for narrowing deployment configuration or credentials. It does not replace a secrets manager, protected refs, or deployment authorization.

GitLab explicitly warns against using environment-scoped variables with rules or include: those decisions can be evaluated before the environment scope is known. Keep pipeline creation decisions based on pre-pipeline/pipeline data, then use the scoped value only inside the eligible environment job.

10. Rollback design: preserve deployable identity before you need it

GitLab rollback creates a new deployment pointing at the older commit and reruns deployment logic. Design the deployment job so it can retrieve or consume the exact historical payload by digest/version. If the job needs expired artifacts or performs a fresh build, the rollback contract is weak.

Record at least: original source SHA, artifact/image digest, deployment ID, environment ID/name, provider target ID, health evidence, and retention/location of the rollback payload.

11. Worked decision table

Scenario Recommended design Prerequisite/tier Observable proof
Long-lived staging and production Stable names + explicit tiers + build-once artifact promotion Free core features Single coherent history per target and digest continuity
Health polling after deploy Same environment + action: verify Free No extra ordinary deployment record; health evidence tied to deployment
Feature preview Dynamic review/* + stop/auto-stop Free core pattern; infra cost varies Environment slug/URL/resource IDs + cleanup proof
Sensitive production approval Protected environment / approvals as available Tier/role dependent Authorization/approval evidence plus deployment record
Rollback months later Registry/package retention by immutable digest Registry/storage policy dependent Old digest is still retrievable and matches prior record

12. Design checklist

  • Name the operational target consistently.
  • Set the deployment tier explicitly when the name is nonstandard.
  • Use start only for actual deployment changes.
  • Keep URL metadata separate from health evidence.
  • Build once and promote exact bytes/digests.
  • Scope variables to the environment only when appropriate; do not rely on them for rules/include.
  • Design rollback retention before production needs it.
  • Record CI_PIPELINE_SOURCE, CI_COMMIT_SHA, job/deployment IDs, digest, and target read-back.

Knowledge check

Why can customer-portal still have deployment_tier: production?

Why use action: verify for a health-check job?

What is the main rollback advantage of build-once promotion?

Why should environment-scoped variables not drive rules/includes?

Does auto_stop_in prove cloud resources were deleted?

Next lesson

Diagnostics, failure modes, security, and performance

Diagnose green deployment jobs with unhealthy targets, split history, lost artifact identity, stale URLs, and rollback rebuilds without erasing evidence.

Version and compatibility note

GitLab and GitLab Runner evolve continuously. Treat version-sensitive YAML, runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations as assumptions to verify against the current official GitLab documentation before production use. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for any reproducible lab or incident record.

Official references and version notes

Documentation verification date: 2026-09-12. Environment/deployment keywords, environment actions, deployment-tier variable support, auto-stop behavior, rollback UI behavior, environment-scoped variables, and deployment safety are version-sensitive. Re-check the GitLab and Runner versions used by production delivery before applying the exact examples.

  • Environments — environment identity/state, tiers, URLs, stop/auto-stop behavior, environment-scoped variables, and operational views.
  • Deployments — deployment history, deployment refs, retry/rollback behavior, and auditability.
  • Deployment safety — deployment serialization, outdated-job prevention, protected environments, and rollback considerations.
  • CI/CD YAML syntax reference — environment, environment:name, url, action, auto_stop_in, deployment_tier, and related job semantics.
  • Deployments API — deployment IDs, statuses, SHA/ref, user, environment, and history queries.
  • Environments API — environment metadata/state/tier management when API access is appropriate.
  • CI/CD variables — environment scope behavior and precedence boundaries.

Current assumptions used in this chapter: environments and deployment history are available on Free, Premium, and Ultimate across GitLab.com, Self-Managed, and Dedicated. Environment states include available, stopping, and stopped. environment:action currently supports start (default, creates a deployment after job start), prepare, verify, access, and stop; the latter four model lifecycle/access work rather than ordinary deployment creation. Deployment tiers are production, staging, testing, development, and other; CI/CD-variable support for deployment_tier was added in GitLab 18.5. auto_stop_in uses natural-language durations; stop processing is background work and is not an exact real-time timer. The mandatory labs use synthetic artifacts, a stable training/ch19 environment, alpine:3.22, a reserved .invalid URL, and filesystem/artifact snapshots as a faithful target simulation—no cloud account, protected production environment, or real credential is required.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.