Search code examples
azure-devopsyamlazure-web-app-serviceazure-pipelinesartifact

Am I doing this wrong with Azure DevOps, an Artifact and YAML?


I am trying to build a web app from an artifact and pass in a variable value for the app in from a JSON file all in YAML.

The problem I have is at the end of the pipeline. I can either build the web app without the value from the variable for the APP name and it will build, but when I try to put the variable as the App name it fails and says it cant see the artifact file.

My Code for the YAML file is below. Any guidance or help would be very much appreciated.

#pool:
 # vmImage: windows-latest
resources: 
  repositories: 
  - repository: Student
    name: PROJECT NAME/Student
    path:
    - include: /Student/Student 
    type: git 
    ref: master #branch name

variables: 
  System.Debug: true
  azureSubscription: 'MY VALUE HERE'
  RG: 'PROJECTNAME'
  containername: 'private'
  
jobs:
- job: job1
  displayName: Create And Publish Artifact
  pool:
    vmImage: vs2017-win2016
  steps:
  - checkout: Student
    clean: true

  - task: DotNetCoreCLI@2
    displayName: dotnet restore
    inputs:
      command: restore
      projects: '**/*.csproj'

  - task: DotNetCoreCLI@2
    displayName: dotnet build
    inputs:
      projects: '**/*.csproj'
      workingDirectory: Student

  - task: DotNetCoreCLI@2
    displayName: dotnet publish
    inputs:
      command: publish
      projects: '**/*.csproj'
      arguments: --output "$(Build.ArtifactStagingDirectory)"
      zipAfterPublish: true
      modifyOutputPath: false
      workingDirectory: Student

  - task: PublishPipelineArtifact@1
    displayName: Publish Pipeline Artifact
    inputs:
      targetPath: '$(Build.ArtifactStagingDirectory)'
      artifact: 'Student'
      publishLocation: 'pipeline'

- job: job2
  displayName: 'Get Variable Value for Student Env'
  dependsOn: job1
  steps:
  - task: AzureCLI@1
    displayName: 'Azure CLI '
    inputs:
      azureSubscription: $(azureSubscription)
      scriptLocation: inlineScript
      inlineScript: |
        mkdir $(Pipeline.Workspace)\BlobFile
        az storage blob download --container-name $(containername) --file '$(Pipeline.Workspace)/s/student.json' --name 'student.json' --connection-string 'DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=devscriptstorage;AccountKey'MY VALUE HERE'

  - pwsh: |
      cd '/home/vsts/work/1/s/'
      ls
      $armOutput = Get-Content '/home/vsts/work/1/s/student.json' | convertfrom-json
      $student = $armOutput.studentvalue #use student not studentvalue
      $type = $armOutput.type
      Write-Host "The value of [$student] is [$type]"
      Write-Host "##vso[task.setvariable variable=studentvalue;isOutput=true]$student" #use studentvalue not $studentvalue
    name: setvarStep

  - script: echo $(setvarStep.studentvalue)
    name: echovar

- job: job3
  displayName: Create Web App 
  dependsOn: job2
  variables:
    webappname: $[ dependencies.job2.outputs['setvarStep.studentvalue'] ]

  steps: 

  # creat empty web app with the student value from variable.
  - task: AzureWebApp@1
    inputs:
      azureSubscription: $(azureSubscription)
      appType: 'webApp'
      resourceGroupName: $(RG)
      appName: $(webappname)

  # download the artifact drop from the previous job
  - task: DownloadBuildArtifacts@0
    inputs:
      artifactName: Student

  # deploy to Azure Web App 
  - task: AzureWebApp@1
    inputs:
      azureSubscription: $(azureSubscription)
      appName: $(webappname)

  - task: AzureAppServiceSettings@1
    inputs:
      azureSubscription: $(azureSubscription)
      appName: $(webappname)
      resourceGroupName: $(RG)
      # To deploy the settings on a slot, provide slot name as below. By default, the settings would be applied to the actual Web App (Production slot)
      # slotName: staging
      appSettings: |
        {
          "name": "DIAGNOSTICS_AZUREBLOBCONTAINERSASURL",
          "value": "VALUEINHERE",
          "slotSetting": false
        },
        {
          "name": "DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS",
          "value": "365",
          "slotSetting": false
        },
        {
          "name": "OEM",
          "value": "netsupport",
          "slotSetting": false
        },
        {
          "name": "SCM_REPOSITORY_PATH",
          "value": "d:\\home\\respository",
          "slotSetting": false
        },
        {
          "name": "VIDEO_CLIENT_URL",
          "value": "https://signal-uks.classroom.cloud",
          "slotSetting": false
        },
        {
          "name": "WEBSITE_NODE_DEFAULT_VERSION",
          "value": "10.15.2",
          "slotSetting": false
        }


Solution

  • I have managed to get a solution to this question, on Alessandro Mouras Blog, "http://www.alessandromoura.com.br/2020/04/23/azure-devops-publish-and-download-artifacts/"

    Once you add in the following code:

    steps: 
      - download: none
      - task: DownloadPipelineArtifact@2
        displayName: 'Download Build Artifacts'
        inputs:
          patterns: '**/*.zip'
          path: '$(Build.ArtifactStagingDirectory)'

    It will find the Artifact and download it. The problem I now have is it wont build the web app because I have a variable runtime name being passed to it and it seems to assume that the resource should already exist.

    This is the current error: Resource 'nsclassroomstudent-dgyn27h2dfoyo' doesn't exist. Resource should exist before deployment.

    Will keep on plodding on if you know anything about Artifacts, WebApps and Azure I would be keen to here your opinion. :)