'GitLab: Dynamically set tags for stage based on previous stages

Is it possible to set tags dynamically, based on results from previous stages?

We have an environment where DEMO/LIVE environments is mapped dynamically to one of two datacenters A/B. The mapping changes frequently. We want to use runners, tagged A and B respectively, and when running deploy_demo stage we want to dynamically choose A or B based on current system setup.

I managed to create a stage which determines which environment should be used A or B and exported this to environment variable. This variable however cannot be used in the 'tags'...

How to dynamically set the 'tags' so that correct runner will be chosen?

stages:
  - configure_demo_live
  - deploy_demo

configure_demo_live:
    stage: configure_demo_live
    tags:
      - dev
      - k8s
    image: alpine/helm:3.4.2
    script:
    - echo "SEL_DEMO=A" >> config.env
    artifacts:
      reports:
        dotenv: config.env

deploy_demo:
  image: alpine/helm:3.4.2
  script:
    - echo "Dummy work"
  stage: deploy_demo
  dependencies:
    - configure_demo_live
  environment:
    name: demo
  tags:
    - $SEL_DEMO
    - k8s


Solution 1:[1]

Another approach would be to change the tags of the runner that is supposed to run

Suppose you have figured that the environment lives in datacenter A, therefore you should use runner A

In configure_demo_live job make a request to the Gitlab API https://docs.gitlab.com/ee/api/runners.html#update-runners-details

In order to add the tag demo to the appropriate runner

curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/runners/<runner_id>" --form "tag_list=demo,k8s"

Now the runner A has the demo tag.

Now configure your gitlab-ci.yml

deploy_demo:
  image: alpine/helm:3.4.2
  script:
    - echo "Dummy work"
  stage: deploy_demo
  dependencies:
    - configure_demo_live
  environment:
    name: demo
  tags:
    - demo
    - k8s

deploy_prod:
  image: alpine/helm:3.4.2
  script:
    - echo "Dummy work"
  stage: deploy_prod
  dependencies:
    - configure_demo_live
  environment:
    name: prod
  tags:
    - prod
    - k8s

With this architecture you have two jobs one for prod and one for demo. One executes to runner with tag prod, the other to runner with tag demo. But only one of this will be true, according to the results of configure_demo_live job. Since it will update the tags of the appropriate runner.

Make sure to add an after_script to reset the tags of the runner A in this example

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1