> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Staging Environment and Canaray Deployment with AutoDevOps part 2

> This article covers staging environments and canary deployments using Auto DevOps, including manual approvals and incremental rollout strategies.

In the previous lesson, we enabled a new Auto DevOps deployment strategy, pushed changes to a feature branch, and reviewed the Merge Request (including security and performance reports). Now we'll merge into `main` and watch Auto DevOps deploy to production using an incremental canary strategy.

## 1. Merge into `main` and Trigger Production Pipeline

Once the Merge Request is accepted, GitLab triggers a new pipeline on the protected `main` branch. This pipeline adds deployment stages on top of the build, test, DAST and performance jobs.

<Frame>
  ![The image shows a GitLab pipeline interface for a project named "testing autodevops canary release," displaying various stages like build, test, review, dast, and performance, all marked as passed.](https://kodekloud.com/kk-media/image/upload/v1752877152/notes-assets/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines-Staging-Environment-and-Canaray-Deployment-with-AutoDevOps-part-2/gitlab-pipeline-testing-autodevops.jpg)
</Frame>

<Frame>
  ![The image shows a GitLab pipeline interface with stages for deployment, including dast, staging, production rollout, performance, and cleanup. The pipeline is currently running a merge from a feature branch into the main branch.](https://kodekloud.com/kk-media/image/upload/v1752877153/notes-assets/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines-Staging-Environment-and-Canaray-Deployment-with-AutoDevOps-part-2/gitlab-pipeline-deployment-stages.jpg)
</Frame>

The full sequence is:

1. build
2. test
3. review (DAST)
4. staging
5. production rollout (10%, 25%, 50%, 100%)
6. performance
7. cleanup

### Cancelling Unneeded Jobs

If you need to skip rerunning certain tests, you can:

* Manually cancel jobs in the GitLab UI
* Disable specific jobs via **Settings > CI/CD**

For this walkthrough, we’ll focus on the staging and manual production rollout stages.

## 2. Staging Deployment

After build, test, and DAST succeed, the `staging` job deploys to the `staging` namespace and then waits for the production approval.

```bash theme={null}
# Check staging resources
kubectl -n staging get all
```

```bash theme={null}
NAME                                 READY   STATUS    RESTARTS   AGE
pod/staging-6548cd9479-tqpgp         1/1     Running   0          2m
service/staging-auto-deploy          10.98.41.96   <none>   3000/TCP   2m
deployment.apps/staging              1/1     1         1          2m
replicaset.apps/staging-6548cd9479   1       1         1          2m
```

You can also verify the deployment under **Operations > Environments**:

<Frame>
  ![The image shows a GitLab interface displaying the "Environments" section with active environments like "production," "review/feature/adsa," and "staging." It highlights a successful deployment in the "staging" environment with options to open the live environment.](https://kodekloud.com/kk-media/image/upload/v1752877155/notes-assets/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines-Staging-Environment-and-Canaray-Deployment-with-AutoDevOps-part-2/gitlab-environments-staging-deployment.jpg)
</Frame>

Opening the live URL confirms the staging app UI:

<Frame>
  ![The image shows a stylized representation of the solar system with planets orbiting the sun, accompanied by a user interface for searching planets.](https://kodekloud.com/kk-media/image/upload/v1752877155/notes-assets/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines-Staging-Environment-and-Canaray-Deployment-with-AutoDevOps-part-2/solar-system-planets-ui-representation.jpg)
</Frame>

<Callout icon="lightbulb" color="#1CB2FE">
  By default, Auto DevOps deploys to staging before production. To skip staging and deploy directly to production, set the CI/CD variable:

  ```yaml theme={null}
  STAGING_ENABLED: "false"
  ```
</Callout>

## 3. Manual Production Deployment

Production is a protected environment requiring manual approval. Before rolling out, inspect current production workloads:

```bash theme={null}
kubectl -n production get all
```

```bash theme={null}
NAME                              READY   STATUS    RESTARTS   AGE
pod/production-df6dd64cf-xxxxx    10/10   Running   0          4h32m
service/production-auto-deploy    10.104.1.52   <none>   3000/TCP   4h32m
deployment.apps/production        10/10   10        10         4h32m
replicaset.apps/production-df6dd6 10      10        10         4h32m
```

Navigate to **Operations > Environments > production** and click **Approve** on the pending rollout:

<Frame>
  ![The image shows a GitLab interface with a pop-up window for approving or rejecting a deployment. It includes details about the environment, deployment tier, and manual job, with options to add comments and approve or reject the deployment.](https://kodekloud.com/kk-media/image/upload/v1752877156/notes-assets/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines-Staging-Environment-and-Canaray-Deployment-with-AutoDevOps-part-2/gitlab-deployment-approval-popup.jpg)
</Frame>

Once approved, click **Run job** on the next percentage rollout:

<Frame>
  ![The image shows a GitLab interface for a job that requires manual action to start a deployment to production. It includes options to input CI/CD variables and a "Run job" button.](https://kodekloud.com/kk-media/image/upload/v1752877157/notes-assets/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines-Staging-Environment-and-Canaray-Deployment-with-AutoDevOps-part-2/gitlab-manual-deployment-job-interface.jpg)
</Frame>

## 4. Canary Rollouts

Use incremental percentages to minimize risk. Below is a summary of each stage:

| Rollout Stage | Percentage | Verification Command                                 |
| ------------- | ---------- | ---------------------------------------------------- |
| Canary        | 10%        | `kubectl -n production get pods`                     |
| Midway        | 50%        | `kubectl -n production get svc`                      |
| Full Release  | 100%       | `kubectl -n production get pods` (only primary pods) |

### 4.1 10% Canary

The job log runs:

```bash theme={null}
$ auto-deploy use_kube_context
$ auto-deploy ensure_namespace
$ auto-deploy create_secret
$ auto-deploy deploy canary $ROLLOUT_PERCENTAGE
# ...
Job succeeded
```

Verify both primary and canary pods:

```bash theme={null}
kubectl -n production get pods
```

```bash theme={null}
NAME                                   READY   STATUS    AGE
production-canary-9d4475cdc-xxxxx      10/10   Running   2m
production-df6dd64cf-xxxxx             10/10   Running   4h32m
```

Check the canary Ingress weight:

```bash theme={null}
kubectl -n production get ing production-canary-auto-deploy -o yaml
```

```yaml theme={null}
annotations:
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-weight: "10"
```

Run load tests to confirm \~10% traffic hits the canary pods:

```bash theme={null}
while true; do \
  curl -sk https://demos-group-solar-system-autodevops.139.84.208.48.nip.io/os \
    | grep --color -E 'production-canary'; \
done
```

### 4.2 50% Midway

Approve and **Run job** for 50% rollout. After success, the weight updates:

```yaml theme={null}
nginx.ingress.kubernetes.io/canary-weight: "50"
```

Validate with a repeat of the traffic test:

```bash theme={null}
while true; do \
  curl -sk https://demos-group-solar-system-autodevops.139.84.208.48.nip.io/os \
    | grep --color -E 'production-canary'; \
done
```

<Frame>
  ![The image shows a GitLab interface displaying a list of production deployments with their statuses, IDs, commit details, and actions. The sidebar includes options for managing code, deployments, and environments.](https://kodekloud.com/kk-media/image/upload/v1752877159/notes-assets/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines-Staging-Environment-and-Canaray-Deployment-with-AutoDevOps-part-2/gitlab-production-deployments-interface.jpg)
</Frame>

### 4.3 100% Full Release

Approve and **Run job** for 100% rollout to merge canary into the primary deployment and remove the canary service:

<Frame>
  ![The image shows a GitLab pipeline interface for merging a branch into the main branch, displaying various stages like review, dast, staging, production, and performance, with progress indicators.](https://kodekloud.com/kk-media/image/upload/v1752877160/notes-assets/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines-Staging-Environment-and-Canaray-Deployment-with-AutoDevOps-part-2/gitlab-pipeline-merge-branch-interface.jpg)
</Frame>

After completion, verify only the updated primary pods remain:

```bash theme={null}
kubectl -n production get pods
```

```bash theme={null}
NAME                              READY   STATUS    AGE
production-84c4bd9684-xxxxx       10/10   Running   16h
```

Cleanup runs automatically:

```bash theme={null}
auto-deploy delete canary    # Removes the canary release
auto-deploy persist_environment_url
# Job succeeded
```

***

## What You Learned

* How Auto DevOps orchestrates staging and production deployments
* Manual approval workflows for protected environments
* Incremental canary rollouts (10%, 50%, 100%) with traffic validation
* Automatic cleanup of canary resources

## Links and References

* [GitLab Auto DevOps](https://docs.gitlab.com/ee/topics/autodevops/)
* [GitLab CI/CD Pipelines](https://docs.gitlab.com/ee/ci/pipelines/)
* [Canary Deployments with Kubernetes](https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#canary-deployments)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/gitlab-ci-cd-architecting-deploying-and-optimizing-pipelines/module/a6a5540f-e7d1-4820-afc8-2be1d6e3061a/lesson/295df1e8-3b85-4ec3-9707-b5fabfd58df9" />
</CardGroup>
