You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过DevOps从同一项目向不同Function App发布多个Azure Functions

单C# Azure Functions项目拆分部署至多个Function App的DevOps流水线配置

核心思路

你的场景是单项目包含3个Timer触发函数,要分别部署到3个独立的Azure Function App。关键点在于让每个Function App只加载对应标记FunctionNameAttribute的函数,可以通过「部署阶段修改配置」或「构建阶段拆分输出」两种方式实现。

方案一:部署阶段拆分(基于同一工件)

先构建包含所有函数的完整工件,再针对每个Function App修改配置后部署:

1. 构建完整工件

在Azure DevOps Build Pipeline中生成包含全部3个函数的发布包:

- task: DotNetCoreCLI@2
  displayName: 'Build & Publish Full Functions Package'
  inputs:
    command: 'publish'
    projects: '**/YourFunctionProject.csproj'
    arguments: '--configuration Release --output $(Build.ArtifactStagingDirectory)/full-package'
    zipAfterPublish: true

2. 单独部署每个函数

为每个Function App复制以下任务流,替换对应名称和函数标识:

部署FunctionA到目标Function App

# 解压完整包到临时目录
- task: ExtractFiles@1
  displayName: 'Extract Package for FunctionA'
  inputs:
    archiveFilePatterns: '$(Pipeline.Workspace)/full-package/YourFunctionProject.zip'
    destinationFolder: '$(Pipeline.Workspace)/temp/func-a'
    cleanDestinationFolder: true

# 修改host.json,指定只加载FunctionA
- task: PowerShell@2
  displayName: 'Restrict Functions to FunctionA'
  inputs:
    targetType: 'inline'
    script: |
      $hostJsonPath = "$(Pipeline.Workspace)/temp/func-a/host.json"
      $hostJson = Get-Content $hostJsonPath | ConvertFrom-Json
      # 添加或覆盖functions节点,指定仅加载目标函数
      $hostJson | Add-Member -MemberType NoteProperty -Name "functions" -Value @("FunctionA") -Force
      $hostJson | ConvertTo-Json -Depth 10 | Set-Content $hostJsonPath

# 重新打包修改后的内容
- task: ArchiveFiles@2
  displayName: 'Package FunctionA Deployment'
  inputs:
    rootFolderOrFile: '$(Pipeline.Workspace)/temp/func-a'
    includeRootFolder: false
    archiveType: 'zip'
    archiveFile: '$(Pipeline.Workspace)/temp/func-a-package.zip'
    replaceExistingArchive: true

# 部署到对应的Function App
- task: AzureFunctionApp@1
  displayName: 'Deploy FunctionA to Azure'
  inputs:
    azureSubscription: '你的Azure订阅名称'
    appType: 'functionApp'
    appName: '你的Function App A名称'
    package: '$(Pipeline.Workspace)/temp/func-a-package.zip'

3. 复制适配其他函数

把上述任务流复制2份,分别修改:

  • 任务名称中的FunctionA改为FunctionB/FunctionC
  • PowerShell脚本中的函数名数组改为@("FunctionB")/@("FunctionC")
  • AzureFunctionApp任务中的appName替换为对应的Function App名称

方案二:构建阶段拆分(更干净的方式)

直接在构建时为每个函数生成独立的发布包,部署时无需额外处理:

1. 添加项目发布配置文件

在你的C# Functions项目中,创建3个发布配置文件(右键项目→添加→新建项→发布配置文件):

  • FunctionA.pubxml
  • FunctionB.pubxml
  • FunctionC.pubxml

每个配置文件中添加排除其他函数的编译规则,比如FunctionA.pubxml:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>Package</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <DesktopBuildPackageLocation>$(Build.ArtifactStagingDirectory)\func-a\YourFunctionProject.zip</DesktopBuildPackageLocation>
    <PackageAsSingleFile>true</PackageAsSingleFile>
    <DeployIisAppPath />
    <PublishDatabaseSettings>
      <Objects xmlns="" />
    </PublishDatabaseSettings>
  </PropertyGroup>
  <ItemGroup>
    <!-- 排除其他函数的源文件 -->
    <Compile Remove="FunctionB.cs" />
    <Compile Remove="FunctionC.cs" />
  </ItemGroup>
</Project>

2. 构建阶段生成独立工件

在Build Pipeline中为每个配置文件执行publish:

# 构建FunctionA的独立包
- task: DotNetCoreCLI@2
  displayName: 'Publish FunctionA'
  inputs:
    command: 'publish'
    projects: '**/YourFunctionProject.csproj'
    arguments: '--configuration Release /p:PublishProfile=FunctionA --output $(Build.ArtifactStagingDirectory)/func-a'
    zipAfterPublish: true

# 构建FunctionB的独立包
- task: DotNetCoreCLI@2
  displayName: 'Publish FunctionB'
  inputs:
    command: 'publish'
    projects: '**/YourFunctionProject.csproj'
    arguments: '--configuration Release /p:PublishProfile=FunctionB --output $(Build.ArtifactStagingDirectory)/func-b'
    zipAfterPublish: true

# 构建FunctionC的独立包
- task: DotNetCoreCLI@2
  displayName: 'Publish FunctionC'
  inputs:
    command: 'publish'
    projects: '**/YourFunctionProject.csproj'
    arguments: '--configuration Release /p:PublishProfile=FunctionC --output $(Build.ArtifactStagingDirectory)/func-c'
    zipAfterPublish: true

3. 部署独立包

每个Function App直接使用对应的zip包部署,比如部署FunctionA:

- task: AzureFunctionApp@1
  displayName: 'Deploy FunctionA to Azure'
  inputs:
    azureSubscription: '你的Azure订阅名称'
    appType: 'functionApp'
    appName: '你的Function App A名称'
    package: '$(Build.ArtifactStagingDirectory)/func-a/YourFunctionProject.zip'

注意事项

  • 确保每个Function App的应用设置(如定时器CRON表达式、连接字符串)单独配置,避免互相干扰
  • 两种方案都会保留函数间的共享依赖,无需额外处理
  • 测试时先在非生产环境验证,确认每个Function App仅运行目标函数

内容的提问来源于stack exchange,提问作者MarkMiddlemist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 06:42:05