简体   繁体   中英

How to make API modules using Terraform?

I was creating fee module API and have created 12 APIs and here is my code.

# api fee/feebills/<school_key

resource "aws_api_gateway_rest_api" "api1"{
  name = "TerraformFeemoduleAPI"
  description = "Test API with terraform"
}

resource "aws_api_gateway_resource" "fee_resource_1"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebills_resource_1"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_1.id}"
  path_part   = "feebills"
}

resource "aws_api_gateway_resource" "feebills_school_key_resource_1"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebills_resource_1.id}"
  path_part   = "{school_key}"
}


resource "aws_api_gateway_method" "get_1"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_1.id}"
  http_method  = "GET"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}



# api /fee/feebills/student/<student_key>/payable


resource "aws_api_gateway_resource" "fee_resource_2"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebills_resource_2"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_2.id}"
  path_part   = "feebills"
}

resource "aws_api_gateway_resource" "feebills_student_resource_2"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebills_resource_2.id}"
  path_part   = "student"
}

resource "aws_api_gateway_resource" "feebills_student_key_resource_2"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebills_student_resource_2.id}"
  path_part   = "{student_key}"
}

resource "aws_api_gateway_resource" "feebills_payable_resource_2"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebills_student_key_resource_2.id}"
  path_part   = "payable"
}

resource "aws_api_gateway_method" "get_2"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_2.id}"
  http_method  = "GET"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}


#api /fee/feebills/student/<student_key>


resource "aws_api_gateway_resource" "fee_resource_3"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebills_resource_3"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_3.id}"
  path_part   = "feebills"
}

resource "aws_api_gateway_resource" "feebills_student_resource_3"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebills_resource_3.id}"
  path_part   = "student"
}

resource "aws_api_gateway_resource" "feebills_student_key_resource_3"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebills_student_resource_3.id}"
  path_part   = "{student_key}"
}


resource "aws_api_gateway_method" "get_3"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_3.id}"
  http_method  = "GET"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}



#api /fee/feebill/<fee_bill_key>


resource "aws_api_gateway_resource" "fee_resource_4"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebill_resource_4"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_4.id}"
  path_part   = "feebill"
}

resource "aws_api_gateway_resource" "feebill_fee_bill_key_resource_4"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_resource_4.id}"
  path_part   = "{fee_bill_key}"
}

resource "aws_api_gateway_method" "get_4"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_4.id}"
  http_method  = "GET"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}


#api /fee/feebill/generate


resource "aws_api_gateway_resource" "fee_resource_5"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebill_resource_5"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_5.id}"
  path_part   = "feebill"
}

resource "aws_api_gateway_resource" "feebill_generate_resource_5"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_resource_5.id}"
  path_part   = "generate"
}


resource "aws_api_gateway_method" "post_5"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_5.id}"
  http_method  = "POST"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}

#api /fee/feebill/paycustombills

resource "aws_api_gateway_resource" "fee_resource_6"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebill_resource_6"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_6.id}"
  path_part   = "feebill"
}

resource "aws_api_gateway_resource" "feebill_paycustombills_resource_6"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_resource_6.id}"
  path_part   = "paycustombills"
}



resource "aws_api_gateway_method" "post_6"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_6.id}"
  http_method  = "POST"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}

#api /fee/feebill/defer

resource "aws_api_gateway_resource" "fee_resource_7"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebill_resource_7"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_7.id}"
  path_part   = "feebill"
}

resource "aws_api_gateway_resource" "feebill_defer_resource_7"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_resource_7.id}"
  path_part   = "defer"
}


resource "aws_api_gateway_method" "post_7"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_7.id}"
  http_method  = "POST"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}

#api /fee/feebill/paybills


resource "aws_api_gateway_resource" "fee_resource_8"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebill_resource_8"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_8.id}"
  path_part   = "feebill"
}

resource "aws_api_gateway_resource" "feebill_paybills_resource_8"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_resource_8.id}"
  path_part   = "paybills"
}



resource "aws_api_gateway_method" "post_8"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_8.id}"
  http_method  = "POST"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}

#api /fee/feebill/undefer


resource "aws_api_gateway_resource" "fee_resource_9"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebill_resource_9"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_9.id}"
  path_part   = "feebill"
}

resource "aws_api_gateway_resource" "feebill_undefer_resource_9"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_resource_9.id}"
  path_part   = "undefer"
}


resource "aws_api_gateway_method" "post_9"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_9.id}"
  http_method  = "POST"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}

#api /fee/feebill/receipt/send


