单租户 Azure 逻辑应用的 DevOps 部署

适用于:Azure 逻辑应用(标准)

随着分布式和本机云应用的趋势,组织需要在更多环境中处理更多分布式组件。 为了保持控制和一致性,可使用 DevOps 工具和流程来自动部署环境,更快,更自信地部署更多组件。

本文介绍并概述了单租户 Azure 逻辑应用当前的持续集成和持续部署 (CI/CD) 体验。

单租户与多租户

在多租户 Azure 逻辑应用中,资源部署基于 Azure 资源管理器模板(ARM 模板),这些模板组合并处理逻辑应用和基础结构的资源预配。 在单租户 Azure 逻辑应用中,部署变得更加容易,因为你可以在应用与基础结构之间分离资源预配。

使用“逻辑应用(标准)”资源类型创建逻辑应用时,工作流由重新设计的单租户 Azure 逻辑应用运行时提供支持。 此运行时使用 Azure Functions 扩展性模型的可扩展性,并作为扩展托管在 Azure Functions 运行时上。 此设计为逻辑应用提供了可移植性、灵活性和更高的性能,以及继承自 Azure Functions 平台和 Azure 应用服务生态系统的其他功能和优势。

例如,可以将重新设计的容器化运行时和工作流一起打包为逻辑应用的一部分。 可以使用一般步骤或任务来生成、组合逻辑应用资源,并将其压缩到随时可部署的项目中。 若要部署应用,请将项目复制到主机环境,然后启动应用以运行工作流。 或者,使用你了解并使用过的工具和进程将项目集成到部署管道中。 例如,如果方案要求容器,则可以容器化逻辑应用并将其集成到现有管道中。

若要设置并部署基础结构资源(如虚拟网络和连接),可以继续使用 ARM 模板,并单独预配这些资源以及用于这些目的的其他进程和管道。

通过使用标准生成和部署选项,你可以将应用程序开发与基础结构部署分开进行关注。 因此,你将获得更通用的项目模型,你可以在其中应用多个用于通用应用的类似或相同的部署选项。 你还可以从更一致的体验中获益,为你的应用项目生成部署管道,以及在发布到生产环境之前运行所需的测试和验证。 无论使用哪种技术堆栈,都可以使用自己选择的工具部署逻辑应用。

DevOps 部署功能

单租户 Azure 逻辑应用从 Azure Functions 平台和 Azure App Service 生态系统继承了许多功能和优势。 这些更新包括全新的部署模型,以及将 DevOps 用于逻辑应用工作流的更多方法。

本地开发和测试

将 Visual Studio Code 与 Azure 逻辑应用(标准)扩展一起使用时,可以在开发环境中本地开发、生成并运行基于单租户的逻辑应用工作流,而无需将其部署到 Azure。

与多租户模型相比,这是一项重大改进,并提供了实质性的好处,因为多租户模式要求你针对 Azure 中现有的和正在运行的资源进行开发。

分离关注事项

单租户模型使你能够将应用与底层基础结构之间的关注事项隔离开来。 例如,可以将应用作为不可变项目单独开发、生成、压缩并部署到不同的环境。 逻辑应用工作流通常具有“应用程序代码”,与基础结构相比,需要更频繁地对该代码进行更新。 通过分隔这些层,你可以将更多精力用在生成逻辑应用的工作流上,而无需花太多的精力来跨多个环境部署所需资源。

Conceptual diagram showing separate deployment pipelines for apps and infrastructure.

逻辑应用资源结构

在多租户 Azure 逻辑应用模型中,消耗逻辑应用资源结构只能包含单个工作流。 由于这种一对一关系,逻辑应用和工作流通常被视为并同义。 但是,在单租户 Azure 逻辑应用模型中,标准逻辑应用资源结构可以包含多个工作流。 这种一对多关系意味着,在同一个逻辑应用中,工作流可以共享并重用其他资源。 此外,由于此共享租用和彼此之间的邻近性,同一个逻辑应用和租户中的工作流可以提高性能。 此资源结构的外观和工作方式与 Azure Functions 相似,在 Azure Functions 中,函数应用可以托管多个函数。

