Azure DevOps 发布.Net项目到Windows IIS站点之Azure项目发布内网VM

发布时间 2023-11-13 22:08:57作者: 初久的私房菜

当你有一个需求,需要通过Azure DevOps发布到一个没有公网的VM的时候,你将需要使用以下脚本

trigger:
- master

pool:
  vmImage: 'windows-2022'

variables:
  - name: Build.ArtifactStagingDirectory
    value: '$(Build.Repository.LocalPath)\artifacts'
  - name: buildConfiguration
    value: 'Release'
  - name: publishFolder
    value: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId)'
  - name: solution
    value: '项目.sln'
  - name: zipFileName
    value: '压缩包xxx.zip'
  - name: storageAccountName
    value: 'storagea名称'
  - name: resourceGroupName
    value: '资源组'
  - name: vmName
    value: 'VM虚拟机名称'
  - name: shareName
    value: 'storage目录'
  - name: destPath
    value: "目录地址"



stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: Build
    displayName: 'Build job'
    steps:
    - script: dotnet restore $(solution)
      displayName: 'Build solution'

    - script: dotnet publish $(solution) --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)
      displayName: 'Publish solution'

    - task: ArchiveFiles@2
      inputs:
        rootFolderOrFile: '$(Build.ArtifactStagingDirectory)'
        includeRootFolder: false
        archiveType: 'zip'
        archiveFile: '$(Build.ArtifactStagingDirectory)\$(zipFileName)'
        replaceExistingArchive: true

    - script: |
        echo "===== Listing files in ArtifactStagingDirectory ====="
        ls "$(Build.ArtifactStagingDirectory)"
        echo "===== Finished listing files ====="
      displayName: 'List files in ArtifactStagingDirectory'
      
    - task: PublishBuildArtifacts@1
      inputs:
        pathtoPublish: '$(Build.ArtifactStagingDirectory)'
        artifactName: 'drop'
        publishLocation: 'Container'

- stage: Deploy
  displayName: 'Deploy to IIS on Azure VM using ARM'
  jobs:
  - deployment: DeployJob
    displayName: 'Deploy'
    environment: 'YourEnvironmentName'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: DownloadBuildArtifacts@0
            inputs:
              buildType: 'current'
              downloadType: 'single'
              artifactName: 'drop'
              downloadPath: '$(System.ArtifactsDirectory)'
              
          - task: AzurePowerShell@5
            inputs:
              azureSubscription: 'PublishAreaDts'
              azurePowerShellVersion: LatestVersion
              ErrorActionPreference: 'Continue'
              ScriptType: 'InlineScript'
              Inline: |
                # Verify the value of $srcPath
                $srcPath = Join-Path -Path $env:AGENT_BUILDDIRECTORY -ChildPath "drop\$(zipFileName)"
                Write-Output "===== Verifying the value of srcPath ====="
                Write-Output "srcPath: $srcPath"
                Write-Output "===== Finished verifying ====="

                # Check if the file exists
                if (Test-Path -Path $srcPath) {
                    Write-Output "File exists"
                } else {
                    Write-Output "File does not exist"
                    throw "File not found: $srcPath"
                }

                # Add more debug output
                Write-Output "===== Getting storage account ====="
                $storageAccount = Get-AzStorageAccount -ResourceGroupName $(resourceGroupName) -Name "$(storageAccountName)" -ErrorAction SilentlyContinue
                Write-Output "===== Finished getting storage account ====="

                Write-Output "===== Getting file share ====="
                $fileShare = Get-AzStorageShare -Name "$(shareName)" -Context $storageAccount.Context -ErrorAction SilentlyContinue
                Write-Output "===== Finished getting file share ====="
                if (-not $fileShare) {
                    $fileShare = New-AzStorageShare -Name "$(shareName)" -Context $storageAccount.Context
                }
                
                # Write-Output "===== Uploading file to storage account ====="
                Set-AzStorageFileContent -ShareName $fileShare.Name -Source $srcPath -Path "$(zipFileName)" -Context $storageAccount.Context
                # Write-Output "===== Finished uploading file ====="

                Write-Output "===== Generating SAS token ====="
                $url = $fileShare.CloudFileShare.Uri.AbsoluteUri + "/$(zipFileName)"
                $sasToken = New-AzStorageShareSASToken -ShareName $fileShare.Name -Context $storageAccount.Context -Permission "r" -ExpiryTime (Get-Date).AddHours(1)
                $urlWithSas = $url + $sasToken
                Write-Output "===== Finished generating SAS sasToken $urlWithSas ====="
                # Write-Output "===== Finished generating SAS file $file ====="
                Write-Output "===== Finished generating SAS url $url ====="
                Write-Output "===== Executing script on target VM ====="

                # Update the script to execute
                $scriptToExecute = @"
                    Add-Type -AssemblyName System.IO.Compression.FileSystem
                    Invoke-WebRequest -Uri `"$urlWithSas`" -OutFile c:\temp\$(zipFileName)
                    Remove-Item -Path $(destPath) -Recurse -Force
                    [System.IO.Compression.ZipFile]::ExtractToDirectory('c:\temp\$(zipFileName)', '$(destPath)')
                "@

                # Execute the script on the target VM and capture the result
                $runCommandResult = Invoke-AzVMRunCommand -ResourceGroupName $(resourceGroupName) -Name $(vmName) -CommandId 'RunPowerShellScript' -ScriptString $scriptToExecute -Verbose

                # Output the result of Invoke-AzVMRunCommand
                Write-Output "===== Invoke-AzVMRunCommand Result ====="
                Write-Output $runCommandResult.Value
                Write-Output "===== End of Invoke-AzVMRunCommand Result ====="

            env:
              ArtifactStagingDirectory: $(Build.ArtifactStagingDirectory)