功能应用 PowerShell – 使用模块发布功能

huangapple go评论60阅读模式
英文:

Function App PowerShell - Publish Function with Module

问题

遇到了一个奇怪的问题,发布 PowerShell 函数到一个函数应用程序。该函数应用程序使用 Windows 消耗配额,使用 Y1 应用服务计划。

该函数使用了 5 个不同的 Az 模块,这些模块作为包的一部分存在于 Modules 目录中:

  • Az.Accounts
  • Az.Resources
  • Az.Compute
  • Az.Sql
  • Az.SqlVirtualMachine

文件结构如下:

wwwroot/
| - .funcignore
| - ahubReporter
| | - function.json
| | - readme.md
| | - run.ps1
| - host.json
| - Modules
| | - Az.Accounts
| | - Az.Compute
| | - Az.Resources
| | - Az.Sql
| | - Az.SqlVirtualMachine
| - profile.ps1
| - requirements.psd1

注意:managedDependency 没有启用,Az 模块不会自动下载。这些模块包含在源代码中的 Modules 目录下,并与函数一起发布。

如果通过 Visual Studio Code 手动发布函数,使用 Azure Function Extension,函数可以正常工作并运行完美。

然而,如果我通过 Azure DevOps 任务 AzureFunctionApp@2 或 Azure PowerShell 任务 AzurePowerShell@5 使用 Publish-AzWebApp 命令发布函数,函数会被发布,但不会运行,并且会出现以下错误:

在模块 'Az.Resources' 中找到了 'Get-AzLocation' 命令但无法加载该模块有关更多信息请运行 'Import-Module Az.Resources'

Azure DevOps Pipeline 配置为使用 Windows 代理。

Azure DevOps 任务 AzureFunctionApp@2 如下所示:

- task: AzureFunctionApp@2
  displayName: '发布函数 | 打包'
  inputs:
    azureSubscription: ${{ parameters.customerServiceConnection }}
    appType: functionApp
    appName: $(functionName)
    package: $(System.ArtifactsDirectory)/**/*.zip
    deploymentMethod: 'runFromPackage' # <--- 我也尝试过 auto

Azure DevOps 任务 AzurePowerShell@5 如下所示:

- task: AzurePowerShell@5
  displayName: '发布函数 | azpwsh'
  inputs:
    azureSubscription: ${{ parameters.customerServiceConnection }}
    ScriptType: 'InlineScript'
    Inline: 'Publish-AzWebapp -ResourceGroupName $(functionAppRg) -Name $(functionName) -ArchivePath $(System.ArtifactsDirectory)/build$(Build.BuildId).zip -Force'
    azurePowerShellVersion: 'LatestVersion'
    pwsh: true

谢谢!

英文:

Got a weird issue publishing a PowerShell Function to a Function App. The Function App uses Windows consumption with a Y1 App Service Plan.

The Function uses 5 different Az Modules that exist in the Modules Directory as part of the Package:

  • Az.Accounts
  • Az.Resources
  • Az.Compute
  • Az.Sql
  • Az.SqlVirtualMachine

The File structure looks like this:

wwwroot/
| - .funcignore
| - ahubReporter
| | - function.json
| | - readme.md
| | - run.ps1
| - host.json
| - Modules
| | - Az.Accounts
| | - Az.Compute
| | - Az.Resources
| | - Az.Sql
| | - Az.SqlVirtualMachine
| - profile.ps1
| - requirements.psd1

> NOTE: managedDependency is not enabled and the Az Modules are not download automatically. The Modules are included in the source under the Modules directory and published with the function

If the Function is published manually through vscode using the Azure Function Extension, the function works and runs perfectly.

However, If I publish the Function by either the Azure DevOps Task AzureFunctionApp@2 or Azure PowerShell Task AzurePowerShell@5 using the command Publish-AzWebApp, the function is published, but does not run and I get the following error:

The &#39;Get-AzLocation&#39; command was found in the module &#39;Az.Resources&#39;, but the module could not be loaded. For more information, run &#39;Import-Module Az.Resources&#39;.