有关组织工作流、性能以及在逻辑应用中进行扩展的详细信息和最佳做法,请查看 Azure Functions 的指南,该指南通常也适用于单租户 Azure 逻辑应用。

逻辑应用项目结构

在 Visual Studio Code 中,逻辑应用项目具有以下类型之一:

  • 基于扩展捆绑包 (Node.js)(默认类型)
  • 基于 NuGet 包 (.NET)(可从默认类型转换)

根据这些类型,项目包含略有不同的文件夹和文件。 基于 NuGet 的项目包含一个 .bin 文件夹,其中包含包和其他库文件。 基于捆绑包的项目不包括 .bin 文件夹和其他文件。 某些场景需要基于 NuGet 的项目以运行应用,例如,在想要开发和运行自定义内置操作时。 有关将项目转换为使用 NuGet 的详细信息,请参阅启用内置连接器创作

默认的基于捆绑包的项目具有类型于以下示例的文件夹和文件结构:

MyBundleBasedLogicAppProjectName
| .vscode
| Artifacts
  || Maps 
     ||| MapName1
     ||| ...
  || Schemas
     ||| SchemaName1
     ||| ...
| WorkflowName1
  || workflow.json
  || ...
| WorkflowName2
  || workflow.json
  || ...
| workflow-designtime
| .funcignore
| connections.json
| host.json
| local.settings.json

你可以在项目的根级别找到包含其他项的以下文件和文件夹:

名称 文件夹或文件 说明
.vscode 文件夹 包含与 Visual Studio Code 相关的设置文件,如 extensions.json、launch.json、settings.json 和 tasks.json 文件 。
项目 文件夹 包含在支持企业对企业 (B2B) 场景的工作流中定义和使用的集成帐户项目。 例如,示例结构包含用于 XML 转换和验证操作的映射和架构。
<WorkflowName> 文件夹 对于每个工作流,<WorkflowName> 文件夹包含 workflow.json 文件,其中包含该工作流的基础 JSON 定义。
workflow-designtime 文件夹 包含与开发环境相关的设置文件。
.funcignore 文件 包含与已安装的 Azure Functions Core Tools 相关的信息。
connections.json 文件 包含工作流使用的用于任何托管连接和 Azure 函数的元数据、终结点和密钥。

重要说明:若要在各种环境中使用不同的连接和函数,请确保实现此 connections.js 文件的参数化并更新终结点。
host.json 文件 包含特定于运行时的配置设置和值,例如,单租户 Azure 逻辑应用平台、逻辑应用、工作流、触发器和操作的默认限制。 在逻辑应用项目的根级别,host.json 元数据文件包含配置设置和默认值,相同逻辑应用中的所有工作流会在运行时(无论是在本地还是在 Azure 中)使用这些配置设置和默认值。

注意:创建逻辑应用时,Visual Studio Code 会在存储容器中创建一个备份 host.snapshot.*.json 文件 。 如果你删除逻辑应用,此备份文件不会被删除。 如果你创建另一个同名的逻辑应用,系统会创建另一个快照文件。 对于同一逻辑应用,最多只能有 10 个快照。 如果超出限制,你将收到以下错误:

Microsoft.Azure.WebJobs.Script.WebHost: Repository has more than 10 non-decryptable secrets backups (host))

若要解决此错误,请从存储容器中删除额外的快照文件。
local.settings.json 文件 包含工作流在本地运行时使用的应用设置、连接字符串和其他设置。 换句话说,这些设置和值仅在本地开发环境中运行项目时适用。 在部署到 Azure 期间,文件和设置将被忽略,并且不包含在部署中。

