Sharat Bhaskar
Sharat Bhaskar

Reputation: 121

Problem when trying to update the Azure API Gateway operation backend via Terraform

All i want is to deploy my Azure API gateway with api operations which are defined in the open API yaml document. My below code deploys the windows function app and the API gateway and also i can see that my required operations are listed with in the API.

Issue is when i am importing the open API document, then i am not able to update the individual API operation backend which should be my Azure function app URL.

resource "azurerm_resource_group" "windows-function-rg" {
  name     = var.resource_group_name
  location = "west europe"

  tags = {
    "Environment"              = "Dev"
    "CostResponsible"          = "IT"
    "projectName"              = "crm-cost-estimate"
    "aks-managed-cluster-name" = "unknown"
  }
}



resource "azurerm_storage_account" "windows-storage-account" {
  name                     = var.storage_account_name
  resource_group_name      = azurerm_resource_group.windows-function-rg.name
  location                 = azurerm_resource_group.windows-function-rg.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  tags = {
    "Environment"              = "Dev"
    "CostResponsible"          = "IT"
    "projectName"              = "crm-cost-estimate"
    "aks-managed-cluster-name" = "unknown"
  }
}


resource "azurerm_service_plan" "windows-service-plan" {
  name                = var.service_plan_name
  resource_group_name = azurerm_resource_group.windows-function-rg.name
  location            = azurerm_resource_group.windows-function-rg.location
  os_type             = "Windows"
  sku_name            = "Y1"
  tags = {
    "Environment"              = "Dev"
    "CostResponsible"          = "IT"
    "projectName"              = "crm-cost-estimate"
    "aks-managed-cluster-name" = "unknown"
  }
}

resource "azurerm_application_insights" "windows-application-insights" {
  name                = "application-insights-${var.azurerm_windows_function_app}"
  location            = azurerm_resource_group.windows-function-rg.location
  resource_group_name = azurerm_resource_group.windows-function-rg.name
  application_type    = "Node.JS"
  tags = {
    "Environment"              = "Dev"
    "CostResponsible"          = "IT"
    "projectName"              = "crm-cost-estimate"
    "aks-managed-cluster-name" = "unknown"
  }
  depends_on = [ azurerm_resource_group.windows-function-rg ]
}


resource "azurerm_windows_function_app" "windows-python-linux-function-app" {
  name                = var.azurerm_windows_function_app
  resource_group_name = azurerm_resource_group.windows-function-rg.name
  location            = azurerm_resource_group.windows-function-rg.location

  service_plan_id            = azurerm_service_plan.windows-service-plan.id
  storage_account_name       = azurerm_storage_account.windows-storage-account.name
  storage_account_access_key = azurerm_storage_account.windows-storage-account.primary_access_key
  https_only                 = true
  site_config {
    application_insights_key               = azurerm_application_insights.windows-application-insights.instrumentation_key

    application_insights_connection_string = azurerm_application_insights.windows-application-insights.connection_string
    application_stack {
      node_version = "~18" #FUNCTIONS_WORKER_RUNTIME        
    }
  }
  app_settings = {
    "APPINSIGHTS_INSTRUMENTATIONKEY" = "${azurerm_application_insights.windows-application-insights.instrumentation_key}"
  }
  tags = {
    "Environment"              = "Dev"
    "CostResponsible"          = "IT"
    "projectName"              = "crm-cost-estimate"
    "aks-managed-cluster-name" = "unknown"
  }

}





resource "azurerm_api_management" "sharatapim" {
  name                = "sharattes-apim-func-001"
  location            = azurerm_resource_group.windows-function-rg.location
  resource_group_name = azurerm_resource_group.windows-function-rg.name
  publisher_name      = "sharat"
  publisher_email     = "[email protected]"
  sku_name            = "Consumption_0"


}


resource "azurerm_api_management_backend" "sharatapibackend" {
  name                = "sharattes-apim-backend-001"
  resource_group_name = azurerm_resource_group.windows-function-rg.name
  api_management_name = azurerm_api_management.sharatapim.name
  protocol            = "http"
  url                 = "https://my-function-app-url/api"

  depends_on          = [azurerm_resource_group.windows-function-rg,
                         azurerm_api_management.sharatapim,
                         azurerm_windows_function_app.windows-python-linux-function-app]

  credentials {
    header = {
      "x-functions-key" = "{{sharattes-apim-backend-001}}"
    }
  }

}

