Is there a way to use VSTS Variable Groups per env

2019-01-28 10:02发布

问题:

I'm moving my configuration from using web.config transforms to being based on VSTS variables. I get process variables, you define a variable, pick an environment, and you're good to go. I also see "Variable Groups", these seem great, have KeyVault integration, and overall seem like a much better option.

But...I don't see a way to bind a Variable Group to a specific environment in my VSTS release process. I can't honestly see how these would be any use to me without this feature.

I've experimented with one workaround, but it didn't work. I tried:

  • Naming my variable group & variables with an environment prefix e.g.
    • Variable Group Name="Production ConnectionStrings"
    • Variable name="Production_LoggingConnectionString"
    • I thought once I linked the "Production_ConnectionStrings" variable, I could reference $(Production_LoggingConnectionString) from within a standard Process variable, but this didn't work.

I think I could come up with some powershell that would do something like the above and set variables, but this seems a bit too custom for me.

Does anyone else have an idea that I can use variable groups per environment, easily, without waiting around for VSTS to build this feature (if ever). Btw, if you want this feature, there is a suggestion here you can upvote: Make it possible to link a variable group to a specific environment in a release definition

回答1:

This has now been implemented in VSTS variable groups as scopes. Go to your release definition -> Variables -> Variable Groups -> Link variable group, and you get the link window as below, where you can choose the scope to be either release or one or more of your environments!

I did not manage to find any release information on this feature, I just stumbled upon it as I was tweaking my releases.



回答2:

I ended up using a powershell script to define my process variable based on the variable groups, it works great.

Let's say I want a variable named "LoggingConnectionString" and this has different values per environment

Steps:

  1. Define a Variable group, e.g. "SharedLoggingVariables"
  2. Inside this Variable group, define a variable/value for each environment, e.g. "LoggingConnectionStringDev", "LoggingConnectionStringProduction"
  3. Back in your Process Variables for the Build/Release, make SURE you don't have a variable named "LoggingConnectionString", otherwise this will overwrite the value coming from the variable group
  4. In your Release process, create a Powershell inline script at the beginning of the Agent with the following code

Param(
   [string]$LoggingConnectionString
)

Write-Host "##vso[task.setvariable variable=LoggingConnectionString]$LoggingConnectionString"
  1. Pass your variable group as an argument to this inline powershell, e.g.

    -LoggingConnectionString "$(LoggingConnectionStringDev)"

The final powershell step should look something like this:

During release, the powershell will set your process variable from the variable groups. If powershell isn't an option for you, there are other options



回答3:

No, there is no way to use variable Groups per environment.

As the user voice you linked, you can vote and follow up for the suggested feature.

The work around for now is using environment variables to overwrite the variables in variable Group.

Assume the variable LoggingConnectionString with the value Server=myDB in variable group need to be used both for Dev environment and staging environment. But for staging environment, it needs to use another value (such as Server=stageDB) from the variable LoggingConnectionString. So you can add the an environment variable LoggingConnectionString with the value Server=stageDB for staging environment.

  • When the variable $(LoggingConnectionString) is used in Dev environment, it will use the value (Server=myDB) defined in variable group.

  • When the variable $(LoggingConnectionString) is used in staging environment, since the variables both defined in environment variable and variable group, it will use the value (Server=stageDB) defined in environment variable.