此文件会将设置和值存储为本地环境变量,本地开发工具会将其用作 appSettings 值。 可以通过使用“应用设置”和“参数”在运行时和部署时调用和引用这些环境变量 。

重要说明:local.settings.json 包含机密,因此请确保从项目源代码理管理中排除此文件。

容器部署

单租户 Azure 逻辑应用支持部署到容器,这意味着可以将逻辑应用工作流容器化,并可在容器可运行的位置运行它们。 容器化应用之后,部署的工作原理与你部署和管理的任何其他容器都大致相同。

有关包括 Azure DevOps 的示例,请查看容器的 CI/CD

应用设置和参数

在多租户 Azure 逻辑应用中,当必须跨各种开发、测试和生产环境维护逻辑应用的环境变量时,ARM 模板会带来挑战。 ARM 模板中的所有内容都是在部署时定义的。 如果只需更改单个变量,必须重新部署所有内容。

在单租户 Azure 逻辑应用中,可以使用应用设置和参数在运行时调用和引用环境变量,这样你就不必经常重新部署。

托管的连接器和内置操作

此 Azure 逻辑应用生态系统提供数百个 Microsoft 托管的连接器和内置操作,这些连接器和内置操作是不断增长的集合的一部分,可用于单租户 Azure 逻辑应用。 Azure 维护这些连接器和内置操作的方式在单租户 Azure 逻辑应用中基本保持不变。

最重要的改进是单租户服务使更流行的托管连接器也作为内置操作提供。 例如,你可以将内置操作用于 Azure 服务总线、Azure 事件中心、SQL 等。 同时,托管连接器版本仍然可用并且可以继续工作。

使用内置操作创建的连接称为内置连接或服务提供程序连接。 内置操作及其连接在本地运行于与工作流相同的进程中。 两者都托管在重新设计的逻辑应用运行时中。 与此相反,托管连接(或 API 连接)作为使用 ARM 模板部署的 Azure 资源单独创建并运行。 因此,由于与工作流的邻近性,内置操作及其连接提供的性能更好。 此设计还适用于部署管道,因为服务提供程序连接被打包到相同的生成项目中。

在 Visual Studio Code 中,当你使用设计器来开发或更改工作流时,逻辑应用引擎会在项目的 connections.js 文件中自动生成任何必需的连接元数据。 以下各节介绍了可在工作流中创建的三种连接。 每种连接类型都有不同的 JSON 结构,理解这一点很重要,因为在环境之间移动时终结点会发生变化。

服务提供程序连接

当对单租户 Azure 逻辑应用中的服务(例如 Azure 服务总线或 Azure 事件中心)使用内置操作时,将创建一个服务提供程序连接,该连接在与工作流相同的进程中运行。 此连接基础结构作为逻辑应用资源的一部分进行托管和管理,并且应用设置存储工作流使用的任何基于服务提供程序的内置操作的连接字符串。

在逻辑应用项目中,每个工作流都有一个 workflow.json 文件,其中包含工作流的基础 JSON 定义。 然后,此工作流定义在项目的 connections.json 文件中引用必要的连接字符串。

以下示例展示了内置服务总线操作的服务提供程序连接如何显示在项目的 connections.json 文件中:

"serviceProviderConnections": {
   "{service-bus-connection-name}": {
      "parameterValues": {
         "connectionString": "@appsetting('servicebus_connectionString')"
      },
      "serviceProvider": {
         "id": "/serviceProviders/serviceBus"
      },
      "displayName": "{service-bus-connection-name}"
   },
   <...>
}

托管连接

在工作流中首次使用托管连接器时,系统会提示你为目标服务或系统创建托管 API 连接,并验证标识。 这些连接器由 Azure 中的共享连接器生态系统管理。 API 连接在 Azure 中作为单独的资源存在并运行。

