'How to set a dynamic gitlab job tag with a variable?

I am trying to create a dynamic job that can switch between two gitlab runners depending on which tag it is given. I would like to do this with an environmental variable, but it seems this cannot be used. The following job:

runner_test:
  image: alpine
  tags:
    - $MY_RUNNER
  stage: deploy_main
  script:
    - echo foobar
  retry: 2

Results in a paused pipeline with the error: This job is stuck because you don't have any active runners online or available with any of these tags assigned to them: $MY_RUNNER



Solution 1:[1]

Dynamic job tags is achievable now (tested on 14.10). Variable interpolation works for job tags, and one way you can dynamically modify CI Variables is with the rules:variables key.

The following example would result in a default job tag of "staging" for most branches, and an override value of "production" for pipelines running against the project's default branch.

job:
  variables:
    RUNNER_TAG: staging           # default CI variable value
  rules:
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
      variables:
        RUNNER_TAG: production    # override CI variable value when the if: check is true
  tags:
    - $RUNNER_TAG                 # use the dynamic CI variable as a job tag
  script:
    - hello world from runner matching $RUNNER_TAG

Solution 2:[2]

Since this is not possible on older versions of Gitlab, as a work around for those on older verisons of Gitlab, to extend on the answer given by Rekovni, if you're looking to run environment specific runners:

.Deploy_template:
  stage: Deploy
  image:
    name: busybox/busybox:latest
    entrypoint: [""]
  rules:
    - when: manual
  before_script:
    - echo "Preflight tests"
  script:
    - echo "Start Deployment"
  after_script:
    - echo "Postflight tests"
  allow_failure: false


Deploy_feature:
  extends: .Deploy_template
  tags:
    - docker
    - feature
  rules:
    - if: $BRANCH =~ /feature/

Deploy_develop:
  extends: .Deploy_template
  tags:
    - docker
    - develop
  rules:
    - if: $BRANCH =~ /develop/

Deploy_stable:
  extends: .Deploy_template
  tags:
    - docker
    - stable
  rules:
    - if: $BRANCH =~ /stable/

Then you just repeat this for every job you have.

Solution 3:[3]

So if I have control of the repo branching structure, I make the CI branch names match the tags (e.g. dev, test, preprod, prod, etc). Then I can do something like this. However, this solution is not very portable for cases where you need to map the branch name to some other tag.

tags:
  - ${CI_COMMIT_BRANCH}

I really don't like the template, extends paradigm. It makes so much extra code. There must be a better way. There is this feature which is almost there. However, I cannot figure out how to make the source variable dynamically derived from another variable. Maybe it meets some people's use cases.

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 ashtonium
Solution 2 doublespaces
Solution 3 dirtAndCoffee