hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.59k stars 4.62k forks source link

Importing the updated OpenSpec file is taking longer time and doesn't deploy in the Azure APIM service. #24559

Closed nikhil0499 closed 8 months ago

nikhil0499 commented 9 months ago

Is there an existing issue for this?

Community Note

Terraform Version

v1.6.6

AzureRM Provider Version

v3.0.0

Affected Resource(s)/Data Source(s)

az

Terraform Configuration Files

resource "azurerm_api_management_api" "SampleAPI" {
  name                = "SampleAPI"
  resource_group_name = data.azurerm_resource_group.rg001.name
  api_management_name = data.azurerm_api_management.apim-devtest.name
  revision            = "1"
  display_name        = "SampleAPI"
  path                = "v1/servicenow"
  protocols           = ["https"]

  import {
    content_format = "openapi"
    content_value  = file("${path.module}/OpenSpec/api-sample.yaml")
  }
}

Debug Output/Panic Output

azurerm_api_management_api.SampleAPI: Still modifying... [id=/subscriptions/7********/apim-devtest/apis/SampleAPI, 3m10s elapsed]
azurerm_api_management_api.SampleAPI: Still modifying... [id=/subscriptions/7******/apim-devtest/apis/SampleAPI, 3m20s elapsed]
azurerm_api_management_api.SampleAPI: Still modifying... [id=/subscriptions/7*******/apim-devtest/apis/SampleAPI, 3m30s elapsed]
Future#WaitForCompletion: the number of retries has been exceeded: StatusCode=400 -- Original Error: Code="ValidationError" Message="One or more fields contain incorrect values:" Details=[{"code":"ValidationError","message":"API with specified name 'SampleAPI ' already exists","target":"name"}]

Expected Behaviour

Import the APIs into Azure APIM which is updated in OpenSpec File.

Actual Behaviour

Taking long time and doesn't deploy it to Azure APIM and fails with an error.

Steps to Reproduce

No response

Important Factoids

No response

References

No response

sinbai commented 9 months ago

Hi @nikhil0499 thanks for opening this issue. In order to find the root cause, a Terraform configuration file (containing dependent resources, and the api-sample.yaml file) and detailed steps would be of great help in quickly reproducing/troubleshooting the issue. Could you please provide the complete Terraform configuration and detailed repro steps to help reproduce this issue? Thanks in advanced.

nikhil0499 commented 9 months ago

Hi @sinbai, Sure let me provide the required details. 1)Please find the terraform configuration file below:

resource "azurerm_api_management_api" "SampleAPI" {
  name                = "SampleAPI"
  resource_group_name = data.azurerm_resource_group.rg001.name
  api_management_name = data.azurerm_api_management.apim-devtest.name
  revision            = "1"
  display_name        = "SampleAPI"
  path                = "v1/servicenow"
  protocols           = ["https"]

  import {
    content_format = "openapi"
    content_value  = file("${path.module}/OpenSpec/api-sample.yaml")
  }
}

2)OpenAPI file - api-sample.yaml

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://petstore.swagger.io/v1
paths:
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      tags:
        - pets
      parameters:
        - name: limit
          in: query
          description: How many items to return at one time (max 100)
          required: false
          schema:
            type: integer
            format: int32
      responses:
        200:
          description: An paged array of pets
          headers:
            x-next:
              description: A link to the next page of responses
              schema:
                type: string
          content:
            application/json:    
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"**
components:
  schemas:
    Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"
    Error:
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string

3) Using this as an input , use terraform plan and apply the changes to deploy this new API.

terraform plan
terraform apply