data "azurerm_function_app_host_keys" "functionkeys" {
  name                = azurerm_windows_function_app.windows-python-linux-function-app.name
  resource_group_name = azurerm_resource_group.windows-function-rg.name


}



resource "azurerm_api_management_api" "sharatapimgmntapi" {
  name                = "sharattes-import-api-001"
  resource_group_name = azurerm_resource_group.windows-function-rg.name
  api_management_name = azurerm_api_management.sharatapim.name
  revision            = "1"
  display_name        = "sharat-latestAPI"
  path                = ""
  protocols           = ["https"]

  import {
    content_format = "openapi"
    content_value  = file("${path.module}/ExtranetAPIopenapi.yaml")

  }

 depends_on = [azurerm_windows_function_app.windows-python-linux-function-app]
}

resource "azurerm_api_management_api_operation" "health" {

    api_management_name = azurerm_api_management.sharatapim.name
    api_name = azurerm_api_management_api.sharatapimgmntapi.name
    display_name = "health"
    method = "GET"
    operation_id = "healthy"
    resource_group_name = azurerm_resource_group.windows-function-rg.name
    url_template = "/health"
    response {
        status_code = 200
    }
    response {
        status_code = 500
    }

}

resource "azurerm_api_management_api_operation_policy" "example" {

  api_name            = azurerm_api_management_api.sharatapimgmntapi.name
  api_management_name = azurerm_api_management.sharatapim.name
  operation_id        = "healthy"
  resource_group_name = azurerm_resource_group.windows-function-rg.name

  xml_content = <<XML
<policies>
  <inbound>
    <base />
    <set-backend-service id="apim-generated-policy" backend-id="sharattes-functionapp-001" />
  </inbound>
</policies>
XML

  depends_on = [
    azurerm_windows_function_app.windows-python-linux-function-app
    
  ]
}

Error Messages:

