Terraform을 사용하여 Azure API Management에 OpenAPI 배포

OpenAPI 정의를 API Management에 배포해야 합니다. 배포는 Terraform으로 수행됩니다. 업데이트된 OpenAPI 정의가 API Management API 및 작업도 업데이트하나요?

전체 코드는 GitHubhttps://github.com/PlanBGmbH/usecases.azure.apimanagement/tree/main/src/APIM-with-OpenAPI에서 찾을 수 있습니다.

목차



1 Terraform
2 Create API
3 Update API

1 테라포밍

With Terraform , API Management 및 예제 API도 생성됩니다.
따라서 로컬 OpenAPI 정의 파일을 가져와야 합니다.

resource "azurerm_api_management" "example" {
  name                = var.apim_name
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  publisher_name      = "PlanB. GmbH"
  publisher_email     = "[email protected]"

  sku_name = "Developer_1"
}

resource "azurerm_api_management_api" "example" {
  name                = "example-api"
  resource_group_name = azurerm_resource_group.rg.name
  api_management_name = azurerm_api_management.example.name
  revision            = "1"
  display_name        = "Example API"
  path                = "example"
  protocols           = ["https"]

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


2 API 생성

The initial version of the OpenAPI contains only the path '/users/{username}' with a GET and PUT operation.
The OpenAPI definition is copied from
https://github.com/Redocly/openapi-template/blob/gh-pages/openapi.yaml

# This is an **example** API to demonstrate features of OpenAPI specification.
# It doesn't cover all OpenAPI features. For more full example check out: https://github.com/APIs-guru/petstore_extended

openapi: 3.0.1
info:
  version: '1.0.0' # Your API version
  # It can be any string but it is better to use semantic versioning: http://semver.org/
  # Warning: OpenAPI requires the version to be a string, but without quotation marks YAML can recognize it as a number.

  title: Example.com # Replace with your API title
  # Keep it simple. Don't add "API" or version at the end of the string.

  termsOfService: 'https://example.com/terms/' # [Optional] Replace with an URL to your ToS
  contact:
    email: [email protected] # [Optional] Replace with your contact email
    url: 'http://example.com/contact' # [Optional] Replace with link to your contact form
  license:
    name: Apache 2.0
    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
  x-logo:
    url: 'https://redocly.github.io/openapi-template/logo.png'

  # Describe your API here, you can use GFM (https://guides.github.com/features/mastering-markdown) here
  description: |
    This is an **example** API to demonstrate features of OpenAPI specification
    # Introduction
    This API definition is intended to to be a good starting point for describing your API in 
    [OpenAPI/Swagger format](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).
    It also demonstrates features of [create-openapi-repo](https://github.com/Redocly/create-openapi-repo) tool and 
    [Redoc](https://github.com/Redocly/Redoc) documentation engine. So beyond the standard OpenAPI syntax we use a few 
    [vendor extensions](https://github.com/Redocly/Redoc/blob/master/docs/redoc-vendor-extensions.md).
    # OpenAPI Specification
    The goal of The OpenAPI Specification is to define a standard, language-agnostic interface to REST APIs which
    allows both humans and computers to discover and understand the capabilities of the service without access to source
    code, documentation, or through network traffic inspection. When properly defined via OpenAPI, a consumer can 
    understand and interact with the remote service with a minimal amount of implementation logic. Similar to what
    interfaces have done for lower-level programming, OpenAPI removes the guesswork in calling the service.
externalDocs:
  description: Find out how to create a GitHub repo for your OpenAPI definition.
  url: 'https://github.com/Rebilly/generator-openapi-repo'

# A list of tags used by the definition with additional metadata.
# The order of the tags can be used to reflect on their order by the parsing tools.
  - name: User
    description: Operations about user
servers:
  - url: 'http://example.com/api/v1'
  - url: 'https://example.com/api/v1'

# Holds the relative paths to the individual endpoints. The path is appended to the
# basePath in order to construct the full URL. 
paths:
  '/users/{username}': # path parameter in curly braces

    # parameters list that are used with each operation for this path
    parameters:
      - name: pretty_print
        in: query
        description: Pretty print response
        schema:
          type: boolean
    get: # documentation for GET operation for this path
      tags:
        - User

      # summary is up to 120 symbold but we recommend to be shortest as possible
      summary: Get user by user name

      # you can use GFM in operation description too: https://guides.github.com/features/mastering-markdown
      description: |
        Some description of the operation. 
        You can use `markdown` here.

      # operationId should be unique across the whole specification
      operationId: getUserByName

      # list of parameters for the operation
      parameters:
        - name: username
          in: path
          description: The name that needs to be fetched
          required: true
          schema:
            type: string
        - name: with_email
          in: query
          description: Filter users without email
          schema:
            type: boolean

      # security schemas applied to this operation
      security:
        - main_auth:
            - 'read:users' # for oauth2 provide list of scopes here
        - api_key: []
      responses: # list of responses
        '200':
          description: Success
          content:
            application/json: # operation response mime type
              schema: # response schema can be specified for each response
                $ref: '#/components/schemas/User'
              example: # response example
                username: user1
                email: [email protected]
        '403':
          description: Forbidden
        '404':
          description: User not found
    # documentation for PUT operation for this path
    put:
      tags:
        - User
      summary: Updated user
      description: This can only be done by the logged in user.
      operationId: updateUser
      parameters:
        - name: username
          in: path
          description: The name that needs to be updated
          required: true
          schema:
            type: string
      security:
        - main_auth:
            - 'write:users'
      responses:
        '200':
          description: OK
        '400':
          description: Invalid user supplied
        '404':
          description: User not found
      # request body documentation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
          application/xml:
            schema:
              $ref: '#/components/schemas/User'
        description: Updated user object
        required: true

# An object to hold reusable parts that can be used across the definition
components:
  schemas:
    Email:
      description: User email address
      type: string
      format: test
      example: [email protected]
    User:
      type: object
      properties:
        username:
          description: User supplied username
          type: string
          minLength: 4
          example: John78
        firstName:
          description: User first name
          type: string
          minLength: 1
          example: John
        lastName:
          description: User last name
          type: string
          minLength: 1
          example: Smith
        email:
          $ref: '#/components/schemas/Email'
  headers:
    ExpiresAfter:
      description: date in UTC when token expires
      schema:
        type: string
        format: date-time
  # Security scheme definitions that can be used across the definition.
  securitySchemes:
    main_auth: # security definition name (you can name it as you want)
      # the following options are specific to oauth2 type
      type: oauth2 # authorization type, one of: oauth2, apiKey, http
      flows:
        implicit:
          authorizationUrl: 'http://example.com/api/oauth/dialog'
          scopes:
            'read:users': read users info
            'write:users': modify or remove users
    api_key:  # security definition name (you can name it as you want)
      type: apiKey 
      # The following options are specific to apiKey type
      in: header # Where API key will be passed: header or query
      name: api_key # API key parameter name
    basic_auth: # security definition name (you can name it as you want)
      type: http
      scheme: basic



테라포밍 실행:

terraform plan



terraform apply


API 'Example API'가 포함된 API Management가 성공적으로 생성되었습니다.



3 업데이트 API

The OpenAPI definition is updated with path '/echo'.

# This is an **example** API to demonstrate features of OpenAPI specification.
# It doesn't cover all OpenAPI features. For more full example check out: https://github.com/APIs-guru/petstore_extended

openapi: 3.0.1
info:
  version: '1.0.0' # Your API version
  # It can be any string but it is better to use semantic versioning: http://semver.org/
  # Warning: OpenAPI requires the version to be a string, but without quotation marks YAML can recognize it as a number.

  title: Example.com # Replace with your API title
  # Keep it simple. Don't add "API" or version at the end of the string.

  termsOfService: 'https://example.com/terms/' # [Optional] Replace with an URL to your ToS
  contact:
    email: [email protected] # [Optional] Replace with your contact email
    url: 'http://example.com/contact' # [Optional] Replace with link to your contact form
  license:
    name: Apache 2.0
    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
  x-logo:
    url: 'https://redocly.github.io/openapi-template/logo.png'

  # Describe your API here, you can use GFM (https://guides.github.com/features/mastering-markdown) here
  description: |
    This is an **example** API to demonstrate features of OpenAPI specification
    # Introduction
    This API definition is intended to to be a good starting point for describing your API in 
    [OpenAPI/Swagger format](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).
    It also demonstrates features of [create-openapi-repo](https://github.com/Redocly/create-openapi-repo) tool and 
    [Redoc](https://github.com/Redocly/Redoc) documentation engine. So beyond the standard OpenAPI syntax we use a few 
    [vendor extensions](https://github.com/Redocly/Redoc/blob/master/docs/redoc-vendor-extensions.md).
    # OpenAPI Specification
    The goal of The OpenAPI Specification is to define a standard, language-agnostic interface to REST APIs which
    allows both humans and computers to discover and understand the capabilities of the service without access to source
    code, documentation, or through network traffic inspection. When properly defined via OpenAPI, a consumer can 
    understand and interact with the remote service with a minimal amount of implementation logic. Similar to what
    interfaces have done for lower-level programming, OpenAPI removes the guesswork in calling the service.
externalDocs:
  description: Find out how to create a GitHub repo for your OpenAPI definition.
  url: 'https://github.com/Rebilly/generator-openapi-repo'

# A list of tags used by the definition with additional metadata.
# The order of the tags can be used to reflect on their order by the parsing tools.
tags:
  - name: Echo
    description: Example echo operations
  - name: User
    description: Operations about user
servers:
  - url: 'http://example.com/api/v1'
  - url: 'https://example.com/api/v1'

# Holds the relative paths to the individual endpoints. The path is appended to the
# basePath in order to construct the full URL. 
paths:
  '/users/{username}': # path parameter in curly braces

    # parameters list that are used with each operation for this path
    parameters:
      - name: pretty_print
        in: query
        description: Pretty print response
        schema:
          type: boolean
    get: # documentation for GET operation for this path
      tags:
        - User

      # summary is up to 120 symbold but we recommend to be shortest as possible
      summary: Get user by user name

      # you can use GFM in operation description too: https://guides.github.com/features/mastering-markdown
      description: |
        Some description of the operation. 
        You can use `markdown` here.

      # operationId should be unique across the whole specification
      operationId: getUserByName

      # list of parameters for the operation
      parameters:
        - name: username
          in: path
          description: The name that needs to be fetched
          required: true
          schema:
            type: string
        - name: with_email
          in: query
          description: Filter users without email
          schema:
            type: boolean

      # security schemas applied to this operation
      security:
        - main_auth:
            - 'read:users' # for oauth2 provide list of scopes here
        - api_key: []
      responses: # list of responses
        '200':
          description: Success
          content:
            application/json: # operation response mime type
              schema: # response schema can be specified for each response
                $ref: '#/components/schemas/User'
              example: # response example
                username: user1
                email: [email protected]
        '403':
          description: Forbidden
        '404':
          description: User not found
    # documentation for PUT operation for this path
    put:
      tags:
        - User
      summary: Updated user
      description: This can only be done by the logged in user.
      operationId: updateUser
      parameters:
        - name: username
          in: path
          description: The name that needs to be updated
          required: true
          schema:
            type: string
      security:
        - main_auth:
            - 'write:users'
      responses:
        '200':
          description: OK
        '400':
          description: Invalid user supplied
        '404':
          description: User not found
      # request body documentation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
          application/xml:
            schema:
              $ref: '#/components/schemas/User'
        description: Updated user object
        required: true
  /echo: # path parameter in curly braces
    post: # documentation for POST operation for this path
      tags:
        - Echo
      summary: Echo test
      description: Receive the exact message you've sent
      operationId: echo
      security:
        - api_key: []
        - basic_auth: []
      responses:
        '200':
          description: OK
          # document headers for this response
          headers:
            X-Rate-Limit: # Header name
              description: calls per hour allowed by the user
              schema: # Header schema
                type: integer
                format: int32
            X-Expires-After:
              $ref: '#/components/headers/ExpiresAfter'
          content:
            application/json:
              schema:
                type: string
              examples:
                response:
                  value: Hello world!
            application/xml:
              schema:
                type: string
            text/csv:
              schema:
                type: string
      requestBody:
        content:
          application/json:
            schema:
              type: string
              example: Hello world!
          application/xml:
            schema:
              type: string
              example: Hello world!
        description: Echo payload
        required: true

# An object to hold reusable parts that can be used across the definition
components:
  schemas:
    Email:
      description: User email address
      type: string
      format: test
      example: [email protected]
    User:
      type: object
      properties:
        username:
          description: User supplied username
          type: string
          minLength: 4
          example: John78
        firstName:
          description: User first name
          type: string
          minLength: 1
          example: John
        lastName:
          description: User last name
          type: string
          minLength: 1
          example: Smith
        email:
          $ref: '#/components/schemas/Email'
  headers:
    ExpiresAfter:
      description: date in UTC when token expires
      schema:
        type: string
        format: date-time
  # Security scheme definitions that can be used across the definition.
  securitySchemes:
    main_auth: # security definition name (you can name it as you want)
      # the following options are specific to oauth2 type
      type: oauth2 # authorization type, one of: oauth2, apiKey, http
      flows:
        implicit:
          authorizationUrl: 'http://example.com/api/oauth/dialog'
          scopes:
            'read:users': read users info
            'write:users': modify or remove users
    api_key:  # security definition name (you can name it as you want)
      type: apiKey 
      # The following options are specific to apiKey type
      in: header # Where API key will be passed: header or query
      name: api_key # API key parameter name
    basic_auth: # security definition name (you can name it as you want)
      type: http
      scheme: basic

Execute Terraform:

terraform plan

Plan: 0 to add, 1 to change, 0 to destroy.

terraform apply

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

After deployment, the changes to the OpenAPI definition were deployed and the added operation Echo test exists:

좋은 웹페이지 즐겨찾기