Use Azure devops release variables group in vue application

228 views Asked by At

I have inherited a project written in Angular with the right configuration to deploy to Azure devops. I have been asked to make a 2.0 version of this project but this time written in Vue. The project is already done and on localhost it works perfectly (with the login pulling against MSAL and all). The problem has been when deploying it. It's deployed correctly but I can't login.

This is because it uses the group variables that are in the release, that with Angular was already configured to access them but with Vue I can't do it. In Angular there is a file called env.js in the root of the project that contains the following code:

(function (window) {
  window.__env = window.__env || {};
  window.__env.clientID = 'variable-id';
}(this));

Then I see that this file is loaded in src/index.html

<script src="env.js"></script>

And in apply-deploy.yml I have this:

args: ["-c", "sed -i -e s/variable-id/#{variable-id}#/g /usr/share/nginx/html/name-of-my-proyect/env.js ;nginx -g 'daemon off;'"]

Then in the config of MSAL, Angular project has this to load clientID:

window['__env']['clientID'];

So, I need to do similar in Vue.js

I have tried different things but none of them work, it always gives me undefined. With the same configuration (using env.js) it doesn't work.

I have tried to use replace tokens in azure release, but maybe I have not idea how to do it correctly, but it doesn't work.

I have environments files like .env and .env.prod and there I have some constants like: VUE_APP_NAME="XXXXX", so I have tried to add something like this:

VUE_APP_CLIENT_ID=#{variable-id}#

But it doesn't work. I have not idea how to do it.

Thanks a lot

[UPDATE]

I have .env.production file with this: VUE_APP_CLIENT_ID=#{client-id}# -> this client-id is a variable inside azure https://i.stack.imgur.com/q3CQk.png one of the variables I have crossed out.

And I have a vsts-ci.yml file and I have added this:

##### REPLACE TOKENS #####
  - task: qetza.replacetokens.replacetokens-task.replacetokens@5
    displayName: "Replace tokens"
    inputs:
      targetFiles: "$(System.DefaultWorkingDirectory)/.env.production"

I would like to access by process.env.VUE_APP_CLIENT_ID in my vue component and I would like to obtain the value inside azure variables.

Now I have deployed this code and pipeline returns:

##[warning]  variable not found: client-id

So I have not idea how to connect it.

2

There are 2 answers

6
SiddheshDesai On BEST ANSWER

I tried referring this Github sample by Sunil Bandla on vue+MSAL and I was able to access the ClientID in the evironment variable by creating .env file in my root project like below:-

My Source code folder:-

enter image description here

My .env file:-

clientID=xxxxxxxxxxxxx

I have also install below package for the .env package to work successfully:-

npm install --save-dev vue-cli-plugin-env

Referenced and edited the above clientID in auth.service.js from the Github sample above like below:-

clientID: process.env.clientID

Complete auth.service.js Code:-

import * as Msal from 'msal';

export default class AuthService {
  constructor() {
    let PROD_REDIRECT_URI = 'https://sunilbandla.github.io/vue-msal-sample/';
    let redirectUri = window.location.origin;
    if (window.location.hostname !== '127.0.0.1') {
      redirectUri = PROD_REDIRECT_URI;
    }
    this.applicationConfig = {
      clientID: process.env.clientID,
      graphScopes: ['user.read']
    };
    this.app = new Msal.UserAgentApplication(
      this.applicationConfig.clientID,
      '',
      () => {
        // callback for login redirect
      },
      {
        redirectUri
      }
    );
  }
  login() {
    return this.app.loginPopup(this.applicationConfig.graphScopes).then(
      idToken => {
        const user = this.app.getUser();
        if (user) {
          return user;
        } else {
          return null;
        }
      },
      () => {
        return null;
      }
    );
  };
  logout() {
    this.app.logout();
  };
  getToken() {
    return this.app.acquireTokenSilent(this.applicationConfig.graphScopes).then(
      accessToken => {
        return accessToken;
      },
      error => {
        return this.app
          .acquireTokenPopup(this.applicationConfig.graphScopes)
          .then(
            accessToken => {
              return accessToken;
            },
            err => {
              console.error(err);
            }
          );
      }
    );
  };
}

Output:-

I was able to Log in successfully like below:-

enter image description here

Adding Environment variable is not required in the Release pipeline as I am using .env to retrieve the variable:-

enter image description here

1
Alvin Zhao - MSFT On

Based on your description, it is estimated that you have neither defined the secret client-id in your key vault, nor defined the variable client-idin the build/YAML pipeline(vsts-ci.yml).

replacetoken@5 task will search the variable name (client-id) between #{ and #} ; and then replace #{varaibleName}# in your selected file with the variable value that is defined in this YAML pipeline.

Since you use the build/YAML pipeline to replace #{client-id}# with its value, you need to either get the value from the secret client-id created in key vault, or define this variable client-id in this pipeline directly for value replacement.

Therefore, plesae consider either changing the variable name in the .env.production file as the secret name that is already added into the referenced key vault, or defining the variable client-id in the pipeline for value replacement. Kindly see the sample below to help us understand better.

  • Original .env.sample file in my repo. enter image description here

  • Define the variable client-id with the value of xxxx-xxxx-xxxx in the YAML pipeline and use replacetokens@5 task to replace #{client-id}# with xxxx-xxxx-xxxx in .env.sample file.

variables:
  client-id: xxxx-xxxx-xxxx

steps:
- task: replacetokens@5
  inputs:
    targetFiles: '.env.sample'
    encoding: 'auto'
    tokenPattern: 'default'
    writeBOM: true
    actionOnMissing: 'warn'
    keepToken: false
    actionOnNoFiles: 'continue'
    enableTransforms: false
    enableRecursion: false
    useLegacyPattern: false
    enableTelemetry: true

- script: vim .env.sample
  • Check the file after value replacement. enter image description here

  • You can also create a secret client-id in key vault, link it to a variable group and reference it in this YAML pipeline. enter image description here

variables:
- group: DEV01-MIlabkv (DATAHUB)

steps:
- task: replacetokens@5
  inputs:
    targetFiles: '.env.sample'
    encoding: 'auto'
    tokenPattern: 'default'
    writeBOM: true
    actionOnMissing: 'warn'
    keepToken: false
    actionOnNoFiles: 'continue'
    enableTransforms: false
    enableRecursion: false
    useLegacyPattern: false
    enableTelemetry: true

- upload: $(System.DefaultWorkingDirectory)/.env.sample

enter image description here

  • For the variable replacement sample in a release pipeline. enter image description here

Hope the information would help address your query.