Developers and Ops should be able to specify different values for secret (and not-so-secret) variables, and tie them to environments. For example, doing a deploy to Heroku might need an app name, which you could specify by $HEROKU_APP_NAME, but that name would be different in staging and production.
Proposal
Add a scope to variables so that you could say var A applies to environment B.
Support wildcards, so you could say that some deploy variable applies to review/* and all review apps would get the variable automatically.
Default scope is *.
If multiple scopes apply to an environment, more specific scopes should have priority over less-specific scopes. e.g. review/foo should have priority over review/*, which itself should have priority over *. This can allow someone to specify a default variable for all environments, but override the production one, for example.
Links
gitlab-ce#17986
gitlab-ce#17633
Documentation blurb
Project variables are often the right solution to define values that are then used during deployments to specific environments. Since different environments (e.g.: staging and production) may require different values for the same task, such as the app name, it is important to create a direct binding between some variables and the related environment.
Scope variables are introduced to solve this issue, letting developers to define environments they will be applied to, even with wildcards like review/*. It is now easy to deploy to different environments with a minimal effort!
As discussed yesterday with @sytses, we need something like this to make sure that developers pushing to side branches are unable to deploy to production.
We now have a security problem.
Our use case:
Developers push to side branches
Developers make a Merge request to master
When code is reviewed and tested, the Merge request is merged
The code is deployed using Gitlab CI and Secret Variables the developers can not view or edit:
.gitlab-ci.yml has a deployment Job with
only: - master
However, the developer could change .gitlab-ci.yml
only: - name-of-sidebranch
Since Secret Variables are available on all side branches, this will deploy the application.
When I was exploring "environments" today, this feature was the first thing I was expecting there. Without it I don't really see use of the environments.
The second thing I was expecting was to use .gitlab-ci.yml only as a template and then each environment would be instance of such template, a new job to run.
Example: I have an application running on staging server and multiple production servers, each for another customer. It does not make sense to create and commit a job in .gitlab-ci.yml for each customer. Each production installation has a SSH key and URL where to deploy, but otherwise the deploy is always the same. So when creating installation to a new customer, I would expect to define a new environment, specify secret variable with ssh key, not-so-secret variable with deploy destination and a task which implements the deploy using environment-specific variables. Then Gitlab CI would kick in and install new version to production server every time the specified branch is updated. Which branch it is should be specified in the environment configuration (customer may have dedicated branch).
Environment-specific variables should take https://gitlab.com/gitlab-org/gitlab-ce/issues/21971#convention-over-configuration into account. One option is to add a scope to variables so that you could say var A applies to environment B. But by including wildcards, you could say that some deploy variable applies to review/* and all review apps would get the variable automatically.
I'm not sure whether gitlab-ce#21770 is worth considering in this (perhaps a consolidated approach?), it discusses global/per-person variables, which might relate to your scope comment.
I think this would probably cover our environment use cases and would probably take care of per-user/global CI variables:
Production
Stage
QA
Single Developer branch/environment + multiple developer branches/environments (idea here is that developers push a branch for a feature and an environment get spun up for them for that feature)
I think this should also have permissions attached to those environment level permissions so that at least production/master environment variables can be heavily locked down.
We're currently looking at moving from Jenkins CI -> GitLab Ci for our primary test suite. A feature we use a lot of in the Jenkins world is the ability for each of the jenkins build projects to environment variables defined in isolation of other other projects. This means that our developers can add flags to their test builds and we have separate master builds based on different configurations of flags. It's important to note that we currently depend on being able to run builds against the same branch with different environment variables.
Is this something that is likely to be addressed? Is it part of this issue? Should I raise another issue? I'm also willing to try and contribute towards its development, as I'd love to get us off of jenkins.
Will this issue be addressed soon?
It's hard for me to estimate, but if the complexity of this feature is not too high i'd be glad to try and contribute.
I'd gladly welcome the feature since I have many variables tied to environment.
For instance, I need to define each build script for each environment while they're doing the same thing, only because they use
different variables values:
I could use this for deploying to rancher. Each rancher environment requires a different access-key/secret-key. And it knows which environment you are interacting with based on the access key. So being able to set this on the environment would be a huge improvement.
Concerning myself, this is the missing piece preventing me to use Gitlab as a complete CI/CD workflow. I think Secret Management per environment should be reprioritize and integrated to Gitlab Product.
Current thinking is to use a single list for variables, but add a field for which environment(s) the variables should be available in, and this field would support wildcards.
If we implement gitlab-ce#24196 in GitLab CE, we'll have basic variable protection for all. We could then consider making this issue EE only as it's a somewhat more advanced requirement.
Is it possible that something in regard to this was already deployed? I'm using secret env vars in the CI and my 'only: master' job works, while my 'only: prod' doesn't. Seems like my env variables are only available in master.
@markpundsack I'm a solo dev working on a tiny side project, but this feature feels pretty important to me. My guess is that not having access to this feature in CE would be bummer for a lot of weekend warriors like myself who want to use GitLab CI to manage their deployment process.
In my view, large organizations are actually less likely to need this feature than we small players, since big orgs will typically push the result of their CI pipeline to a container orchestration system like K8 which has its own system for managing environment-specific variables.
As it stands, I'm having to commit (thankfully non-secret) environment-specific variables like AWS CloudFormation IDs to my .gitlab-ci.yml file, which works but feels silly.
On the other hand, I'm incredibly grateful that GitLab has released their CI tool as part of GitLab CE, and I totally understand that you have to draw the CE/EE line somewhere. Just my 2¢.
Added "If multiple scopes apply to an environment, more specific scopes should have priority over less-specific scopes. e.g. review/foo should have priority over review/*, which itself should have priority over *. This can allow someone to specify a default variable for all environments, but override the production one, for example." to description.
I just realized that we would need to relax the uniqueness constraint for variable keys. We need to make it that variables could have the same key, yet having different scopes in order to implement:
If multiple scopes apply to an environment, more specific scopes should have priority over less-specific scopes. e.g. review/foo should have priority over review/*, which itself should have priority over *. This can allow someone to specify a default variable for all environments, but override the production one, for example.
Maybe we should show the variables in environment specific pages as well, so that they're more accessible (and maybe also easier to debug to see which variables would apply)
I recently refactored my deploy scripts to use this new resource mas as of today my pipeline throw an error because apparently this resource isn't available anymore.