4)After this make some changes in OpenSpec file , lets say I add a new operation to it. Updated OpenAPI file - api-sample.yaml file

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://petstore.swagger.io/v1
paths:
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      tags:
        - pets
      parameters:
        - name: limit
          in: query
          description: How many items to return at one time (max 100)
          required: false
          schema:
            type: integer
            format: int32
      responses:
        200:
          description: An paged array of pets
          headers:
            x-next:
              description: A link to the next page of responses
              schema:
                type: string
          content:
            application/json:    
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    post:
      summary: Create a pet
      operationId: createPets
      tags:
        - pets
      responses:
        201:
          description: Null response
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /pets/{petId}:
    get:
      summary: Info for a specific pet
      operationId: showPetById
      tags:
        - pets
      parameters:
        - name: petId
          in: path
          required: true
          description: The id of the pet to retrieve
          schema:
            type: string
      responses:
        200:
          description: Expected response to a valid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
components:
  schemas:
    Pet:
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        tag:
          type: string
    Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"
    Error:
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string

5) After this, again run the terraform plan and apply this changes.

terraform plan
terraform apply

6)This is where it errors out: Future#WaitForCompletion: the number of retries has been exceeded: StatusCode=400 -- Original Error: Code="ValidationError" Message="One or more fields contain incorrect values:" Details=[{"code":"ValidationError","message":"API with specified name 'Swagger Petstore' already exists","target":"name"}]

Please let me know if you need any further details. Thanks, Nikhil

sinbai commented 9 months ago

@nikhil0499 thanks for the information. Unfortunately, when I ran the terraform apply command in step 3) , I encountered the following error:


"error":{"code":"ValidationError","message":"One or more fields contain incorrect values:",
"details":[{"code":"ValidationError","target":"representation","message":"Parsing error(s): (Lin: 40, Col: 50, Chr: 1047) - (Lin: 40, Col: 51, Chr: 1048): While scanning an anchor or alias, did not find expected alphabetic or numeric character."},{"code":"ValidationError","target":"representation","message":"Parsing error(s): The input OpenAPI file is not valid for the OpenAPI specification https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md (schema https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v3.0/schema.yaml)."}]}}

​ From above error message (returned by Azure Rest API), we can see that there seems to be an error in the content of provided spec file. It is recommended to check whether the file content is correct and try again. Also, since Terraform does not verify the validity of the OpenAPI-spec content, if there are no errors in providing the spec content but you still receive an error message, it is recommended to create an issue in this repository to request assistance.

Note: May be you can use openapi-spec-validator to verify the spec?

nikhil0499 commented 9 months ago

Hi @sinbai , Apologies for the confusion, the OpenAPI which I used was different from which I gave in the above example. It would be great if you can please try using your own spec file and try to replicate this. Thanks, Nikhil

nikhil0499 commented 9 months ago

Is there any way to label this or refer this issue to the repository which you have mentioned?

sinbai commented 9 months ago

Hi @sinbai , Apologies for the confusion, the OpenAPI which I used was different from which I gave in the above example. It would be great if you can please try using your own spec file and try to replicate this. Thanks, Nikhil

I could not reproduce this issue with my own OpenAPI spec file after running terraform apply from step 5 above, as detailed below.

image

