【问题标题】:Logic Apps workflows via Terraform and Azure通过 Terraform 和 Azure 的逻辑应用工作流
【发布时间】:2022-02-16 22:22:40
【问题描述】:

我们有 Terraform 来创建和部署逻辑应用程序。

我们还在逻辑应用中创建了工作流。

我们希望自动创建逻辑应用程序和其中的工作流。

例如,请查看以下工作流程:

https://docs.microsoft.com/en-us/azure/logic-apps/tutorial-build-schedule-recurring-logic-app-workflow

【问题讨论】:

  • 使用 Terraform 创建和销毁服务时如何保持工作流?你能解释一下吗?您是在问逻辑应用程序是否被销毁然后工作流将存在?
  • 我们希望自动创建逻辑应用程序和其中的工作流。
  • 将继续努力并回来。谢谢。

标签: terraform-provider-azure


【解决方案1】:

部署逻辑应用工作流程时 terraform 存在限制您无法创建工作流程所需的 api 连接只能通过 arm 模板部署或从门户手动部署,然后需要在工作流中手动配置 喜欢 bingsmap 连接和outlook 连接

如果您开始从 terraform 部署逻辑应用程序,那么快速修复将是在手动创建工作流后参考工作流的 ARM 模板并转到逻辑应用程序代码视图,了解如何在 terraform 中编写自定义操作。

您可以只需从 terraform 部署 logicapp,然后使用逻辑应用代码视图中的代码从 terraform 部署 使用 azurerm_resource_group_template_deployment

参考资料:

Another SO thread where I have mentioned about configuring webapiconnections for logic app using ARM template

***Example provide by AZApril on how to use terraform to deploy logic app and then workflow using template deployment***


为了部署逻辑应用和工作流,您可以使用 terraform 中的以下内容:

provider "azurerm" {
  features{}
}

data "azurerm_resource_group" "example" {
  name="ansumantest"
}

resource "azurerm_logic_app_workflow" "example" {
  name                = "workflow1"
  location           = data.azurerm_resource_group.example.location
  resource_group_name = data.azurerm_resource_group.example.name
}