resource "aws_api_gateway_resource" "fee_resource_10"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebill_resource_10"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_10.id}"
  path_part   = "feebill"
}

resource "aws_api_gateway_resource" "feebill_receipt_resource_10"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_resource_10.id}"
  path_part   = "receipt"
}

resource "aws_api_gateway_resource" "feebill_send_resource_10"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_receipt_resource_10.id}"
  path_part   = "send"
}


resource "aws_api_gateway_method" "post_10"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_10.id}"
  http_method  = "POST"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}

#api /fee/feebill/cancel/receipt


resource "aws_api_gateway_resource" "fee_resource_11"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebill_resource_11"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_11.id}"
  path_part   = "feebill"
}

resource "aws_api_gateway_resource" "feebill_cancel_resource_11"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_resource_11.id}"
  path_part   = "cancel"
}

resource "aws_api_gateway_resource" "feebill_receipt_resource_11"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_cancel_resource_11.id}"
  path_part   = "receipt"
}


resource "aws_api_gateway_method" "post_11"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_11.id}"
  http_method  = "POST"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}

#api /fee/feebill/refundbills


resource "aws_api_gateway_resource" "fee_resource_12"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}


resource "aws_api_gateway_resource" "feebill_resource_12"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.fee_resource_12.id}"
  path_part   = "feebill"
}

resource "aws_api_gateway_resource" "feebill_refundbills_resource_12"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebill_resource_12.id}"
  path_part   = "refundbills"
}



resource "aws_api_gateway_method" "post_12"{
  rest_api_id  = "${aws_api_gateway_rest_api.api1.id}"
  resource_id  = "${aws_api_gateway_resource.fee_resource_12.id}"
  http_method  = "POST"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}

I have got an error like this

Error: Error creating API Gateway Resource: ConflictException: Another resource with the same parent already has this name: fee

with aws_api_gateway_resource.fee_resource_1, on FeemoduleAPI.tf line 8, in resource "aws_api_gateway_resource" "fee_resource_1": 8: resource "aws_api_gateway_resource" "fee_resource_1"{

Got this error for all the resources. Kindly looking for someone's skills to solve this. Thanks in advance.

The following two resource blocks from your example both seem to declare the same object:

resource "aws_api_gateway_resource" "fee_resource_1"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}
resource "aws_api_gateway_resource" "fee_resource_2"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_rest_api.api1.root_resource_id}"
  path_part   = "fee"
}

API gateway requires that path_part be unique for all resources that have the same parent_id .

To address this you'll need to remove the duplicate declarations and then make the different leaf resources all refer to the same parent. It seems like the "student" resource is the first point where the two URL paths diverge and so that is the one that would need to refer to the single shared feebills resource, like this:

resource "aws_api_gateway_resource" "feebills_student_resource_2"{
  rest_api_id = "${aws_api_gateway_rest_api.api1.id}"
  parent_id   = "${aws_api_gateway_resource.feebills_resource_1.id}"
  path_part   = "student"
}

Notice that parent_id now refers to feebills_resource_1 instead of feebills_resource_2 . You can then delete the fee_resource_2 and feebills_resource_2 resources altogether, and thus fix the duplication problem.


It seems like you are hoping to declare each path independently and have API gateway "just figure it out". The raw API gateway API isn't designed to work that way, but there is an alternative:

If you can describe your intended API structure using the OpenAPI specification (with some API Gateway specific extensions you can learn about in the API Gateway documentation) then you can reduce all of this to just a single aws_api_gateway_rest_api resource which sets the body argument :

resource "aws_api_gateway_rest_api" "example" {
  body = jsonencode({
    openapi = "3.0.1"
    info = {
      title   = "example"
      version = "1.0"
    }
    paths = {
      "/path1" = {
        get = {
          x-amazon-apigateway-integration = {
            httpMethod           = "GET"
            payloadFormatVersion = "1.0"
            type                 = "HTTP_PROXY"
            uri                  = "https://ip-ranges.amazonaws.com/ip-ranges.json"
          }
        }
      }
    }
  })

  name = "example"

  endpoint_configuration {
    types = ["REGIONAL"]
  }
}

(This is just the raw example copied from the AWS provider documentation at the time of writing. You'd need to adapt it to describe the API you actually want to define, by referring to the OpenAPI Specification and Amazon's own documentation .

OpenAPI is path-template-oriented rather than using hierarchical resource definitions, and so in this syntax you can separately define both fee/feebills/schools/<school_key> and fee/feebills/student/<student_key> and then the API Gateway service will automatically notice that both of these share the fee and feebills component and create the shared resource objects on your behalf.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM