skip to Main Content

I’m trying to add endpoints from 2 Swagger.json files to an existing common API management API via Terraform.

Common API definition:

resource "azurerm_api_management_api" "test_api" {
  provider            = azurerm.test
  name                = "test"
  api_management_name = var.apim_name
  resource_group_name = var.common_rg
  display_name        = "test"
  description         = "test APIM"
  path                = "test"
  revision            = "1"
  protocols           = ["https"]

  subscription_key_parameter_names {
    header = "Ocp-Apim-Subscription-Key"
    query  = "subscription-key"
  }
}

Normally you can just add:

  import {
    content_format = "openapi+json"
    content_value  = data.test_swagger.content
  }

But it only accepts 1 file.

I could obviously merge multiple Swaggers using Powershell or use Az cli to do import multiple files, but if there’s a way to do it via Terraform it would be a cleaner solution.

I tried playing with creating multiple azurerm_api_management_api resources and referencing test_api via source_api_id.

Also tried creating a azurerm_api_management_api_schema, but turned out it’s not anything I wanted.

Does Terraform support importing (appending) multiple openapi jsons?

2

Answers


  1. Chosen as BEST ANSWER

    Since the above solution didn't work for me, I came up with a powershell script wrapped into a null_resource, which works nice.

    One thing to remember is the -Force flag, which basically will overwrite some objects if there are duplicates. For me it was ProblemDetails component.

    locals {
      swaggerFiles = "swagger1.json,swagger2.json"
      mergedSwaggerName = "merged_swagger.json"
    }
    
    data "local_file" "merged_swagger" {
      depends_on = [null_resource.apim_swagger_merger]
      filename = local.mergedSwaggerName
    }
    
    resource "null_resource" "apim_swagger_merger" {
      triggers = {
        always_run = timestamp()
      }
      
      provisioner "local-exec" {
        interpreter = ["pwsh", "-Command"]
        command = <<EOT
    
        $ErrorActionPreference = "Stop"
    
        $InputDirectory = "./"
    
        Write-Host "Merging Swagger files"
    
        $Filenames = "${local.swaggerFiles}" -Split ","
    
        $SwaggerFiles = Get-ChildItem -Path $InputDirectory -Include $Filenames -Recurse
        $OutputContent = Get-Content -Path $SwaggerFiles[0].FullName | ConvertFrom-Json
        
        $Paths = [PSCustomObject]@{}
        $ComponentSchemas = [PSCustomObject]@{}
        
        foreach ($File in $SwaggerFiles) {
            $Content = Get-Content -Path $File.FullName | ConvertFrom-Json
        
            foreach ($Prop in $Content.paths.psobject.properties) {
                $Name = $Prop.Name
                $Value = $Prop.Value
                $Paths | Add-Member -Name $Name -Type NoteProperty -Value $Value
            }
        
            foreach ($Prop in $Content.components.schemas.psobject.properties) {
                $Name = $Prop.Name
                $Value = $Prop.Value
                $ComponentSchemas | Add-Member -Name $Name -Type NoteProperty -Value $Value -Force
            }
        }
        
        $OutputContent.paths = $Paths
        $OutputContent.components.schemas = $ComponentSchemas 
        
        $OutputContent | ConvertTo-Json -Depth 100 | Out-File -FilePath ${local.mergedSwaggerName} -Force
        
        Write-Host "Finished merging Swagger files"
    
        EOT
      }
    }
    

  2. Import multiple OpenApi documents into existing Azure Api management API via Terraform

    The requirement you mentioned is not properly supported by terraform this is because of Azure API mangement provider only supports one import at a time per API resource.

    This importing referencing as single openAPI/Swagger file which doesnt included more than one. If you still have multiple file better to merge them into single file as merged file and use in terraform

    configuration:

    data "azurerm_api_management" "apim" {
      name                = "demo-apim-instance" 
      resource_group_name = data.azurerm_resource_group.rg.name
    }
    
    resource "null_resource" "merge_and_import_swagger" {
      depends_on = [data.azurerm_api_management.apim]
    
      provisioner "local-exec" {
        interpreter = ["pwsh", "-Command"]
    
        command = <<EOT
        # Define variables
        $InputDirectory = "./" # Directory containing swagger1 and swagger2
        $MergedFile = "./merged-swagger.json"
        $ApiManagementName = "${data.azurerm_api_management.apim.name}"
        $ResourceGroupName = "${data.azurerm_resource_group.rg.name}"
        $ApiName = "demo-api" # Replace with your desired API name
    
        # Merge all JSON/YAML Swagger files in the directory
        Write-Host "Merging Swagger files from $InputDirectory..."
        $swaggerFiles = Get-ChildItem -Path $InputDirectory -Include swagger1.json, swagger2.json -Recurse
        $mergedContent = @{}
    
        foreach ($file in $swaggerFiles) {
            $content = Get-Content -Path $file.FullName | ConvertFrom-Json
            $mergedContent += $content
        }
    
        # Save the merged Swagger file
        $mergedContent | ConvertTo-Json -Depth 100 | Out-File -FilePath $MergedFile -Force
        Write-Host "Merged Swagger file saved to $MergedFile"
    
        # Import the merged Swagger file into API Management
        Write-Host "Importing Swagger into API Management..."
        az apim api import --resource-group $ResourceGroupName `
                           --service-name $ApiManagementName `
                           --path $ApiName `
                           --specification-url $MergedFile `
                           --format swagger-json
    
        Write-Host "Swagger import complete!"
        EOT
      }
    }
    

    deployment:

    enter image description here

    enter image description here

    Refer:

    https://learn.microsoft.com/en-us/azure/api-management/azure-openai-api-from-specification

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search