Chapter 19Lesson 01~155 minutes

Environments, Deployments, Environment Tiers, URLs, Deployment History, and Operational Traceability: Concepts, Architecture, and Mental Model

Separate job success, GitLab deployment records, and actual target health while tracking environment identity, deployment tier, URL, artifact digest, history, and rollback evidence.

EnvironmentsDeploymentsTiersURLsTraceability

Learning objectives

  • Explain why a successful deployment job, a successful GitLab deployment record, and a healthy external target are three different states.
  • Trace a verified artifact through deployment job, environment name/tier/URL, GitLab deployment record, target-state change, independent health verification, and rollback reference.
  • Distinguish static environment identity from a deployment instance and from a URL that merely points at an intended target.
  • Explain current environment actions and which actions create deployment records versus only prepare, verify, access, or stop an environment.
  • Use artifact digest, source SHA, pipeline/job/deployment identity, and target read-back as the minimum operational traceability chain.

1. The practical problem: “deploy job passed” is not the same as “service is healthy”

Chapter 18 controlled competing side effects with source-aware pipeline suppression, safe interruption, resource serialization, bounded retries, and reconciliation. Chapter 19 adds the missing operational identity: what environment did we intend to change, which exact artifact did we place there, what did GitLab record, and what does the target actually report now?

A deployment job can exit zero after copying files to the wrong directory. GitLab can record a successful deployment whose URL points at an old target. A target can become unhealthy minutes after a correct deployment because of an external dependency. These are different states and must have different evidence.

Chapter invariant: do not infer external health from job status or deployment status. Tie every intended change to source SHA + immutable-ish artifact digest + environment identity + deployment record + target read-back.

2. Mental model: verified bytes become an operationally traceable change

Read this model left to right. The verified artifact is evidence from the build layer. A deployment job consumes those exact bytes and declares an environment. GitLab creates a deployment record for a start action. The script changes some external target. A separate health/read-back check proves whether the external state matches the intended artifact. Deployment history then gives you a rollback reference, but the rollback is only reproducible if the original bytes are still available.

Deployment traceability flow
            flowchart TD
             A[Verified artifact + SHA + digest] --> B[Deployment job]
             B --> C[Environment name / tier / URL]
             C --> D[GitLab deployment record]
             B --> E[External target change]
             E --> F[Independent health / read-back]
             D --> G[History + rollback reference]
             F --> G
          

The arrows matter: GitLab can know that a deployment job succeeded without knowing that your custom external service is healthy. Your pipeline must create the missing evidence explicitly.

3. Keep seven state domains separate before changing anything

State domain Examples to record Why it is separate
Source/revision CI_PIPELINE_SOURCE, ref, CI_COMMIT_SHA Defines the repository state that initiated the pipeline.
Compiled configuration environment name/tier/URL/action, rules, needs Defines what GitLab decided the job should represent.
Job/runner pipeline ID, job ID, runner/executor/image Proves who executed the deployment script and when.
Artifact producer job, path, SHA-256 digest, retention Defines the exact bytes intended for promotion.
Environment environment ID/name/state/tier/URL Long-lived GitLab identity for a target, not a single deployment.
Deployment deployment ID/status/actor/SHA/ref/job One recorded deployment event in environment history.
External target host/path/resource ID, observed digest, health result The real/simulated state GitLab cannot infer from job success.

4. Smallest useful environment declaration

A job becomes a deployment job when it declares an environment with the default start action. Use a stable environment name for one logical target; changing spelling creates a different GitLab environment and splits history.

deploy:training:
  stage: deploy
  image: alpine:3.22
  script:
    - ./ci/deploy-simulated-target.sh dist/app.txt
  environment:
    name: training/ch19
    deployment_tier: testing
    url: https://training.invalid/ch19

The URL is metadata and a navigation link; it is not a health check. The reserved .invalid domain keeps the course from accidentally pointing at a real service.

5. Environment identity versus deployment identity

An environment is the stable GitLab representation of a target such as staging, production, or training/ch19. A deployment is one event recorded against that environment. Repeated successful deploy jobs create a history under the same environment name.

Question Environment answers Deployment answers
Identity Where is software intended to run? Which deployment event changed it?
Examples name, tier, URL, state ID/IID, status, actor, SHA/ref, deployable job
Lifetime Can outlive many pipelines One event in history
Failure mode Wrong name fragments history Wrong SHA/digest destroys provenance

6. Environment states and deployment tiers are metadata, not health

