使用本地 Open API 标准文件为 Web 服务创建 ARM 模板

Using a local Open API Standard file to to create an ARM template for a web service

我正在处理一个旧的 Web 服务,我在其中使用自定义工具生成符合 OAS 标准的其余端点文档。使用此 OAS json 文件,我可以通过门户将 API 部署到 Azure API 管理服务,一切正常。但是,我需要自动执行此过程,因此需要使用 ARM 模板将所有 Web 服务部署到 Azure APIM。我一直在研究 https://docs.microsoft.com/en-us/azure/templates/microsoft.apimanagement/service/apis 提供的示例,但似乎无法理解如何使用本地 OAS.json 文件或 github 中的文件。

{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location for all resources."
      }
    }
  },
  "variables": {
    "apiManagementServiceName": "price-capture"
  },
  "resources": [    
    {      
      "apiVersion": "2018-01-01",
      "type": "Microsoft.ApiManagement/service/apis",
      "name": "[variables('apiManagementServiceName')]",
      "properties": {
        "displayName": "Service display Name",
        "apiRevision": "1",
        "description": "API description",
      //need help since it's not a swagger url 
      //wondering if there is a way to ref a local file like the option 
      //provided in the portal when we register api's manually.
        "serviceUrl": "----", 
        "path": "----",                            
        "protocols": [    
            "https"
        ],            
        "isCurrent": true,
        "apiVersion": "v1",
        "apiVersionDescription": "apiVersionDescription"        
      }
    }
  ]
}

我认为无法通过模板部署 APIs 配置。

我一直在尝试自己解决这个问题,但我很确定您不能在服务中包含您想要的实际 API。

据我所知,您不能使用 GIT 存储库执行此操作,因为它需要在门户中手动创建的身份验证

我认为您唯一可以使用 ARM 模板自动化的是实际的 API 管理服务,然后您需要使用 Azure API 添加和配置 API就可以了。

但是,我还没有想出自己该怎么做。

实际上我有一张服务单可以得到这方面的帮助。

您可以通过 ARM 模板在 API 管理上部署和配置整个 API,但您不能使用本地文件来提供 OpenApi/Swagger。 在您的情况下,OpenApi/Swagger 需要可公开访问,以便资源管理器可以从中读取,因此如果 Github URL 可以自由访问,它应该可以工作。 我通常将 OpenApi/Swagger 存储到存储帐户并使用 SAS 令牌从 ARM 模板访问它。

您可以查看此博客以了解有关在 API 中自动执行 API 部署的详细信息: https://blog.eldert.net/api-management-ci-cd-using-arm-templates-linked-template/

您可以使用 Microsoft.ApiManagement/service/apis 类型的 Azure Resource Manager 模板部署 API,要使用 Open API / swagger 定义,您需要指定 [= template

的 13=] 和 contentFormat 参数
{
  "name": "awesome-api-management/petstore",
  "type": "Microsoft.ApiManagement/service/apis",
  "apiVersion": "2018-06-01-preview",
  "properties": {
    "path": "petstore"
    "contentValue": "petstore swagger file contents here", // or it's URL
    "contentFormat": "swagger-json", // or swagger-link-json if externally available
    }
 }

API 略有变化,因此可以正常工作:

需要先将 yaml 文件 (calculatorApiFile) 上传到 blob 存储,但这可以作为部署管道的一部分完成

 {
            "type": "Microsoft.ApiManagement/service/apis",
            "apiVersion": "2019-01-01",
            "name": "[concat(parameters('service_name'), '/b12b1d5ab8204cg6b695e3e861fdd709')]",
            "dependsOn": [
                "[resourceId('Microsoft.ApiManagement/service', parameters('service_name'))]"
            ],
            "properties": {
                "displayName": "Calculator",
                "apiRevision": "1",
                "description": "A simple Calculator ",                   
                "path": "calc",
                "value": "[concat(parameters('containerUri'), parameters('calculatorApiFile'), parameters('containerSasToken'))]",
                "format": "openapi-link",
                "protocols": [
                    "https"
                ],
                "isCurrent": true
            }
        }  

我找到了答案..我所要做的就是编写一个 azure 函数,从私有 github 存储库中获取 oas.yaml 文件。

"variables":{
    "swagger_json":"[concat(parameters('url_of_azurefunctionwithaccesskey'),'&&githuburi='parameter('raw_url'),'&githubaccesstoken=',parameter('personalaccesstoken')]" 
},
"resources": [
        {
            "type": "Microsoft.ApiManagement/service/apis",
            "name": "[concat(parameters('apimName') ,'/' ,parameters('serviceName'))]",
            "apiVersion": "2018-06-01-preview",
            "properties": {
                "apiRevision": "[parameters('apiRevision')]",
                "path": "pricecapture",
                "contentValue": "[variables('swagger_json')]",
                "contentFormat": "openapi-link"
            }
        }]

我必须编写的 Azure 函数是这样的:

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.IO;
using System.Text;

public static async Task<HttpResponseMessage> Run(HttpRequest req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    var gitHubUri = req.Query["githuburi"];

    var gitHubAccessToken = req.Query["githubaccesstoken"];
    var encoding = Encoding.ASCII;
    if (string.IsNullOrEmpty(gitHubUri))
    {

        var errorcontent = new StringContent("please pass the raw file content URI (raw.githubusercontent.com) in the request URI string", Encoding.ASCII);
        return new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.BadRequest,
            Content = errorcontent
        };
    }
    else if (string.IsNullOrEmpty(gitHubAccessToken))
    {
        var errorcontent = new StringContent("please pass the GitHub personal access token in the request URI string", Encoding.ASCII);
        return new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.BadRequest,
            Content = errorcontent
        };
    }
    else
    {
        var strAuthHeader = "token " + gitHubAccessToken;
        var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3.raw");
        client.DefaultRequestHeaders.Add("Authorization", strAuthHeader);
        var response = await client.GetAsync(gitHubUri);
        return response;
    }
}

如果将 YAML 加载到变量中,则可以将其传递给 ARM 模板并作为值传递:

deploy.bat:

SETLOCAL EnableDelayedExpansion
set API_DEPLOYMENT=<deployment name>
set API_GROUP=<deployment group>
set API=<api file path.yml>
set OPENAPI=
for /f "delims=" %%x in ('type %API%') do set "OPENAPI=!OPENAPI!%%x\n"
call az deployment group create -n %API_DEPLOYMENT% -g %API_GROUP% --mode Complete -f deploy.json -p openApi="!OPENAPI!"
ENDLOCAL

deploy.json(注意replace的使用)

...
        {
            "type": "Microsoft.ApiManagement/service/apis",
            "apiVersion": "2020-12-01",
            "name": "[variables('apiName')]",
            "properties": {
                "path": "[variables('service')]",
                "apiType": "http",
                "displayName": "[variables('apiDisplayName')]",
                "format": "openapi",
                "value": "[replace(parameters('openApi'), '\n', '\n')]"
            },
            ...
        },
...