The Azure DevOps Pipeline is configured to use a Windows Agent.

The Azure DevOps Task AzureFunctionApp@2 is:

- task: AzureFunctionApp@2
  displayName: &#39;Publish Function | package&#39;
  inputs:
    azureSubscription: ${{ parameters.customerServiceConnection }}
    appType: functionApp
    appName: $(functionName)
    package: $(System.ArtifactsDirectory)/**/*.zip
    deploymentMethod: &#39;runFromPackage&#39; # &lt;--- I&#39;ve tried auto as well

The Azure DevOps Task AzurePowerShell@5 is:

- task: AzurePowerShell@5
  displayName: &#39;Publish Function | azpwsh&#39;
  inputs:
    azureSubscription: ${{ parameters.customerServiceConnection }}
    ScriptType: &#39;InlineScript&#39;
    Inline: &#39;Publish-AzWebapp -ResourceGroupName $(functionAppRg) -Name $(functionName) -ArchivePath $(System.ArtifactsDirectory)/build$(Build.BuildId).zip -Force&#39;
    azurePowerShellVersion: &#39;LatestVersion&#39;
     pwsh: true

Thanks!

答案1

得分: 1

I looked into this a little as the error messages suggests that the PSModulePath is not configured correctly as it can locate the function/cmdlet and the module but it's not able to load it.

根据错误消息,我稍微调查了一下,似乎PSModulePath配置不正确,它能够定位到函数/cmdlet和模块,但无法加载它。

It is my understanding that the Modules folder in the root of the project is appended to the PSModulePath when the worker is initialised.

据我了解,项目根目录中的Modules文件夹在初始化工作时会添加到PSModulePath。

I quickly built a project in a devcontainer to do some tests, disabled managed dependencies as you advised.

我迅速在devcontainer中建立了一个项目进行了一些测试,按照您的建议禁用了托管依赖项。

Ran Save-Module to save the Az.Resources module and added it to a Modules folder within the project.

运行Save-Module以保存Az.Resources模块,并将其添加到项目中的一个Modules文件夹中。

When running the project you can see the logs in a bit better detail than you get from AzDo or the portal and there are a large amount of errors coming from the internal commands within Az.Resources & Az.Accounts there are also internal modules Az.Authorisation & Az.MsGraph which show in the logs with Newtonsoft collision errors.

在运行项目时,您可以看到比AzDo或门户提供的更详细的日志,其中有大量的错误来自Az.ResourcesAz.Accounts内部命令,还有内部模块Az.AuthorisationAz.MsGraph,这些模块在日志中显示出Newtonsoft冲突错误。

Message: The 'Get-AzLocation' command was found in the module 'Az.Resources', but the module could not be loaded. For more information, run 'Import-Module Az.Resources'.

消息:在模块'Az.Resources'中找到了'Get-AzLocation'命令,但无法加载该模块。有关更多信息,请运行'Import-Module Az.Resources'。

I pushed the project to Github here so you can see the errors it generates.

我将项目推送到了Github,您可以在这里看到它生成的错误。

Out of curiosity have you tried using the Azure Functions Deploy v2 task instead of a powershell task and using the PowerShell equivalent?

出于好奇,您尝试过使用Azure Functions Deploy v2任务而不是PowerShell任务,并使用PowerShell等效命令吗?

- task: AzureFunctionApp@2
  displayName: Azure Function App Deploy
  inputs:
    azureSubscription: $(azureSubscription)
    appName: samplefunctionapp
    appType: functionApp
    package: $(System.DefaultWorkingDirectory)/**/*.zip

https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/azure-function-app-v2?view=azure-pipelines

英文:

I looked into this a little as the error messages suggests that the PSModulePath is not configured correctly as it can locate the function/cmdlet and the module but it's not able to load it.

It is my understanding that the Modules folder in the root of the project is appended to the PSModulePath when the worker is initialised.

I quickly built a project in a devcontainer to do some tests, disabled managed dependencies as you advised.