在 Visual Studio Code 中,当继续使用设计器创建和开发工作流时,逻辑应用引擎会自动在 Azure 中为工作流中的托管连接器创建必要的资源。 该引擎会自动将这些连接资源添加到你设计来包含逻辑应用的 Azure 资源组中。

以下示例展示了托管服务总线连接器的 API 连接如何显示在项目的 connections.json 文件中:

"managedApiConnections": {
   "{service-bus-connection-name}": { 
      "api": {
         "id": "/subscriptions/{subscription-ID}/providers/Microsoft.Web/locations/{region}/managedApis/servicebus"
      },
      "connection": { 
         "id": "/subscriptions/{subscription-ID}/resourcegroups/{resource-group-name}/providers/Microsoft.Web/connections/servicebus"
      }, 
      "connectionRuntimeUrl": "{connection-runtime-URL}",
      "authentication": { 
         "type": "Raw",
         "scheme": "Key",
         "parameter": "@appsetting('servicebus_1-connectionKey')"
      },
   },
   <...>
}

Azure Functions 连接

若要调用在 Azure Functions 中创建和托管的函数,请使用内置 Azure Functions 操作。 Azure Functions 调用的连接元数据与其他内置连接不同。 此元数据存储在逻辑应用项目的 connections.json 文件中,但看起来不同:

"functionConnections": {
   "{function-operation-name}": {
      "function": { 
         "id": "/subscriptions/{subscription-ID}/resourceGroups/{resource-group-name}/providers/Microsoft.Web/sites/{function-app-name}/functions/{function-name}"
      },
      "triggerUrl": "{function-url}",
      "authentication": {
        "type": "QueryString",
         "name": "Code",
         "value": "@appsetting('azureFunctionOperation_functionAppKey')"
      }, 
      "displayName": "{functions-connection-display-name}"
   },
   <...>
}

身份验证

在单租户 Azure 逻辑应用中,逻辑应用工作流的托管模型是单租户,与多租户模型相比,工作负载可从更多的隔离中受益。 此外,单租户 Azure 逻辑应用运行时是可移植的,这意味着你可以在其他环境中运行工作流(例如,在 Visual Studio Code 中以本地方式运行工作流)。 不过,此设计要求逻辑应用通过一种方法来验证其标识,以便它们可以访问 Azure 中的托管连接器生态系统。 使用托管连接时,应用还需要正确的权限才能运行操作。

默认情况下,每个基于单租户的逻辑应用都有一个自动启用的、系统分配的托管标识。 该标识与创建连接时使用的身份验证凭据或连接字符串不同。 在运行时,逻辑应用使用此标识通过 Azure 访问策略对连接进行身份验证。 如果禁用该标识,则运行时连接无效。

以下各节提供了更多关于身份验证类型的详细信息,你可以根据逻辑应用的运行位置,使用这些身份验证类型来对托管连接进行身份验证。 对于每个托管连接,逻辑应用项目的 connections.js 文件都有一个 authentication 对象,该对象指定逻辑应用可以用来验证该托管连接的身份验证类型。

托管标识

对于在 Azure 中托管和运行的逻辑应用,托管标识是默认的和推荐的身份验证类型,用于对 Azure 中托管和运行的托管连接进行身份验证。 在逻辑应用项目的 connections.json 文件中,托管连接有一个 authentication 对象,该对象指定 ManagedServiceIdentity 为身份验证类型:

"authentication": {
   "type": "ManagedServiceIdentity"
}

原始

对于使用 Visual Studio Code 在本地开发环境中运行的逻辑应用,将使用原始身份验证密钥来验证在 Azure 中托管和运行的托管连接。 这些密钥仅用于开发用途,不能用于生产,并且有效期为 7 天。 在逻辑应用项目的 connections.json 文件中,托管连接具有一个 authentication 对象,该对象指定以下身份验证信息:

"authentication": {
   "type": "Raw", 
   "scheme": "Key", 
   "parameter": "@appsetting('connectionKey')"
 }

后续步骤