Current environment lifecycle states include available, stopping, and stopped. A stopped environment is a GitLab lifecycle state; it does not by itself prove that every external resource was deleted.

Current deployment tiers are production, staging, testing, development, and other. GitLab can infer a tier from common names, but explicit deployment_tier removes ambiguity—especially when teams use business names such as customer-portal.

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

7. environment:action changes what GitLab records

Do not attach a deployment record to every job that merely touches an environment. GitLab distinguishes deployment and lifecycle/access intents:

Action Deployment record? Use
start (default) Yes Deploy/change the environment.
prepare No ordinary deployment Prepare environment state before deployment.
verify No ordinary deployment Verify health/state without pretending another deployment occurred.
access No ordinary deployment Access environment-scoped context without deployment semantics.
stop Stops environment Run teardown/stop workflow.

This is why Chapter 19 uses a separate verify job after deployment: a health check should not manufacture another deployment event.

8. Artifact identity is the bridge from CI evidence to CD evidence

A commit SHA names source, not necessarily the exact deployable bytes. Compilers, generated assets, dependency resolution, build flags, and toolchains can make two rebuilds of the same source differ. Record a digest when the artifact is created, verify it when consumed, and carry that digest into the deployment receipt.

sha256sum dist/app.txt | tee dist/app.sha256
# Later, before deployment:
sha256sum -c dist/app.sha256

For larger systems, the equivalent identity may be a container image digest, package checksum, signed provenance statement, or registry/package version whose immutability policy is independently enforced.

9. An environment URL is not target-health evidence

environment:url makes navigation convenient. It tells GitLab where an operator should look; it does not prove that DNS resolves, TLS is valid, the application serves the expected version, dependencies are healthy, or the artifact digest matches the deployment record.

Use an independent verification step that reads version/digest/health from the target and compares it with intended evidence. In this chapter’s Free path, a filesystem snapshot stands in for an external target and the verification job checks its recorded digest.

10. Rollback is a deployment decision, not a magical byte-for-byte restore

GitLab can retry or roll back deployments by running deployment jobs associated with older commits. That creates a new deployment event. The deployment script still determines what happens. If the old deploy job requires upstream artifacts that expired—or rebuilds them—your “rollback” can produce different bytes.

Safer pattern: build once, retain/promote the exact artifact or image digest, and make deploy/rollback consume that identity. A rollback target is source SHA + artifact digest + deployment record + target verification, not merely “the old commit.”

11. Read-only inspection before any deployment change

Before changing a deployment pipeline, capture safe identity metadata rather than dumping the whole environment:

printf 'source=%s ref=%s sha=%s pipeline=%s job=%s
'   "$CI_PIPELINE_SOURCE" "$CI_COMMIT_REF_NAME" "$CI_COMMIT_SHA"   "$CI_PIPELINE_ID" "$CI_JOB_ID"
printf 'env=%s env_id=%s env_url=%s
'   "${CI_ENVIRONMENT_NAME:-not-a-deploy-job}"   "${CI_ENVIRONMENT_ID:-not-set}"   "${CI_ENVIRONMENT_URL:-not-set}"

Then inspect Operate → Environments and the deployment history. If API access is authorized, a read-only GET /projects/:id/deployments can provide deployment IDs/status/SHA/ref/environment. Do not print access tokens into traces.

12. Common wrong mental models

  • “Green deploy job means production is healthy.” It only proves the script exited successfully.
  • “The environment URL is a health monitor.” It is metadata/navigation.
  • “A new environment name is harmless.” It creates a separate identity/history and can break scoped controls.
  • “Rollback to an old commit means the old bytes return.” Not if the deployment job rebuilds or artifacts expired.
  • “Stopped in GitLab proves external deletion.” Teardown must be independently verified.

13. Chapter trajectory

Lesson 2 builds and deploys a synthetic artifact once, then verifies the simulated target separately. Lesson 3 chooses naming, tiers, actions, scoping, promotion, and rollback policy. Lesson 4 diagnoses misleading green states and broken provenance. Lesson 5 produces two traceable deployments and a rollback dossier that bridges naturally into Chapter 20’s dynamic review environments.

Knowledge check

What are the three states this chapter refuses to collapse?

Does environment:url prove that the service is healthy?

Which environment action creates the ordinary deployment record?

Why record an artifact digest in addition to CI_COMMIT_SHA?

Why can rollback-by-rebuild be unsafe?

Next lesson

Guided hands-on workflow and core operations

Build once, deploy a synthetic artifact to one stable training environment, inspect deployment history, update once, and verify target state independently.

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.