Ran Save-Module to save the Az.Resources module and added it to a Modules folder within the project.

When running the project you can see the logs in a bit better detail than you get from AzDo or the portal and there are a large amount of errors coming from the internal commands within Az.Resources & Az.Accounts there are also internal modules Az.Authorisation & Az.MsGraph which show in the logs with Newtonsoft collision errors.

 Message        : The &#39;Get-AzLocation&#39; command was found in the module &#39;Az.Resources&#39;, but the module could not be loaded. For more information, run &#39;Import-Module Az.Resources&#39;.
[2023-06-09T10:22:21.599Z]     Data           : System.Collections.ListDictionaryInternal
[2023-06-09T10:22:21.599Z]     InnerException : 
[2023-06-09T10:22:21.599Z]         Type           : System.Management.Automation.CmdletInvocationException
[2023-06-09T10:22:21.599Z]         ErrorRecord    : 
[2023-06-09T10:22:21.599Z]             Exception             : 
[2023-06-09T10:22:21.599Z]                 Type       : System.IO.FileLoadException
[2023-06-09T10:22:21.600Z]                 Message    : Assembly with same name is already loaded
[2023-06-09T10:22:21.600Z]                 TargetSite : 
[2023-06-09T10:22:21.600Z]                     Name          : Bind_LoadAssemblies
[2023-06-09T10:22:21.600Z]                     DeclaringType : initialsessionstate
[2023-06-09T10:22:21.600Z]                     MemberType    : Method
[2023-06-09T10:22:21.600Z]                     Module        : System.Management.Automation.dll

I pushed the project to Github here so you can see the errors it generates

https://github.com/brettmillerb/stackoverflowTest

Out of curiosity have you tried using the Azure Functions Deploy v2 task instead of a powershell task and using the PowerShell equivalent?

- task: AzureFunctionApp@2
  displayName: Azure Function App Deploy
  inputs:
    azureSubscription: $(azureSubscription)
    appName: samplefunctionapp
    appType: functionApp
    package: $(System.DefaultWorkingDirectory)/**/*.zip

https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/azure-function-app-v2?view=azure-pipelines

答案2

得分: 0

以下是您要翻译的内容:

Instead of adding your Powershell Modules in a separate Module folder, Directly add them in requirements.psd1 folder, the requirements.psd1 will automatically download those packages for you.

我使用Azure DevOps管道部署了Azure Powershell HTTP触发器,成功了。请参考以下内容:

我的存储库:

功能应用 PowerShell – 使用模块发布功能

功能应用 PowerShell – 使用模块发布功能

requirements.psd1

@{
    'Az' = '9.*'
    'Az.Accounts' = '1.1.0'
    'Az.Compute' = '0.5.0'
    'Az.Resources' = '6.7.0'
    'Az.Sql' = '4.7.0'
    'Az.SqlVirtualMachine' = '2.0.0'
}
trigger:
- main

variables:

  azureSubscription: 'xxxxxxxxx-52801a7de72a'

  functionAppName: 'siliconfunc5431'


  vmImageName: 'windows-2019'

  workingDirectory: '$(System.DefaultWorkingDirectory)/'

stages:
- stage: Build
  displayName: 构建阶段

  jobs:
  - job: Build
    displayName: 构建
    pool:
      vmImage: $(vmImageName)

    steps:
    - powershell: |
        if (Test-Path "extensions.csproj") {
            dotnet build extensions.csproj --output ./$(workingDirectory)/bin
        }        
      displayName: '构建扩展'

    - task: ArchiveFiles@2
      displayName: '归档文件'
      inputs:
        rootFolderOrFile: $(workingDirectory)
        includeRootFolder: false
        archiveType: zip
        archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
        replaceExistingArchive: true

    - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
      artifact: drop

- stage: Deploy
  displayName: 部署阶段
  dependsOn: Build
  condition: succeeded()

  jobs:
  - deployment: Deploy
    displayName: 部署
    environment: $(functionAppName)
    pool:
      vmImage: $(vmImageName)

    strategy:
      runOnce:
        deploy:

          steps:
          - task: AzureFunctionApp@1
            displayName: 'Azure函数应用部署'
            inputs:
              azureSubscription: '$(azureSubscription)'
              appType: functionApp
              appName: $(functionAppName)
              package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'