resource "azurerm_resource_group_template_deployment" "apiconnections" {
  name                = "group-deploy"
  resource_group_name = data.azurerm_resource_group.example.name
  deployment_mode     = "Incremental"
  template_content = <<TEMPLATE
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "connections_bingmaps_name": {
            "defaultValue": "bingmaps",
            "type": "string"
        },
        "connections_office365_name": {
            "defaultValue": "office365",
            "type": "string"
        }
    },
    "variables": {},
    "resources": [
        {
    "type": "Microsoft.Web/connections",
    "apiVersion": "2016-06-01",
    "name": "[parameters('connections_bingmaps_name')]",
    "location": "eastus",
    "kind": "V1",
    "properties": {
        "displayName": "BingMapsConnection",
        "statuses": [
            {
                "status": "Connected"
            }
        ],
        "customParameterValues": {},
        "nonSecretParameterValues": {},
        "createdTime": "2022-01-24T08:26:56.8147674Z",
        "changedTime": "2022-01-24T08:28:05.4634315Z",
        "api": {
            "name": "[parameters('connections_bingmaps_name')]",
            "displayName": "Bing Maps",
            "description": "Bing Maps",
            "iconUri": "[concat('https://connectoricons-prod.azureedge.net/releases/v1.0.1538/1.0.1538.2619/', parameters('connections_bingmaps_name'), '/icon.png')]",
            "brandColor": "#008372",
            "id": "[concat('/subscriptions/<subscriptionId>/providers/Microsoft.Web/locations/eastus/managedApis/', parameters('connections_bingmaps_name'))]",
            "type": "Microsoft.Web/locations/managedApis"
        },
        "testLinks": []
    }
},
{
    "type": "Microsoft.Web/connections",
    "apiVersion": "2016-06-01",
    "name": "[parameters('connections_office365_name')]",
    "location": "eastus",
    "kind": "V1",
    "properties": {
        "displayName": "<emailid>",
        "statuses": [
            {
                "status": "Connected"
            }
        ],
        "customParameterValues": {},
        "nonSecretParameterValues": {},
        "createdTime": "2022-01-24T08:33:55.8159813Z",
        "changedTime": "2022-01-24T08:35:04.9083183Z",
        "api": {
            "name": "[parameters('connections_office365_name')]",
            "displayName": "Office 365 Outlook",
            "description": "Microsoft Office 365 is a cloud-based service that is designed to help meet your organization's needs for robust security, reliability, and user productivity.",
            "iconUri": "[concat('https://connectoricons-prod.azureedge.net/releases/v1.0.1538/1.0.1538.2621/', parameters('connections_office365_name'), '/icon.png')]",
            "brandColor": "#0078D4",
            "id": "[concat('/subscriptions/<subscriptionId>/providers/Microsoft.Web/locations/eastus/managedApis/', parameters('connections_office365_name'))]",
            "type": "Microsoft.Web/locations/managedApis"
        },
        "testLinks": [
            {
                "requestUri": "[concat('https://management.azure.com:443/subscriptions/<subscriptionId>/resourceGroups/ansumantest/providers/Microsoft.Web/connections/', parameters('connections_office365_name'), '/extensions/proxy/testconnection?api-version=2016-06-01')]",
                "method": "get"
            }
        ]
    }
}
    ],
    "outputs": {
        "bingmapid":{
            "type": "string",
            "value" : "[resourceId('Microsoft.Web/connections', parameters('connections_bingmaps_name'))]"
        } ,
        "officeid": {
            "type": "string",
            "value": "[resourceId('Microsoft.Web/connections', parameters('connections_office365_name'))]"
        }
    }
}
TEMPLATE
depends_on = [
  azurerm_logic_app_workflow.example
]
}
locals {
  bingmapconnectionid = jsondecode(azurerm_resource_group_template_deployment.apiconnections.output_content).bingmapid.value
  office365connectionid = jsondecode(azurerm_resource_group_template_deployment.apiconnections.output_content).officeid.value
}
resource "azurerm_logic_app_trigger_recurrence" "trigger" {
  name         = "Recurrence"
  logic_app_id = azurerm_logic_app_workflow.example.id
  frequency    = "Week"
  interval     = 1
  schedule {
    at_these_minutes=[0,15,30,45]
    at_these_hours =["8","9","7"]
    on_these_days=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"]
  }
  depends_on = [
    azurerm_resource_group_template_deployment.apiconnections
  ]
}