│ Error: creating/updating Operation (Subscription: "xxxxxxxxxxxxxxxxxx" │ Resource Group Name: "sharattes-rg-test-001" │ Service Name: "sharattes-apim-func-001" │ Api: "sharattes-import-api-001" │ Operation: "healthy"): unexpected status 400 with error: ValidationError: One or more fields contain incorrect values: │ │ with azurerm_api_management_api_operation.health, │ on main.tf line 215, in resource "azurerm_api_management_api_operation" "health": │ 215: resource "azurerm_api_management_api_operation" "health" { │ ╵ ╷

│ Error: creating or updating Operation (Subscription: "xxxxxxxxx" │ Resource Group Name: "sharattes-rg-test-001" │ Service Name: "sharattes-apim-func-001" │ Api: "sharattes-import-api-001" │ Operation: "healthy"): unexpected status 400 with error: ValidationError: Entity with specified identifier not found │ │ with azurerm_api_management_api_operation_policy.example, │ on main.tf line 252, in resource "azurerm_api_management_api_operation_policy" "example": │ 252: resource "azurerm_api_management_api_operation_policy" "example" { │ ╵ PS C:\Users\sbhaskar\Desktop\testing_api>

Upvotes: 0

Views: 439

Answers (1)

Jahnavi
Jahnavi

Reputation: 8018

Problem when trying to update the Azure API Gateway operation backend via Terraform:

I have made below changes to your code and was able to deploy it succcessfully.

Identifier in policy content is not properly given. Modify your policy content as <set-backend-service backend-id="sharattes-apim-backend-001jjj" />. And also made few other changes accordingly to meet your requirement.

provider "azurerm" {
  features {
   
  }
}
 
data "azurerm_resource_group" "windows-function-rg" {
  name     = "xxx"
}
 
 data "azurerm_storage_account" "windows-storage-account" {
  name                     = "functionsappjah"
  resource_group_name      = data.azurerm_resource_group.windows-function-rg.name
}
 
 
resource "azurerm_service_plan" "windows-service-plan" {
  name                = "apikurk"
  resource_group_name = data.azurerm_resource_group.windows-function-rg.name
  location            = data.azurerm_resource_group.windows-function-rg.location
  os_type             = "Windows"
  sku_name            = "Y1"
}
 
resource "azurerm_application_insights" "windows-application-insights" {
  name                = "application-insights-jah"
  location            = data.azurerm_resource_group.windows-function-rg.location
  resource_group_name = data.azurerm_resource_group.windows-function-rg.name
  application_type    = "Node.JS"
  depends_on = [ data.azurerm_resource_group.windows-function-rg ]
}
 
 
resource "azurerm_windows_function_app" "windows-python-linux-function-app" {
  name                = "kurkfuncj"
  resource_group_name = data.azurerm_resource_group.windows-function-rg.name
  location            = data.azurerm_resource_group.windows-function-rg.location
 
  service_plan_id            = azurerm_service_plan.windows-service-plan.id
  storage_account_name       = data.azurerm_storage_account.windows-storage-account.name
  storage_account_access_key = data.azurerm_storage_account.windows-storage-account.primary_access_key
  https_only                 = true
  site_config {
    application_insights_key      = azurerm_application_insights.windows-application-insights.instrumentation_key
 
    application_insights_connection_string = azurerm_application_insights.windows-application-insights.connection_string
    application_stack {
      node_version = "~18" #FUNCTIONS_WORKER_RUNTIME        
    }
  }
  app_settings = {
    "APPINSIGHTS_INSTRUMENTATIONKEY" = "${azurerm_application_insights.windows-application-insights.instrumentation_key}"
  }
}
 
resource "azurerm_api_management" "sharatapim" {
  name                = "sharattes-apim-func-001jjj"
  location            = data.azurerm_resource_group.windows-function-rg.location
  resource_group_name = data.azurerm_resource_group.windows-function-rg.name
  publisher_name      = "sharat"
  publisher_email     = "[email protected]"
  sku_name            = "Consumption_0"
 
 
}
 
 
resource "azurerm_api_management_backend" "sharatapibackend" {
  name                = "sharattes-apim-backend-001jjj"
  resource_group_name = data.azurerm_resource_group.windows-function-rg.name
  api_management_name = azurerm_api_management.sharatapim.name
  protocol            = "http"
  url                 = "https://my-function-app-url/api"
 
  depends_on          = [data.azurerm_resource_group.windows-function-rg,
                         azurerm_api_management.sharatapim,
                         azurerm_windows_function_app.windows-python-linux-function-app]
 
  credentials {
    header = {
      "x-functions-key" = "[sharattes-apim-backend-001]"
    }
  }
 
}
 
data "azurerm_function_app_host_keys" "functionkeys" {
  name                = azurerm_windows_function_app.windows-python-linux-function-app.name
  resource_group_name = data.azurerm_resource_group.windows-function-rg.name
 
 
}
 
 
resource "azurerm_api_management_api" "sharatapimgmntapi" {
  name                = "sharattes-import-api-001"
  resource_group_name = data.azurerm_resource_group.windows-function-rg.name
  api_management_name = azurerm_api_management.sharatapim.name
  revision            = "1"
  display_name        = "sharat-latestAPI"
  path                = ""
  protocols           = ["https"]
 
depends_on = [azurerm_windows_function_app.windows-python-linux-function-app]
}
 
resource "azurerm_api_management_api_operation" "health" {
 
    api_management_name = azurerm_api_management.sharatapim.name
    api_name = azurerm_api_management_api.sharatapimgmntapi.name
    display_name = "health"
    method = "GET"
    operation_id = "healthy"
    resource_group_name = data.azurerm_resource_group.windows-function-rg.name
    url_template = "/health"
    response {
        status_code = 200
    }
    response {
        status_code = 500
    }
 
}
 
resource "azurerm_api_management_api_operation_policy" "example" {
 
  api_name            = azurerm_api_management_api.sharatapimgmntapi.name
  api_management_name = azurerm_api_management.sharatapim.name
  operation_id        = azurerm_api_management_api_operation.health.operation_id
  resource_group_name = data.azurerm_resource_group.windows-function-rg.name
 
  xml_content = <<XML
<policies>
  <inbound>
    <set-backend-service backend-id="sharattes-apim-backend-001jjj" />
  </inbound>
</policies>
XML
 
  depends_on = [
    azurerm_windows_function_app.windows-python-linux-function-app
   
  ]
}

Deployment succeeded:

enter image description here

enter image description here

enter image description here

Upvotes: 1

Related Questions