功能应用 PowerShell – 使用模块发布功能

门户:

功能应用 PowerShell – 使用模块发布功能

功能应用 PowerShell – 使用模块发布功能

如果您想运行模块文件,请确保像下面这样在PowerShell任务中导入或安装它们,然后运行您的函数发布任务。

Import-Module -Name Az.Accounts -Force
Import-Module -Name Az.Resources -Force
Import-Module -Name Az.Compute -Force
Import-Module -Name Az.Sql -Force
Import-Module -Name Az.SqlVirtualMachine -Force

如果错误仍然存在,请通过启用诊断或在PowerShell命令的末尾添加--Verbose标志来运行您的管道,如下所示:

- task: AzurePowerShell@5
  displayName: '发布函数 | azpwsh'
  inputs:
    azureSubscription: ${{ parameters.customerServiceConnection }}
    ScriptType: 'InlineScript'
    Inline: 'Publish-AzWebapp -ResourceGroupName $(functionAppRg) -Name $(functionName) -ArchivePath $(System.ArtifactsDirectory)/build$(Build.BuildId).zip -Force -Verbose'
    azurePowerShellVersion: 'LatestVersion'
    pwsh: true

如果您有任何其他翻译需求,请随时告诉我。

英文:

> Instead of adding your Powershell Modules in a separate Module folder, Directly add them in requirements.psd1 folder, the requirements.psd1 will automatically download those packages for you.

I ran one Azure DevOps pipeline to deploy Azure Powershell HTTP Trigger and it was successful, Refer below:-

My repository:-

功能应用 PowerShell – 使用模块发布功能

功能应用 PowerShell – 使用模块发布功能

requirements.psd1

@{
    &#39;Az&#39; = &#39;9.*&#39;
    &#39;Az.Accounts&#39; = &#39;1.1.0&#39;
    &#39;Az.Compute&#39; = &#39;0.5.0&#39;
    &#39;Az.Resources&#39; = &#39;6.7.0&#39;
    &#39;Az.Sql&#39; = &#39;4.7.0&#39;
    &#39;Az.SqlVirtualMachine&#39; = &#39;2.0.0&#39;
}
trigger:
- main

variables:

  azureSubscription: &#39;xxxxxxxxx-52801a7de72a&#39;

  functionAppName: &#39;siliconfunc5431&#39;


  vmImageName: &#39;windows-2019&#39;

  workingDirectory: &#39;$(System.DefaultWorkingDirectory)/&#39;

stages:
- stage: Build
  displayName: Build stage

  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)

    steps:
    - powershell: |
        if (Test-Path &quot;extensions.csproj&quot;) {
            dotnet build extensions.csproj --output ./$(workingDirectory)/bin
        }        
      displayName: &#39;Build extensions&#39;

    - task: ArchiveFiles@2
      displayName: &#39;Archive files&#39;
      inputs:
        rootFolderOrFile: $(workingDirectory)
        includeRootFolder: false
        archiveType: zip
        archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
        replaceExistingArchive: true

    - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
      artifact: drop

- stage: Deploy
  displayName: Deploy stage
  dependsOn: Build
  condition: succeeded()

  jobs:
  - deployment: Deploy
    displayName: Deploy
    environment: $(functionAppName)
    pool:
      vmImage: $(vmImageName)

    strategy:
      runOnce:
        deploy:

          steps:
          - task: AzureFunctionApp@1
            displayName: &#39;Azure functions app deploy&#39;
            inputs:
              azureSubscription: &#39;$(azureSubscription)&#39;
              appType: functionApp
              appName: $(functionAppName)
              package: &#39;$(Pipeline.Workspace)/drop/$(Build.BuildId).zip&#39;

功能应用 PowerShell – 使用模块发布功能

Portal:-