resource "azurerm_logic_app_action_custom" "action1" {
  name         = "Get_route_and_travel_time_with_traffic"
  logic_app_id = azurerm_logic_app_workflow.example.id

  body = <<BODY
{
                            "runAfter": {},
                            "type": "ApiConnection",
                            "inputs": {
                                "host": {
                                    "connection": {
                                        "name": "${local.bingmapconnectionid}"
                                    }
                                },
                                "method": "get",
                                "path": "/V3/REST/V1/Routes/@{encodeURIComponent('Driving')}",
                                "queries": {
                                    "distanceUnit": "Mile",
                                    "optimize": "timeWithTraffic",
                                    "wp.0": "21930 SE 51st ,Issaugh,WA,98029",
                                    "wp.1": "3003 160th Ave,Bellevue,WA,98029"
                                }
                            }
                        }
BODY
depends_on = [
  azurerm_logic_app_trigger_recurrence.trigger
]
}
resource "azurerm_logic_app_action_custom" "action2" {
  name         = "Create_variable_to_store_travel_time"
  logic_app_id = azurerm_logic_app_workflow.example.id

  body = <<BODY
                       {
                "inputs": {
                    "variables": [
                        {
                            "name": "travelTime",
                            "type": "integer",
                            "value": "@div(body('Get_route_and_travel_time_with_traffic')?['travelDurationTraffic'],60)"
                        }
                    ]
                },
                "runAfter": {
                    "Get_route_and_travel_time_with_traffic": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable"
            }
BODY
depends_on = [
  azurerm_logic_app_action_custom.action1
]
}
resource "azurerm_logic_app_action_custom" "condition" {
  name         = "If_travel_time_exceeds_limit"
  logic_app_id = azurerm_logic_app_workflow.example.id

  body = <<BODY
{
                            "actions": {
                                "Send_email_with_travel_time": {
                                    "runAfter": {},
                                    "type": "ApiConnection",
                                    "inputs": {
                                        "body": {
                                            "Body": "<p>Add extra travel time (minutes): @{sub(variables('travelTime'),15)}</p>",
                                            "Subject": "Current travel time (minutes): @{variables('travelTime')}",
                                            "To": "admin@xxxxxxxxxx.onmicrosoft.com"
                                        },
                                        "host": {
                                            "connection": {
                                                "name": "${local.office365connectionid}"
                                            }
                                        },
                                        "method": "post",
                                        "path": "/v2/Mail"
                                    }
                                }
                            },
                            "runAfter": {
                                "Create_variable_to_store_travel_time": [
                                    "Succeeded"
                                ]
                            },
                            "expression": {
                                "and": [
                                    {
                                        "greater": [
                                            "@variables('travelTime')",
                                            15
                                        ]
                                    }
                                ]
                            },
                            "type": "If"
                        }
BODY
depends_on = [
  azurerm_logic_app_action_custom.action2
]
}

输出:

所有东西都已部署,但 api 连接在逻辑应用中出现错误,因此您必须手动或通过以下方式进行配置我在另一个 SO 线程中提到的解决方案

【讨论】:

  • 谢谢,我会看看再回来。第一个解决方案有点复杂。这个链接有更简单的解决方案吗? azapril.dev/2021/04/12/deploying-a-logicapp-with-terraform
  • @Pingpong,是的,如果您手动创建了工作流程,那么您可以从代码视图中获取代码并进行模板部署。
【解决方案2】:

您应该查看Logic Apps (Standard)。它们提供了更好的开发/部署体验。您可以创建Logic App Standard runtime using terraform 并使用Azure CI/CD pipelines 部署您的工作流。

但是,对于逻辑应用程序(标准),只有 three pricing tiers availabe:WS1、WS2 和 WS3。即使您的实例处于空闲状态,您也始终需要付费。逻辑应用(标准)将托管在应用服务中。 好处:您的工作流代码可以在 git 中进行源代码控制,并且您可以develop/debug locally in VSCode

所以归结为这个比较:

逻辑应用消费

优点

  • 您只需按使用量付费(消费定价模型)
  • 在 VSCode 本地开发,但没有调试(恕我直言) - VSCode 只是连接到 Azure

缺点

  • 目前自动化部署工作流非常困难(请参阅上面的复杂 terraform 脚本)
  • 不提供源代码控制
  • 您的工作流定义仅存在于 Azure 中
  • 没有 CI/CD

逻辑应用(标准)

优点

  • 可以通过 CI/CD 管道进行部署
  • 通过 git 对您的工作流程和连接进行源代码控制
  • VSCode 集成(使用可移植工作流运行时在本地开发和调试)
  • 可以参数化(也使用 appsettings)

缺点

  • 您必须运行完整的 AppService 才能进行托管
  • 最便宜的定价型号是 WS1,每月大约 130 美元

目前,我们决定运行标准模型,因为任何东西都可以使用 CI/CD 进行源代码控制和自动化。但是,我们只运行少量的工作流,成本很高。我们最好走消费的路。

【讨论】:

    猜你喜欢
    • 2017-08-28
    • 2021-01-27
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多