Gitlab automatically stops environment after merge

In our team we have multiple static environments. There is always dev and test and for certain customers where our infrastructure is allowed to deploy also staging and prod. We want to migrate our CI/CD Pipelines from Teamcity to Gitlab but something that was causing many troubles is how Gitlab behaves when we merge a MR which is able to be deployed onto a static environment. We’re not able to just deploy each MR on its own environment which was no problem with TeamCity as we could just deploy every branch onto every environment.

For the deployment itself we use Terraform although I have a testing repository which just echos a small text as a test.

Something which is especially confusing is that Gitlab stops an environment even though it was never deployed from the MR.

  • Something gets merged into develop
  • This commit is deployed onto e.g. test
  • A new branch is merged into develop
  • Gitlab stops the test environment even though it got never deployed to from the MR

Is this something that is just not possible with Gitlab as of now or have we missed a configuration option? Protected environments are not available for us but I also feel like this wouldn’t be the right option for the problem we’re facing.

The following is the pipeline of my test repository.

stages:
  - deploy
  - destroy-deployment

### Deployment
deployment-prod:
  extends: .deployment
  environment:
    on_stop: destroy-deployment-prod
    url: http://proto.url
    deployment_tier: production
  variables:
    ENVIRONMENT: prod
  rules:
    - if: $CI_COMMIT_TAG

destroy-deployment-prod:
  extends: .destroy-deployment
  variables:
    ENVIRONMENT: prod
  environment:
    url: http://proto.url
    deployment_tier: production
    action: stop
  rules:
    - if: $CI_COMMIT_TAG
      when: manual

### Deployment-Test

deployment-test:
  extends: .deployment
  environment:
    on_stop: destroy-deployment-test
    url: http://test.proto.url
    deployment_tier: testing
  variables:
    ENVIRONMENT: test
  when: manual

destroy-deployment-test:
  extends: .destroy-deployment
  variables:
    ENVIRONMENT: test
  environment:
    url: http://test.proto.url
    deployment_tier: testing
    action: stop

### Deployment-Staging

deployment-staging:
  extends: .deployment
  environment:
    on_stop: destroy-deployment-staging
    url: http://staging.proto.url
    deployment_tier: staging
  variables:
    ENVIRONMENT: staging
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'

destroy-deployment-staging:
  extends: .destroy-deployment
  variables:
    ENVIRONMENT: staging
    TF_VAR_host: staging.proto.url
  environment:
    url: http://staging.proto.url
    deployment_tier: staging
    action: stop
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: manual

### Deployment-Dev

deployment-dev:
  extends: .deployment
  environment:
    on_stop: destroy-deployment-dev
    url: http://dev.proto.url
    deployment_tier: development
  variables:
    ENVIRONMENT: dev
  rules:
    - if: '$CI_COMMIT_BRANCH == "develop"'

destroy-deployment-dev:
  extends: .destroy-deployment
  variables:
    ENVIRONMENT: dev
    TF_VAR_host: dev.proto.url
  environment:
    url: http://dev.proto.url
    deployment_tier: development
    action: stop
  rules:
    - if: '$CI_COMMIT_BRANCH == "develop"'
      when: manual

### Deployment Templates

.deployment:
  image: alpine
  stage: deploy
  script:
    - echo "Deploying $ENVIRONMENT"
  resource_group: proto-$ENVIRONMENT
  environment:
    name: $ENVIRONMENT
    url: http://$ENVIRONMENT.proto.url
  rules:
    - when: manual

.destroy-deployment:
  image: alpine
  stage: destroy-deployment
  script:
    - echo "Destroy $ENVIRONMENT"
  resource_group: proto-$ENVIRONMENT
  environment:
    name: $ENVIRONMENT
    url: http://$ENVIRONMENT.proto.url
    action: stop
  when: manual
  rules:
    - when: manual