功能应用 PowerShell – 使用模块发布功能

功能应用 PowerShell – 使用模块发布功能

If you want to run the module files, Make sure you Import or Install them in a Powershell task like below and then run your Function Publish task.

Import-Module -Name Az.Accounts -Force
Import-Module -Name Az.Resources -Force
Import-Module -Name Az.Compute -Force
Import-Module -Name Az.Sql -Force
Import-Module -Name Az.SqlVirtualMachine -Force

If still the error persists, Run your Pipeline by enabling diagnostics or by adidng --Verbose flag at the end of your Powershell command like below:-

- task: AzurePowerShell@5
  displayName: &#39;Publish Function | azpwsh&#39;
  inputs:
    azureSubscription: ${{ parameters.customerServiceConnection }}
    ScriptType: &#39;InlineScript&#39;
    Inline: &#39;Publish-AzWebapp -ResourceGroupName $(functionAppRg) -Name $(functionName) -ArchivePath $(System.ArtifactsDirectory)/build$(Build.BuildId).zip -Force -Verbose&#39;
    azurePowerShellVersion: &#39;LatestVersion&#39;
    pwsh: true

答案3

得分: 0

OK, I got it working.

虽然我仍然不明白为什么使用Azure DevOps任务AzureFunctionApp@2或Azure PowerShell任务AzurePowerShell@5使用命令Publish-AzWebApp不起作用,但如果通过vscode发布,则可以。

基本上,我简化了代码(我原本没有编写),删除了模块并更新了以下文件:

host.json

启用了managedDependency

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[3.*, 4.0.0)"
  },
  "functionTimeout": "00:10:00",
  "managedDependency": {
    "enabled": true // <----- 这
  }
}

requirements.psd1

删除了'Az' = '10.*'并添加了以下内容:

@{
    'Az.Accounts' = '2.12.3'
    'Az.Compute' = '6.0.0'
    'Az.Resources' = '6.7.0'
    'Az.Sql' = '4.7.0'
    'Az.SqlVirtualMachine' = '2.0.0'
}

感谢大家的回应。每个人都给了我一些想法,我最终尝试了不同的配置并改进了原始代码。

谢谢!

英文:

OK I got it working.

Although, I still don't understand why it wouldn't work using the Azure DevOps Task AzureFunctionApp@2 or the Azure PowerShell Task AzurePowerShell@5 using the command Publish-AzWebApp, but it would if it was published via vscode.

Basically, I streamlined the code (I didn't write originally), removed the modules and updated the following files:

host.json

Enabled managedDependency

{
  &quot;version&quot;: &quot;2.0&quot;,
  &quot;logging&quot;: {
    &quot;applicationInsights&quot;: {
      &quot;samplingSettings&quot;: {
        &quot;isEnabled&quot;: true,
        &quot;excludedTypes&quot;: &quot;Request&quot;
      }
    }
  },
  &quot;extensionBundle&quot;: {
    &quot;id&quot;: &quot;Microsoft.Azure.Functions.ExtensionBundle&quot;,
    &quot;version&quot;: &quot;[3.*, 4.0.0)&quot;
  },
  &quot;functionTimeout&quot;: &quot;00:10:00&quot;,
  &quot;managedDependency&quot;: {
    &quot;enabled&quot;: true // &lt;----- This
  }
}

requirements.psd1

Removed &#39;Az&#39; = &#39;10.*&#39; and added the following:

@{
    &#39;Az.Accounts&#39; = &#39;2.12.3&#39;
    &#39;Az.Compute&#39; = &#39;6.0.0&#39;
    &#39;Az.Resources&#39; = &#39;6.7.0&#39;
    &#39;Az.Sql&#39; = &#39;4.7.0&#39;
    &#39;Az.SqlVirtualMachine&#39; = &#39;2.0.0&#39;
}

Thanks for all in responding. Everyone gave me some ideas and I just ended up trying different configurations and enhancing the original code.

Thanks!

huangapple
  • 本文由 发表于 2023年6月9日 12:58:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76437324.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定