D:\TerraformTest\APIM-investigate>terraform apply -auto-approve
azurerm_resource_group.test: Refreshing state... [id=/subscriptions/xxx/resourceGroups/acctestRG-elena-0122-24559]
azurerm_api_management.test: Refreshing state... [id=/subscriptions/xxx/resourceGroups/acctestRG-elena-0122-24559/providers/Microsoft.ApiManagement/service/acctestAM-westeurope]
azurerm_api_management_api.test: Refreshing state... [id=/subscriptions/xxx/resourceGroups/acctestRG-elena-0122-24559/providers/Microsoft.ApiManagement/service/acctestAM-westeurope/apis/SampleAPI]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # azurerm_api_management_api.test will be updated in-place
  ~ resource "azurerm_api_management_api" "test" {
        id                    = "/subscriptions/xxx/resourceGroups/acctestRG-elena-0122-24559/providers/Microsoft.ApiManagement/service/acctestAM-westeurope/apis/SampleAPI"
        name                  = "SampleAPI"
        # (11 unchanged attributes hidden)

      ~ import {
          ~ content_value  = <<-EOT
                # Copyright (c) HashiCorp, Inc.
                # SPDX-License-Identifier: MPL-2.0

                openapi: 3.0.0
                info:
                  title: api1
                  description: api
                  version: 1.0.0
                servers:
                  - url: "https://terraform.com/test/v1/api1"
                    description: test
                paths:
                  /default:
              +     get:
              +       summary: List all pets
              +       operationId: listPets
              +       tags:
              +         - pets
              +       parameters:
              +         - name: limit
              +           in: query
              +           description: How many items to return at one time (max 100)
              +           required: false
              +           schema:
              +             type: integer
              +             format: int32
              +       responses:
              +         200:
              +           description: An paged array of pets
              +           headers:
              +             x-next:
              +               description: A link to the next page of responses
              +               schema:
              +                 type: string
              +           content:
              +             application/json:
              +               schema:
              +                 $ref: "#/components/schemas/Pets"
              +         default:
              +           description: unexpected error
              +           content:
              +             application/json:
              +               schema:
              +                 $ref: "#/components/schemas/Error"
                    post:
                      operationId: default
                      summary: Default
                      description: Default operation
                      responses:
                        "200":
                          description: Accepted
                          content:
                            application/json:
                              schema:
                                $ref: "#/components/schemas/response"
                components:
                  schemas:
              +     Pet:
              +       required:
              +         - id
              +         - name
              +       properties:
              +         id:
              +           type: integer
              +           format: int64
              +         name:
              +           type: string
              +         tag:
              +           type: string
              +     Pets:
              +       type: array
              +       items:
              +         $ref: "#/components/schemas/Pet"
                    response:
                      type: object
                      properties:
                        status:
                          type: string
                          example: success
              +     Error:
              +       required:
              +         - code
              +         - message
              +       properties:
              +         code:
              +           type: integer
              +           format: int32
              +         message:
              +           type: string
                  securitySchemes:
                    basicAuth:
                      type: http
                      scheme: basic
            EOT
            # (1 unchanged attribute hidden)
        }

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
azurerm_api_management_api.test: Modifying... [id=/subscriptions/xxx/resourceGroups/acctestRG-elena-0122-24559/providers/Microsoft.ApiManagement/service/acctestAM-westeurope/apis/SampleAPI]
azurerm_api_management_api.test: Still modifying... [id=/subscriptions/85b3dbca-5974-4067-9669-...ce/acctestAM-westeurope/apis/SampleAPI, 10s elapsed]
azurerm_api_management_api.test: Still modifying... [id=/subscriptions/85b3dbca-5974-4067-9669-...ce/acctestAM-westeurope/apis/SampleAPI, 20s elapsed]
azurerm_api_management_api.test: Modifications complete after 28s [id=/subscriptions/xxx/resourceGroups/acctestRG-elena-0122-24559/providers/Microsoft.ApiManagement/service/acctestAM-westeurope/apis/SampleAPI]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

Based on the following provided error message (returned by the Azure Rest API), it appears that the Swagger Petstore API name already exists, you can check to see if this is the case in the Azure portal. In addition, it is recommended to check the TF_LOG information to see why it took a long time and what was specifically done during this time. Hope this information is helpful to you.

Future#WaitForCompletion: the number of retries has been exceeded: StatusCode=400 -- Original Error: Code="ValidationError" Message="One or more fields contain incorrect values:" Details=[{"code":"ValidationError","message":"API with specified name 'Swagger Petstore' already exists","target":"name"}]

nikhil0499 commented 9 months ago

Sure, Thanks @sinbai . After few tries again now its working. Now terraform is able to push the updated OpenSpec and update the operations in API. Not sure where this error exactly happened. Let me check the logs during the time of error.

Thanks, Nikhil

nikhil0499 commented 8 months ago

Hi @sinbai , Thanks for the help, I am able to update the operations in azure APIM , yet I am not able to find the root cause for the error which it caused before. With this I am closing the issue. If I face this issue again, I will reopen an issue. Thanks, Nikhil

github-actions[bot] commented 5 months ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.